On Mon, Jan 8, 2018 at 11:15 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > > Both dwc2_hsotg and ehci-hcd use the tasklets embedded in the > giveback_urb_bh member of struct usb_hcd. See usb_hcd_giveback_urb() > in drivers/usb/core/hcd.c; the calls are > > else if (high_prio_bh) > tasklet_hi_schedule(&bh->bh); > else > tasklet_schedule(&bh->bh); > > As it turns out, high_prio_bh gets set for interrupt and isochronous > URBs but not for bulk and control URBs. The DVB driver in question > uses bulk transfers. Ok, so we could try out something like the appended? NOTE! I have not tested this at all. It LooksObvious(tm), but... Linus
kernel/softirq.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/softirq.c b/kernel/softirq.c index 2f5e87f1bae2..97b080956fea 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -79,12 +79,16 @@ static void wakeup_softirqd(void) /* * If ksoftirqd is scheduled, we do not want to process pending softirqs - * right now. Let ksoftirqd handle this at its own rate, to get fairness. + * right now. Let ksoftirqd handle this at its own rate, to get fairness, + * unless we're doing some of the synchronous softirqs. */ -static bool ksoftirqd_running(void) +#define SOFTIRQ_NOW_MASK ((1 << HI_SOFTIRQ) | (1 << TASKLET_SOFTIRQ)) +static bool ksoftirqd_running(unsigned long pending) { struct task_struct *tsk = __this_cpu_read(ksoftirqd); + if (pending & SOFTIRQ_NOW_MASK) + return false; return tsk && (tsk->state == TASK_RUNNING); } @@ -325,7 +329,7 @@ asmlinkage __visible void do_softirq(void) pending = local_softirq_pending(); - if (pending && !ksoftirqd_running()) + if (pending && !ksoftirqd_running(pending)) do_softirq_own_stack(); local_irq_restore(flags); @@ -352,7 +356,7 @@ void irq_enter(void) static inline void invoke_softirq(void) { - if (ksoftirqd_running()) + if (ksoftirqd_running(local_softirq_pending())) return; if (!force_irqthreads) {