UNTESTED so far, I want to know you opinion.

--

tty, centralize works

Schedule only one work for all works, use set_bit/test_and_clear_bit as a
logic. This is because of patch which would add yet another work for
scheduled wakeups. Now it is sufficient to add 3 lines of code.

Signed-off-by: Jiri Slaby <[EMAIL PROTECTED]>
Cc: Alan Cox <[EMAIL PROTECTED]>

---
commit 1ce760b56883d3c99b914266bca939f8d3ade1fd
tree 5767d113dd80da1ec5acf233fa47fee3398f74b3
parent f87566db6dd9613dde8de59380cd2f423166511e
author Jiri Slaby <[EMAIL PROTECTED]> Thu, 01 Nov 2007 10:55:42 +0100
committer Jiri Slaby <[EMAIL PROTECTED]> Thu, 01 Nov 2007 10:55:42 +0100

 drivers/char/tty_io.c |   37 +++++++++++++++++++++----------------
 include/linux/tty.h   |    4 +++-
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 13a5357..0eb979d 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -110,6 +110,9 @@
 #define TTY_PARANOIA_CHECK 1
 #define CHECK_TTY_COUNT 1
 
+#define TTY_WORK_HANGUP                1
+#define TTY_WORK_SAK           2
+
 struct ktermios tty_std_termios = {    /* for the benefit of tty drivers  */
        .c_iflag = ICRNL | IXON,
        .c_oflag = OPOST | ONLCR,
@@ -1331,7 +1334,7 @@ static void tty_reset_termios(struct tty_struct *tty)
        
 /**
  *     do_tty_hangup           -       actual handler for hangup events
- *     @work: tty device
+ *     @tty: tty device
  *
  *     This can be called by the "eventd" kernel thread.  That is process
  *     synchronous but doesn't hold any locks, so we need to make sure we
@@ -1351,10 +1354,8 @@ static void tty_reset_termios(struct tty_struct *tty)
  *               tasklist_lock to walk task list for hangup event
  *                 ->siglock to protect ->signal/->sighand
  */
-static void do_tty_hangup(struct work_struct *work)
+static void do_tty_hangup(struct tty_struct *tty)
 {
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, hangup_work);
        struct file * cons_filp = NULL;
        struct file *filp, *f = NULL;
        struct task_struct *p;
@@ -1493,7 +1494,8 @@ void tty_hangup(struct tty_struct * tty)
        
        printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
 #endif
-       schedule_work(&tty->hangup_work);
+       set_bit(TTY_WORK_HANGUP, tty->work_todo);
+       schedule_work(&tty->work);
 }
 
 EXPORT_SYMBOL(tty_hangup);
@@ -1514,7 +1516,7 @@ void tty_vhangup(struct tty_struct * tty)
 
        printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
 #endif
-       do_tty_hangup(&tty->hangup_work);
+       do_tty_hangup(tty);
 }
 EXPORT_SYMBOL(tty_vhangup);
 
@@ -3573,13 +3575,6 @@ void __do_SAK(struct tty_struct *tty)
 #endif
 }
 
-static void do_SAK_work(struct work_struct *work)
-{
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, SAK_work);
-       __do_SAK(tty);
-}
-
 /*
  * The tq handling here is a little racy - tty->SAK_work may already be queued.
  * Fortunately we don't need to worry, because if ->SAK_work is already queued,
@@ -3590,11 +3585,22 @@ void do_SAK(struct tty_struct *tty)
 {
        if (!tty)
                return;
-       schedule_work(&tty->SAK_work);
+       set_bit(TTY_WORK_SAK, tty->work_todo);
+       schedule_work(&tty->work);
 }
 
 EXPORT_SYMBOL(do_SAK);
 
+static void tty_work(struct work_struct *work)
+{
+       struct tty_struct *tty = container_of(work, struct tty_struct, work);
+
+       if (test_and_clear_bit(TTY_WORK_HANGUP, tty->work_todo))
+               do_tty_hangup(tty);
+       if (test_and_clear_bit(TTY_WORK_SAK, tty->work_todo))
+               __do_SAK(tty);
+}
+
 /**
  *     flush_to_ldisc
  *     @work: tty structure passed from work queue.
@@ -3725,12 +3731,11 @@ static void initialize_tty_struct(struct tty_struct 
*tty)
        mutex_init(&tty->termios_mutex);
        init_waitqueue_head(&tty->write_wait);
        init_waitqueue_head(&tty->read_wait);
-       INIT_WORK(&tty->hangup_work, do_tty_hangup);
+       INIT_WORK(&tty->work, tty_work);
        mutex_init(&tty->atomic_read_lock);
        mutex_init(&tty->atomic_write_lock);
        spin_lock_init(&tty->read_lock);
        INIT_LIST_HEAD(&tty->tty_files);
-       INIT_WORK(&tty->SAK_work, do_SAK_work);
 }
 
 /*
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 56164d7..a5828a0 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -13,6 +13,7 @@
 #include <linux/tty_driver.h>
 #include <linux/tty_ldisc.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 
@@ -208,7 +209,8 @@ struct tty_struct {
        int alt_speed;          /* For magic substitution of 38400 bps */
        wait_queue_head_t write_wait;
        wait_queue_head_t read_wait;
-       struct work_struct hangup_work;
+       DECLARE_BITMAP(work_todo, 32);
+       struct work_struct work;
        void *disc_data;
        void *driver_data;
        struct list_head tty_files;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to