aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-10-10 16:00:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-18 00:11:29 -0400
commitaba24888d9af19e0bd1c7e7344fd27841611d7a8 (patch)
tree8a463e798166f2a6938687b3b2c9b32dbf385f1e
parent9b9ab1b3f0860138681862cf6e4c48be59377ef1 (diff)
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>
-rw-r--r--drivers/tty/n_r3964.c20
-rw-r--r--include/linux/n_r3964.h5
2 files changed, 16 insertions, 9 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)
978 } 978 }
979 979
980 spin_lock_init(&pInfo->lock); 980 spin_lock_init(&pInfo->lock);
981 mutex_init(&pInfo->read_lock);
981 pInfo->tty = tty; 982 pInfo->tty = tty;
982 pInfo->priority = R3964_MASTER; 983 pInfo->priority = R3964_MASTER;
983 pInfo->rx_first = pInfo->rx_last = NULL; 984 pInfo->rx_first = pInfo->rx_last = NULL;
@@ -1063,7 +1064,16 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1063 1064
1064 TRACE_L("read()"); 1065 TRACE_L("read()");
1065 1066
1066 tty_lock(tty); 1067 /*
1068 * Internal serialization of reads.
1069 */
1070 if (file->f_flags & O_NONBLOCK) {
1071 if (!mutex_trylock(&pInfo->read_lock))
1072 return -EAGAIN;
1073 } else {
1074 if (mutex_lock_interruptible(&pInfo->read_lock))
1075 return -ERESTARTSYS;
1076 }
1067 1077
1068 pClient = findClient(pInfo, task_pid(current)); 1078 pClient = findClient(pInfo, task_pid(current));
1069 if (pClient) { 1079 if (pClient) {
@@ -1075,7 +1085,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1075 goto unlock; 1085 goto unlock;
1076 } 1086 }
1077 /* block until there is a message: */ 1087 /* block until there is a message: */
1078 wait_event_interruptible_tty(tty, tty->read_wait, 1088 wait_event_interruptible(tty->read_wait,
1079 (pMsg = remove_msg(pInfo, pClient))); 1089 (pMsg = remove_msg(pInfo, pClient)));
1080 } 1090 }
1081 1091
@@ -1105,7 +1115,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1105 } 1115 }
1106 ret = -EPERM; 1116 ret = -EPERM;
1107unlock: 1117unlock:
1108 tty_unlock(tty); 1118 mutex_unlock(&pInfo->read_lock);
1109 return ret; 1119 return ret;
1110} 1120}
1111 1121
@@ -1154,8 +1164,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1154 pHeader->locks = 0; 1164 pHeader->locks = 0;
1155 pHeader->owner = NULL; 1165 pHeader->owner = NULL;
1156 1166
1157 tty_lock(tty);
1158
1159 pClient = findClient(pInfo, task_pid(current)); 1167 pClient = findClient(pInfo, task_pid(current));
1160 if (pClient) { 1168 if (pClient) {
1161 pHeader->owner = pClient; 1169 pHeader->owner = pClient;
@@ -1173,8 +1181,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1173 add_tx_queue(pInfo, pHeader); 1181 add_tx_queue(pInfo, pHeader);
1174 trigger_transmit(pInfo); 1182 trigger_transmit(pInfo);
1175 1183
1176 tty_unlock(tty);
1177
1178 return 0; 1184 return 0;
1179} 1185}
1180 1186
diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h
index e9adb4226224..90a803aa42e8 100644
--- a/include/linux/n_r3964.h
+++ b/include/linux/n_r3964.h
@@ -161,8 +161,9 @@ struct r3964_info {
161 unsigned char last_rx; 161 unsigned char last_rx;
162 unsigned char bcc; 162 unsigned char bcc;
163 unsigned int blocks_in_rx_queue; 163 unsigned int blocks_in_rx_queue;
164 164
165 165 struct mutex read_lock; /* serialize r3964_read */
166
166 struct r3964_client_info *firstClient; 167 struct r3964_client_info *firstClient;
167 unsigned int state; 168 unsigned int state;
168 unsigned int flags; 169 unsigned int flags;