Patch "USB: Increase usbfs transfer limit" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
USB: Increase usbfs transfer limit
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-increase-usbfs-transfer-limit.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
1129d270cbfbb7e2b1ec3dede4a13930bdd10e41Mon Sep 17 00:00:00 2001
From: Mateusz Berezecki <[email protected]>
Date: Wed, 21 Dec 2016 09:19:14 -0800
Subject: USB: Increase usbfs transfer limit
From: Mateusz Berezecki <[email protected]>
commit 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 upstream.
Promote a variable keeping track of USB transfer memory usage to a wider data type and allow for higher bandwidth transfers from a large number of USB devices connected to a single host.
--- drivers/usb/core/devio.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-)
drivers/usb/core/devio.c +16 -27
@@ -134,42 +134,35 @@ enum snoop_when {#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)/* Limit on the total amount of memory we can allocate for transfers */ -static unsigned usbfs_memory_mb =16 ; +static u32 usbfs_memory_mb =16 ;module_param (usbfs_memory_mb, uint,0644 );MODULE_PARM_DESC (usbfs_memory_mb,"maximum MB allowed for usbfs buffers (0 = no limit)" ); -/* Hard limit, necessary to avoid arithmetic overflow */ -#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000) - -static atomic_t usbfs_memory_usage;/* Total memory currently allocated */ +static atomic64_t usbfs_memory_usage;/* Total memory currently allocated */ /* Check whether it's okay to allocate more memory for a transfer */ -static int usbfs_increase_memory_usage (unsigned amount) +static int usbfs_increase_memory_usage (u64 amount) { -unsigned lim; +u64 lim; -/* -* Convert usbfs_memory_mb to bytes, avoiding overflows. -* 0 means use the hard limit (effectively unlimited). -*/ lim =ACCESS_ONCE (usbfs_memory_mb); -if (lim ==0 || lim > (USBFS_XFER_MAX >>20 )) - lim =USBFS_XFER_MAX ; -else - lim <<=20 ; + lim <<=20 ; -atomic_add (amount, &usbfs_memory_usage); -if (atomic_read (&usbfs_memory_usage) <= lim) -return 0 ; -atomic_sub (amount, &usbfs_memory_usage); -return -ENOMEM ; +atomic64_add (amount, &usbfs_memory_usage); + +if (lim >0 &&atomic64_read (&usbfs_memory_usage) > lim) { +atomic64_sub (amount, &usbfs_memory_usage); +return -ENOMEM ; + } + +return 0 ; }/* Memory for a transfer is being deallocated */ -static void usbfs_decrease_memory_usage (unsigned amount) +static void usbfs_decrease_memory_usage (u64 amount) { -atomic_sub (amount, &usbfs_memory_usage); +atomic64_sub (amount, &usbfs_memory_usage); }static int connected (struct usb_dev_state *ps)
@@ -1191,7 +1184,7 @@ static int proc_bulk(struct usb_dev_statif (!usb_maxpacket (dev, pipe, !(bulk.ep &USB_DIR_IN )))return -EINVAL ; len1 = bulk.len; -if (len1 >=USBFS_XFER_MAX ) +if (len1 >= (INT_MAX -sizeof (struct urb )))return -EINVAL ; ret =usbfs_increase_memory_usage (len1 +sizeof (struct urb ));if (ret)
@@ -1584,10 +1577,6 @@ static int proc_do_submiturb(struct usb_return -EINVAL ; } -if (uurb->buffer_length >=USBFS_XFER_MAX ) { - ret = -EINVAL ; - goto error; - }if (uurb->buffer_length >0 && !access_ok (is_in ?VERIFY_WRITE :VERIFY_READ , uurb->buffer, uurb->buffer_length)) {
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/usb-increase-usbfs-transfer-limit.patch