Skip to content

Commit c816b2e

Browse files
kosuke-tatsugregkh
authored andcommitted
n_tty: wake up poll(POLLRDNORM) on receiving data
The poll man page says POLLRDNORM is equivalent to POLLIN when used as an event. $ man poll <snip> POLLRDNORM Equivalent to POLLIN. However, in n_tty driver, POLLRDNORM does not return until timeout even if there is terminal input, whereas POLLIN returns. The following test program works until kernel-3.17, but the test stops in poll() after commit 57087d5 ("tty: Fix spurious poll() wakeups"). [Steps to run test program] $ cc -o test-pollrdnorm test-pollrdnorm.c $ ./test-pollrdnorm foo <-- Type in something from the terminal followed by [RET]. The string should be echoed back. ------------------------< test-pollrdnorm.c >------------------------ #include <stdio.h> #include <errno.h> #include <poll.h> #include <unistd.h> void main(void) { int n; unsigned char buf[8]; struct pollfd fds[1] = {{ 0, POLLRDNORM, 0 }}; n = poll(fds, 1, -1); if (n < 0) perror("poll"); n = read(0, buf, 8); if (n < 0) perror("read"); if (n > 0) write(1, buf, n); } ------------------------------------------------------------------------ The attached patch fixes this problem. Many calls to wake_up_interruptible_poll() in the kernel source code already specify "POLLIN | POLLRDNORM". Fixes: 57087d5 ("tty: Fix spurious poll() wakeups") Cc: [email protected] Signed-off-by: Kosuke Tatsukawa <[email protected]> Link: https://lore.kernel.org/r/TYCPR01MB81901C0F932203D30E452B3EA5209@TYCPR01MB8190.jpnprd01.prod.outlook.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 26291c5 commit c816b2e

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/tty/n_tty.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
13291329
put_tty_queue(c, ldata);
13301330
smp_store_release(&ldata->canon_head, ldata->read_head);
13311331
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1332-
wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
1332+
wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM);
13331333
return;
13341334
}
13351335
}
@@ -1561,7 +1561,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
15611561

15621562
if (read_cnt(ldata)) {
15631563
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1564-
wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
1564+
wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM);
15651565
}
15661566
}
15671567

0 commit comments

Comments
 (0)