All of lore.kernel.org
 help / color / mirror / Atom feed
* Killing the tty lock
@ 2012-05-01 16:37 Alan Cox
  2012-05-02  4:45 ` Greg KH
  2012-05-02 11:32 ` Arnd Bergmann
  0 siblings, 2 replies; 7+ messages in thread
From: Alan Cox @ 2012-05-01 16:37 UTC (permalink / raw)
  To: linux-kernel

This is a first stab at it by making the lock per tty and using tty_mutex
to cover the lookup for now. We ought to move to the lookup handing back
ttys with a ref but thats a further step.

It seems to mostly work but not quite reliably, so coul do with some more
eyes and review for ideas.

Alan

commit 4a86662551c2b3f0b5e5119f7dd2623dd5fc2f7a
Author: Alan Cox <alan@linux.intel.com>
Date:   Tue May 1 17:05:59 2012 +0100

    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.
    
    Signed-off-by: Alan Cox <alan@linux.intel.com>

diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 24145c3..aa4f433 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -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_lock(tty);
 	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_unlock(tty);
 	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_lock(tty);
 	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_unlock(tty);
 		return -EINVAL;
 	}
   
@@ -1082,7 +1082,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
 	}
 
 	if (new_serial.baud_base < 9600) {
-		tty_unlock();
+		tty_unlock(tty);
 		return -EINVAL;
 	}
 
@@ -1114,7 +1114,7 @@ check_and_exit:
 		}
 	} else
 		retval = startup(tty, state);
-	tty_unlock();
+	tty_unlock(tty);
 	return retval;
 }
 
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index e61cabd..6984e1a 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -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(info->port.close_wait,
+		wait_event_interruptible_tty(tty, info->port.close_wait,
 				!(info->port.flags & ASYNC_CLOSING));
 		return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
 	}
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
index 5c6c314..656ad93 100644
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -1065,7 +1065,8 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
 
 	TRACE_L("read()");
 
-	tty_lock();
+	/* FIXME: should use a private lock */
+	tty_lock(tty);
 
 	pClient = findClient(pInfo, task_pid(current));
 	if (pClient) {
@@ -1077,7 +1078,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(pInfo->read_wait,
+			wait_event_interruptible_tty(tty, pInfo->read_wait,
 					(pMsg = remove_msg(pInfo, pClient)));
 		}
 
@@ -1107,7 +1108,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
 	}
 	ret = -EPERM;
 unlock:
-	tty_unlock();
+	tty_unlock(tty);
 	return ret;
 }
 
@@ -1156,7 +1157,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
 	pHeader->locks = 0;
 	pHeader->owner = NULL;
 
-	tty_lock();
+	tty_lock(tty);
 
 	pClient = findClient(pInfo, task_pid(current));
 	if (pClient) {
@@ -1175,7 +1176,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
 	add_tx_queue(pInfo, pHeader);
 	trigger_transmit(pInfo);
 
-	tty_unlock();
+	tty_unlock(tty);
 
 	return 0;
 }
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 5505ffc..c2d938f 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -47,6 +47,7 @@ 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;
@@ -62,9 +63,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
 		        mutex_unlock(&devpts_mutex);
 		}
 #endif
-		tty_unlock();
 		tty_vhangup(tty->link);
-		tty_lock();
 	}
 }
 
@@ -622,9 +621,9 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 		return retval;
 
 	/* find a device that is not in use. */
-	tty_lock();
+	mutex_lock(&devpts_mutex);
 	index = devpts_new_index(inode);
-	tty_unlock();
+	mutex_unlock(&devpts_mutex);
 	if (index < 0) {
 		retval = index;
 		goto err_file;
@@ -634,7 +633,8 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 	mutex_lock(&devpts_mutex);
 	tty = tty_init_dev(ptm_driver, index);
 	mutex_unlock(&devpts_mutex);
-	tty_lock();
+	/* Must take this under the tty_mutex until lookups keep a kref */
+	tty_lock(tty);
 	mutex_unlock(&tty_mutex);
 
 	if (IS_ERR(tty)) {
@@ -654,15 +654,17 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 	if (retval)
 		goto err_release;
 
-	tty_unlock();
+	tty_unlock(tty);
 	return 0;
 err_release:
-	tty_unlock();
+	tty_unlock(tty);
 	tty_release(inode, filp);
 	return retval;
 out:
+        mutex_lock(&devpts_mutex);
 	devpts_kill_index(inode, index);
-	tty_unlock();
+        mutex_unlock(&devpts_mutex);
+	tty_unlock(tty);
 err_file:
 	tty_free_file(filp);
 	return retval;
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index 593d40a..5ed0daa 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -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_unlock(tty);
 		schedule();
-		tty_lock();
+		tty_lock(tty);
 	}
 	
 	set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index aa1debf..45b43f1 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -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_unlock(tty);
 		schedule();
-		tty_lock();
+		tty_lock(tty);
 	}
 
 	set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index a3dddc1..4a1e4f0 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -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_unlock(tty);
 		schedule();
-		tty_lock();
+		tty_lock(tty);
 	}
 
 	set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index b425c79..1ca0629 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -573,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty)
 	}
 	spin_unlock(&redirect_lock);
 
-	tty_lock();
+	tty_lock(tty);
 
 	/* some functions below drop BTM, so we need this bit */
 	set_bit(TTY_HUPPING, &tty->flags);
@@ -666,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty)
 	clear_bit(TTY_HUPPING, &tty->flags);
 	tty_ldisc_enable(tty);
 
-	tty_unlock();
+	tty_unlock(tty);
 
 	if (f)
 		fput(f);
@@ -1103,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
 {
 	if (tty) {
 		mutex_lock(&tty->atomic_write_lock);
-		tty_lock();
+		tty_lock(tty);
 		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
-			tty_unlock();
+			tty_unlock(tty);
 			tty->ops->write(tty, msg, strlen(msg));
 		} else
-			tty_unlock();
+			tty_unlock(tty);
 		tty_write_unlock(tty);
 	}
 	return;
@@ -1403,6 +1403,7 @@ 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;
@@ -1418,6 +1419,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
 	return tty;
 
 err_deinit_tty:
+	tty_unlock(tty);
 	deinitialize_tty_struct(tty);
 	free_tty_struct(tty);
 err_module_put:
@@ -1426,6 +1428,7 @@ 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);
@@ -1628,7 +1631,7 @@ int tty_release(struct inode *inode, struct file *filp)
 	if (tty_paranoia_check(tty, inode, __func__))
 		return 0;
 
-	tty_lock();
+	tty_lock(tty);
 	check_tty_count(tty, __func__);
 
 	__tty_fasync(-1, filp, 0);
@@ -1637,10 +1640,11 @@ 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_unlock(tty);
 		return 0;
 	}
 
@@ -1652,7 +1656,7 @@ int tty_release(struct inode *inode, struct file *filp)
 	if (tty->ops->close)
 		tty->ops->close(tty, filp);
 
-	tty_unlock();
+	tty_unlock(tty);
 	/*
 	 * 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
@@ -1675,7 +1679,7 @@ int tty_release(struct inode *inode, struct file *filp)
 		   opens on /dev/tty */
 
 		mutex_lock(&tty_mutex);
-		tty_lock();
+		tty_lock_pair(tty, o_tty);
 		tty_closing = tty->count <= 1;
 		o_tty_closing = o_tty &&
 			(o_tty->count <= (pty_master ? 1 : 0));
@@ -1706,7 +1710,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();
+		tty_unlock_pair(tty, o_tty);
 		mutex_unlock(&tty_mutex);
 		schedule();
 	}
@@ -1769,7 +1773,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();
+		tty_unlock_pair(tty, o_tty);
 		return 0;
 	}
 
@@ -1789,7 +1793,7 @@ int tty_release(struct inode *inode, struct file *filp)
 	/* Make this pty number available for reallocation */
 	if (devpts)
 		devpts_kill_index(inode, idx);
-	tty_unlock();
+	tty_unlock_pair(tty, o_tty);
 	return 0;
 }
 
@@ -1893,6 +1897,9 @@ 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)
@@ -1916,8 +1923,7 @@ retry_open:
 	retval = 0;
 
 	mutex_lock(&tty_mutex);
-	tty_lock();
-
+	/* This is protected by the tty_mutex */
 	tty = tty_open_current_tty(device, filp);
 	if (IS_ERR(tty)) {
 		retval = PTR_ERR(tty);
@@ -1938,17 +1944,19 @@ retry_open:
 	}
 
 	if (tty) {
+		tty_lock(tty);
 		retval = tty_reopen(tty);
-		if (retval)
+		if (retval < 0) {
+			tty_unlock(tty);
 			tty = ERR_PTR(retval);
-	} else
+		}
+	} else	/* Returns with the tty_lock held for now */
 		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;
 	}
@@ -1977,7 +1985,7 @@ retry_open:
 		printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__,
 				retval, tty->name);
 #endif
-		tty_unlock(); /* need to call tty_release without BTM */
+		tty_unlock(tty); /* need to call tty_release without BTM */
 		tty_release(inode, filp);
 		if (retval != -ERESTARTSYS)
 			return retval;
@@ -1989,17 +1997,17 @@ retry_open:
 		/*
 		 * Need to reset f_op in case a hangup happened.
 		 */
-		tty_lock();
+		tty_lock(tty);
 		if (filp->f_op == &hung_up_tty_fops)
 			filp->f_op = &tty_fops;
-		tty_unlock();
+		tty_unlock(tty);
 		goto retry_open;
 	}
-	tty_unlock();
+	tty_unlock(tty);
 
 
 	mutex_lock(&tty_mutex);
-	tty_lock();
+	tty_lock(tty);
 	spin_lock_irq(&current->sighand->siglock);
 	if (!noctty &&
 	    current->signal->leader &&
@@ -2007,11 +2015,10 @@ retry_open:
 	    tty->session == NULL)
 		__proc_set_tty(current, tty);
 	spin_unlock_irq(&current->sighand->siglock);
-	tty_unlock();
+	tty_unlock(tty);
 	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))
@@ -2094,10 +2101,13 @@ out:
 
 static int tty_fasync(int fd, struct file *filp, int on)
 {
+	struct tty_struct *tty = file_tty(filp);
 	int retval;
-	tty_lock();
+
+	tty_lock(tty);
 	retval = __tty_fasync(fd, filp, on);
-	tty_unlock();
+	tty_unlock(tty);
+
 	return retval;
 }
 
@@ -2934,6 +2944,7 @@ 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);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 24b95db..fa65cde 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -567,7 +567,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 	if (IS_ERR(new_ldisc))
 		return PTR_ERR(new_ldisc);
 
-	tty_lock();
+	tty_lock(tty);
 	/*
 	 *	We need to look at the tty locking here for pty/tty pairs
 	 *	when both sides try to change in parallel.
@@ -581,12 +581,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 	 */
 
 	if (tty->ldisc->ops->num == ldisc) {
-		tty_unlock();
+		tty_unlock(tty);
 		tty_ldisc_put(new_ldisc);
 		return 0;
 	}
 
-	tty_unlock();
+	tty_unlock(tty);
 	/*
 	 *	Problem: What do we do if this blocks ?
 	 *	We could deadlock here
@@ -594,7 +594,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 	tty_wait_until_sent(tty, 0);
 
-	tty_lock();
+	tty_lock(tty);
 	mutex_lock(&tty->ldisc_mutex);
 
 	/*
@@ -604,10 +604,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_unlock(tty);
 		wait_event(tty_ldisc_wait,
 			test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
-		tty_lock();
+		tty_lock(tty);
 		mutex_lock(&tty->ldisc_mutex);
 	}
 
@@ -622,7 +622,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 	o_ldisc = tty->ldisc;
 
-	tty_unlock();
+	tty_unlock(tty);
 	/*
 	 *	Make sure we don't change while someone holds a
 	 *	reference to the line discipline. The TTY_LDISC bit
@@ -649,7 +649,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 	retval = tty_ldisc_wait_idle(tty, 5 * HZ);
 
-	tty_lock();
+	tty_lock(tty);
 	mutex_lock(&tty->ldisc_mutex);
 
 	/* handle wait idle failure locked */
@@ -664,7 +664,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_unlock(tty);
 		return -EIO;
 	}
 
@@ -707,7 +707,7 @@ enable:
 	if (o_work)
 		schedule_work(&o_tty->buf.work);
 	mutex_unlock(&tty->ldisc_mutex);
-	tty_unlock();
+	tty_unlock(tty);
 	return retval;
 }
 
@@ -815,11 +815,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_unlock(tty);
 	cancel_work_sync(&tty->buf.work);
 	mutex_unlock(&tty->ldisc_mutex);
 retry:
-	tty_lock();
+	tty_lock(tty);
 	mutex_lock(&tty->ldisc_mutex);
 
 	/* At this point we have a closed ldisc and we want to
@@ -830,7 +830,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_unlock(tty);
 
 			while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
 				timeout = MAX_SCHEDULE_TIMEOUT;
@@ -911,10 +911,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
 	 * race with the set_ldisc code path.
 	 */
 
-	tty_unlock();
+	tty_unlock(tty);
 	tty_ldisc_halt(tty);
 	tty_ldisc_flush_works(tty);
-	tty_lock();
+	tty_lock(tty);
 
 	mutex_lock(&tty->ldisc_mutex);
 	/*
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 9ff986c..7664b10 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -4,29 +4,56 @@
 #include <linux/semaphore.h>
 #include <linux/sched.h>
 
-/*
- * 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);
+/* Legacy tty mutex glue */
 
 /*
  * Getting the big tty mutex.
  */
-void __lockfunc tty_lock(void)
+
+void __lockfunc tty_lock(struct tty_struct *tty)
 {
-	mutex_lock(&big_tty_mutex);
+	if (mutex_is_locked(&tty->legacy_mutex)) {
+		WARN_ON(1);
+		return;
+	}
+	mutex_lock(&tty->legacy_mutex);
 }
 EXPORT_SYMBOL(tty_lock);
 
-void __lockfunc tty_unlock(void)
+void __lockfunc tty_unlock(struct tty_struct *tty)
 {
-	mutex_unlock(&big_tty_mutex);
+	if (!mutex_is_locked(&tty->legacy_mutex)) {
+		WARN_ON(1);
+		return;
+	}
+	mutex_unlock(&tty->legacy_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(tty2);
+	} else {
+		if (tty2 && tty2 != tty)
+			tty_lock(tty2);
+		tty_lock(tty);
+	}
+}
+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);
+
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index bf6e238..d9cca95 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -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(port->close_wait,
+		wait_event_interruptible_tty(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_unlock(tty);
 		schedule();
-		tty_lock();
+		tty_lock(tty);
 	}
 	finish_wait(&port->open_wait, &wait);
 
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 9f47ab5..4990ef2 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -268,6 +268,7 @@ 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 */
@@ -605,8 +606,12 @@ extern long vt_compat_ioctl(struct tty_struct *tty,
 
 /* tty_mutex.c */
 /* functions for preparation of BKL removal */
-extern void __lockfunc tty_lock(void) __acquires(tty_lock);
-extern void __lockfunc tty_unlock(void) __releases(tty_lock);
+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);
 
 /*
  * this shall be called only from where BTM is held (like close)
@@ -621,9 +626,9 @@ extern void __lockfunc tty_unlock(void) __releases(tty_lock);
 static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,
 		long timeout)
 {
-	tty_unlock(); /* tty->ops->close holds the BTM, drop it while waiting */
+	tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */
 	tty_wait_until_sent(tty, timeout);
-	tty_lock();
+	tty_lock(tty);
 }
 
 /*
@@ -638,16 +643,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(wq, condition)			\
+#define wait_event_interruptible_tty(tty, wq, condition)		\
 ({									\
 	int __ret = 0;							\
 	if (!(condition)) {						\
-		__wait_event_interruptible_tty(wq, condition, __ret);	\
+		__wait_event_interruptible_tty(tty, wq, condition, __ret);	\
 	}								\
 	__ret;								\
 })
 
-#define __wait_event_interruptible_tty(wq, condition, ret)		\
+#define __wait_event_interruptible_tty(tty, wq, condition, ret)		\
 do {									\
 	DEFINE_WAIT(__wait);						\
 									\
@@ -656,9 +661,9 @@ do {									\
 		if (condition)						\
 			break;						\
 		if (!signal_pending(current)) {				\
-			tty_unlock();					\
+			tty_unlock(tty);					\
 			schedule();					\
-			tty_lock();					\
+			tty_lock(tty);					\
 			continue;					\
 		}							\
 		ret = -ERESTARTSYS;					\

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-01 16:37 Killing the tty lock Alan Cox
@ 2012-05-02  4:45 ` Greg KH
  2012-05-02 10:45   ` Alan Cox
  2012-05-02 11:32 ` Arnd Bergmann
  1 sibling, 1 reply; 7+ messages in thread
From: Greg KH @ 2012-05-02  4:45 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

On Tue, May 01, 2012 at 05:37:39PM +0100, Alan Cox wrote:
> This is a first stab at it by making the lock per tty and using tty_mutex
> to cover the lookup for now. We ought to move to the lookup handing back
> ttys with a ref but thats a further step.
> 
> It seems to mostly work but not quite reliably, so coul do with some more
> eyes and review for ideas.

It's mostly pretty "sane", but what is this:

> +/*
> + * 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(tty2);
> +	} else {
> +		if (tty2 && tty2 != tty)
> +			tty_lock(tty2);
> +		tty_lock(tty);
> +	}
> +}
> +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);

for?

And what's with the comparing of pointers as "<"?  How portable is that
really, and how are we supposed to control the memory location of these
structures?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-02  4:45 ` Greg KH
@ 2012-05-02 10:45   ` Alan Cox
  2012-05-02 20:36     ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Alan Cox @ 2012-05-02 10:45 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

> It's mostly pretty "sane", but what is this:
> 
> > +/*
> > + * 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(tty2);
> > +	} else {
> > +		if (tty2 && tty2 != tty)
> > +			tty_lock(tty2);
> > +		tty_lock(tty);
> > +	}
> > +}
> > +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);
> 
> for?

We need to take locks on a pair of tty devices at the same time in some
cases (pty/tty pairs).

> And what's with the comparing of pointers as "<"?  How portable is that
> really, and how are we supposed to control the memory location of these
> structures?

You don't need to. The point is that we must lock any arbitrary pair of
tty structs in a defined order. Pointer comparisons work just fine for
this. The fs layer uses similar logic for inode locking. We only care
that for any given pair of objects the lock ordering is consistent.

Alan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-01 16:37 Killing the tty lock Alan Cox
  2012-05-02  4:45 ` Greg KH
@ 2012-05-02 11:32 ` Arnd Bergmann
  1 sibling, 0 replies; 7+ messages in thread
From: Arnd Bergmann @ 2012-05-02 11:32 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

On Tuesday 01 May 2012, Alan Cox wrote:
> This is a first stab at it by making the lock per tty and using tty_mutex
> to cover the lookup for now. We ought to move to the lookup handing back
> ttys with a ref but thats a further step.
> 
> It seems to mostly work but not quite reliably, so coul do with some more
> eyes and review for ideas.

Hi Alan,

I had tried the same some time ago but couldn't get it working because
some of the prerequisites were not there. I'll comment on the differences
between your patch and mine. In my version, I completely removed the
tty_mutex.c file and just open-coded mutex_lock() functions, but you
version with the extra checks also has its benefits. I found two differences
where I think your version is wrong, but I could be missing something.

> @@ -62,9 +63,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
>  		        mutex_unlock(&devpts_mutex);
>  		}
>  #endif
> -		tty_unlock();
>  		tty_vhangup(tty->link);
> -		tty_lock();
>  	}
>  }

I had missed that we don't need to unlock here once the lock is per-tty,
this looks better than my version.

> @@ -654,15 +654,17 @@ static int ptmx_open(struct inode *inode, struct file *filp)
>  	if (retval)
>  		goto err_release;
>  
> -	tty_unlock();
> +	tty_unlock(tty);
>  	return 0;
>  err_release:
> -	tty_unlock();
> +	tty_unlock(tty);
>  	tty_release(inode, filp);
>  	return retval;
>  out:
> +        mutex_lock(&devpts_mutex);
>  	devpts_kill_index(inode, index);
> -	tty_unlock();
> +        mutex_unlock(&devpts_mutex);
> +	tty_unlock(tty);
>  err_file:
>  	tty_free_file(filp);
>  	return retval;

This one looks wrong: when you get to the "out" label, tty is not valid.

> @@ -1403,6 +1403,7 @@ 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;
> @@ -1418,6 +1419,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
>  	return tty;
>  
>  err_deinit_tty:
> +	tty_unlock(tty);
>  	deinitialize_tty_struct(tty);
>  	free_tty_struct(tty);
>  err_module_put:
> @@ -1426,6 +1428,7 @@ 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);

So tty_init_dev returns a locked tty on success? If so, a comment about this
might be helpful. The part I don't understand is how ptmx_open takes the
lock right after calling tty_init_dev without anyone releasing it inbetween.
Or does it get released in tty_driver_install_tty or tty_ldisc_setup?

> @@ -1675,7 +1679,7 @@ int tty_release(struct inode *inode, struct file *filp)
>  		   opens on /dev/tty */
>  
>  		mutex_lock(&tty_mutex);
> -		tty_lock();
> +		tty_lock_pair(tty, o_tty);
>  		tty_closing = tty->count <= 1;
>  		o_tty_closing = o_tty &&
>  			(o_tty->count <= (pty_master ? 1 : 0));

Very clever.

>  static int tty_open(struct inode *inode, struct file *filp)
> @@ -1916,8 +1923,7 @@ retry_open:
>  	retval = 0;
>  
>  	mutex_lock(&tty_mutex);
> -	tty_lock();
> -
> +	/* This is protected by the tty_mutex */
>  	tty = tty_open_current_tty(device, filp);
>  	if (IS_ERR(tty)) {
>  		retval = PTR_ERR(tty);
> @@ -1938,17 +1944,19 @@ retry_open:
>  	}
>  
>  	if (tty) {
> +		tty_lock(tty);
>  		retval = tty_reopen(tty);
> -		if (retval)
> +		if (retval < 0) {
> +			tty_unlock(tty);
>  			tty = ERR_PTR(retval);
> -	} else
> +		}
> +	} else	/* Returns with the tty_lock held for now */
>  		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;
>  	}

Ah, so this is why tty_init_dev takes the lock. In my version, I take
the lock after tty_init_dev in the else path, but I guess the result
is pretty much the same.

	Arnd

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-02 10:45   ` Alan Cox
@ 2012-05-02 20:36     ` Greg KH
  2012-05-08 18:08       ` Yinghai Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Greg KH @ 2012-05-02 20:36 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

On Wed, May 02, 2012 at 11:45:15AM +0100, Alan Cox wrote:
> > It's mostly pretty "sane", but what is this:
> > 
> > > +/*
> > > + * 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(tty2);
> > > +	} else {
> > > +		if (tty2 && tty2 != tty)
> > > +			tty_lock(tty2);
> > > +		tty_lock(tty);
> > > +	}
> > > +}
> > > +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);
> > 
> > for?
> 
> We need to take locks on a pair of tty devices at the same time in some
> cases (pty/tty pairs).

Ok.

> > And what's with the comparing of pointers as "<"?  How portable is that
> > really, and how are we supposed to control the memory location of these
> > structures?
> 
> You don't need to. The point is that we must lock any arbitrary pair of
> tty structs in a defined order. Pointer comparisons work just fine for
> this. The fs layer uses similar logic for inode locking. We only care
> that for any given pair of objects the lock ordering is consistent.

Ah, ok, that makes more sense, sorry, I didn't understand that.

greg

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-02 20:36     ` Greg KH
@ 2012-05-08 18:08       ` Yinghai Lu
  2012-05-09 15:36         ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Yinghai Lu @ 2012-05-08 18:08 UTC (permalink / raw)
  To: Greg KH; +Cc: Alan Cox, linux-kernel

On Wed, May 2, 2012 at 1:36 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, May 02, 2012 at 11:45:15AM +0100, Alan Cox wrote:
>> > It's mostly pretty "sane", but what is this:
>> >
>> > > +/*
>> > > + * 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(tty2);
>> > > + } else {
>> > > +         if (tty2 && tty2 != tty)
>> > > +                 tty_lock(tty2);
>> > > +         tty_lock(tty);
>> > > + }
>> > > +}
>> > > +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);
>> >
>> > for?
>>
>> We need to take locks on a pair of tty devices at the same time in some
>> cases (pty/tty pairs).
>
> Ok.
>
>> > And what's with the comparing of pointers as "<"?  How portable is that
>> > really, and how are we supposed to control the memory location of these
>> > structures?
>>
>> You don't need to. The point is that we must lock any arbitrary pair of
>> tty structs in a defined order. Pointer comparisons work just fine for
>> this. The fs layer uses similar logic for inode locking. We only care
>> that for any given pair of objects the lock ordering is consistent.
>
> Ah, ok, that makes more sense, sorry, I didn't understand that.

looks like some patches from Alan in your tty-next cause dead look...


[ INFO: possible recursive locking detected ]
udevd (3502): /proc/3502/oom_adj is deprecated, please use
/proc/3502/oom_score_adj instead.
udevd version 128 started
3.4.0-rc6-yh-03495-g952810c-dirty #304 Not tainted
---------------------------------------------
boot.ipconfig/3484 is trying to acquire lock:
 (
&tty->legacy_mutex
){+.+.+.}
, at:
[<ffffffff81dc8fc6>] tty_lock+0x69/0x6d

but task is already holding lock:
 (
&tty->legacy_mutex
){+.+.+.}
, at:
[<ffffffff81dc8fc6>] tty_lock+0x69/0x6d

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(
&tty->legacy_mutex
);
  lock(
&tty->legacy_mutex
);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by boot.ipconfig/3484:
 #0:
 (
tty_mutex
){+.+.+.}
, at:
[<ffffffff81469a46>] tty_release+0x126/0x410
 #1:
 (
&tty->legacy_mutex
){+.+.+.}
, at:
[<ffffffff81dc8fc6>] tty_lock+0x69/0x6d

stack backtrace:
Pid: 3484, comm: boot.ipconfig Not tainted
3.4.0-rc6-yh-03495-g952810c-dirty #304
Call Trace:
 [<ffffffff810b2cac>] print_deadlock_bug+0xde/0xe9
 [<ffffffff810b2ddc>] check_deadlock.isra.15+0x125/0x149
 [<ffffffff810b4393>] validate_chain.isra.16+0x481/0x48b
 [<ffffffff810b66c8>] __lock_acquire+0x6e3/0x76c
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff810b6c5b>] lock_acquire+0xcb/0xf1
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff81dc64c8>] mutex_lock_nested+0x4c/0x2b4
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff810b4d91>] ? trace_hardirqs_on_caller+0xff/0x110
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff81dc8fc6>] tty_lock+0x69/0x6d
 [<ffffffff81dc9005>] tty_lock_pair+0x3b/0x40
 [<ffffffff81469a51>] tty_release+0x131/0x410
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8106d9ba>] close_files+0xa2/0xc9
 [<ffffffff8106d918>] ? exit_mm+0x115/0x115
 [<ffffffff8106eb93>] put_files_struct+0x22/0x94
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff8106eca0>] exit_files+0x49/0x51
 [<ffffffff8106eef2>] do_exit+0x24a/0x361
 [<ffffffff810b4d91>] ? trace_hardirqs_on_caller+0xff/0x110
 [<ffffffff8106f1d1>] do_group_exit+0x88/0xb6
 [<ffffffff8106f216>] sys_exit_group+0x17/0x17
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
g952810c-dirty/modules.dep: No such file or directory

hwclock: With --noadjfile, you must specify either --utc or --localtime
                                                                     failed
Disabling IP forwarding                                              done
                                                                     done
Starting udevd:                                                      done
Loading drivers, configuring devices: ata_id[4471]: HDIO_GET_IDENTITY
failed for '/dev/.tmp-8-0'

                                                                     done
Loading required kernel modules                                      done
Activating device mapper...
FATAL: Could not load
/lib/modules/3.4.0-rc6-yh-03495-g952810c-dirty/modules.dep: mdadm:
sending ioctl 800c0910 to a partition!
mdadm: sending ioctl 800c0910 to a partition!
mdadm: sending ioctl 1261 to a partition!
No such file or mdadm: sending ioctl 1261 to a partition!
directory
dadm: sending ioctl 1261 to a partition!
?25l
dadm: sending ioctl 1261 to a partition!
[1;31mfailedmdadm: sending ioctl 1261 to a partition!
mdadm: sending ioctl 1261 to a partition!

Startmdadm: sending ioctl 1261 to a partition!
ing MD Raid mdadm: sending ioctl 1261 to a partition!
                                                                     unused
Waiting for udev to settle...
Scanning for LVM volume groups...
File descriptor 3 left open
  Reading all phdevice: '9:0': device_unregister
PM: Removing info for No Bus:9:0
ysical volumes. device: '9:0': device_create_release
 This may take aPM: Removing info for No Bus:md0
 while...
Activating LVM volume groups...
File descriptor 3 left open
                                                                     done
Waiting for /firmware
microcode . no more events
Checking file systems...
fsck 1.41.1 (01-Sep-2008)
Checking all file systems.                                           done
                                                                     done
Mounting local file systems...
/proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
udev on /dev type tmpfs (rw)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/firmware on /lib/firmware type tmpfs (rw)
microcode on /usr/lib/microcode type tmpfs (rw)
done      evice: 'vcs4': device_addp-devices in /etc/fstab...
         done
PM: Adding info for No Bus:vcs4                                      done
device: 'vcsa4': device_addtc/ld.so.cache) using ldconfig            done
PM: Adding info for No Bus:vcsa4ca05-0a81e09e'
0D3ting up hostname 'sca05-0a81e09e'                                 done
device: 'vcs5': device_addace     lo
PM: Adding info for No Bus:vcs5.0.1/8
device: 'vcsa5': device_add27.0.0.2/8
PM: Adding info for No Bus:vcsa5                                     done
Starting D-Bus ddevice: 'vcs10': device_add                          set up
PM: Adding info for No Bus:vcs10                                 boot.md
device: 'vcsa10': device_add /etc/init.d/boot.local                  done
device: 'vcs7': device_addvcsa10
PM: Adding info for No Bus:vcs7yS0(/dev/console) at Wed May  9 18:00:37 2012
device: 'vcsa7': device_addvcs6us runlevel: N, device: 'vcs2': device_add
PM: Adding info for No Bus:vcsa7
PM: Adding info for No Bus:vcsa6
Initializing rdevice: 'vcs8': device_add
PM: Adding info for No Bus:vcs8 device_add
device: 'vcsa8': device_addvcs3
PM: Adding info for No Bus:vcsa8
andom number gendevice: 'vcs9': device_add
PM: Adding info for No Bus:vcs9
device: 'vcsa9': device_add
PM: Adding info for No Bus:vcsa9
^[device: 'vcs11': device_add
PM: Adding info for No Bus:vcs11
device: 'vcsa11': device_add
PM: Adding info for No Bus:vcsa11
device: 'vcs12': device_add
PM: Adding info for No Bus:vcs12
device: 'vcsa12': device_add
PM: Adding info for No Bus:vcsa12
done  device: 'vcs13': device_add
PM: Adding info for No Bus:vcs13
device: 'vcsa13': device_add
PM: Adding info for No Bus:vcsa13

device: 'vcs14': device_add
PM: Adding info for No Bus:vcs14
device: 'vcsa14': device_add
PM: Adding info for No Bus:vcsa14
Starting syslog device: 'vcs15': device_add
PM: Adding info for No Bus:vcs15
device: 'vcsa15': device_add
PM: Adding info for No Bus:vcsa15
servicesdevice: 'vcs16': device_add
PM: Adding info for No Bus:vcs16
device: 'vcsa16': device_add
PM: Adding info for No Bus:vcsa16

^[[1;3device: 'vcs17': device_add
PM: Adding info for No Bus:vcs17
device: 'vcsa17': device_add
PM: Adding info for No Bus:vcsa17
2mdone  ^[[?2device: 'vcs18': device_add
PM: Adding info for No Bus:vcs18
device: 'vcsa18': device_add
PM: Adding info for No Bus:vcsa18
5h
device: 'vcs19': device_add
PM: Adding info for No Bus:vcs19
device: 'vcsa19': device_add
PM: Adding info for No Bus:vcsa19
device: 'vcs20': device_add
PM: Adding info for No Bus:vcs20
device: 'vcsa20': device_add
PM: Adding info for No Bus:vcsa20
device: 'vcs21': device_add
PM: Adding info for No Bus:vcs21
device: 'vcsa21': device_add
PM: Adding info for No Bus:vcsa21
device: 'vcs22': device_add
PM: Adding info for No Bus:vcs22
device: 'vcsa22': device_add
PM: Adding info for No Bus:vcsa22
device: 'vcs23': device_add
PM: Adding info for No Bus:vcs23
device: 'vcsa23': device_add
PM: Adding info for No Bus:vcsa23
device: 'vcs24': device_add
PM: Adding info for No Bus:vcs24
device: 'vcsa24': device_add
PM: Adding info for No Bus:vcsa24
Loading CPUFreq modules (CPUFreq not supported)
Starting HAL daemon                                                  done
Setting up (localfs) network interfaces:
    lo
    lo        IP address: 127.0.0.1/8
              IP address: 127.0.0.2/8                                done
    eth0      device: Intel Corporation I350 Gigabit Network Connection (rev 01)
              No configuration found for eth0                        unused
    eth1      device: Intel Corporation I350 Gigabit Network Connection (rev 01)
              No configuration found for eth1                        unused
    eth2      device: Intel Corporation Ethernet Controller 10 Gigabit
X540-AT2 (rev 01)
              No configuration found for eth2                        unused
    eth3      device: Intel Corporation Ethernet Controller 10 Gigabit
X540-AT2 (rev 01)
              No configuration found for eth3                        unused
    ib0       device: Mellanox Technologies MT26428 [ConnectX VPI PCIe
2.0 5GT/s - IB QDR / 10GigE] (rev b0)
              No configuration found for ib0                         unused
    ib1       device: Mellanox Technologies MT26428 [ConnectX VPI PCIe
2.0 5GT/s - IB QDR / 10GigE] (rev b0)
              No configuration found for ib1                         unused
    usb0
              No configuration found for usb0                        unused
Setting up service (localfs) network  .  .  .  .  .  .  .  .  .  .   done
Starting RPC portmap daemon                                          done
Setting up (remotefs) network interfaces:
Setting up service (remotefs) network  .  .  .  .  .  .  .  .  .  .  done
Master Resource Control: runlevel 3 has been                         reached
INFO: task ifup:6216 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
ifup            D ffffffff8262c3b8     0  6216      1 0x00000000
 ffff880271b97c28 0000000000000046 ffff88026f88a260 ffff880271b97fd8
 0000000000004000 00000000001d2a00 ffff880178dcc4c0 ffff88026f88a260
 0000000000000001 ffff88017723c4c0 ffff88026f88a260 ffff88026f88a260
Call Trace:
 [<ffffffff81dc8e67>] ? _raw_spin_unlock_irqrestore+0x38/0x46
 [<ffffffff810b1ecc>] ? trace_hardirqs_off_caller+0x1f/0x10e
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff81469a46>] tty_release+0x126/0x410
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8106d9ba>] close_files+0xa2/0xc9
 [<ffffffff8106d918>] ? exit_mm+0x115/0x115
 [<ffffffff8106eb93>] put_files_struct+0x22/0x94
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff8106eca0>] exit_files+0x49/0x51
 [<ffffffff8106eef2>] do_exit+0x24a/0x361
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff8106f1d1>] do_group_exit+0x88/0xb6
 [<ffffffff8106f216>] sys_exit_group+0x17/0x17
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task startpar:6270 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
startpar        D ffffffff8262c3b8     0  6270      1 0x00000000
 ffff8801775e9c28 0000000000000046 0000000000000246 ffff8801775e9fd8
 0000000000004000 00000000001d2a00 ffff880178dca260 ffff88017723c4c0
 ffff8801775e9bc8 0000000000000046 0000000000000000 ffff88017723c4c0
Call Trace:
 [<ffffffff81dc8e6e>] ? _raw_spin_unlock_irqrestore+0x3f/0x46
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff81469a46>] tty_release+0x126/0x410
 [<ffffffff8112501b>] ? remove_vma+0x6e/0x76
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8106d9ba>] close_files+0xa2/0xc9
 [<ffffffff8106d918>] ? exit_mm+0x115/0x115
 [<ffffffff8106eb93>] put_files_struct+0x22/0x94
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff8106eca0>] exit_files+0x49/0x51
 [<ffffffff8106eef2>] do_exit+0x24a/0x361
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff8106f1d1>] do_group_exit+0x88/0xb6
 [<ffffffff8106f216>] sys_exit_group+0x17/0x17
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task blogd:6290 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
blogd           D ffff880265e870e0     0  6290      1 0x00000000
 ffff880272a61b48 0000000000000046 ffff880272a61a58 ffff880272a61fd8
 0000000000004000 00000000001d2a00 ffffffff825b9410 ffff880272e2a260
 ffff880272a61b38 ffff880272e2a260 0000000000000000 ffffffff81082fb7
Call Trace:
 [<ffffffff81082fb7>] ? wait_on_cpu_work+0x2f/0x97
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff81dc8fc6>] ? tty_lock+0x69/0x6d
 [<ffffffff81dc8fc6>] tty_lock+0x69/0x6d
 [<ffffffff81dc9005>] tty_lock_pair+0x3b/0x40
 [<ffffffff81469a51>] tty_release+0x131/0x410
 [<ffffffff81dc8e6e>] ? _raw_spin_unlock_irqrestore+0x3f/0x46
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff814690b1>] __tty_hangup+0x321/0x330
 [<ffffffff814690e5>] tty_vhangup+0xe/0x10
 [<ffffffff81470e84>] pty_close+0x13d/0x142
 [<ffffffff81469a06>] tty_release+0xe6/0x410
 [<ffffffff8146ebac>] ? put_ldisc+0xb4/0xb9
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8114717d>] sys_close+0x97/0xd9
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task ifup:6951 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
ifup            D ffffffff8262c3b8     0  6951      1 0x00000000
 ffff8802709d1c28 0000000000000046 ffff88026bb12260 ffff8802709d1fd8
 0000000000004000 00000000001d2a00 ffff880178dcc4c0 ffff88026bb12260
 0000000000000001 ffff8802709a8000 ffff88026bb12260 ffff88026bb12260
Call Trace:
 [<ffffffff81dc8e67>] ? _raw_spin_unlock_irqrestore+0x38/0x46
 [<ffffffff810b1ecc>] ? trace_hardirqs_off_caller+0x1f/0x10e
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff81469a46>] tty_release+0x126/0x410
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8106d9ba>] close_files+0xa2/0xc9
 [<ffffffff8106d918>] ? exit_mm+0x115/0x115
 [<ffffffff8106eb93>] put_files_struct+0x22/0x94
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff8106eca0>] exit_files+0x49/0x51
 [<ffffffff8106eef2>] do_exit+0x24a/0x361
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff8106f1d1>] do_group_exit+0x88/0xb6
 [<ffffffff8106f216>] sys_exit_group+0x17/0x17
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task startpar:6990 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
startpar        D ffffffff8262c3b8     0  6990      1 0x00000000
 ffff88026a58dc28 0000000000000046 0000000000000246 ffff88026a58dfd8
 0000000000004000 00000000001d2a00 ffff880178da44c0 ffff8802709a8000
 ffff88026a58dbc8 0000000000000046 0000000000000000 ffff8802709a8000
Call Trace:
 [<ffffffff81dc8e6e>] ? _raw_spin_unlock_irqrestore+0x3f/0x46
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff81469a46>] ? tty_release+0x126/0x410
 [<ffffffff81469a46>] tty_release+0x126/0x410
 [<ffffffff8112501b>] ? remove_vma+0x6e/0x76
 [<ffffffff8114a4f8>] __fput+0xf3/0x1dd
 [<ffffffff8114a5fc>] fput+0x1a/0x1c
 [<ffffffff811470db>] filp_close+0x71/0x7c
 [<ffffffff8106d9ba>] close_files+0xa2/0xc9
 [<ffffffff8106d918>] ? exit_mm+0x115/0x115
 [<ffffffff8106eb93>] put_files_struct+0x22/0x94
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff8106eca0>] exit_files+0x49/0x51
 [<ffffffff8106eef2>] do_exit+0x24a/0x361
 [<ffffffff810b4ca8>] ? trace_hardirqs_on_caller+0x16/0x110
 [<ffffffff8106f1d1>] do_group_exit+0x88/0xb6
 [<ffffffff8106f216>] sys_exit_group+0x17/0x17
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task init:7164 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
init            D ffffffff8262c3b8     0  7164      1 0x00000000
 ffff88017871fb28 0000000000000046 0000000000000000 ffff88017871ffd8
 0000000000004000 00000000001d2a00 ffff880178e2a260 ffff880176768000
 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] tty_open+0x7b/0x386
 [<ffffffff8114c896>] ? chrdev_open+0xdd/0x14a
 [<ffffffff8114c8da>] chrdev_open+0x121/0x14a
 [<ffffffff81149be5>] ? files_lglock_local_unlock+0x21/0x36
 [<ffffffff8114c7b9>] ? cdev_put+0x26/0x26
 [<ffffffff811475f6>] __dentry_open.isra.14+0x180/0x2a6
 [<ffffffff811482a7>] nameidata_to_filp+0x48/0x4f
 [<ffffffff81155613>] do_last.isra.31+0x49e/0x541
 [<ffffffff811557bd>] path_openat+0xd4/0x348
 [<ffffffff81dcc3a3>] ? do_page_fault+0x3b3/0x40a
 [<ffffffff811601c5>] ? alloc_fd+0x3c/0xfe
 [<ffffffff81155b35>] do_filp_open+0x38/0x86
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff81160275>] ? alloc_fd+0xec/0xfe
 [<ffffffff811483b3>] do_sys_open+0x105/0x19e
 [<ffffffff8114846d>] sys_open+0x21/0x23
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task init:7165 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
init            D ffffffff8262c3b8     0  7165      1 0x00000000
 ffff88017742fb28 0000000000000046 ffffea0009fcbe40 ffff88017742ffd8
 0000000000004000 00000000001d2a00 ffff880178e2a260 ffff88017676a260
 ffffea0009fcbe40 0000000000000000 ffff88027fbfae80 0000000000000000
Call Trace:
 [<ffffffff81109660>] ? get_page_from_freelist+0x40f/0x4b8
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] tty_open+0x7b/0x386
 [<ffffffff8114c896>] ? chrdev_open+0xdd/0x14a
 [<ffffffff8114c8da>] chrdev_open+0x121/0x14a
 [<ffffffff81149be5>] ? files_lglock_local_unlock+0x21/0x36
 [<ffffffff8114c7b9>] ? cdev_put+0x26/0x26
 [<ffffffff811475f6>] __dentry_open.isra.14+0x180/0x2a6
 [<ffffffff811482a7>] nameidata_to_filp+0x48/0x4f
 [<ffffffff81155613>] do_last.isra.31+0x49e/0x541
 [<ffffffff811557bd>] path_openat+0xd4/0x348
 [<ffffffff81dcc3a3>] ? do_page_fault+0x3b3/0x40a
 [<ffffffff811601c5>] ? alloc_fd+0x3c/0xfe
 [<ffffffff81155b35>] do_filp_open+0x38/0x86
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff81160275>] ? alloc_fd+0xec/0xfe
 [<ffffffff811483b3>] do_sys_open+0x105/0x19e
 [<ffffffff8114846d>] sys_open+0x21/0x23
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task init:7166 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
init            D ffffffff8262c3b8     0  7166      1 0x00000000
 ffff88016574fb28 0000000000000046 0000000000000246 ffff88016574ffd8
 0000000000004000 00000000001d2a00 ffff880178e2a260 ffff88017676c4c0
 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff81109d6f>] ? __alloc_pages_nodemask+0x1ea/0x826
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] tty_open+0x7b/0x386
 [<ffffffff8114c896>] ? chrdev_open+0xdd/0x14a
 [<ffffffff8114c8da>] chrdev_open+0x121/0x14a
 [<ffffffff81149be5>] ? files_lglock_local_unlock+0x21/0x36
 [<ffffffff8114c7b9>] ? cdev_put+0x26/0x26
 [<ffffffff811475f6>] __dentry_open.isra.14+0x180/0x2a6
 [<ffffffff811482a7>] nameidata_to_filp+0x48/0x4f
 [<ffffffff81155613>] do_last.isra.31+0x49e/0x541
 [<ffffffff811557bd>] path_openat+0xd4/0x348
 [<ffffffff811601c5>] ? alloc_fd+0x3c/0xfe
 [<ffffffff81155b35>] do_filp_open+0x38/0x86
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff81160275>] ? alloc_fd+0xec/0xfe
 [<ffffffff811483b3>] do_sys_open+0x105/0x19e
 [<ffffffff8114846d>] sys_open+0x21/0x23
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task init:7167 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
init            D ffffffff8262c3b8     0  7167      1 0x00000000
 ffff880165437b28 0000000000000046 ffffea0009768300 ffff880165437fd8
 0000000000004000 00000000001d2a00 ffff880178e2a260 ffff8801767c2260
 ffffea0009768300 0000000000000000 ffff88027fbfae80 0000000000000000
Call Trace:
 [<ffffffff81109660>] ? get_page_from_freelist+0x40f/0x4b8
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] tty_open+0x7b/0x386
 [<ffffffff8114c896>] ? chrdev_open+0xdd/0x14a
 [<ffffffff8114c8da>] chrdev_open+0x121/0x14a
 [<ffffffff81149be5>] ? files_lglock_local_unlock+0x21/0x36
 [<ffffffff8114c7b9>] ? cdev_put+0x26/0x26
 [<ffffffff811475f6>] __dentry_open.isra.14+0x180/0x2a6
 [<ffffffff811482a7>] nameidata_to_filp+0x48/0x4f
 [<ffffffff81155613>] do_last.isra.31+0x49e/0x541
 [<ffffffff811557bd>] path_openat+0xd4/0x348
 [<ffffffff81dcc3a3>] ? do_page_fault+0x3b3/0x40a
 [<ffffffff811601c5>] ? alloc_fd+0x3c/0xfe
 [<ffffffff81155b35>] do_filp_open+0x38/0x86
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff81160275>] ? alloc_fd+0xec/0xfe
 [<ffffffff811483b3>] do_sys_open+0x105/0x19e
 [<ffffffff8114846d>] sys_open+0x21/0x23
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.
INFO: task init:7168 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
init            D ffffffff8262c3b8     0  7168      1 0x00000000
 ffff8801657f1b28 0000000000000046 0000000000000246 ffff8801657f1fd8
 0000000000004000 00000000001d2a00 ffff880178e2a260 ffff8801767c0000
 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff81109d6f>] ? __alloc_pages_nodemask+0x1ea/0x826
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff810b5819>] ? __lock_contended+0x38/0x263
 [<ffffffff81dc65f8>] ? mutex_lock_nested+0x17c/0x2b4
 [<ffffffff81dc79f8>] schedule+0x64/0x66
 [<ffffffff81dc7c5c>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff81dc6600>] mutex_lock_nested+0x184/0x2b4
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] ? tty_open+0x7b/0x386
 [<ffffffff81469dab>] tty_open+0x7b/0x386
 [<ffffffff8114c896>] ? chrdev_open+0xdd/0x14a
 [<ffffffff8114c8da>] chrdev_open+0x121/0x14a
 [<ffffffff81149be5>] ? files_lglock_local_unlock+0x21/0x36
 [<ffffffff8114c7b9>] ? cdev_put+0x26/0x26
 [<ffffffff811475f6>] __dentry_open.isra.14+0x180/0x2a6
 [<ffffffff811482a7>] nameidata_to_filp+0x48/0x4f
 [<ffffffff81155613>] do_last.isra.31+0x49e/0x541
 [<ffffffff811557bd>] path_openat+0xd4/0x348
 [<ffffffff81dcc3a3>] ? do_page_fault+0x3b3/0x40a
 [<ffffffff811601c5>] ? alloc_fd+0x3c/0xfe
 [<ffffffff81155b35>] do_filp_open+0x38/0x86
 [<ffffffff81dc8e2a>] ? _raw_spin_unlock+0x29/0x2e
 [<ffffffff81160275>] ? alloc_fd+0xec/0xfe
 [<ffffffff811483b3>] do_sys_open+0x105/0x19e
 [<ffffffff8114846d>] sys_open+0x21/0x23
 [<ffffffff81dcfd52>] system_call_fastpath+0x16/0x1b
INFO: lockdep is turned off.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Killing the tty lock
  2012-05-08 18:08       ` Yinghai Lu
@ 2012-05-09 15:36         ` Greg KH
  0 siblings, 0 replies; 7+ messages in thread
From: Greg KH @ 2012-05-09 15:36 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: Alan Cox, linux-kernel

On Tue, May 08, 2012 at 11:08:29AM -0700, Yinghai Lu wrote:
> On Wed, May 2, 2012 at 1:36 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> > On Wed, May 02, 2012 at 11:45:15AM +0100, Alan Cox wrote:
> >> > It's mostly pretty "sane", but what is this:
> >> >
> >> > > +/*
> >> > > + * 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(tty2);
> >> > > + } else {
> >> > > +         if (tty2 && tty2 != tty)
> >> > > +                 tty_lock(tty2);
> >> > > +         tty_lock(tty);
> >> > > + }
> >> > > +}
> >> > > +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);
> >> >
> >> > for?
> >>
> >> We need to take locks on a pair of tty devices at the same time in some
> >> cases (pty/tty pairs).
> >
> > Ok.
> >
> >> > And what's with the comparing of pointers as "<"?  How portable is that
> >> > really, and how are we supposed to control the memory location of these
> >> > structures?
> >>
> >> You don't need to. The point is that we must lock any arbitrary pair of
> >> tty structs in a defined order. Pointer comparisons work just fine for
> >> this. The fs layer uses similar logic for inode locking. We only care
> >> that for any given pair of objects the lock ordering is consistent.
> >
> > Ah, ok, that makes more sense, sorry, I didn't understand that.
> 
> looks like some patches from Alan in your tty-next cause dead look...

Yes, Alan is currently working on it...

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-05-09 15:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-01 16:37 Killing the tty lock Alan Cox
2012-05-02  4:45 ` Greg KH
2012-05-02 10:45   ` Alan Cox
2012-05-02 20:36     ` Greg KH
2012-05-08 18:08       ` Yinghai Lu
2012-05-09 15:36         ` Greg KH
2012-05-02 11:32 ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.