USB: cdc-acm: fix possible deadlock with multiple openers
The lock must be dropped before usb_autopm_interface_put() is called Signed-off-by: Oliver Neukum <oliver@neukum.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
d7e18a9f2c
commit
2b626dc134
@ -553,7 +553,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|||||||
|
|
||||||
acm = acm_table[tty->index];
|
acm = acm_table[tty->index];
|
||||||
if (!acm || !acm->dev)
|
if (!acm || !acm->dev)
|
||||||
goto err_out;
|
goto out;
|
||||||
else
|
else
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
@ -569,8 +569,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|||||||
|
|
||||||
mutex_lock(&acm->mutex);
|
mutex_lock(&acm->mutex);
|
||||||
if (acm->port.count++) {
|
if (acm->port.count++) {
|
||||||
|
mutex_unlock(&acm->mutex);
|
||||||
usb_autopm_put_interface(acm->control);
|
usb_autopm_put_interface(acm->control);
|
||||||
goto done;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
acm->ctrlurb->dev = acm->dev;
|
acm->ctrlurb->dev = acm->dev;
|
||||||
@ -599,18 +600,18 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|||||||
set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
|
set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
|
||||||
rv = tty_port_block_til_ready(&acm->port, tty, filp);
|
rv = tty_port_block_til_ready(&acm->port, tty, filp);
|
||||||
tasklet_schedule(&acm->urb_task);
|
tasklet_schedule(&acm->urb_task);
|
||||||
done:
|
|
||||||
mutex_unlock(&acm->mutex);
|
mutex_unlock(&acm->mutex);
|
||||||
err_out:
|
out:
|
||||||
mutex_unlock(&open_mutex);
|
mutex_unlock(&open_mutex);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
full_bailout:
|
full_bailout:
|
||||||
usb_kill_urb(acm->ctrlurb);
|
usb_kill_urb(acm->ctrlurb);
|
||||||
bail_out:
|
bail_out:
|
||||||
usb_autopm_put_interface(acm->control);
|
|
||||||
acm->port.count--;
|
acm->port.count--;
|
||||||
mutex_unlock(&acm->mutex);
|
mutex_unlock(&acm->mutex);
|
||||||
|
usb_autopm_put_interface(acm->control);
|
||||||
early_bail:
|
early_bail:
|
||||||
mutex_unlock(&open_mutex);
|
mutex_unlock(&open_mutex);
|
||||||
tty_port_tty_set(&acm->port, NULL);
|
tty_port_tty_set(&acm->port, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user