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 d29f3ef39b ("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:

  fde86d3108 - tty: add lockdep annotations
  8f6576ad47 - tty: fix ldisc lock inversion trace
  d3ca8b64b9 - pty: Fix lock inversion
  b1d679afd7 - tty: drop the pty lock during hangup
  abcefe5fc3 - tty/amiserial: Add missing argument for tty_unlock()
  fd11b42e35 - cris: fix missing tty arg in wait_event_interruptible_tty call
  d29f3ef39b - 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>
This commit is contained in:
Linus Torvalds 2012-06-02 15:21:43 -07:00
parent 233e562eac
commit f309532bf3
14 changed files with 119 additions and 191 deletions

View File

@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
if (!retinfo)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
tty_lock(tty);
tty_lock();
tmp.line = tty->index;
tmp.port = state->port;
tmp.flags = state->tport.flags;
@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
tmp.close_delay = state->tport.close_delay;
tmp.closing_wait = state->tport.closing_wait;
tmp.custom_divisor = state->custom_divisor;
tty_unlock(tty);
tty_unlock();
if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
return -EFAULT;
return 0;
@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
return -EFAULT;
tty_lock(tty);
tty_lock();
change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
new_serial.custom_divisor != state->custom_divisor;
if (new_serial.irq || new_serial.port != state->port ||
new_serial.xmit_fifo_size != state->xmit_fifo_size) {
tty_unlock(tty);
tty_unlock();
return -EINVAL;
}
@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
(new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
((new_serial.flags & ~ASYNC_USR_MASK) !=
(port->flags & ~ASYNC_USR_MASK))) {
tty_unlock(tty);
tty_unlock();
return -EPERM;
}
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
}
if (new_serial.baud_base < 9600) {
tty_unlock(tty);
tty_unlock();
return -EINVAL;
}
@ -1116,7 +1116,7 @@ check_and_exit:
}
} else
retval = startup(tty, state);
tty_unlock(tty);
tty_unlock();
return retval;
}

View File

@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->port.close_wait,
wait_event_interruptible_tty(info->port.close_wait,
!(info->port.flags & ASYNC_CLOSING));
return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}

View File

@ -1065,8 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
TRACE_L("read()");
/* FIXME: should use a private lock */
tty_lock(tty);
tty_lock();
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
@ -1078,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
goto unlock;
}
/* block until there is a message: */
wait_event_interruptible_tty(tty, pInfo->read_wait,
wait_event_interruptible_tty(pInfo->read_wait,
(pMsg = remove_msg(pInfo, pClient)));
}
@ -1108,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
}
ret = -EPERM;
unlock:
tty_unlock(tty);
tty_unlock();
return ret;
}
@ -1157,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
pHeader->locks = 0;
pHeader->owner = NULL;
tty_lock(tty);
tty_lock();
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
@ -1176,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
add_tx_queue(pInfo, pHeader);
trigger_transmit(pInfo);
tty_unlock(tty);
tty_unlock();
return 0;
}

View File

@ -47,7 +47,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
wake_up_interruptible(&tty->read_wait);
wake_up_interruptible(&tty->write_wait);
tty->packet = 0;
/* Review - krefs on tty_link ?? */
if (!tty->link)
return;
tty->link->packet = 0;
@ -63,9 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&devpts_mutex);
}
#endif
tty_unlock(tty);
tty_unlock();
tty_vhangup(tty->link);
tty_lock(tty);
tty_lock();
}
}
@ -623,27 +622,26 @@ static int ptmx_open(struct inode *inode, struct file *filp)
return retval;
/* find a device that is not in use. */
mutex_lock(&devpts_mutex);
tty_lock();
index = devpts_new_index(inode);
tty_unlock();
if (index < 0) {
retval = index;
goto err_file;
}
mutex_unlock(&devpts_mutex);
mutex_lock(&tty_mutex);
mutex_lock(&devpts_mutex);
tty = tty_init_dev(ptm_driver, index);
mutex_unlock(&devpts_mutex);
tty_lock();
mutex_unlock(&tty_mutex);
if (IS_ERR(tty)) {
retval = PTR_ERR(tty);
goto out;
}
/* The tty returned here is locked so we can safely
drop the mutex */
mutex_unlock(&tty_mutex);
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
tty_add_file(tty, filp);
@ -656,17 +654,16 @@ static int ptmx_open(struct inode *inode, struct file *filp)
if (retval)
goto err_release;
tty_unlock(tty);
tty_unlock();
return 0;
err_release:
tty_unlock(tty);
tty_unlock();
tty_release(inode, filp);
return retval;
out:
mutex_unlock(&tty_mutex);
devpts_kill_index(inode, index);
tty_unlock();
err_file:
mutex_unlock(&devpts_mutex);
tty_free_file(filp);
return retval;
}

View File

@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->close_wait,
wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
if (info->flags & ASYNC_HUP_NOTIFY)
@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
printk("block_til_ready blocking: ttyS%d, count = %d\n",
info->line, info->count);
#endif
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->close_wait,
wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ?

View File

@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
printk("%s(%d):block_til_ready blocking on %s count=%d\n",
__FILE__,__LINE__, tty->driver->name, port->count );
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
set_current_state(TASK_RUNNING);

View File

@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
set_current_state(TASK_RUNNING);

View File

@ -3357,9 +3357,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
printk("%s(%d):%s block_til_ready() count=%d\n",
__FILE__,__LINE__, tty->driver->name, port->count );
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
set_current_state(TASK_RUNNING);

View File

@ -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(&current->sighand->siglock);
if (!noctty &&
current->signal->leader &&
@ -2017,10 +2007,11 @@ retry_open:
tty->session == NULL)
__proc_set_tty(current, tty);
spin_unlock_irq(&current->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);

View File

@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (IS_ERR(new_ldisc))
return PTR_ERR(new_ldisc);
tty_lock(tty);
tty_lock();
/*
* We need to look at the tty locking here for pty/tty pairs
* when both sides try to change in parallel.
@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
*/
if (tty->ldisc->ops->num == ldisc) {
tty_unlock(tty);
tty_unlock();
tty_ldisc_put(new_ldisc);
return 0;
}
tty_unlock(tty);
tty_unlock();
/*
* Problem: What do we do if this blocks ?
* We could deadlock here
@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_wait_until_sent(tty, 0);
tty_lock(tty);
tty_lock();
mutex_lock(&tty->ldisc_mutex);
/*
@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
mutex_unlock(&tty->ldisc_mutex);
tty_unlock(tty);
tty_unlock();
wait_event(tty_ldisc_wait,
test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
tty_lock(tty);
tty_lock();
mutex_lock(&tty->ldisc_mutex);
}
@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
o_ldisc = tty->ldisc;
tty_unlock(tty);
tty_unlock();
/*
* Make sure we don't change while someone holds a
* reference to the line discipline. The TTY_LDISC bit
@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
retval = tty_ldisc_wait_idle(tty, 5 * HZ);
tty_lock(tty);
tty_lock();
mutex_lock(&tty->ldisc_mutex);
/* handle wait idle failure locked */
@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
clear_bit(TTY_LDISC_CHANGING, &tty->flags);
mutex_unlock(&tty->ldisc_mutex);
tty_ldisc_put(new_ldisc);
tty_unlock(tty);
tty_unlock();
return -EIO;
}
@ -708,7 +708,7 @@ enable:
if (o_work)
schedule_work(&o_tty->buf.work);
mutex_unlock(&tty->ldisc_mutex);
tty_unlock(tty);
tty_unlock();
return retval;
}
@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty)
* need to wait for another function taking the BTM
*/
clear_bit(TTY_LDISC, &tty->flags);
tty_unlock(tty);
tty_unlock();
cancel_work_sync(&tty->buf.work);
mutex_unlock(&tty->ldisc_mutex);
retry:
tty_lock(tty);
tty_lock();
mutex_lock(&tty->ldisc_mutex);
/* At this point we have a closed ldisc and we want to
@ -831,7 +831,7 @@ retry:
if (atomic_read(&tty->ldisc->users) != 1) {
char cur_n[TASK_COMM_LEN], tty_n[64];
long timeout = 3 * HZ;
tty_unlock(tty);
tty_unlock();
while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
timeout = MAX_SCHEDULE_TIMEOUT;
@ -894,23 +894,6 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
tty_ldisc_enable(tty);
return 0;
}
static void tty_ldisc_kill(struct tty_struct *tty)
{
mutex_lock(&tty->ldisc_mutex);
/*
* Now kill off the ldisc
*/
tty_ldisc_close(tty, tty->ldisc);
tty_ldisc_put(tty->ldisc);
/* Force an oops if we mess this up */
tty->ldisc = NULL;
/* Ensure the next open requests the N_TTY ldisc */
tty_set_termios_ldisc(tty, N_TTY);
mutex_unlock(&tty->ldisc_mutex);
}
/**
* tty_ldisc_release - release line discipline
* @tty: tty being shut down
@ -929,19 +912,27 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
* race with the set_ldisc code path.
*/
tty_unlock_pair(tty, o_tty);
tty_unlock();
tty_ldisc_halt(tty);
tty_ldisc_flush_works(tty);
if (o_tty) {
tty_ldisc_halt(o_tty);
tty_ldisc_flush_works(o_tty);
}
tty_lock_pair(tty, o_tty);
tty_lock();
mutex_lock(&tty->ldisc_mutex);
/*
* Now kill off the ldisc
*/
tty_ldisc_close(tty, tty->ldisc);
tty_ldisc_put(tty->ldisc);
/* Force an oops if we mess this up */
tty->ldisc = NULL;
tty_ldisc_kill(tty);
/* Ensure the next open requests the N_TTY ldisc */
tty_set_termios_ldisc(tty, N_TTY);
mutex_unlock(&tty->ldisc_mutex);
/* This will need doing differently if we need to lock */
if (o_tty)
tty_ldisc_kill(o_tty);
tty_ldisc_release(o_tty, NULL);
/* And the memory resources remaining (buffers, termios) will be
disposed of when the kref hits zero */

View File

@ -4,70 +4,29 @@
#include <linux/semaphore.h>
#include <linux/sched.h>
/* Legacy tty mutex glue */
enum {
TTY_MUTEX_NORMAL,
TTY_MUTEX_NESTED,
};
/*
* The 'big tty mutex'
*
* This mutex is taken and released by tty_lock() and tty_unlock(),
* replacing the older big kernel lock.
* It can no longer be taken recursively, and does not get
* released implicitly while sleeping.
*
* Don't use in new code.
*/
static DEFINE_MUTEX(big_tty_mutex);
/*
* Getting the big tty mutex.
*/
static void __lockfunc tty_lock_nested(struct tty_struct *tty,
unsigned int subclass)
void __lockfunc tty_lock(void)
{
if (tty->magic != TTY_MAGIC) {
printk(KERN_ERR "L Bad %p\n", tty);
WARN_ON(1);
return;
}
tty_kref_get(tty);
mutex_lock_nested(&tty->legacy_mutex, subclass);
}
void __lockfunc tty_lock(struct tty_struct *tty)
{
return tty_lock_nested(tty, TTY_MUTEX_NORMAL);
mutex_lock(&big_tty_mutex);
}
EXPORT_SYMBOL(tty_lock);
void __lockfunc tty_unlock(struct tty_struct *tty)
void __lockfunc tty_unlock(void)
{
if (tty->magic != TTY_MAGIC) {
printk(KERN_ERR "U Bad %p\n", tty);
WARN_ON(1);
return;
}
mutex_unlock(&tty->legacy_mutex);
tty_kref_put(tty);
mutex_unlock(&big_tty_mutex);
}
EXPORT_SYMBOL(tty_unlock);
/*
* Getting the big tty mutex for a pair of ttys with lock ordering
* On a non pty/tty pair tty2 can be NULL which is just fine.
*/
void __lockfunc tty_lock_pair(struct tty_struct *tty,
struct tty_struct *tty2)
{
if (tty < tty2) {
tty_lock(tty);
tty_lock_nested(tty2, TTY_MUTEX_NESTED);
} else {
if (tty2 && tty2 != tty)
tty_lock(tty2);
tty_lock_nested(tty, TTY_MUTEX_NESTED);
}
}
EXPORT_SYMBOL(tty_lock_pair);
void __lockfunc tty_unlock_pair(struct tty_struct *tty,
struct tty_struct *tty2)
{
tty_unlock(tty);
if (tty2 && tty2 != tty)
tty_unlock(tty2);
}
EXPORT_SYMBOL(tty_unlock_pair);

View File

@ -230,7 +230,7 @@ int tty_port_block_til_ready(struct tty_port *port,
/* block if port is in the process of being closed */
if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
wait_event_interruptible_tty(tty, port->close_wait,
wait_event_interruptible_tty(port->close_wait,
!(port->flags & ASYNC_CLOSING));
if (port->flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
@ -296,9 +296,9 @@ int tty_port_block_til_ready(struct tty_port *port,
retval = -ERESTARTSYS;
break;
}
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
finish_wait(&port->open_wait, &wait);

View File

@ -268,7 +268,6 @@ struct tty_struct {
struct mutex ldisc_mutex;
struct tty_ldisc *ldisc;
struct mutex legacy_mutex;
struct mutex termios_mutex;
spinlock_t ctrl_lock;
/* Termios values are protected by the termios mutex */
@ -606,12 +605,8 @@ extern long vt_compat_ioctl(struct tty_struct *tty,
/* tty_mutex.c */
/* functions for preparation of BKL removal */
extern void __lockfunc tty_lock(struct tty_struct *tty);
extern void __lockfunc tty_unlock(struct tty_struct *tty);
extern void __lockfunc tty_lock_pair(struct tty_struct *tty,
struct tty_struct *tty2);
extern void __lockfunc tty_unlock_pair(struct tty_struct *tty,
struct tty_struct *tty2);
extern void __lockfunc tty_lock(void) __acquires(tty_lock);
extern void __lockfunc tty_unlock(void) __releases(tty_lock);
/*
* this shall be called only from where BTM is held (like close)
@ -626,9 +621,9 @@ extern void __lockfunc tty_unlock_pair(struct tty_struct *tty,
static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,
long timeout)
{
tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */
tty_unlock(); /* tty->ops->close holds the BTM, drop it while waiting */
tty_wait_until_sent(tty, timeout);
tty_lock(tty);
tty_lock();
}
/*
@ -643,16 +638,16 @@ static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,
*
* Do not use in new code.
*/
#define wait_event_interruptible_tty(tty, wq, condition) \
#define wait_event_interruptible_tty(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) { \
__wait_event_interruptible_tty(tty, wq, condition, __ret); \
__wait_event_interruptible_tty(wq, condition, __ret); \
} \
__ret; \
})
#define __wait_event_interruptible_tty(tty, wq, condition, ret) \
#define __wait_event_interruptible_tty(wq, condition, ret) \
do { \
DEFINE_WAIT(__wait); \
\
@ -661,9 +656,9 @@ do { \
if (condition) \
break; \
if (!signal_pending(current)) { \
tty_unlock(tty); \
tty_unlock(); \
schedule(); \
tty_lock(tty); \
tty_lock(); \
continue; \
} \
ret = -ERESTARTSYS; \

View File

@ -710,9 +710,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
break;
}
tty_unlock(tty);
tty_unlock();
schedule();
tty_lock(tty);
tty_lock();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->wait, &wait);