aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-06-01 16:53:01 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:43 -0400
commitec79d6056de58511d8e46d9ae59d3878f958dc3e (patch)
tree8e73cf399c4cb3c31dbf3caced385cfc018a706a /drivers/char/tty_io.c
parent3f582b8c11014e4ce310d9839fb335164195333f (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>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c115
1 files changed, 64 insertions, 51 deletions
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
152static int __tty_fasync(int fd, struct file *filp, int on);
152static int tty_fasync(int fd, struct file *filp, int on); 153static int tty_fasync(int fd, struct file *filp, int on);
153static void release_tty(struct tty_struct *tty, int idx); 154static void release_tty(struct tty_struct *tty, int idx);
154static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); 155static 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)
774void no_tty(void) 779void 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
1019void tty_write_message(struct tty_struct *tty, char *msg) 1024void 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(&current->sighand->siglock); 1892 spin_lock_irq(&current->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(&current->sighand->siglock); 1898 spin_unlock_irq(&current->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
1929static int tty_fasync(int fd, struct file *filp, int on) 1935static 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;
1968out: 1973out:
1969 unlock_kernel(); 1974 return retval;
1975}
1976
1977static 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