________________________________________ From: Zhang, Qiang <qiang.zhang@xxxxxxxxxxxxx> Sent: Tuesday, 29 June 2021 11:32 To: gregkh@xxxxxxxxxxxxxxxxxxx; stern@xxxxxxxxxxxxxxxxxxx; dvyukov@xxxxxxxxxx Cc: paulmck@xxxxxxxxxx; dpenkler@xxxxxxxxx; guido.kiener@xxxxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx Hello Greg KH Have you reviewed this change? Thanks Qiang >Subject: [PATCH] USB: usbtmc: Fix RCU stall warning > >From: Zqiang <qiang.zhang@xxxxxxxxxxxxx> > >rcu: INFO: rcu_preempt self-detected stall on CPU >rcu: 1-...!: (2 ticks this GP) idle=d92/1/0x4000000000000000 > softirq=25390/25392 fqs=3 > (t=12164 jiffies g=31645 q=43226) >rcu: rcu_preempt kthread starved for 12162 jiffies! g31645 f0x0 > RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=0 >rcu: Unless rcu_preempt kthread gets sufficient CPU time, > OOM is now expected behavior. >rcu: RCU grace-period kthread stack dump: >task:rcu_preempt state:R running task > >In the case of system use dummy_hcd as usb controller, when the >usbtmc devices is disconnected, in usbtmc_interrupt(), if the urb >status is unknown, the urb will be resubmit, the urb may be insert >to dum_hcd->urbp_list again, this will cause the dummy_timer() not >to exit for a long time, beacause the dummy_timer() be called in >softirq and local_bh is disable, this not only causes the RCU reading >critical area to consume too much time but also makes the tasks in >the current CPU runq not run in time, and that triggered RCU stall. > >return directly when find the urb status is not zero to fix it. > >Reported-by: syzbot+e2eae5639e7203360018@xxxxxxxxxxxxxxxxxxxxxxxxx >Signed-off-by: Zqiang <qiang.zhang@xxxxxxxxxxxxx> >--- > drivers/usb/class/usbtmc.c | 12 ++---------- > 1 file changed, 2 insertions(+), 10 deletions(-) > >diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c >index 74d5a9c5238a..c4e1a88fff78 100644 >--- a/drivers/usb/class/usbtmc.c >+++ b/drivers/usb/class/usbtmc.c >@@ -2324,17 +2324,9 @@ static void usbtmc_interrupt(struct urb *urb) > dev_err(dev, "overflow with length %d, actual length is %d\n", > data->iin_wMaxPacketSize, urb->actual_length); > fallthrough; >- case -ECONNRESET: >- case -ENOENT: >- case -ESHUTDOWN: >- case -EILSEQ: >- case -ETIME: >- case -EPIPE: >- /* urb terminated, clean up */ >- dev_dbg(dev, "urb terminated, status: %d\n", status); >- return; > default: >- dev_err(dev, "unknown status received: %d\n", status); >+ dev_err(dev, "error status received: %d\n", status); >+ return; > } > exit: > rv = usb_submit_urb(urb, GFP_ATOMIC); >-- >2.17.1