• M
    USB: HCD: support giveback of URB in tasklet context · 94dfd7ed
    Ming Lei 提交于
    This patch implements the mechanism of giveback of URB in
    tasklet context, so that hardware interrupt handling time for
    usb host controller can be saved much, and HCD interrupt handling
    can be simplified.
    
    Motivations:
    
    1), on some arch(such as ARM), DMA mapping/unmapping is a bit
    time-consuming, for example: when accessing usb mass storage
    via EHCI on pandaboard, the common length of transfer buffer is 120KB,
    the time consumed on DMA unmapping may reach hundreds of microseconds;
    even on A15 based box, the time is still about scores of microseconds
    
    2), on some arch, reading DMA coherent memoery is very time-consuming,
    the most common example is usb video class driver[1]
    
    3), driver's complete() callback may do much things which is driver
    specific, so the time is consumed unnecessarily in hardware irq context.
    
    4), running driver's complete() callback in hardware irq context causes
    that host controller driver has to release its lock in interrupt handler,
    so reacquiring the lock after return may busy wait a while and increase
    interrupt handling time. More seriously, releasing the HCD lock makes
    HCD becoming quite complicated to deal with introduced races.
    
    So the patch proposes to run giveback of URB in tasklet context, then
    time consumed in HCD irq handling doesn't depend on drivers' complete and
    DMA mapping/unmapping any more, also we can simplify HCD since the HCD
    lock isn't needed to be released during irq handling.
    
    The patch should be reasonable and doable:
    
    1), for drivers, they don't care if the complete() is called in hard irq
    context or softirq context
    
    2), the biggest change is the situation in which usb_submit_urb() is called
    in complete() callback, so the introduced tasklet schedule delay might be a
    con, but it shouldn't be a big deal:
    
    	- control/bulk asynchronous transfer isn't sensitive to schedule
    	  delay
    
    	- the patch schedules giveback of periodic URBs using
    	  tasklet_hi_schedule, so the introduced delay should be very
    	  small
    
    	- for ISOC transfer, generally, drivers submit several URBs
    	  concurrently to avoid interrupt delay, so it is OK with the
    	  little schedule delay.
    
    	- for interrupt transfer, generally, drivers only submit one URB
    	  at the same time, but interrupt transfer is often used in event
    	  report, polling, ... situations, and a little delay should be OK.
    
    Considered that HCDs may optimize on submitting URB in complete(), the
    patch may cause the optimization not working, so introduces one flag to mark
    if the HCD supports to run giveback URB in tasklet context. When all HCDs
    are ready, the flag can be removed.
    
    [1], http://marc.info/?t=136438111600010&r=1&w=2
    
    Cc: Oliver Neukum <oliver@neukum.org>
    Acked-by: NAlan Stern <stern@rowland.harvard.edu>
    Signed-off-by: NMing Lei <ming.lei@canonical.com>
    Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    94dfd7ed
hcd.h 24.2 KB