Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: move global ldisc idle waitqueue to the individual ldisc

The global wait_queue that is used for line discipline idle handling is
moved to a separate wait_queue for each line instance. This prevents
unnecessary blocking on one line, because of idle handling on another
line.

Signed-off-by: Ivo Sieben <meltedpianoman@gmail.com>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ivo Sieben and committed by
Greg Kroah-Hartman
1541f845 3e62c413

+6 -3
+4 -3
drivers/tty/tty_ldisc.c
··· 28 28 29 29 static DEFINE_SPINLOCK(tty_ldisc_lock); 30 30 static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 31 - static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); 32 31 /* Line disc dispatch table */ 33 32 static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; 34 33 ··· 64 65 return; 65 66 } 66 67 local_irq_restore(flags); 67 - wake_up(&tty_ldisc_idle); 68 + wake_up(&ld->wq_idle); 68 69 } 69 70 70 71 /** ··· 199 200 200 201 ld->ops = ldops; 201 202 atomic_set(&ld->users, 1); 203 + init_waitqueue_head(&ld->wq_idle); 204 + 202 205 return ld; 203 206 } 204 207 ··· 539 538 static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) 540 539 { 541 540 long ret; 542 - ret = wait_event_timeout(tty_ldisc_idle, 541 + ret = wait_event_timeout(tty->ldisc->wq_idle, 543 542 atomic_read(&tty->ldisc->users) == 1, timeout); 544 543 return ret > 0 ? 0 : -EBUSY; 545 544 }
+2
include/linux/tty_ldisc.h
··· 110 110 #include <linux/fs.h> 111 111 #include <linux/wait.h> 112 112 #include <linux/pps_kernel.h> 113 + #include <linux/wait.h> 113 114 114 115 struct tty_ldisc_ops { 115 116 int magic; ··· 155 154 struct tty_ldisc { 156 155 struct tty_ldisc_ops *ops; 157 156 atomic_t users; 157 + wait_queue_head_t wq_idle; 158 158 }; 159 159 160 160 #define TTY_LDISC_MAGIC 0x5403