diff options
author | Arnd Bergmann <arnd@arndb.de> | 2010-06-01 16:53:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 16:47:43 -0400 |
commit | ec79d6056de58511d8e46d9ae59d3878f958dc3e (patch) | |
tree | 8e73cf399c4cb3c31dbf3caced385cfc018a706a | |
parent | 3f582b8c11014e4ce310d9839fb335164195333f (diff) |
tty: replace BKL with a new tty_lock
As a preparation for replacing the big kernel lock
in the TTY layer, wrap all the callers in new
macros tty_lock, tty_lock_nested and tty_unlock.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/char/amiserial.c | 16 | ||||
-rw-r--r-- | drivers/char/briq_panel.c | 6 | ||||
-rw-r--r-- | drivers/char/n_hdlc.c | 16 | ||||
-rw-r--r-- | drivers/char/n_r3964.c | 8 | ||||
-rw-r--r-- | drivers/char/pty.c | 4 | ||||
-rw-r--r-- | drivers/char/selection.c | 4 | ||||
-rw-r--r-- | drivers/char/serial167.c | 4 | ||||
-rw-r--r-- | drivers/char/sx.c | 12 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 115 | ||||
-rw-r--r-- | drivers/char/tty_ldisc.c | 24 | ||||
-rw-r--r-- | drivers/char/vc_screen.c | 4 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 10 | ||||
-rw-r--r-- | drivers/serial/68360serial.c | 4 | ||||
-rw-r--r-- | drivers/serial/crisv10.c | 4 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 10 | ||||
-rw-r--r-- | drivers/video/console/vgacon.c | 4 | ||||
-rw-r--r-- | include/linux/tty.h | 31 |
17 files changed, 161 insertions, 115 deletions
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 4f8d60c25a98..1b21a7adeb58 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1072,7 +1072,7 @@ static int get_serial_info(struct async_struct * info, | |||
1072 | if (!retinfo) | 1072 | if (!retinfo) |
1073 | return -EFAULT; | 1073 | return -EFAULT; |
1074 | memset(&tmp, 0, sizeof(tmp)); | 1074 | memset(&tmp, 0, sizeof(tmp)); |
1075 | lock_kernel(); | 1075 | tty_lock(); |
1076 | tmp.type = state->type; | 1076 | tmp.type = state->type; |
1077 | tmp.line = state->line; | 1077 | tmp.line = state->line; |
1078 | tmp.port = state->port; | 1078 | tmp.port = state->port; |
@@ -1083,7 +1083,7 @@ static int get_serial_info(struct async_struct * info, | |||
1083 | tmp.close_delay = state->close_delay; | 1083 | tmp.close_delay = state->close_delay; |
1084 | tmp.closing_wait = state->closing_wait; | 1084 | tmp.closing_wait = state->closing_wait; |
1085 | tmp.custom_divisor = state->custom_divisor; | 1085 | tmp.custom_divisor = state->custom_divisor; |
1086 | unlock_kernel(); | 1086 | tty_unlock(); |
1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
1088 | return -EFAULT; | 1088 | return -EFAULT; |
1089 | return 0; | 1089 | return 0; |
@@ -1100,14 +1100,14 @@ static int set_serial_info(struct async_struct * info, | |||
1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
1101 | return -EFAULT; | 1101 | return -EFAULT; |
1102 | 1102 | ||
1103 | lock_kernel(); | 1103 | tty_lock(); |
1104 | state = info->state; | 1104 | state = info->state; |
1105 | old_state = *state; | 1105 | old_state = *state; |
1106 | 1106 | ||
1107 | change_irq = new_serial.irq != state->irq; | 1107 | change_irq = new_serial.irq != state->irq; |
1108 | change_port = (new_serial.port != state->port); | 1108 | change_port = (new_serial.port != state->port); |
1109 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { | 1109 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { |
1110 | unlock_kernel(); | 1110 | tty_unlock(); |
1111 | return -EINVAL; | 1111 | return -EINVAL; |
1112 | } | 1112 | } |
1113 | 1113 | ||
@@ -1127,7 +1127,7 @@ static int set_serial_info(struct async_struct * info, | |||
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | if (new_serial.baud_base < 9600) { | 1129 | if (new_serial.baud_base < 9600) { |
1130 | unlock_kernel(); | 1130 | tty_unlock(); |
1131 | return -EINVAL; | 1131 | return -EINVAL; |
1132 | } | 1132 | } |
1133 | 1133 | ||
@@ -1163,7 +1163,7 @@ check_and_exit: | |||
1163 | } | 1163 | } |
1164 | } else | 1164 | } else |
1165 | retval = startup(info); | 1165 | retval = startup(info); |
1166 | unlock_kernel(); | 1166 | tty_unlock(); |
1167 | return retval; | 1167 | return retval; |
1168 | } | 1168 | } |
1169 | 1169 | ||
@@ -1538,7 +1538,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1538 | 1538 | ||
1539 | orig_jiffies = jiffies; | 1539 | orig_jiffies = jiffies; |
1540 | 1540 | ||
1541 | lock_kernel(); | 1541 | tty_lock_nested(); /* tty_wait_until_sent is called from lots of places */ |
1542 | /* | 1542 | /* |
1543 | * Set the check interval to be 1/5 of the estimated time to | 1543 | * Set the check interval to be 1/5 of the estimated time to |
1544 | * send a single character, and make it at least 1. The check | 1544 | * send a single character, and make it at least 1. The check |
@@ -1579,7 +1579,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1579 | break; | 1579 | break; |
1580 | } | 1580 | } |
1581 | __set_current_state(TASK_RUNNING); | 1581 | __set_current_state(TASK_RUNNING); |
1582 | unlock_kernel(); | 1582 | tty_unlock(); |
1583 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1583 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1584 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1584 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1585 | #endif | 1585 | #endif |
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c index 555cd93c2ee5..d5fa113afe37 100644 --- a/drivers/char/briq_panel.c +++ b/drivers/char/briq_panel.c | |||
@@ -67,15 +67,15 @@ static void set_led(char state) | |||
67 | 67 | ||
68 | static int briq_panel_open(struct inode *ino, struct file *filep) | 68 | static int briq_panel_open(struct inode *ino, struct file *filep) |
69 | { | 69 | { |
70 | lock_kernel(); | 70 | tty_lock(); |
71 | /* enforce single access, vfd_is_open is protected by BKL */ | 71 | /* enforce single access, vfd_is_open is protected by BKL */ |
72 | if (vfd_is_open) { | 72 | if (vfd_is_open) { |
73 | unlock_kernel(); | 73 | tty_unlock(); |
74 | return -EBUSY; | 74 | return -EBUSY; |
75 | } | 75 | } |
76 | vfd_is_open = 1; | 76 | vfd_is_open = 1; |
77 | 77 | ||
78 | unlock_kernel(); | 78 | tty_unlock(); |
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index c68118efad84..47d32281032c 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -598,18 +598,18 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
598 | return -EFAULT; | 598 | return -EFAULT; |
599 | } | 599 | } |
600 | 600 | ||
601 | lock_kernel(); | 601 | tty_lock(); |
602 | 602 | ||
603 | for (;;) { | 603 | for (;;) { |
604 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { | 604 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
605 | unlock_kernel(); | 605 | tty_unlock(); |
606 | return -EIO; | 606 | return -EIO; |
607 | } | 607 | } |
608 | 608 | ||
609 | n_hdlc = tty2n_hdlc (tty); | 609 | n_hdlc = tty2n_hdlc (tty); |
610 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || | 610 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || |
611 | tty != n_hdlc->tty) { | 611 | tty != n_hdlc->tty) { |
612 | unlock_kernel(); | 612 | tty_unlock(); |
613 | return 0; | 613 | return 0; |
614 | } | 614 | } |
615 | 615 | ||
@@ -619,13 +619,13 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
619 | 619 | ||
620 | /* no data */ | 620 | /* no data */ |
621 | if (file->f_flags & O_NONBLOCK) { | 621 | if (file->f_flags & O_NONBLOCK) { |
622 | unlock_kernel(); | 622 | tty_unlock(); |
623 | return -EAGAIN; | 623 | return -EAGAIN; |
624 | } | 624 | } |
625 | 625 | ||
626 | interruptible_sleep_on (&tty->read_wait); | 626 | interruptible_sleep_on (&tty->read_wait); |
627 | if (signal_pending(current)) { | 627 | if (signal_pending(current)) { |
628 | unlock_kernel(); | 628 | tty_unlock(); |
629 | return -EINTR; | 629 | return -EINTR; |
630 | } | 630 | } |
631 | } | 631 | } |
@@ -648,7 +648,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
648 | kfree(rbuf); | 648 | kfree(rbuf); |
649 | else | 649 | else |
650 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); | 650 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); |
651 | unlock_kernel(); | 651 | tty_unlock(); |
652 | return ret; | 652 | return ret; |
653 | 653 | ||
654 | } /* end of n_hdlc_tty_read() */ | 654 | } /* end of n_hdlc_tty_read() */ |
@@ -691,7 +691,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
691 | count = maxframe; | 691 | count = maxframe; |
692 | } | 692 | } |
693 | 693 | ||
694 | lock_kernel(); | 694 | tty_lock(); |
695 | 695 | ||
696 | add_wait_queue(&tty->write_wait, &wait); | 696 | add_wait_queue(&tty->write_wait, &wait); |
697 | set_current_state(TASK_INTERRUPTIBLE); | 697 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
731 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); | 731 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); |
732 | n_hdlc_send_frames(n_hdlc,tty); | 732 | n_hdlc_send_frames(n_hdlc,tty); |
733 | } | 733 | } |
734 | unlock_kernel(); | 734 | tty_unlock(); |
735 | return error; | 735 | return error; |
736 | 736 | ||
737 | } /* end of n_hdlc_tty_write() */ | 737 | } /* end of n_hdlc_tty_write() */ |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index c1d8b54c816d..f4bd2591e39f 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -1067,7 +1067,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1067 | 1067 | ||
1068 | TRACE_L("read()"); | 1068 | TRACE_L("read()"); |
1069 | 1069 | ||
1070 | lock_kernel(); | 1070 | tty_lock(); |
1071 | 1071 | ||
1072 | pClient = findClient(pInfo, task_pid(current)); | 1072 | pClient = findClient(pInfo, task_pid(current)); |
1073 | if (pClient) { | 1073 | if (pClient) { |
@@ -1109,7 +1109,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1109 | } | 1109 | } |
1110 | ret = -EPERM; | 1110 | ret = -EPERM; |
1111 | unlock: | 1111 | unlock: |
1112 | unlock_kernel(); | 1112 | tty_unlock(); |
1113 | return ret; | 1113 | return ret; |
1114 | } | 1114 | } |
1115 | 1115 | ||
@@ -1158,7 +1158,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1158 | pHeader->locks = 0; | 1158 | pHeader->locks = 0; |
1159 | pHeader->owner = NULL; | 1159 | pHeader->owner = NULL; |
1160 | 1160 | ||
1161 | lock_kernel(); | 1161 | tty_lock(); |
1162 | 1162 | ||
1163 | pClient = findClient(pInfo, task_pid(current)); | 1163 | pClient = findClient(pInfo, task_pid(current)); |
1164 | if (pClient) { | 1164 | if (pClient) { |
@@ -1177,7 +1177,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1177 | add_tx_queue(pInfo, pHeader); | 1177 | add_tx_queue(pInfo, pHeader); |
1178 | trigger_transmit(pInfo); | 1178 | trigger_transmit(pInfo); |
1179 | 1179 | ||
1180 | unlock_kernel(); | 1180 | tty_unlock(); |
1181 | 1181 | ||
1182 | return 0; | 1182 | return 0; |
1183 | } | 1183 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index b640ef29be1c..622e21ca9a5c 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -692,9 +692,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
692 | { | 692 | { |
693 | int ret; | 693 | int ret; |
694 | 694 | ||
695 | lock_kernel(); | 695 | tty_lock(); |
696 | ret = __ptmx_open(inode, filp); | 696 | ret = __ptmx_open(inode, filp); |
697 | unlock_kernel(); | 697 | tty_unlock(); |
698 | return ret; | 698 | return ret; |
699 | } | 699 | } |
700 | 700 | ||
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 6e79340d732f..85211a3a5811 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -313,7 +313,7 @@ int paste_selection(struct tty_struct *tty) | |||
313 | struct tty_ldisc *ld; | 313 | struct tty_ldisc *ld; |
314 | DECLARE_WAITQUEUE(wait, current); | 314 | DECLARE_WAITQUEUE(wait, current); |
315 | 315 | ||
316 | lock_kernel(); | 316 | tty_lock_nested(); /* always called with BTM from vt_ioctl */ |
317 | 317 | ||
318 | acquire_console_sem(); | 318 | acquire_console_sem(); |
319 | poke_blanked_console(); | 319 | poke_blanked_console(); |
@@ -338,6 +338,6 @@ int paste_selection(struct tty_struct *tty) | |||
338 | __set_current_state(TASK_RUNNING); | 338 | __set_current_state(TASK_RUNNING); |
339 | 339 | ||
340 | tty_ldisc_deref(ld); | 340 | tty_ldisc_deref(ld); |
341 | unlock_kernel(); | 341 | tty_unlock(); |
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index ecbe479c7d68..90b3ec0aabdd 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1505,7 +1505,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1505 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ | 1505 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ |
1506 | #endif | 1506 | #endif |
1507 | 1507 | ||
1508 | lock_kernel(); | 1508 | tty_lock(); |
1509 | 1509 | ||
1510 | switch (cmd) { | 1510 | switch (cmd) { |
1511 | case CYGETMON: | 1511 | case CYGETMON: |
@@ -1561,7 +1561,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1561 | default: | 1561 | default: |
1562 | ret_val = -ENOIOCTLCMD; | 1562 | ret_val = -ENOIOCTLCMD; |
1563 | } | 1563 | } |
1564 | unlock_kernel(); | 1564 | tty_unlock(); |
1565 | 1565 | ||
1566 | #ifdef SERIAL_DEBUG_OTHER | 1566 | #ifdef SERIAL_DEBUG_OTHER |
1567 | printk("cy_ioctl done\n"); | 1567 | printk("cy_ioctl done\n"); |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index a81ec4fcf6ff..5b24db4ff7f1 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1699,7 +1699,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
1699 | if (!capable(CAP_SYS_RAWIO)) | 1699 | if (!capable(CAP_SYS_RAWIO)) |
1700 | return -EPERM; | 1700 | return -EPERM; |
1701 | 1701 | ||
1702 | lock_kernel(); | 1702 | tty_lock(); |
1703 | 1703 | ||
1704 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); | 1704 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); |
1705 | 1705 | ||
@@ -1848,7 +1848,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
1848 | break; | 1848 | break; |
1849 | } | 1849 | } |
1850 | out: | 1850 | out: |
1851 | unlock_kernel(); | 1851 | tty_unlock(); |
1852 | func_exit(); | 1852 | func_exit(); |
1853 | return rc; | 1853 | return rc; |
1854 | } | 1854 | } |
@@ -1859,7 +1859,7 @@ static int sx_break(struct tty_struct *tty, int flag) | |||
1859 | int rv; | 1859 | int rv; |
1860 | 1860 | ||
1861 | func_enter(); | 1861 | func_enter(); |
1862 | lock_kernel(); | 1862 | tty_lock(); |
1863 | 1863 | ||
1864 | if (flag) | 1864 | if (flag) |
1865 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); | 1865 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); |
@@ -1868,7 +1868,7 @@ static int sx_break(struct tty_struct *tty, int flag) | |||
1868 | if (rv != 1) | 1868 | if (rv != 1) |
1869 | printk(KERN_ERR "sx: couldn't send break (%x).\n", | 1869 | printk(KERN_ERR "sx: couldn't send break (%x).\n", |
1870 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | 1870 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); |
1871 | unlock_kernel(); | 1871 | tty_unlock(); |
1872 | func_exit(); | 1872 | func_exit(); |
1873 | return 0; | 1873 | return 0; |
1874 | } | 1874 | } |
@@ -1909,7 +1909,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1909 | /* func_enter2(); */ | 1909 | /* func_enter2(); */ |
1910 | 1910 | ||
1911 | rc = 0; | 1911 | rc = 0; |
1912 | lock_kernel(); | 1912 | tty_lock(); |
1913 | switch (cmd) { | 1913 | switch (cmd) { |
1914 | case TIOCGSERIAL: | 1914 | case TIOCGSERIAL: |
1915 | rc = gs_getserial(&port->gs, argp); | 1915 | rc = gs_getserial(&port->gs, argp); |
@@ -1921,7 +1921,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1921 | rc = -ENOIOCTLCMD; | 1921 | rc = -ENOIOCTLCMD; |
1922 | break; | 1922 | break; |
1923 | } | 1923 | } |
1924 | unlock_kernel(); | 1924 | tty_unlock(); |
1925 | 1925 | ||
1926 | /* func_exit(); */ | 1926 | /* func_exit(); */ |
1927 | return rc; | 1927 | return rc; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 507441ac6edb..5ee9081a560f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -149,6 +149,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
149 | #else | 149 | #else |
150 | #define tty_compat_ioctl NULL | 150 | #define tty_compat_ioctl NULL |
151 | #endif | 151 | #endif |
152 | static int __tty_fasync(int fd, struct file *filp, int on); | ||
152 | static int tty_fasync(int fd, struct file *filp, int on); | 153 | static int tty_fasync(int fd, struct file *filp, int on); |
153 | static void release_tty(struct tty_struct *tty, int idx); | 154 | static void release_tty(struct tty_struct *tty, int idx); |
154 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | 155 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
@@ -483,7 +484,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
483 | * remains intact. | 484 | * remains intact. |
484 | * | 485 | * |
485 | * Locking: | 486 | * Locking: |
486 | * BKL | 487 | * BTM |
487 | * redirect lock for undoing redirection | 488 | * redirect lock for undoing redirection |
488 | * file list lock for manipulating list of ttys | 489 | * file list lock for manipulating list of ttys |
489 | * tty_ldisc_lock from called functions | 490 | * tty_ldisc_lock from called functions |
@@ -513,8 +514,11 @@ static void do_tty_hangup(struct work_struct *work) | |||
513 | } | 514 | } |
514 | spin_unlock(&redirect_lock); | 515 | spin_unlock(&redirect_lock); |
515 | 516 | ||
516 | /* inuse_filps is protected by the single kernel lock */ | 517 | /* inuse_filps is protected by the single tty lock, |
517 | lock_kernel(); | 518 | this really needs to change if we want to flush the |
519 | workqueue with the lock held */ | ||
520 | tty_lock_nested(); /* called with BTM held from pty_close and | ||
521 | others */ | ||
518 | check_tty_count(tty, "do_tty_hangup"); | 522 | check_tty_count(tty, "do_tty_hangup"); |
519 | 523 | ||
520 | file_list_lock(); | 524 | file_list_lock(); |
@@ -525,7 +529,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
525 | if (filp->f_op->write != tty_write) | 529 | if (filp->f_op->write != tty_write) |
526 | continue; | 530 | continue; |
527 | closecount++; | 531 | closecount++; |
528 | tty_fasync(-1, filp, 0); /* can't block */ | 532 | __tty_fasync(-1, filp, 0); /* can't block */ |
529 | filp->f_op = &hung_up_tty_fops; | 533 | filp->f_op = &hung_up_tty_fops; |
530 | } | 534 | } |
531 | file_list_unlock(); | 535 | file_list_unlock(); |
@@ -594,7 +598,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
594 | */ | 598 | */ |
595 | set_bit(TTY_HUPPED, &tty->flags); | 599 | set_bit(TTY_HUPPED, &tty->flags); |
596 | tty_ldisc_enable(tty); | 600 | tty_ldisc_enable(tty); |
597 | unlock_kernel(); | 601 | tty_unlock(); |
598 | if (f) | 602 | if (f) |
599 | fput(f); | 603 | fput(f); |
600 | } | 604 | } |
@@ -696,7 +700,8 @@ static void session_clear_tty(struct pid *session) | |||
696 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 700 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
697 | * | 701 | * |
698 | * Locking: | 702 | * Locking: |
699 | * BKL is taken for hysterical raisins | 703 | * BTM is taken for hysterical raisins, and held when |
704 | * called from no_tty(). | ||
700 | * tty_mutex is taken to protect tty | 705 | * tty_mutex is taken to protect tty |
701 | * ->siglock is taken to protect ->signal/->sighand | 706 | * ->siglock is taken to protect ->signal/->sighand |
702 | * tasklist_lock is taken to walk process list for sessions | 707 | * tasklist_lock is taken to walk process list for sessions |
@@ -714,10 +719,10 @@ void disassociate_ctty(int on_exit) | |||
714 | tty = get_current_tty(); | 719 | tty = get_current_tty(); |
715 | if (tty) { | 720 | if (tty) { |
716 | tty_pgrp = get_pid(tty->pgrp); | 721 | tty_pgrp = get_pid(tty->pgrp); |
717 | lock_kernel(); | 722 | tty_lock_nested(); /* see above */ |
718 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 723 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
719 | tty_vhangup(tty); | 724 | tty_vhangup(tty); |
720 | unlock_kernel(); | 725 | tty_unlock(); |
721 | tty_kref_put(tty); | 726 | tty_kref_put(tty); |
722 | } else if (on_exit) { | 727 | } else if (on_exit) { |
723 | struct pid *old_pgrp; | 728 | struct pid *old_pgrp; |
@@ -774,9 +779,9 @@ void disassociate_ctty(int on_exit) | |||
774 | void no_tty(void) | 779 | void no_tty(void) |
775 | { | 780 | { |
776 | struct task_struct *tsk = current; | 781 | struct task_struct *tsk = current; |
777 | lock_kernel(); | 782 | tty_lock(); |
778 | disassociate_ctty(0); | 783 | disassociate_ctty(0); |
779 | unlock_kernel(); | 784 | tty_unlock(); |
780 | proc_clear_tty(tsk); | 785 | proc_clear_tty(tsk); |
781 | } | 786 | } |
782 | 787 | ||
@@ -1013,19 +1018,19 @@ out: | |||
1013 | * We don't put it into the syslog queue right now maybe in the future if | 1018 | * We don't put it into the syslog queue right now maybe in the future if |
1014 | * really needed. | 1019 | * really needed. |
1015 | * | 1020 | * |
1016 | * We must still hold the BKL and test the CLOSING flag for the moment. | 1021 | * We must still hold the BTM and test the CLOSING flag for the moment. |
1017 | */ | 1022 | */ |
1018 | 1023 | ||
1019 | void tty_write_message(struct tty_struct *tty, char *msg) | 1024 | void tty_write_message(struct tty_struct *tty, char *msg) |
1020 | { | 1025 | { |
1021 | if (tty) { | 1026 | if (tty) { |
1022 | mutex_lock(&tty->atomic_write_lock); | 1027 | mutex_lock(&tty->atomic_write_lock); |
1023 | lock_kernel(); | 1028 | tty_lock(); |
1024 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1029 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1025 | unlock_kernel(); | 1030 | tty_unlock(); |
1026 | tty->ops->write(tty, msg, strlen(msg)); | 1031 | tty->ops->write(tty, msg, strlen(msg)); |
1027 | } else | 1032 | } else |
1028 | unlock_kernel(); | 1033 | tty_unlock(); |
1029 | tty_write_unlock(tty); | 1034 | tty_write_unlock(tty); |
1030 | } | 1035 | } |
1031 | return; | 1036 | return; |
@@ -1208,18 +1213,18 @@ static int tty_driver_install_tty(struct tty_driver *driver, | |||
1208 | int ret; | 1213 | int ret; |
1209 | 1214 | ||
1210 | if (driver->ops->install) { | 1215 | if (driver->ops->install) { |
1211 | lock_kernel(); | 1216 | tty_lock_nested(); /* already called with BTM held */ |
1212 | ret = driver->ops->install(driver, tty); | 1217 | ret = driver->ops->install(driver, tty); |
1213 | unlock_kernel(); | 1218 | tty_unlock(); |
1214 | return ret; | 1219 | return ret; |
1215 | } | 1220 | } |
1216 | 1221 | ||
1217 | if (tty_init_termios(tty) == 0) { | 1222 | if (tty_init_termios(tty) == 0) { |
1218 | lock_kernel(); | 1223 | tty_lock_nested(); |
1219 | tty_driver_kref_get(driver); | 1224 | tty_driver_kref_get(driver); |
1220 | tty->count++; | 1225 | tty->count++; |
1221 | driver->ttys[idx] = tty; | 1226 | driver->ttys[idx] = tty; |
1222 | unlock_kernel(); | 1227 | tty_unlock(); |
1223 | return 0; | 1228 | return 0; |
1224 | } | 1229 | } |
1225 | return -ENOMEM; | 1230 | return -ENOMEM; |
@@ -1312,14 +1317,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1312 | struct tty_struct *tty; | 1317 | struct tty_struct *tty; |
1313 | int retval; | 1318 | int retval; |
1314 | 1319 | ||
1315 | lock_kernel(); | 1320 | tty_lock_nested(); /* always called with tty lock held already */ |
1321 | |||
1316 | /* Check if pty master is being opened multiple times */ | 1322 | /* Check if pty master is being opened multiple times */ |
1317 | if (driver->subtype == PTY_TYPE_MASTER && | 1323 | if (driver->subtype == PTY_TYPE_MASTER && |
1318 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { | 1324 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { |
1319 | unlock_kernel(); | 1325 | tty_unlock(); |
1320 | return ERR_PTR(-EIO); | 1326 | return ERR_PTR(-EIO); |
1321 | } | 1327 | } |
1322 | unlock_kernel(); | 1328 | tty_unlock(); |
1323 | 1329 | ||
1324 | /* | 1330 | /* |
1325 | * First time open is complex, especially for PTY devices. | 1331 | * First time open is complex, especially for PTY devices. |
@@ -1363,9 +1369,9 @@ release_mem_out: | |||
1363 | if (printk_ratelimit()) | 1369 | if (printk_ratelimit()) |
1364 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1370 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1365 | "clearing slot %d\n", idx); | 1371 | "clearing slot %d\n", idx); |
1366 | lock_kernel(); | 1372 | tty_lock_nested(); |
1367 | release_tty(tty, idx); | 1373 | release_tty(tty, idx); |
1368 | unlock_kernel(); | 1374 | tty_unlock(); |
1369 | return ERR_PTR(retval); | 1375 | return ERR_PTR(retval); |
1370 | } | 1376 | } |
1371 | 1377 | ||
@@ -1512,10 +1518,10 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1512 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1518 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1513 | return 0; | 1519 | return 0; |
1514 | 1520 | ||
1515 | lock_kernel(); | 1521 | tty_lock(); |
1516 | check_tty_count(tty, "tty_release_dev"); | 1522 | check_tty_count(tty, "tty_release_dev"); |
1517 | 1523 | ||
1518 | tty_fasync(-1, filp, 0); | 1524 | __tty_fasync(-1, filp, 0); |
1519 | 1525 | ||
1520 | idx = tty->index; | 1526 | idx = tty->index; |
1521 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1527 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -1527,18 +1533,18 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1527 | if (idx < 0 || idx >= tty->driver->num) { | 1533 | if (idx < 0 || idx >= tty->driver->num) { |
1528 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | 1534 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1529 | "free (%s)\n", tty->name); | 1535 | "free (%s)\n", tty->name); |
1530 | unlock_kernel(); | 1536 | tty_unlock(); |
1531 | return 0; | 1537 | return 0; |
1532 | } | 1538 | } |
1533 | if (!devpts) { | 1539 | if (!devpts) { |
1534 | if (tty != tty->driver->ttys[idx]) { | 1540 | if (tty != tty->driver->ttys[idx]) { |
1535 | unlock_kernel(); | 1541 | tty_unlock(); |
1536 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | 1542 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1537 | "for (%s)\n", idx, tty->name); | 1543 | "for (%s)\n", idx, tty->name); |
1538 | return 0; | 1544 | return 0; |
1539 | } | 1545 | } |
1540 | if (tty->termios != tty->driver->termios[idx]) { | 1546 | if (tty->termios != tty->driver->termios[idx]) { |
1541 | unlock_kernel(); | 1547 | tty_unlock(); |
1542 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | 1548 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1543 | "for (%s)\n", | 1549 | "for (%s)\n", |
1544 | idx, tty->name); | 1550 | idx, tty->name); |
@@ -1556,21 +1562,21 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1556 | if (tty->driver->other && | 1562 | if (tty->driver->other && |
1557 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1563 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1558 | if (o_tty != tty->driver->other->ttys[idx]) { | 1564 | if (o_tty != tty->driver->other->ttys[idx]) { |
1559 | unlock_kernel(); | 1565 | tty_unlock(); |
1560 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | 1566 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1561 | "not o_tty for (%s)\n", | 1567 | "not o_tty for (%s)\n", |
1562 | idx, tty->name); | 1568 | idx, tty->name); |
1563 | return 0 ; | 1569 | return 0 ; |
1564 | } | 1570 | } |
1565 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1571 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1566 | unlock_kernel(); | 1572 | tty_unlock(); |
1567 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | 1573 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1568 | "not o_termios for (%s)\n", | 1574 | "not o_termios for (%s)\n", |
1569 | idx, tty->name); | 1575 | idx, tty->name); |
1570 | return 0; | 1576 | return 0; |
1571 | } | 1577 | } |
1572 | if (o_tty->link != tty) { | 1578 | if (o_tty->link != tty) { |
1573 | unlock_kernel(); | 1579 | tty_unlock(); |
1574 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | 1580 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
1575 | return 0; | 1581 | return 0; |
1576 | } | 1582 | } |
@@ -1579,7 +1585,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1579 | if (tty->ops->close) | 1585 | if (tty->ops->close) |
1580 | tty->ops->close(tty, filp); | 1586 | tty->ops->close(tty, filp); |
1581 | 1587 | ||
1582 | unlock_kernel(); | 1588 | tty_unlock(); |
1583 | /* | 1589 | /* |
1584 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1590 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1585 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1591 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1602,7 +1608,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1602 | opens on /dev/tty */ | 1608 | opens on /dev/tty */ |
1603 | 1609 | ||
1604 | mutex_lock(&tty_mutex); | 1610 | mutex_lock(&tty_mutex); |
1605 | lock_kernel(); | 1611 | tty_lock(); |
1606 | tty_closing = tty->count <= 1; | 1612 | tty_closing = tty->count <= 1; |
1607 | o_tty_closing = o_tty && | 1613 | o_tty_closing = o_tty && |
1608 | (o_tty->count <= (pty_master ? 1 : 0)); | 1614 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1633,7 +1639,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1633 | 1639 | ||
1634 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1640 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
1635 | "active!\n", tty_name(tty, buf)); | 1641 | "active!\n", tty_name(tty, buf)); |
1636 | unlock_kernel(); | 1642 | tty_unlock(); |
1637 | mutex_unlock(&tty_mutex); | 1643 | mutex_unlock(&tty_mutex); |
1638 | schedule(); | 1644 | schedule(); |
1639 | } | 1645 | } |
@@ -1698,7 +1704,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1698 | 1704 | ||
1699 | /* check whether both sides are closing ... */ | 1705 | /* check whether both sides are closing ... */ |
1700 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1706 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1701 | unlock_kernel(); | 1707 | tty_unlock(); |
1702 | return 0; | 1708 | return 0; |
1703 | } | 1709 | } |
1704 | 1710 | ||
@@ -1718,7 +1724,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1718 | /* Make this pty number available for reallocation */ | 1724 | /* Make this pty number available for reallocation */ |
1719 | if (devpts) | 1725 | if (devpts) |
1720 | devpts_kill_index(inode, idx); | 1726 | devpts_kill_index(inode, idx); |
1721 | unlock_kernel(); | 1727 | tty_unlock(); |
1722 | return 0; | 1728 | return 0; |
1723 | } | 1729 | } |
1724 | 1730 | ||
@@ -1760,12 +1766,12 @@ retry_open: | |||
1760 | retval = 0; | 1766 | retval = 0; |
1761 | 1767 | ||
1762 | mutex_lock(&tty_mutex); | 1768 | mutex_lock(&tty_mutex); |
1763 | lock_kernel(); | 1769 | tty_lock(); |
1764 | 1770 | ||
1765 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1771 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { |
1766 | tty = get_current_tty(); | 1772 | tty = get_current_tty(); |
1767 | if (!tty) { | 1773 | if (!tty) { |
1768 | unlock_kernel(); | 1774 | tty_unlock(); |
1769 | mutex_unlock(&tty_mutex); | 1775 | mutex_unlock(&tty_mutex); |
1770 | return -ENXIO; | 1776 | return -ENXIO; |
1771 | } | 1777 | } |
@@ -1797,14 +1803,14 @@ retry_open: | |||
1797 | goto got_driver; | 1803 | goto got_driver; |
1798 | } | 1804 | } |
1799 | } | 1805 | } |
1800 | unlock_kernel(); | 1806 | tty_unlock(); |
1801 | mutex_unlock(&tty_mutex); | 1807 | mutex_unlock(&tty_mutex); |
1802 | return -ENODEV; | 1808 | return -ENODEV; |
1803 | } | 1809 | } |
1804 | 1810 | ||
1805 | driver = get_tty_driver(device, &index); | 1811 | driver = get_tty_driver(device, &index); |
1806 | if (!driver) { | 1812 | if (!driver) { |
1807 | unlock_kernel(); | 1813 | tty_unlock(); |
1808 | mutex_unlock(&tty_mutex); | 1814 | mutex_unlock(&tty_mutex); |
1809 | return -ENODEV; | 1815 | return -ENODEV; |
1810 | } | 1816 | } |
@@ -1814,7 +1820,7 @@ got_driver: | |||
1814 | tty = tty_driver_lookup_tty(driver, inode, index); | 1820 | tty = tty_driver_lookup_tty(driver, inode, index); |
1815 | 1821 | ||
1816 | if (IS_ERR(tty)) { | 1822 | if (IS_ERR(tty)) { |
1817 | unlock_kernel(); | 1823 | tty_unlock(); |
1818 | mutex_unlock(&tty_mutex); | 1824 | mutex_unlock(&tty_mutex); |
1819 | return PTR_ERR(tty); | 1825 | return PTR_ERR(tty); |
1820 | } | 1826 | } |
@@ -1830,7 +1836,7 @@ got_driver: | |||
1830 | mutex_unlock(&tty_mutex); | 1836 | mutex_unlock(&tty_mutex); |
1831 | tty_driver_kref_put(driver); | 1837 | tty_driver_kref_put(driver); |
1832 | if (IS_ERR(tty)) { | 1838 | if (IS_ERR(tty)) { |
1833 | unlock_kernel(); | 1839 | tty_unlock(); |
1834 | return PTR_ERR(tty); | 1840 | return PTR_ERR(tty); |
1835 | } | 1841 | } |
1836 | 1842 | ||
@@ -1862,11 +1868,11 @@ got_driver: | |||
1862 | #endif | 1868 | #endif |
1863 | tty_release(inode, filp); | 1869 | tty_release(inode, filp); |
1864 | if (retval != -ERESTARTSYS) { | 1870 | if (retval != -ERESTARTSYS) { |
1865 | unlock_kernel(); | 1871 | tty_unlock(); |
1866 | return retval; | 1872 | return retval; |
1867 | } | 1873 | } |
1868 | if (signal_pending(current)) { | 1874 | if (signal_pending(current)) { |
1869 | unlock_kernel(); | 1875 | tty_unlock(); |
1870 | return retval; | 1876 | return retval; |
1871 | } | 1877 | } |
1872 | schedule(); | 1878 | schedule(); |
@@ -1875,14 +1881,14 @@ got_driver: | |||
1875 | */ | 1881 | */ |
1876 | if (filp->f_op == &hung_up_tty_fops) | 1882 | if (filp->f_op == &hung_up_tty_fops) |
1877 | filp->f_op = &tty_fops; | 1883 | filp->f_op = &tty_fops; |
1878 | unlock_kernel(); | 1884 | tty_unlock(); |
1879 | goto retry_open; | 1885 | goto retry_open; |
1880 | } | 1886 | } |
1881 | unlock_kernel(); | 1887 | tty_unlock(); |
1882 | 1888 | ||
1883 | 1889 | ||
1884 | mutex_lock(&tty_mutex); | 1890 | mutex_lock(&tty_mutex); |
1885 | lock_kernel(); | 1891 | tty_lock(); |
1886 | spin_lock_irq(¤t->sighand->siglock); | 1892 | spin_lock_irq(¤t->sighand->siglock); |
1887 | if (!noctty && | 1893 | if (!noctty && |
1888 | current->signal->leader && | 1894 | current->signal->leader && |
@@ -1890,7 +1896,7 @@ got_driver: | |||
1890 | tty->session == NULL) | 1896 | tty->session == NULL) |
1891 | __proc_set_tty(current, tty); | 1897 | __proc_set_tty(current, tty); |
1892 | spin_unlock_irq(¤t->sighand->siglock); | 1898 | spin_unlock_irq(¤t->sighand->siglock); |
1893 | unlock_kernel(); | 1899 | tty_unlock(); |
1894 | mutex_unlock(&tty_mutex); | 1900 | mutex_unlock(&tty_mutex); |
1895 | return 0; | 1901 | return 0; |
1896 | } | 1902 | } |
@@ -1926,13 +1932,12 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1926 | return ret; | 1932 | return ret; |
1927 | } | 1933 | } |
1928 | 1934 | ||
1929 | static int tty_fasync(int fd, struct file *filp, int on) | 1935 | static int __tty_fasync(int fd, struct file *filp, int on) |
1930 | { | 1936 | { |
1931 | struct tty_struct *tty; | 1937 | struct tty_struct *tty; |
1932 | unsigned long flags; | 1938 | unsigned long flags; |
1933 | int retval = 0; | 1939 | int retval = 0; |
1934 | 1940 | ||
1935 | lock_kernel(); | ||
1936 | tty = (struct tty_struct *)filp->private_data; | 1941 | tty = (struct tty_struct *)filp->private_data; |
1937 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1942 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1938 | goto out; | 1943 | goto out; |
@@ -1966,7 +1971,15 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
1966 | } | 1971 | } |
1967 | retval = 0; | 1972 | retval = 0; |
1968 | out: | 1973 | out: |
1969 | unlock_kernel(); | 1974 | return retval; |
1975 | } | ||
1976 | |||
1977 | static int tty_fasync(int fd, struct file *filp, int on) | ||
1978 | { | ||
1979 | int retval; | ||
1980 | tty_lock(); | ||
1981 | retval = __tty_fasync(fd, filp, on); | ||
1982 | tty_unlock(); | ||
1970 | return retval; | 1983 | return retval; |
1971 | } | 1984 | } |
1972 | 1985 | ||
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 500e740ec5e4..97681ffd6cbd 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -440,6 +440,8 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | |||
440 | * | 440 | * |
441 | * A helper opening method. Also a convenient debugging and check | 441 | * A helper opening method. Also a convenient debugging and check |
442 | * point. | 442 | * point. |
443 | * | ||
444 | * Locking: always called with BTM already held. | ||
443 | */ | 445 | */ |
444 | 446 | ||
445 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | 447 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) |
@@ -447,10 +449,10 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | |||
447 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); | 449 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); |
448 | if (ld->ops->open) { | 450 | if (ld->ops->open) { |
449 | int ret; | 451 | int ret; |
450 | /* BKL here locks verus a hangup event */ | 452 | /* BTM here locks versus a hangup event */ |
451 | lock_kernel(); | 453 | tty_lock_nested(); /* always held here already */ |
452 | ret = ld->ops->open(tty); | 454 | ret = ld->ops->open(tty); |
453 | unlock_kernel(); | 455 | tty_unlock(); |
454 | return ret; | 456 | return ret; |
455 | } | 457 | } |
456 | return 0; | 458 | return 0; |
@@ -553,7 +555,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
553 | if (IS_ERR(new_ldisc)) | 555 | if (IS_ERR(new_ldisc)) |
554 | return PTR_ERR(new_ldisc); | 556 | return PTR_ERR(new_ldisc); |
555 | 557 | ||
556 | lock_kernel(); | 558 | tty_lock(); |
557 | /* | 559 | /* |
558 | * We need to look at the tty locking here for pty/tty pairs | 560 | * We need to look at the tty locking here for pty/tty pairs |
559 | * when both sides try to change in parallel. | 561 | * when both sides try to change in parallel. |
@@ -567,12 +569,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
567 | */ | 569 | */ |
568 | 570 | ||
569 | if (tty->ldisc->ops->num == ldisc) { | 571 | if (tty->ldisc->ops->num == ldisc) { |
570 | unlock_kernel(); | 572 | tty_unlock(); |
571 | tty_ldisc_put(new_ldisc); | 573 | tty_ldisc_put(new_ldisc); |
572 | return 0; | 574 | return 0; |
573 | } | 575 | } |
574 | 576 | ||
575 | unlock_kernel(); | 577 | tty_unlock(); |
576 | /* | 578 | /* |
577 | * Problem: What do we do if this blocks ? | 579 | * Problem: What do we do if this blocks ? |
578 | * We could deadlock here | 580 | * We could deadlock here |
@@ -594,7 +596,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
594 | mutex_lock(&tty->ldisc_mutex); | 596 | mutex_lock(&tty->ldisc_mutex); |
595 | } | 597 | } |
596 | 598 | ||
597 | lock_kernel(); | 599 | tty_lock(); |
598 | 600 | ||
599 | set_bit(TTY_LDISC_CHANGING, &tty->flags); | 601 | set_bit(TTY_LDISC_CHANGING, &tty->flags); |
600 | 602 | ||
@@ -607,7 +609,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
607 | 609 | ||
608 | o_ldisc = tty->ldisc; | 610 | o_ldisc = tty->ldisc; |
609 | 611 | ||
610 | unlock_kernel(); | 612 | tty_unlock(); |
611 | /* | 613 | /* |
612 | * Make sure we don't change while someone holds a | 614 | * Make sure we don't change while someone holds a |
613 | * reference to the line discipline. The TTY_LDISC bit | 615 | * reference to the line discipline. The TTY_LDISC bit |
@@ -633,14 +635,14 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
633 | flush_scheduled_work(); | 635 | flush_scheduled_work(); |
634 | 636 | ||
635 | mutex_lock(&tty->ldisc_mutex); | 637 | mutex_lock(&tty->ldisc_mutex); |
636 | lock_kernel(); | 638 | tty_lock(); |
637 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 639 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
638 | /* We were raced by the hangup method. It will have stomped | 640 | /* We were raced by the hangup method. It will have stomped |
639 | the ldisc data and closed the ldisc down */ | 641 | the ldisc data and closed the ldisc down */ |
640 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 642 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
641 | mutex_unlock(&tty->ldisc_mutex); | 643 | mutex_unlock(&tty->ldisc_mutex); |
642 | tty_ldisc_put(new_ldisc); | 644 | tty_ldisc_put(new_ldisc); |
643 | unlock_kernel(); | 645 | tty_unlock(); |
644 | return -EIO; | 646 | return -EIO; |
645 | } | 647 | } |
646 | 648 | ||
@@ -682,7 +684,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
682 | if (o_work) | 684 | if (o_work) |
683 | schedule_delayed_work(&o_tty->buf.work, 1); | 685 | schedule_delayed_work(&o_tty->buf.work, 1); |
684 | mutex_unlock(&tty->ldisc_mutex); | 686 | mutex_unlock(&tty->ldisc_mutex); |
685 | unlock_kernel(); | 687 | tty_unlock(); |
686 | return retval; | 688 | return retval; |
687 | } | 689 | } |
688 | 690 | ||
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index c1791a63d99d..bcce46c96b88 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -463,10 +463,10 @@ vcs_open(struct inode *inode, struct file *filp) | |||
463 | unsigned int currcons = iminor(inode) & 127; | 463 | unsigned int currcons = iminor(inode) & 127; |
464 | int ret = 0; | 464 | int ret = 0; |
465 | 465 | ||
466 | lock_kernel(); | 466 | tty_lock(); |
467 | if(currcons && !vc_cons_allocated(currcons-1)) | 467 | if(currcons && !vc_cons_allocated(currcons-1)) |
468 | ret = -ENXIO; | 468 | ret = -ENXIO; |
469 | unlock_kernel(); | 469 | tty_unlock(); |
470 | return ret; | 470 | return ret; |
471 | } | 471 | } |
472 | 472 | ||
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 72dcfb2dc126..cf87c5336229 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -509,7 +509,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
509 | 509 | ||
510 | console = vc->vc_num; | 510 | console = vc->vc_num; |
511 | 511 | ||
512 | lock_kernel(); | 512 | tty_lock(); |
513 | 513 | ||
514 | if (!vc_cons_allocated(console)) { /* impossible? */ | 514 | if (!vc_cons_allocated(console)) { /* impossible? */ |
515 | ret = -ENOIOCTLCMD; | 515 | ret = -ENOIOCTLCMD; |
@@ -1336,7 +1336,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
1336 | ret = -ENOIOCTLCMD; | 1336 | ret = -ENOIOCTLCMD; |
1337 | } | 1337 | } |
1338 | out: | 1338 | out: |
1339 | unlock_kernel(); | 1339 | tty_unlock(); |
1340 | return ret; | 1340 | return ret; |
1341 | eperm: | 1341 | eperm: |
1342 | ret = -EPERM; | 1342 | ret = -EPERM; |
@@ -1503,7 +1503,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, | |||
1503 | 1503 | ||
1504 | console = vc->vc_num; | 1504 | console = vc->vc_num; |
1505 | 1505 | ||
1506 | lock_kernel(); | 1506 | tty_lock(); |
1507 | 1507 | ||
1508 | if (!vc_cons_allocated(console)) { /* impossible? */ | 1508 | if (!vc_cons_allocated(console)) { /* impossible? */ |
1509 | ret = -ENOIOCTLCMD; | 1509 | ret = -ENOIOCTLCMD; |
@@ -1571,11 +1571,11 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, | |||
1571 | goto fallback; | 1571 | goto fallback; |
1572 | } | 1572 | } |
1573 | out: | 1573 | out: |
1574 | unlock_kernel(); | 1574 | tty_unlock(); |
1575 | return ret; | 1575 | return ret; |
1576 | 1576 | ||
1577 | fallback: | 1577 | fallback: |
1578 | unlock_kernel(); | 1578 | tty_unlock(); |
1579 | return vt_ioctl(tty, file, cmd, arg); | 1579 | return vt_ioctl(tty, file, cmd, arg); |
1580 | } | 1580 | } |
1581 | 1581 | ||
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 768612f8e41e..16f5f2fab032 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -1705,7 +1705,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1705 | printk("jiff=%lu...", jiffies); | 1705 | printk("jiff=%lu...", jiffies); |
1706 | #endif | 1706 | #endif |
1707 | 1707 | ||
1708 | lock_kernel(); | 1708 | tty_lock_nested(); /* always held already since we come from ->close */ |
1709 | /* We go through the loop at least once because we can't tell | 1709 | /* We go through the loop at least once because we can't tell |
1710 | * exactly when the last character exits the shifter. There can | 1710 | * exactly when the last character exits the shifter. There can |
1711 | * be at least two characters waiting to be sent after the buffers | 1711 | * be at least two characters waiting to be sent after the buffers |
@@ -1734,7 +1734,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1734 | bdp--; | 1734 | bdp--; |
1735 | } while (bdp->status & BD_SC_READY); | 1735 | } while (bdp->status & BD_SC_READY); |
1736 | current->state = TASK_RUNNING; | 1736 | current->state = TASK_RUNNING; |
1737 | unlock_kernel(); | 1737 | tty_unlock(); |
1738 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1738 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1739 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1739 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1740 | #endif | 1740 | #endif |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 30626440a062..f848e188deae 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -3935,7 +3935,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3935 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO | 3935 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO |
3936 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) | 3936 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) |
3937 | */ | 3937 | */ |
3938 | lock_kernel(); | 3938 | tty_lock_nested(); /* locked already when coming from close */ |
3939 | orig_jiffies = jiffies; | 3939 | orig_jiffies = jiffies; |
3940 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ | 3940 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ |
3941 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ | 3941 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ |
@@ -3952,7 +3952,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3952 | curr_time_usec - info->last_tx_active_usec; | 3952 | curr_time_usec - info->last_tx_active_usec; |
3953 | } | 3953 | } |
3954 | set_current_state(TASK_RUNNING); | 3954 | set_current_state(TASK_RUNNING); |
3955 | unlock_kernel(); | 3955 | tty_unlock(); |
3956 | } | 3956 | } |
3957 | 3957 | ||
3958 | /* | 3958 | /* |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 3d2acc2265f7..851d7c29132b 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1274,7 +1274,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1274 | struct uart_port *uport; | 1274 | struct uart_port *uport; |
1275 | unsigned long flags; | 1275 | unsigned long flags; |
1276 | 1276 | ||
1277 | BUG_ON(!kernel_locked()); | 1277 | BUG_ON(!tty_locked()); |
1278 | 1278 | ||
1279 | if (!state) | 1279 | if (!state) |
1280 | return; | 1280 | return; |
@@ -1382,7 +1382,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1382 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) | 1382 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) |
1383 | return; | 1383 | return; |
1384 | 1384 | ||
1385 | lock_kernel(); | 1385 | tty_lock_nested(); /* already locked when coming from close */ |
1386 | 1386 | ||
1387 | /* | 1387 | /* |
1388 | * Set the check interval to be 1/5 of the estimated time to | 1388 | * Set the check interval to be 1/5 of the estimated time to |
@@ -1429,7 +1429,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1429 | break; | 1429 | break; |
1430 | } | 1430 | } |
1431 | set_current_state(TASK_RUNNING); /* might not be needed */ | 1431 | set_current_state(TASK_RUNNING); /* might not be needed */ |
1432 | unlock_kernel(); | 1432 | tty_unlock(); |
1433 | } | 1433 | } |
1434 | 1434 | ||
1435 | /* | 1435 | /* |
@@ -1444,7 +1444,7 @@ static void uart_hangup(struct tty_struct *tty) | |||
1444 | struct tty_port *port = &state->port; | 1444 | struct tty_port *port = &state->port; |
1445 | unsigned long flags; | 1445 | unsigned long flags; |
1446 | 1446 | ||
1447 | BUG_ON(!kernel_locked()); | 1447 | BUG_ON(!tty_locked()); |
1448 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); | 1448 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); |
1449 | 1449 | ||
1450 | mutex_lock(&port->mutex); | 1450 | mutex_lock(&port->mutex); |
@@ -1578,7 +1578,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1578 | struct tty_port *port; | 1578 | struct tty_port *port; |
1579 | int retval, line = tty->index; | 1579 | int retval, line = tty->index; |
1580 | 1580 | ||
1581 | BUG_ON(!kernel_locked()); | 1581 | BUG_ON(!tty_locked()); |
1582 | pr_debug("uart_open(%d) called\n", line); | 1582 | pr_debug("uart_open(%d) called\n", line); |
1583 | 1583 | ||
1584 | /* | 1584 | /* |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 182dd6f8aadd..71970057c118 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -1108,7 +1108,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) | |||
1108 | charmap += 4 * cmapsz; | 1108 | charmap += 4 * cmapsz; |
1109 | #endif | 1109 | #endif |
1110 | 1110 | ||
1111 | unlock_kernel(); | 1111 | tty_unlock(); |
1112 | spin_lock_irq(&vga_lock); | 1112 | spin_lock_irq(&vga_lock); |
1113 | /* First, the Sequencer */ | 1113 | /* First, the Sequencer */ |
1114 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); | 1114 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); |
@@ -1192,7 +1192,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) | |||
1192 | vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); | 1192 | vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); |
1193 | } | 1193 | } |
1194 | spin_unlock_irq(&vga_lock); | 1194 | spin_unlock_irq(&vga_lock); |
1195 | lock_kernel(); | 1195 | tty_lock(); |
1196 | return 0; | 1196 | return 0; |
1197 | } | 1197 | } |
1198 | 1198 | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 2df60e4ff40e..6ead6b60c743 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/tty_driver.h> | 13 | #include <linux/tty_driver.h> |
14 | #include <linux/tty_ldisc.h> | 14 | #include <linux/tty_ldisc.h> |
15 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
16 | #include <linux/smp_lock.h> | ||
16 | 17 | ||
17 | #include <asm/system.h> | 18 | #include <asm/system.h> |
18 | 19 | ||
@@ -576,5 +577,35 @@ extern int vt_ioctl(struct tty_struct *tty, struct file *file, | |||
576 | extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, | 577 | extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, |
577 | unsigned int cmd, unsigned long arg); | 578 | unsigned int cmd, unsigned long arg); |
578 | 579 | ||
580 | /* functions for preparation of BKL removal */ | ||
581 | |||
582 | /* | ||
583 | * tty_lock_nested get the tty_lock while potentially holding it | ||
584 | * | ||
585 | * The Big TTY Mutex is a recursive lock, meaning you can take it | ||
586 | * from a thread that is already holding it. | ||
587 | * This is bad for a number of reasons, so tty_lock_nested should | ||
588 | * really be used as rarely as possible. If a code location can | ||
589 | * be shown to never get called with this held already, it should | ||
590 | * use tty_lock() instead. | ||
591 | */ | ||
592 | static inline void __lockfunc tty_lock_nested(void) __acquires(kernel_lock) | ||
593 | { | ||
594 | lock_kernel(); | ||
595 | } | ||
596 | static inline void tty_lock(void) __acquires(kernel_lock) | ||
597 | { | ||
598 | #ifdef CONFIG_LOCK_KERNEL | ||
599 | /* kernel_locked is 1 for !CONFIG_LOCK_KERNEL */ | ||
600 | WARN_ON(kernel_locked()); | ||
601 | #endif | ||
602 | lock_kernel(); | ||
603 | } | ||
604 | static inline void tty_unlock(void) __releases(kernel_lock) | ||
605 | { | ||
606 | unlock_kernel(); | ||
607 | } | ||
608 | #define tty_locked() (kernel_locked()) | ||
609 | |||
579 | #endif /* __KERNEL__ */ | 610 | #endif /* __KERNEL__ */ |
580 | #endif | 611 | #endif |