[RFC 1/2] Char: tty, centralize works

From: Jiri Slaby
Date: Thu Nov 01 2007 - 07:26:14 EST


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 <jirislaby@xxxxxxxxx>
Cc: Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>

---
commit 1ce760b56883d3c99b914266bca939f8d3ade1fd
tree 5767d113dd80da1ec5acf233fa47fee3398f74b3
parent f87566db6dd9613dde8de59380cd2f423166511e
author Jiri Slaby <jirislaby@xxxxxxxxx> Thu, 01 Nov 2007 10:55:42 +0100
committer Jiri Slaby <jirislaby@xxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/