aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-02-10 04:44:34 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 13:51:24 -0500
commit8b6312f4dcc1efe7975731b6c47dd134282bd9ac (patch)
tree71c94b01bda940c5610d448d0f4a2aa3c7665b4c /drivers/char/tty_io.c
parent0a7b35cb18c52d651f6ed9cd59edc979200ab880 (diff)
[PATCH] vt: refactor console SAK processing
This does several things. - It moves looking up of the current foreground console into process context where we can safely take the semaphore that protects this operation. - It uses the new flavor of work queue processing. - This generates a factor of do_SAK, __do_SAK that runs immediately. - This calls __do_SAK with the console semaphore held ensuring nothing else happens to the console while we process the SAK operation. - With the console SAK processing moved into process context this patch removes the xchg operations that I used to attempt to attomically update struct pid, because of the strange locking used in the SAK processing. With SAK using the normal console semaphore nothing special is needed. Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 47a6eacb10bc..c57b1f434652 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3324,10 +3324,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
3324 * Nasty bug: do_SAK is being called in interrupt context. This can 3324 * Nasty bug: do_SAK is being called in interrupt context. This can
3325 * deadlock. We punt it up to process context. AKPM - 16Mar2001 3325 * deadlock. We punt it up to process context. AKPM - 16Mar2001
3326 */ 3326 */
3327static void __do_SAK(struct work_struct *work) 3327void __do_SAK(struct tty_struct *tty)
3328{ 3328{
3329 struct tty_struct *tty =
3330 container_of(work, struct tty_struct, SAK_work);
3331#ifdef TTY_SOFT_SAK 3329#ifdef TTY_SOFT_SAK
3332 tty_hangup(tty); 3330 tty_hangup(tty);
3333#else 3331#else
@@ -3394,6 +3392,13 @@ static void __do_SAK(struct work_struct *work)
3394#endif 3392#endif
3395} 3393}
3396 3394
3395static void do_SAK_work(struct work_struct *work)
3396{
3397 struct tty_struct *tty =
3398 container_of(work, struct tty_struct, SAK_work);
3399 __do_SAK(tty);
3400}
3401
3397/* 3402/*
3398 * The tq handling here is a little racy - tty->SAK_work may already be queued. 3403 * The tq handling here is a little racy - tty->SAK_work may already be queued.
3399 * Fortunately we don't need to worry, because if ->SAK_work is already queued, 3404 * Fortunately we don't need to worry, because if ->SAK_work is already queued,
@@ -3404,7 +3409,7 @@ void do_SAK(struct tty_struct *tty)
3404{ 3409{
3405 if (!tty) 3410 if (!tty)
3406 return; 3411 return;
3407 PREPARE_WORK(&tty->SAK_work, __do_SAK); 3412 PREPARE_WORK(&tty->SAK_work, do_SAK_work);
3408 schedule_work(&tty->SAK_work); 3413 schedule_work(&tty->SAK_work);
3409} 3414}
3410 3415