summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Ryazanov <ryazanov.s.a@gmail.com>2022-05-01 20:58:28 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-05-18 09:15:43 +0200
commit90bcb9afaeaa7943dafe4e7ad6c01ba6dddf8b08 (patch)
tree43a3e79a839e359b9c269be318c43210f00fd2dd
parent0e47cde8720a4fe931d76efb07a169ce1159e587 (diff)
usb: cdc-wdm: fix reading stuck on device close
commit 01e01f5c89773c600a9f0b32c888de0146066c3a upstream. cdc-wdm tracks whether a response reading request is in-progress and blocks the next request from being sent until the previous request is completed. As soon as last user closes the cdc-wdm device file, the driver cancels any ongoing requests, resets the pending response counter, but leaves the response reading in-progress flag (WDM_RESPONDING) untouched. So if the user closes the device file during the response receive request is being performed, no more data will be obtained from the modem. The request will be cancelled, effectively preventing the WDM_RESPONDING flag from being reseted. Keeping the flag set will prevent a new response receive request from being sent, permanently blocking the read path. The read path will staying blocked until the module will be reloaded or till the modem will be re-attached. This stuck has been observed with a Huawei E3372 modem attached to an OpenWrt router and using the comgt utility to set up a network connection. Fix this issue by clearing the WDM_RESPONDING flag on the device file close. Without this fix, the device reading stuck can be easily reproduced in a few connection establishing attempts. With this fix, a load test for modem connection re-establishing worked for several hours without any issues. Fixes: 922a5eadd5a3 ("usb: cdc-wdm: Fix race between autosuspend and reading from the device") Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> Cc: stable <stable@vger.kernel.org> Acked-by: Oliver Neukum <oneukum@suse.com> Link: https://lore.kernel.org/r/20220501175828.8185-1-ryazanov.s.a@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/class/cdc-wdm.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index f9d39c993f2f..fb41efd6b892 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -744,6 +744,7 @@ static int wdm_release(struct inode *inode, struct file *file)
kill_urbs(desc);
spin_lock_irq(&desc->iuspin);
desc->resp_count = 0;
+ clear_bit(WDM_RESPONDING, &desc->flags);
spin_unlock_irq(&desc->iuspin);
desc->manage_power(desc->intf, 0);
} else {