On Wed, Apr 07, 2010 at 10:59:47AM -0400, Alan Stern wrote:
On Wed, 7 Apr 2010, Daniel Mack wrote:
Depending on the condition of the memory management, things might work or not, and especially right after a reboot, there's a better chance to get lower memory.
The fix is to use usb_buffer_alloc() for that purpose which ensures memory that is suitable for DMA. And on x86_64, this also means that the upper 32 bits of the address returned are all 0's.
That is not a good fix. usb_buffer_alloc() provides coherent memory, which is not what we want. I believe the correct fix is to specify the GFP_DMA32 flag in the kzalloc() call.
Of course, some EHCI hardware _is_ capable of using 64-bit addresses. But not all, and other controller types aren't. In principle we could create a new allocation routine, which would take a pointer to the USB bus as an additional argument and use it to decide whether the memory needs to lie below 4 GB. I'm not sure adding this extra complexity would be worthwhile.
Well, I thought this is exactly what the usb_buffer_alloc() abstraction functions are there for. We already pass a pointer to a struct usb_device, so the routine knows which host controller it operates on. So we can safely dispatch all the magic inside this function, no?
If not, I would rather introduce a new function than adding GFP_ flags to all existing drivers.
I vote for a clean solution, a fixup of existing implementations and a clear note about how to allocate buffers for USB drivers. I believe faulty allocations of this kind can explain quite a lot of problems on x86_64 machines.
If what I've stated is true, there are quite some more drivers affected by this issue.
Practically every USB driver, I should think. And maybe a lot of non-USB drivers too.
I found many such problems in drivers/media/{dvb,video}, drivers/usb/serial, sound/usb and even in the USB core. If we agree on how to fix that nicely, I can take some of them.
Daniel