diff options
author | Alan Cox <alan@linux.intel.com> | 2012-05-03 17:24:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-04 19:58:47 -0400 |
commit | d29f3ef39be4eec0362b985305fc526d9be318cf (patch) | |
tree | 35da6af15a899ca767841b864cb1ef290a0f3d4a /drivers/tty/tty_io.c | |
parent | d739e65bb21d34f0f5d3bf4048410e534fbec148 (diff) |
tty_lock: Localise the lock
In each remaining case the tty_lock is associated with a specific tty. This
means we can now lock on a per tty basis. We do need tty_lock_pair() for
the pty case. Uglier but still a step in the right direction.
[fixed up calls in 3 missing drivers - gregkh]
Signed-off-by: Alan Cox <alan@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..9e930c009bf2 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -185,6 +185,7 @@ void free_tty_struct(struct tty_struct *tty) | |||
185 | put_device(tty->dev); | 185 | put_device(tty->dev); |
186 | kfree(tty->write_buf); | 186 | kfree(tty->write_buf); |
187 | tty_buffer_free_all(tty); | 187 | tty_buffer_free_all(tty); |
188 | tty->magic = 0xDEADDEAD; | ||
188 | kfree(tty); | 189 | kfree(tty); |
189 | } | 190 | } |
190 | 191 | ||
@@ -573,7 +574,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
573 | } | 574 | } |
574 | spin_unlock(&redirect_lock); | 575 | spin_unlock(&redirect_lock); |
575 | 576 | ||
576 | tty_lock(); | 577 | tty_lock(tty); |
577 | 578 | ||
578 | /* some functions below drop BTM, so we need this bit */ | 579 | /* some functions below drop BTM, so we need this bit */ |
579 | set_bit(TTY_HUPPING, &tty->flags); | 580 | set_bit(TTY_HUPPING, &tty->flags); |
@@ -666,7 +667,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
666 | clear_bit(TTY_HUPPING, &tty->flags); | 667 | clear_bit(TTY_HUPPING, &tty->flags); |
667 | tty_ldisc_enable(tty); | 668 | tty_ldisc_enable(tty); |
668 | 669 | ||
669 | tty_unlock(); | 670 | tty_unlock(tty); |
670 | 671 | ||
671 | if (f) | 672 | if (f) |
672 | fput(f); | 673 | fput(f); |
@@ -1103,12 +1104,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1103 | { | 1104 | { |
1104 | if (tty) { | 1105 | if (tty) { |
1105 | mutex_lock(&tty->atomic_write_lock); | 1106 | mutex_lock(&tty->atomic_write_lock); |
1106 | tty_lock(); | 1107 | tty_lock(tty); |
1107 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1108 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1108 | tty_unlock(); | 1109 | tty_unlock(tty); |
1109 | tty->ops->write(tty, msg, strlen(msg)); | 1110 | tty->ops->write(tty, msg, strlen(msg)); |
1110 | } else | 1111 | } else |
1111 | tty_unlock(); | 1112 | tty_unlock(tty); |
1112 | tty_write_unlock(tty); | 1113 | tty_write_unlock(tty); |
1113 | } | 1114 | } |
1114 | return; | 1115 | return; |
@@ -1403,6 +1404,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1403 | } | 1404 | } |
1404 | initialize_tty_struct(tty, driver, idx); | 1405 | initialize_tty_struct(tty, driver, idx); |
1405 | 1406 | ||
1407 | tty_lock(tty); | ||
1406 | retval = tty_driver_install_tty(driver, tty); | 1408 | retval = tty_driver_install_tty(driver, tty); |
1407 | if (retval < 0) | 1409 | if (retval < 0) |
1408 | goto err_deinit_tty; | 1410 | goto err_deinit_tty; |
@@ -1415,9 +1417,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1415 | retval = tty_ldisc_setup(tty, tty->link); | 1417 | retval = tty_ldisc_setup(tty, tty->link); |
1416 | if (retval) | 1418 | if (retval) |
1417 | goto err_release_tty; | 1419 | goto err_release_tty; |
1420 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
1418 | return tty; | 1421 | return tty; |
1419 | 1422 | ||
1420 | err_deinit_tty: | 1423 | err_deinit_tty: |
1424 | tty_unlock(tty); | ||
1421 | deinitialize_tty_struct(tty); | 1425 | deinitialize_tty_struct(tty); |
1422 | free_tty_struct(tty); | 1426 | free_tty_struct(tty); |
1423 | err_module_put: | 1427 | err_module_put: |
@@ -1426,6 +1430,7 @@ err_module_put: | |||
1426 | 1430 | ||
1427 | /* call the tty release_tty routine to clean out this slot */ | 1431 | /* call the tty release_tty routine to clean out this slot */ |
1428 | err_release_tty: | 1432 | err_release_tty: |
1433 | tty_unlock(tty); | ||
1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1434 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1430 | "clearing slot %d\n", idx); | 1435 | "clearing slot %d\n", idx); |
1431 | release_tty(tty, idx); | 1436 | release_tty(tty, idx); |
@@ -1628,7 +1633,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1633 | if (tty_paranoia_check(tty, inode, __func__)) |
1629 | return 0; | 1634 | return 0; |
1630 | 1635 | ||
1631 | tty_lock(); | 1636 | tty_lock(tty); |
1632 | check_tty_count(tty, __func__); | 1637 | check_tty_count(tty, __func__); |
1633 | 1638 | ||
1634 | __tty_fasync(-1, filp, 0); | 1639 | __tty_fasync(-1, filp, 0); |
@@ -1637,10 +1642,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1642 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1643 | tty->driver->subtype == PTY_TYPE_MASTER); |
1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1644 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1645 | /* Review: parallel close */ | ||
1640 | o_tty = tty->link; | 1646 | o_tty = tty->link; |
1641 | 1647 | ||
1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1648 | if (tty_release_checks(tty, o_tty, idx)) { |
1643 | tty_unlock(); | 1649 | tty_unlock(tty); |
1644 | return 0; | 1650 | return 0; |
1645 | } | 1651 | } |
1646 | 1652 | ||
@@ -1652,7 +1658,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1652 | if (tty->ops->close) | 1658 | if (tty->ops->close) |
1653 | tty->ops->close(tty, filp); | 1659 | tty->ops->close(tty, filp); |
1654 | 1660 | ||
1655 | tty_unlock(); | 1661 | tty_unlock(tty); |
1656 | /* | 1662 | /* |
1657 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1663 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1658 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1664 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1675,7 +1681,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1675 | opens on /dev/tty */ | 1681 | opens on /dev/tty */ |
1676 | 1682 | ||
1677 | mutex_lock(&tty_mutex); | 1683 | mutex_lock(&tty_mutex); |
1678 | tty_lock(); | 1684 | tty_lock_pair(tty, o_tty); |
1679 | tty_closing = tty->count <= 1; | 1685 | tty_closing = tty->count <= 1; |
1680 | o_tty_closing = o_tty && | 1686 | o_tty_closing = o_tty && |
1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1687 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1706,7 +1712,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1706 | 1712 | ||
1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1713 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1708 | __func__, tty_name(tty, buf)); | 1714 | __func__, tty_name(tty, buf)); |
1709 | tty_unlock(); | 1715 | tty_unlock_pair(tty, o_tty); |
1710 | mutex_unlock(&tty_mutex); | 1716 | mutex_unlock(&tty_mutex); |
1711 | schedule(); | 1717 | schedule(); |
1712 | } | 1718 | } |
@@ -1769,7 +1775,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1769 | 1775 | ||
1770 | /* check whether both sides are closing ... */ | 1776 | /* check whether both sides are closing ... */ |
1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1777 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1772 | tty_unlock(); | 1778 | tty_unlock_pair(tty, o_tty); |
1773 | return 0; | 1779 | return 0; |
1774 | } | 1780 | } |
1775 | 1781 | ||
@@ -1782,14 +1788,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1782 | tty_ldisc_release(tty, o_tty); | 1788 | tty_ldisc_release(tty, o_tty); |
1783 | /* | 1789 | /* |
1784 | * The release_tty function takes care of the details of clearing | 1790 | * The release_tty function takes care of the details of clearing |
1785 | * the slots and preserving the termios structure. | 1791 | * the slots and preserving the termios structure. The tty_unlock_pair |
1792 | * should be safe as we keep a kref while the tty is locked (so the | ||
1793 | * unlock never unlocks a freed tty). | ||
1786 | */ | 1794 | */ |
1787 | release_tty(tty, idx); | 1795 | release_tty(tty, idx); |
1796 | tty_unlock_pair(tty, o_tty); | ||
1788 | 1797 | ||
1789 | /* Make this pty number available for reallocation */ | 1798 | /* Make this pty number available for reallocation */ |
1790 | if (devpts) | 1799 | if (devpts) |
1791 | devpts_kill_index(inode, idx); | 1800 | devpts_kill_index(inode, idx); |
1792 | tty_unlock(); | ||
1793 | return 0; | 1801 | return 0; |
1794 | } | 1802 | } |
1795 | 1803 | ||
@@ -1893,6 +1901,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1893 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1901 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1894 | * tty->count should protect the rest. | 1902 | * tty->count should protect the rest. |
1895 | * ->siglock protects ->signal/->sighand | 1903 | * ->siglock protects ->signal/->sighand |
1904 | * | ||
1905 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
1906 | * tty_mutex | ||
1896 | */ | 1907 | */ |
1897 | 1908 | ||
1898 | static int tty_open(struct inode *inode, struct file *filp) | 1909 | static int tty_open(struct inode *inode, struct file *filp) |
@@ -1916,8 +1927,7 @@ retry_open: | |||
1916 | retval = 0; | 1927 | retval = 0; |
1917 | 1928 | ||
1918 | mutex_lock(&tty_mutex); | 1929 | mutex_lock(&tty_mutex); |
1919 | tty_lock(); | 1930 | /* This is protected by the tty_mutex */ |
1920 | |||
1921 | tty = tty_open_current_tty(device, filp); | 1931 | tty = tty_open_current_tty(device, filp); |
1922 | if (IS_ERR(tty)) { | 1932 | if (IS_ERR(tty)) { |
1923 | retval = PTR_ERR(tty); | 1933 | retval = PTR_ERR(tty); |
@@ -1938,17 +1948,19 @@ retry_open: | |||
1938 | } | 1948 | } |
1939 | 1949 | ||
1940 | if (tty) { | 1950 | if (tty) { |
1951 | tty_lock(tty); | ||
1941 | retval = tty_reopen(tty); | 1952 | retval = tty_reopen(tty); |
1942 | if (retval) | 1953 | if (retval < 0) { |
1954 | tty_unlock(tty); | ||
1943 | tty = ERR_PTR(retval); | 1955 | tty = ERR_PTR(retval); |
1944 | } else | 1956 | } |
1957 | } else /* Returns with the tty_lock held for now */ | ||
1945 | tty = tty_init_dev(driver, index); | 1958 | tty = tty_init_dev(driver, index); |
1946 | 1959 | ||
1947 | mutex_unlock(&tty_mutex); | 1960 | mutex_unlock(&tty_mutex); |
1948 | if (driver) | 1961 | if (driver) |
1949 | tty_driver_kref_put(driver); | 1962 | tty_driver_kref_put(driver); |
1950 | if (IS_ERR(tty)) { | 1963 | if (IS_ERR(tty)) { |
1951 | tty_unlock(); | ||
1952 | retval = PTR_ERR(tty); | 1964 | retval = PTR_ERR(tty); |
1953 | goto err_file; | 1965 | goto err_file; |
1954 | } | 1966 | } |
@@ -1977,7 +1989,7 @@ retry_open: | |||
1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1989 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1978 | retval, tty->name); | 1990 | retval, tty->name); |
1979 | #endif | 1991 | #endif |
1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1992 | tty_unlock(tty); /* need to call tty_release without BTM */ |
1981 | tty_release(inode, filp); | 1993 | tty_release(inode, filp); |
1982 | if (retval != -ERESTARTSYS) | 1994 | if (retval != -ERESTARTSYS) |
1983 | return retval; | 1995 | return retval; |
@@ -1989,17 +2001,15 @@ retry_open: | |||
1989 | /* | 2001 | /* |
1990 | * Need to reset f_op in case a hangup happened. | 2002 | * Need to reset f_op in case a hangup happened. |
1991 | */ | 2003 | */ |
1992 | tty_lock(); | ||
1993 | if (filp->f_op == &hung_up_tty_fops) | 2004 | if (filp->f_op == &hung_up_tty_fops) |
1994 | filp->f_op = &tty_fops; | 2005 | filp->f_op = &tty_fops; |
1995 | tty_unlock(); | ||
1996 | goto retry_open; | 2006 | goto retry_open; |
1997 | } | 2007 | } |
1998 | tty_unlock(); | 2008 | tty_unlock(tty); |
1999 | 2009 | ||
2000 | 2010 | ||
2001 | mutex_lock(&tty_mutex); | 2011 | mutex_lock(&tty_mutex); |
2002 | tty_lock(); | 2012 | tty_lock(tty); |
2003 | spin_lock_irq(¤t->sighand->siglock); | 2013 | spin_lock_irq(¤t->sighand->siglock); |
2004 | if (!noctty && | 2014 | if (!noctty && |
2005 | current->signal->leader && | 2015 | current->signal->leader && |
@@ -2007,11 +2017,10 @@ retry_open: | |||
2007 | tty->session == NULL) | 2017 | tty->session == NULL) |
2008 | __proc_set_tty(current, tty); | 2018 | __proc_set_tty(current, tty); |
2009 | spin_unlock_irq(¤t->sighand->siglock); | 2019 | spin_unlock_irq(¤t->sighand->siglock); |
2010 | tty_unlock(); | 2020 | tty_unlock(tty); |
2011 | mutex_unlock(&tty_mutex); | 2021 | mutex_unlock(&tty_mutex); |
2012 | return 0; | 2022 | return 0; |
2013 | err_unlock: | 2023 | err_unlock: |
2014 | tty_unlock(); | ||
2015 | mutex_unlock(&tty_mutex); | 2024 | mutex_unlock(&tty_mutex); |
2016 | /* after locks to avoid deadlock */ | 2025 | /* after locks to avoid deadlock */ |
2017 | if (!IS_ERR_OR_NULL(driver)) | 2026 | if (!IS_ERR_OR_NULL(driver)) |
@@ -2094,10 +2103,13 @@ out: | |||
2094 | 2103 | ||
2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2104 | static int tty_fasync(int fd, struct file *filp, int on) |
2096 | { | 2105 | { |
2106 | struct tty_struct *tty = file_tty(filp); | ||
2097 | int retval; | 2107 | int retval; |
2098 | tty_lock(); | 2108 | |
2109 | tty_lock(tty); | ||
2099 | retval = __tty_fasync(fd, filp, on); | 2110 | retval = __tty_fasync(fd, filp, on); |
2100 | tty_unlock(); | 2111 | tty_unlock(tty); |
2112 | |||
2101 | return retval; | 2113 | return retval; |
2102 | } | 2114 | } |
2103 | 2115 | ||
@@ -2934,6 +2946,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2934 | tty->pgrp = NULL; | 2946 | tty->pgrp = NULL; |
2935 | tty->overrun_time = jiffies; | 2947 | tty->overrun_time = jiffies; |
2936 | tty_buffer_init(tty); | 2948 | tty_buffer_init(tty); |
2949 | mutex_init(&tty->legacy_mutex); | ||
2937 | mutex_init(&tty->termios_mutex); | 2950 | mutex_init(&tty->termios_mutex); |
2938 | mutex_init(&tty->ldisc_mutex); | 2951 | mutex_init(&tty->ldisc_mutex); |
2939 | init_waitqueue_head(&tty->write_wait); | 2952 | init_waitqueue_head(&tty->write_wait); |