Hi, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> writes: > diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c > index 0296612..66fa4e1 100644 > --- a/drivers/char/tty_buffer.c > +++ b/drivers/char/tty_buffer.c > @@ -468,7 +468,7 @@ static void flush_to_ldisc(struct work_struct *work) > */ > void tty_flush_to_ldisc(struct tty_struct *tty) > { > - flush_to_ldisc(&tty->buf.work.work); > + flush_delayed_work(&tty->buf.work); > } This might wait unnecessary scheduled-work on input_available_p(). This is nitpick though, we can call tty_flush_to_ldisc() only when data is unavailable. I.e. the following or something, static inline int input_available_p(struct tty_struct *tty, int amt) { int try = 0; retry: if (tty->icanon) { if (tty->canon_data) return 1; } else if (tty->read_cnt >= (amt ? amt : 1)) return 1; if (!checked) { tty_flush_to_ldisc(tty); try = 1; goto retry; } return 0; } > +void flush_delayed_work(struct delayed_work *dwork) > +{ > + if (del_timer(&dwork->timer)) { > + struct cpu_workqueue_struct *cwq; > + cwq = wq_per_cpu(keventd_wq, get_cpu()); > + __queue_work(cwq, &dwork->work); > + put_cpu(); > + } > + flush_work(&dwork->work); > +} > +EXPORT_SYMBOL(flush_delayed_work); > + > +/** Sorry if I'm missing the point. Doesn't this have (possible) race with schedule_delayed_work() (i.e. by tty writer)? cpu0 cpu1 if (del_timer(&dwork->timer)) { // cpu0 doesn't set _PENDING schedule_delayed_work() cwq = wq_per_cpu(); __queue_work(cwq, &dwork->work); put_cpu(); } // run timer delayed_work_timer_fn() __queue_work() list_add_tail() // re-add without list_del(), // so this will break the list? flush_work(&dwork->work); Thanks. -- OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe kernel-testers" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html