Commit 0afccd76 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

cdc-acm: close race betrween suspend() and acm_softint

Suspend increments a counter, then kills the URBs,
then kills the scheduled work. The scheduled work, however,
may reschedule the URBs. Fix this by having the work
check the counter.
Signed-off-by: default avatarOliver Neukum <oneukum@suse.com>
Cc: stable <stable@vger.kernel.org>
Tested-by: default avatarJonas Karlsson <jonas.karlsson@actia.se>
Link: https://lore.kernel.org/r/20200415151358.32664-1-oneukum@suse.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f6cc6093
...@@ -557,14 +557,14 @@ static void acm_softint(struct work_struct *work) ...@@ -557,14 +557,14 @@ static void acm_softint(struct work_struct *work)
struct acm *acm = container_of(work, struct acm, work); struct acm *acm = container_of(work, struct acm, work);
if (test_bit(EVENT_RX_STALL, &acm->flags)) { if (test_bit(EVENT_RX_STALL, &acm->flags)) {
if (!(usb_autopm_get_interface(acm->data))) { smp_mb(); /* against acm_suspend() */
if (!acm->susp_count) {
for (i = 0; i < acm->rx_buflimit; i++) for (i = 0; i < acm->rx_buflimit; i++)
usb_kill_urb(acm->read_urbs[i]); usb_kill_urb(acm->read_urbs[i]);
usb_clear_halt(acm->dev, acm->in); usb_clear_halt(acm->dev, acm->in);
acm_submit_read_urbs(acm, GFP_KERNEL); acm_submit_read_urbs(acm, GFP_KERNEL);
usb_autopm_put_interface(acm->data); clear_bit(EVENT_RX_STALL, &acm->flags);
} }
clear_bit(EVENT_RX_STALL, &acm->flags);
} }
if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags)) if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment