
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

ldisc close can race with the flush_to_ldisc workqueue.

This patch fixes it by killing the workqueue first.


---

 25-akpm/drivers/char/tty_io.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff -puN drivers/char/tty_io.c~fix-race-on-tty-close drivers/char/tty_io.c
--- 25/drivers/char/tty_io.c~fix-race-on-tty-close	2004-05-05 22:04:05.108818712 -0700
+++ 25-akpm/drivers/char/tty_io.c	2004-05-05 22:04:05.112818104 -0700
@@ -1267,6 +1267,18 @@ static void release_dev(struct file * fi
 #endif
 
 	/*
+	 * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
+	 * kill any delayed work.
+	 */
+	clear_bit(TTY_DONT_FLIP, &tty->flags);
+	cancel_delayed_work(&tty->flip.work);
+
+	/*
+	 * Wait for ->hangup_work and ->flip.work handlers to terminate
+	 */
+	flush_scheduled_work();
+
+	/*
 	 * Shutdown the current line discipline, and reset it to N_TTY.
 	 * N.B. why reset ldisc when we're releasing the memory??
 	 */
@@ -1282,18 +1294,6 @@ static void release_dev(struct file * fi
 		module_put(o_tty->ldisc.owner);
 		o_tty->ldisc = ldiscs[N_TTY];
 	}
-	
-	/*
-	 * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
-	 * kill any delayed work.
-	 */
-	clear_bit(TTY_DONT_FLIP, &tty->flags);
-	cancel_delayed_work(&tty->flip.work);
-
-	/*
-	 * Wait for ->hangup_work and ->flip.work handlers to terminate
-	 */
-	flush_scheduled_work();
 
 	/* 
 	 * The release_mem function takes care of the details of clearing

_
