summaryrefslogtreecommitdiff
path: root/drivers/usb/mon/mon_bin.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/mon/mon_bin.c')
-rw-r--r--drivers/usb/mon/mon_bin.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 094e812e9e69..e713fc5964b1 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -68,18 +68,20 @@
* The magic limit was calculated so that it allows the monitoring
* application to pick data once in two ticks. This way, another application,
* which presumably drives the bus, gets to hog CPU, yet we collect our data.
- * If HZ is 100, a 480 mbit/s bus drives 614 KB every jiffy. USB has an
- * enormous overhead built into the bus protocol, so we need about 1000 KB.
+ *
+ * Originally, for a 480 Mbit/s bus this required a buffer of about 1 MB. For
+ * modern 20 Gbps buses, this value increases to over 50 MB. The maximum
+ * buffer size is set to 64 MiB to accommodate this.
*
* This is still too much for most cases, where we just snoop a few
* descriptor fetches for enumeration. So, the default is a "reasonable"
- * amount for systems with HZ=250 and incomplete bus saturation.
+ * amount for typical, low-throughput use cases.
*
* XXX What about multi-megabyte URBs which take minutes to transfer?
*/
-#define BUFF_MAX CHUNK_ALIGN(1200*1024)
-#define BUFF_DFL CHUNK_ALIGN(300*1024)
-#define BUFF_MIN CHUNK_ALIGN(8*1024)
+#define BUFF_MAX CHUNK_ALIGN(64*1024*1024)
+#define BUFF_DFL CHUNK_ALIGN(300*1024)
+#define BUFF_MIN CHUNK_ALIGN(8*1024)
/*
* The per-event API header (2 per URB).
@@ -213,7 +215,10 @@ static unsigned char xfer_to_pipe[4] = {
PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
};
-static struct class *mon_bin_class;
+static const struct class mon_bin_class = {
+ .name = "usbmon",
+};
+
static dev_t mon_bin_dev0;
static struct cdev mon_bin_cdev;
@@ -820,7 +825,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
ep = MON_OFF2HDR(rp, rp->b_out);
if (rp->b_read < hdrbytes) {
- step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read));
+ step_len = min_t(size_t, nbytes, hdrbytes - rp->b_read);
ptr = ((char *)ep) + rp->b_read;
if (step_len && copy_to_user(buf, ptr, step_len)) {
mutex_unlock(&rp->fetch_lock);
@@ -1247,14 +1252,19 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf)
struct mon_reader_bin *rp = vmf->vma->vm_private_data;
unsigned long offset, chunk_idx;
struct page *pageptr;
+ unsigned long flags;
+ spin_lock_irqsave(&rp->b_lock, flags);
offset = vmf->pgoff << PAGE_SHIFT;
- if (offset >= rp->b_size)
+ if (offset >= rp->b_size) {
+ spin_unlock_irqrestore(&rp->b_lock, flags);
return VM_FAULT_SIGBUS;
+ }
chunk_idx = offset / CHUNK_SIZE;
pageptr = rp->b_vec[chunk_idx].pg;
get_page(pageptr);
vmf->page = pageptr;
+ spin_unlock_irqrestore(&rp->b_lock, flags);
return 0;
}
@@ -1272,8 +1282,7 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
if (vma->vm_flags & VM_WRITE)
return -EPERM;
- vma->vm_flags &= ~VM_MAYWRITE;
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vm_flags_mod(vma, VM_DONTEXPAND | VM_DONTDUMP, VM_MAYWRITE);
vma->vm_private_data = filp->private_data;
mon_bin_vma_open(vma);
return 0;
@@ -1282,7 +1291,6 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
static const struct file_operations mon_fops_binary = {
.owner = THIS_MODULE,
.open = mon_bin_open,
- .llseek = no_llseek,
.read = mon_bin_read,
/* .write = mon_text_write, */
.poll = mon_bin_poll,
@@ -1361,7 +1369,7 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
if (minor >= MON_BIN_MAX_MINOR)
return 0;
- dev = device_create(mon_bin_class, ubus ? ubus->controller : NULL,
+ dev = device_create(&mon_bin_class, ubus ? ubus->controller : NULL,
MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
"usbmon%d", minor);
if (IS_ERR(dev))
@@ -1373,18 +1381,16 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
void mon_bin_del(struct mon_bus *mbus)
{
- device_destroy(mon_bin_class, mbus->classdev->devt);
+ device_destroy(&mon_bin_class, mbus->classdev->devt);
}
int __init mon_bin_init(void)
{
int rc;
- mon_bin_class = class_create(THIS_MODULE, "usbmon");
- if (IS_ERR(mon_bin_class)) {
- rc = PTR_ERR(mon_bin_class);
+ rc = class_register(&mon_bin_class);
+ if (rc)
goto err_class;
- }
rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon");
if (rc < 0)
@@ -1402,7 +1408,7 @@ int __init mon_bin_init(void)
err_add:
unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
err_dev:
- class_destroy(mon_bin_class);
+ class_unregister(&mon_bin_class);
err_class:
return rc;
}
@@ -1411,5 +1417,5 @@ void mon_bin_exit(void)
{
cdev_del(&mon_bin_cdev);
unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
- class_destroy(mon_bin_class);
+ class_unregister(&mon_bin_class);
}