From 0290cc9f044a4d24d9a64e81761ac84498dc9d73 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:22 -0500 Subject: USB: limit usbfs snooping of URB contents The usbfs_snoop facility can be very useful for debugging problems involving usbfs. However, it always prints out the entire contents of every URB. When dealing with large quantities of data, this can be less than helpful. This patch ameliorates the situation by adding a module parameter to usbcore for controlling the maximum number of bytes to print when snooping an URB. This makes debugging much easier. For backward compatibility, the default value is set unreasonably high. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/usb/core/devio.c') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 38ae877c46e3..3d41faf6e607 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -100,6 +100,11 @@ static bool usbfs_snoop; module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); +static unsigned usbfs_snoop_max = 65536; +module_param(usbfs_snoop_max, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(usbfs_snoop_max, + "maximum number of bytes to print while snooping"); + #define snoop(dev, format, arg...) \ do { \ if (usbfs_snoop) \ @@ -392,6 +397,7 @@ static void snoop_urb(struct usb_device *udev, ep, t, d, length, timeout_or_status); } + data_len = min(data_len, usbfs_snoop_max); if (data && data_len > 0) { print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, data, data_len, 1); @@ -402,7 +408,8 @@ static void snoop_urb_data(struct urb *urb, unsigned len) { int i, size; - if (!usbfs_snoop) + len = min(len, usbfs_snoop_max); + if (!usbfs_snoop || len == 0) return; if (urb->num_sgs == 0) { -- cgit v1.2.3 From a016a816bb96088ce4cd0ec890e256e4a63dfb47 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 20 Nov 2015 13:53:35 -0500 Subject: USB: add usbfs snooping for REAP and DISCARD This patch improves the usbfs_snoop debugging facility by adding messages for a couple of significant events which, up to now, have not been logged. The events are reaping and discarding (i.e., cancelling) an URB. The debugging messages include the userspace address of the URB being reaped or discarded. The reaping messages have to be added in four places, in order to handle blocking and non-blocking reaps in both normal and 32-bit compatibility mode. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/usb/core/devio.c') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3d41faf6e607..e9f0de3e06db 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1716,8 +1716,12 @@ static struct async *reap_as(struct usb_dev_state *ps) static int proc_reapurb(struct usb_dev_state *ps, void __user *arg) { struct async *as = reap_as(ps); + if (as) { - int retval = processcompl(as, (void __user * __user *)arg); + int retval; + + snoop(&ps->dev->dev, "reap %p\n", as->userurb); + retval = processcompl(as, (void __user * __user *)arg); free_async(as); return retval; } @@ -1733,6 +1737,7 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) as = async_getcompleted(ps); if (as) { + snoop(&ps->dev->dev, "reap %p\n", as->userurb); retval = processcompl(as, (void __user * __user *)arg); free_async(as); } else { @@ -1859,8 +1864,12 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg) { struct async *as = reap_as(ps); + if (as) { - int retval = processcompl_compat(as, (void __user * __user *)arg); + int retval; + + snoop(&ps->dev->dev, "reap %p\n", as->userurb); + retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); return retval; } @@ -1876,6 +1885,7 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar as = async_getcompleted(ps); if (as) { + snoop(&ps->dev->dev, "reap %p\n", as->userurb); retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); } else { @@ -2280,7 +2290,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, #endif case USBDEVFS_DISCARDURB: - snoop(&dev->dev, "%s: DISCARDURB\n", __func__); + snoop(&dev->dev, "%s: DISCARDURB %p\n", __func__, p); ret = proc_unlinkurb(ps, p); break; -- cgit v1.2.3