Commit c42b4e65 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Revert "n_gsm: race between ld close and gsmtty open"

This reverts commit c284ee2c.  Turns out
the locking was incorrect.
Reported-by: default avatarFengguang Wu <fengguang.wu@intel.com>
Cc: Chao Bi <chao.bi@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aebf0453
...@@ -2054,11 +2054,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) ...@@ -2054,11 +2054,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm)
dlci->state == DLCI_CLOSED); dlci->state == DLCI_CLOSED);
} }
/* Free up any link layer users */ /* Free up any link layer users */
spin_lock(&gsm->lock);
for (i = 0; i < NUM_DLCI; i++) for (i = 0; i < NUM_DLCI; i++)
if (gsm->dlci[i]) if (gsm->dlci[i])
gsm_dlci_release(gsm->dlci[i]); gsm_dlci_release(gsm->dlci[i]);
spin_unlock(&gsm->lock);
/* Now wipe the queues */ /* Now wipe the queues */
list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
kfree(txq); kfree(txq);
...@@ -2911,33 +2909,23 @@ static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) ...@@ -2911,33 +2909,23 @@ static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
This is ok from a locking This is ok from a locking
perspective as we don't have to worry about this perspective as we don't have to worry about this
if DLCI0 is lost */ if DLCI0 is lost */
spin_lock(&gsm->lock); if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN)
if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) {
spin_unlock(&gsm->lock);
return -EL2NSYNC; return -EL2NSYNC;
}
dlci = gsm->dlci[line]; dlci = gsm->dlci[line];
if (dlci == NULL) { if (dlci == NULL) {
alloc = true; alloc = true;
dlci = gsm_dlci_alloc(gsm, line); dlci = gsm_dlci_alloc(gsm, line);
} }
if (dlci == NULL) { if (dlci == NULL)
spin_unlock(&gsm->lock);
return -ENOMEM; return -ENOMEM;
}
ret = tty_port_install(&dlci->port, driver, tty); ret = tty_port_install(&dlci->port, driver, tty);
if (ret) { if (ret) {
if (alloc) if (alloc)
dlci_put(dlci); dlci_put(dlci);
spin_unlock(&gsm->lock);
return ret; return ret;
} }
dlci_get(dlci);
dlci_get(gsm->dlci[0]);
mux_get(gsm);
tty->driver_data = dlci; tty->driver_data = dlci;
spin_unlock(&gsm->lock);
return 0; return 0;
} }
...@@ -2948,6 +2936,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) ...@@ -2948,6 +2936,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
struct tty_port *port = &dlci->port; struct tty_port *port = &dlci->port;
port->count++; port->count++;
dlci_get(dlci);
dlci_get(dlci->gsm->dlci[0]);
mux_get(dlci->gsm);
tty_port_tty_set(port, tty); tty_port_tty_set(port, tty);
dlci->modem_rx = 0; dlci->modem_rx = 0;
...@@ -2974,7 +2965,7 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) ...@@ -2974,7 +2965,7 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&dlci->mutex); mutex_unlock(&dlci->mutex);
gsm = dlci->gsm; gsm = dlci->gsm;
if (tty_port_close_start(&dlci->port, tty, filp) == 0) if (tty_port_close_start(&dlci->port, tty, filp) == 0)
return; goto out;
gsm_dlci_begin_close(dlci); gsm_dlci_begin_close(dlci);
if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
if (C_HUPCL(tty)) if (C_HUPCL(tty))
...@@ -2982,7 +2973,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) ...@@ -2982,7 +2973,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
} }
tty_port_close_end(&dlci->port, tty); tty_port_close_end(&dlci->port, tty);
tty_port_tty_set(&dlci->port, NULL); tty_port_tty_set(&dlci->port, NULL);
return; out:
dlci_put(dlci);
dlci_put(gsm->dlci[0]);
mux_put(gsm);
} }
static void gsmtty_hangup(struct tty_struct *tty) static void gsmtty_hangup(struct tty_struct *tty)
...@@ -3159,16 +3153,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) ...@@ -3159,16 +3153,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
return gsmtty_modem_update(dlci, encode); return gsmtty_modem_update(dlci, encode);
} }
static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
struct gsm_mux *gsm = dlci->gsm;
dlci_put(dlci);
dlci_put(gsm->dlci[0]);
mux_put(gsm);
driver->ttys[tty->index] = NULL;
}
/* Virtual ttys for the demux */ /* Virtual ttys for the demux */
static const struct tty_operations gsmtty_ops = { static const struct tty_operations gsmtty_ops = {
...@@ -3188,7 +3172,6 @@ static const struct tty_operations gsmtty_ops = { ...@@ -3188,7 +3172,6 @@ static const struct tty_operations gsmtty_ops = {
.tiocmget = gsmtty_tiocmget, .tiocmget = gsmtty_tiocmget,
.tiocmset = gsmtty_tiocmset, .tiocmset = gsmtty_tiocmset,
.break_ctl = gsmtty_break_ctl, .break_ctl = gsmtty_break_ctl,
.remove = gsmtty_remove,
}; };
......
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