[PATCH] usb: core: buffer: smallest buffer should start at ARCH_DMA_MINALIGN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



the following error pops up during "testusb -a -t 10"
| musb-hdrc musb-hdrc.1.auto: dma_pool_free buffer-128,	f134e000/be842000 (bad dma)
hcd_buffer_create() creates a few buffers, the smallest has 32 bytes of
size. ARCH_KMALLOC_MINALIGN is set to 64 bytes. This combo results in
hcd_buffer_alloc() returning memory which is 32bytes aligned and it
might by identified by buffer_offset() as another buffer. This means the
buffer which is on a 32byte boundary will not get freed, instead it
tries to free another buffer with the error message.

This patch fixes the issue by creating the smallest DMA buffer with the
size of ARCH_KMALLOC_MINALIGN. This will be either 32 or 64 bytes. If the
ARCH_KMALLOC_MINALIGN is 128 (currently powerpc64, mips ip32, x86 pentium
4) then it will create the first buffer with 128 bytes and will have only 3
buffers in total. There is a BUILD_BUG_ON() now in case someone has a
ARCH_KMALLOC_MINALIGN greater than 256 bytes.

Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/core/buffer.c | 5 +++++
 include/linux/usb/hcd.h   | 8 ++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 684ef70dc09d..a80d1ec8b1b0 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -26,7 +26,11 @@ static const size_t	pool_max[HCD_BUFFER_POOLS] = {
 	/* platforms without dma-friendly caches might need to
 	 * prevent cacheline sharing...
 	 */
+#if ARCH_KMALLOC_MINALIGN <= 32
 	32,
+#elif ARCH_KMALLOC_MINALIGN <= 64
+	64,
+#endif
 	128,
 	512,
 	PAGE_SIZE / 2
@@ -58,6 +62,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 	    !(hcd->driver->flags & HCD_LOCAL_MEM))
 		return 0;
 
+	BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN > 128);
 	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
 		size = pool_max[i];
 		if (!size)
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index cd96a2bc3388..1e2234ca448d 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -23,6 +23,7 @@
 
 #include <linux/rwsem.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define MAX_TOPO_LEVEL		6
 
@@ -171,8 +172,11 @@ struct usb_hcd {
 	struct usb_hcd		*shared_hcd;
 	struct usb_hcd		*primary_hcd;
 
-
-#define HCD_BUFFER_POOLS	4
+#if ARCH_KMALLOC_MINALIGN <= 64
+	#define HCD_BUFFER_POOLS	4
+#else
+	#define HCD_BUFFER_POOLS	3
+#endif
 	struct dma_pool		*pool[HCD_BUFFER_POOLS];
 
 	int			state;
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux