On Mon, 24 Nov 2014, Sebastian Andrzej Siewior wrote: > 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. Okay, this is a little awkward but not too bad. And I prefer it over the earlier proposal, even though the source code ends up a little bigger. > 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]; What about the ARCH_KMALLOC_MINALIGN <= 32 case? Alan Stern -- 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