diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-02 15:21:43 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-02 15:21:43 -0700 |
commit | f309532bf3e1cc1b787403d84e3039812a7dbe50 (patch) | |
tree | 6508ac81e94bfc137d1d9a55b973a2e0e0ac007b /drivers/tty/tty_io.c | |
parent | 233e562eac549f4f719176bbddeb50c3f17a9c8d (diff) |
tty: Revert the tty locking series, it needs more work
This reverts the tty layer change to use per-tty locking, because it's
not correct yet, and fixing it will require some more deep surgery.
The main revert is d29f3ef39be4 ("tty_lock: Localise the lock"), but
there are several smaller commits that built upon it, they also get
reverted here. The list of reverted commits is:
fde86d310886 - tty: add lockdep annotations
8f6576ad476b - tty: fix ldisc lock inversion trace
d3ca8b64b97e - pty: Fix lock inversion
b1d679afd766 - tty: drop the pty lock during hangup
abcefe5fc357 - tty/amiserial: Add missing argument for tty_unlock()
fd11b42e3598 - cris: fix missing tty arg in wait_event_interruptible_tty call
d29f3ef39be4 - tty_lock: Localise the lock
The revert had a trivial conflict in the 68360serial.c staging driver
that got removed in the meantime.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 67 |
1 files changed, 27 insertions, 40 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9e930c009bf..b425c79675a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -185,7 +185,6 @@ void free_tty_struct(struct tty_struct *tty) put_device(tty->dev); kfree(tty->write_buf); tty_buffer_free_all(tty); - tty->magic = 0xDEADDEAD; kfree(tty); } @@ -574,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty) } spin_unlock(&redirect_lock); - tty_lock(tty); + tty_lock(); /* some functions below drop BTM, so we need this bit */ set_bit(TTY_HUPPING, &tty->flags); @@ -667,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty) clear_bit(TTY_HUPPING, &tty->flags); tty_ldisc_enable(tty); - tty_unlock(tty); + tty_unlock(); if (f) fput(f); @@ -1104,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) { if (tty) { mutex_lock(&tty->atomic_write_lock); - tty_lock(tty); + tty_lock(); if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { - tty_unlock(tty); + tty_unlock(); tty->ops->write(tty, msg, strlen(msg)); } else - tty_unlock(tty); + tty_unlock(); tty_write_unlock(tty); } return; @@ -1404,7 +1403,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) } initialize_tty_struct(tty, driver, idx); - tty_lock(tty); retval = tty_driver_install_tty(driver, tty); if (retval < 0) goto err_deinit_tty; @@ -1417,11 +1415,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) retval = tty_ldisc_setup(tty, tty->link); if (retval) goto err_release_tty; - /* Return the tty locked so that it cannot vanish under the caller */ return tty; err_deinit_tty: - tty_unlock(tty); deinitialize_tty_struct(tty); free_tty_struct(tty); err_module_put: @@ -1430,7 +1426,6 @@ err_module_put: /* call the tty release_tty routine to clean out this slot */ err_release_tty: - tty_unlock(tty); printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " "clearing slot %d\n", idx); release_tty(tty, idx); @@ -1633,7 +1628,7 @@ int tty_release(struct inode *inode, struct file *filp) if (tty_paranoia_check(tty, inode, __func__)) return 0; - tty_lock(tty); + tty_lock(); check_tty_count(tty, __func__); __tty_fasync(-1, filp, 0); @@ -1642,11 +1637,10 @@ int tty_release(struct inode *inode, struct file *filp) pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; - /* Review: parallel close */ o_tty = tty->link; if (tty_release_checks(tty, o_tty, idx)) { - tty_unlock(tty); + tty_unlock(); return 0; } @@ -1658,7 +1652,7 @@ int tty_release(struct inode *inode, struct file *filp) if (tty->ops->close) tty->ops->close(tty, filp); - tty_unlock(tty); + tty_unlock(); /* * Sanity check: if tty->count is going to zero, there shouldn't be * any waiters on tty->read_wait or tty->write_wait. We test the @@ -1681,7 +1675,7 @@ int tty_release(struct inode *inode, struct file *filp) opens on /dev/tty */ mutex_lock(&tty_mutex); - tty_lock_pair(tty, o_tty); + tty_lock(); tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); @@ -1712,7 +1706,7 @@ int tty_release(struct inode *inode, struct file *filp) printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", __func__, tty_name(tty, buf)); - tty_unlock_pair(tty, o_tty); + tty_unlock(); mutex_unlock(&tty_mutex); schedule(); } @@ -1775,7 +1769,7 @@ int tty_release(struct inode *inode, struct file *filp) /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) { - tty_unlock_pair(tty, o_tty); + tty_unlock(); return 0; } @@ -1788,16 +1782,14 @@ int tty_release(struct inode *inode, struct file *filp) tty_ldisc_release(tty, o_tty); /* * The release_tty function takes care of the details of clearing - * the slots and preserving the termios structure. The tty_unlock_pair - * should be safe as we keep a kref while the tty is locked (so the - * unlock never unlocks a freed tty). + * the slots and preserving the termios structure. */ release_tty(tty, idx); - tty_unlock_pair(tty, o_tty); /* Make this pty number available for reallocation */ if (devpts) devpts_kill_index(inode, idx); + tty_unlock(); return 0; } @@ -1901,9 +1893,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. * tty->count should protect the rest. * ->siglock protects ->signal/->sighand - * - * Note: the tty_unlock/lock cases without a ref are only safe due to - * tty_mutex */ static int tty_open(struct inode *inode, struct file *filp) @@ -1927,7 +1916,8 @@ retry_open: retval = 0; mutex_lock(&tty_mutex); - /* This is protected by the tty_mutex */ + tty_lock(); + tty = tty_open_current_tty(device, filp); if (IS_ERR(tty)) { retval = PTR_ERR(tty); @@ -1948,19 +1938,17 @@ retry_open: } if (tty) { - tty_lock(tty); retval = tty_reopen(tty); - if (retval < 0) { - tty_unlock(tty); + if (retval) tty = ERR_PTR(retval); - } - } else /* Returns with the tty_lock held for now */ + } else tty = tty_init_dev(driver, index); mutex_unlock(&tty_mutex); if (driver) tty_driver_kref_put(driver); if (IS_ERR(tty)) { + tty_unlock(); retval = PTR_ERR(tty); goto err_file; } @@ -1989,7 +1977,7 @@ retry_open: printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, retval, tty->name); #endif - tty_unlock(tty); /* need to call tty_release without BTM */ + tty_unlock(); /* need to call tty_release without BTM */ tty_release(inode, filp); if (retval != -ERESTARTSYS) return retval; @@ -2001,15 +1989,17 @@ retry_open: /* * Need to reset f_op in case a hangup happened. */ + tty_lock(); if (filp->f_op == &hung_up_tty_fops) filp->f_op = &tty_fops; + tty_unlock(); goto retry_open; } - tty_unlock(tty); + tty_unlock(); mutex_lock(&tty_mutex); - tty_lock(tty); + tty_lock(); spin_lock_irq(¤t->sighand->siglock); if (!noctty && current->signal->leader && @@ -2017,10 +2007,11 @@ retry_open: tty->session == NULL) __proc_set_tty(current, tty); spin_unlock_irq(¤t->sighand->siglock); - tty_unlock(tty); + tty_unlock(); mutex_unlock(&tty_mutex); return 0; err_unlock: + tty_unlock(); mutex_unlock(&tty_mutex); /* after locks to avoid deadlock */ if (!IS_ERR_OR_NULL(driver)) @@ -2103,13 +2094,10 @@ out: static int tty_fasync(int fd, struct file *filp, int on) { - struct tty_struct *tty = file_tty(filp); int retval; - - tty_lock(tty); + tty_lock(); retval = __tty_fasync(fd, filp, on); - tty_unlock(tty); - + tty_unlock(); return retval; } @@ -2946,7 +2934,6 @@ void initialize_tty_struct(struct tty_struct *tty, tty->pgrp = NULL; tty->overrun_time = jiffies; tty_buffer_init(tty); - mutex_init(&tty->legacy_mutex); mutex_init(&tty->termios_mutex); mutex_init(&tty->ldisc_mutex); init_waitqueue_head(&tty->write_wait); |