On Thu, Jul 07, 2011 at 01:53:46PM +0200, Daniel Mack wrote:
So my approach was to force the driver using memory that is DMA coherent, which leads to 32bit addressable memory if the device's DMA_MASK is set accordingly. Other drivers do the same, and the patch for doing this is found here: http://lkml.org/lkml/2010/5/7/61. Users that see the bug all report that this patch fixes their problem with my driver. However, it was rejected back then as other developers said it was fixing the wrong end, and that the driver doesn't necessarily need coherent memory.
I think this is a valid approach, and since it avoids using bounce buffers it is potentially better wrt performance. BTW, usb_alloc_coherent() doc comment says you need to set the URB_NO_TRANSFER_DMA_MAP flag, which your patch fails to do.
Takashi recently posted a patch to the bugzilla entry which uses a different approach: it introduces a function to determine suitable GFP flags for USB devices, and passes __DMA32 to kmalloc() eventually. However, using this flags directly with the SLUB allocator is illegal and causes a BUG() in mm/slub.c, cache_grow().
from gfp.h: /* Do not use these with a slab allocator */ #define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)
I think it means you can only use __GFP_DMA32 for get_free_pages(), not for kmalloc().
- Find out exactly why these machines fail to install bounce buffers
or set up their IOMMU correctly
I think this needs to be done.
Johannes