tty: BKL pushdown
- Push the BKL down into the line disciplines
- Switch the tty layer to unlocked_ioctl
- Introduce a new ctrl_lock spin lock for the control bits
- Eliminate much of the lock_kernel use in n_tty
- Prepare to (but don't yet) call the drivers with the lock dropped
on the paths that historically held the lock
BKL now primarily protects open/close/ldisc change in the tty layer
[jirislaby@gmail.com: a couple of fixes]
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 6b918b8..3f6486e 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1075,12 +1075,15 @@
TRACE_L("read()");
+ lock_kernel();
+
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
pMsg = remove_msg(pInfo, pClient);
if (pMsg == NULL) {
/* no messages available. */
if (file->f_flags & O_NONBLOCK) {
+ unlock_kernel();
return -EAGAIN;
}
/* block until there is a message: */
@@ -1090,8 +1093,10 @@
/* If we still haven't got a message, we must have been signalled */
- if (!pMsg)
+ if (!pMsg) {
+ unlock_kernel();
return -EINTR;
+ }
/* deliver msg to client process: */
theMsg.msg_id = pMsg->msg_id;
@@ -1102,12 +1107,15 @@
kfree(pMsg);
TRACE_M("r3964_read - msg kfree %p", pMsg);
- if (copy_to_user(buf, &theMsg, count))
+ if (copy_to_user(buf, &theMsg, count)) {
+ unlock_kernel();
return -EFAULT;
+ }
TRACE_PS("read - return %d", count);
return count;
}
+ unlock_kernel();
return -EPERM;
}
@@ -1156,6 +1164,8 @@
pHeader->locks = 0;
pHeader->owner = NULL;
+ lock_kernel();
+
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
pHeader->owner = pClient;
@@ -1173,6 +1183,8 @@
add_tx_queue(pInfo, pHeader);
trigger_transmit(pInfo);
+ unlock_kernel();
+
return 0;
}