Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+10 −27
Original line number Diff line number Diff line
@@ -2054,11 +2054,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm)
					dlci->state == DLCI_CLOSED);
	}
	/* Free up any link layer users */
	spin_lock(&gsm->lock);
	for (i = 0; i < NUM_DLCI; i++)
		if (gsm->dlci[i])
			gsm_dlci_release(gsm->dlci[i]);
	spin_unlock(&gsm->lock);
	/* Now wipe the queues */
	list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
		kfree(txq);
@@ -2911,33 +2909,23 @@ static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
	This is ok from a locking
	perspective as we don't have to worry about this
	if DLCI0 is lost */
	spin_lock(&gsm->lock);
	if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) {
		spin_unlock(&gsm->lock);
	if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN)
		return -EL2NSYNC;
	}
	dlci = gsm->dlci[line];
	if (dlci == NULL) {
		alloc = true;
		dlci = gsm_dlci_alloc(gsm, line);
	}
	if (dlci == NULL) {
		spin_unlock(&gsm->lock);
	if (dlci == NULL)
		return -ENOMEM;
	}
	ret = tty_port_install(&dlci->port, driver, tty);
	if (ret) {
		if (alloc)
			dlci_put(dlci);
		spin_unlock(&gsm->lock);
		return ret;
	}

	dlci_get(dlci);
	dlci_get(gsm->dlci[0]);
	mux_get(gsm);
	tty->driver_data = dlci;
	spin_unlock(&gsm->lock);

	return 0;
}
@@ -2948,6 +2936,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
	struct tty_port *port = &dlci->port;

	port->count++;
	dlci_get(dlci);
	dlci_get(dlci->gsm->dlci[0]);
	mux_get(dlci->gsm);
	tty_port_tty_set(port, tty);

	dlci->modem_rx = 0;
@@ -2974,7 +2965,7 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
	mutex_unlock(&dlci->mutex);
	gsm = dlci->gsm;
	if (tty_port_close_start(&dlci->port, tty, filp) == 0)
		return;
		goto out;
	gsm_dlci_begin_close(dlci);
	if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
		if (C_HUPCL(tty))
@@ -2982,7 +2973,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
	}
	tty_port_close_end(&dlci->port, tty);
	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)
@@ -3159,16 +3153,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
	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 */
static const struct tty_operations gsmtty_ops = {
@@ -3188,7 +3172,6 @@ static const struct tty_operations gsmtty_ops = {
	.tiocmget		= gsmtty_tiocmget,
	.tiocmset		= gsmtty_tiocmset,
	.break_ctl		= gsmtty_break_ctl,
	.remove			= gsmtty_remove,
};