summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-10-10 22:00:56 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-18 06:11:29 +0200
commitaba24888d9af19e0bd1c7e7344fd27841611d7a8 (patch)
tree8a463e798166f2a6938687b3b2c9b32dbf385f1e /drivers
parenttty: r3964: Use tty->read_wait waitqueue (diff)
downloadlinux-aba24888d9af19e0bd1c7e7344fd27841611d7a8.tar.xz
linux-aba24888d9af19e0bd1c7e7344fd27841611d7a8.zip
tty: r3964: Replace/remove bogus tty lock use
The tty lock is strictly for serializing tty lifetime events (open/close/hangup), and not for line discipline serialization. The tty core already provides serialization of concurrent writes to the same tty, and line discipline lifetime management (by ldisc references), so pinning the tty via tty_lock() is unnecessary and counter-productive; remove tty lock use. However, the line discipline is responsible for serializing reads (if required by the line discipline); add read_lock mutex to serialize calls of r3964_read(). Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/n_r3964.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
index 6fdef921cdb7..345111467b85 100644
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -978,6 +978,7 @@ static int r3964_open(struct tty_struct *tty)
}
spin_lock_init(&pInfo->lock);
+ mutex_init(&pInfo->read_lock);
pInfo->tty = tty;
pInfo->priority = R3964_MASTER;
pInfo->rx_first = pInfo->rx_last = NULL;
@@ -1063,7 +1064,16 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
TRACE_L("read()");
- tty_lock(tty);
+ /*
+ * Internal serialization of reads.
+ */
+ if (file->f_flags & O_NONBLOCK) {
+ if (!mutex_trylock(&pInfo->read_lock))
+ return -EAGAIN;
+ } else {
+ if (mutex_lock_interruptible(&pInfo->read_lock))
+ return -ERESTARTSYS;
+ }
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
@@ -1075,7 +1085,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
goto unlock;
}
/* block until there is a message: */
- wait_event_interruptible_tty(tty, tty->read_wait,
+ wait_event_interruptible(tty->read_wait,
(pMsg = remove_msg(pInfo, pClient)));
}
@@ -1105,7 +1115,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
}
ret = -EPERM;
unlock:
- tty_unlock(tty);
+ mutex_unlock(&pInfo->read_lock);
return ret;
}
@@ -1154,8 +1164,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
pHeader->locks = 0;
pHeader->owner = NULL;
- tty_lock(tty);
-
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
pHeader->owner = pClient;
@@ -1173,8 +1181,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
add_tx_queue(pInfo, pHeader);
trigger_transmit(pInfo);
- tty_unlock(tty);
-
return 0;
}