Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1290477
| From | Peter Hurley <peter@hurleysoftware.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 1/6] n_tty: Always wake up read()/poll() if new input |
| Date | 2015-12-12 23:20 +0100 |
| Message-ID | <qF0Ge-8bC-13@gated-at.bofh.it> (permalink) |
| References | <qF0Gd-8bC-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
A read() in non-canonical mode when VMIN > 0 and VTIME == 0 does not
complete until at least VMIN chars have been read (or the user buffer is
full). In this infrequent read mode, n_tty_read() attempts to reduce
wakeups by computing the amount of data still necessary to complete the
read (minimum_to_wake) and only waking the read()/poll() when that much
unread data has been processed. This is the only read mode for which
new data does not necessarily generate a wakeup.
However, this optimization is broken and commonly leads to hung reads
even though the necessary amount of data has been received. Since the
optimization is of marginal value anyway, just remove the whole
thing. This also remedies a race between a concurrent poll() and
read() in this mode, where the poll() can reset the minimum_to_wake
of the read() (and vice versa).
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
drivers/tty/n_tty.c | 33 ++-------------------------------
1 file changed, 2 insertions(+), 31 deletions(-)
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 4e1867a..16ba07b 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -113,7 +113,6 @@ struct n_tty_data {
DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
unsigned char echo_buf[N_TTY_BUF_SIZE];
- int minimum_to_wake;
int closing;
/* consumer-published */
@@ -1632,7 +1631,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
/* publish read_head to consumer */
smp_store_release(&ldata->commit_head, ldata->read_head);
- if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) {
+ if (read_cnt(ldata)) {
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
wake_up_interruptible_poll(&tty->read_wait, POLLIN);
}
@@ -1899,7 +1898,6 @@ static int n_tty_open(struct tty_struct *tty)
reset_buffer_flags(tty->disc_data);
ldata->column = 0;
ldata->canon_column = 0;
- ldata->minimum_to_wake = 1;
ldata->num_overrun = 0;
ldata->no_room = 0;
ldata->lnext = 0;
@@ -2162,14 +2160,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
minimum = MIN_CHAR(tty);
if (minimum) {
time = (HZ / 10) * TIME_CHAR(tty);
- if (time)
- ldata->minimum_to_wake = 1;
- else if (!waitqueue_active(&tty->read_wait) ||
- (ldata->minimum_to_wake > minimum))
- ldata->minimum_to_wake = minimum;
} else {
timeout = (HZ / 10) * TIME_CHAR(tty);
- ldata->minimum_to_wake = minimum = 1;
+ minimum = 1;
}
}
@@ -2196,10 +2189,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
break;
}
- if (((minimum - (b - buf)) < ldata->minimum_to_wake) &&
- ((minimum - (b - buf)) >= 1))
- ldata->minimum_to_wake = (minimum - (b - buf));
-
done = check_other_done(tty);
if (!input_available_p(tty, 0)) {
@@ -2265,9 +2254,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
up_read(&tty->termios_rwsem);
remove_wait_queue(&tty->read_wait, &wait);
- if (!waitqueue_active(&tty->read_wait))
- ldata->minimum_to_wake = minimum;
-
mutex_unlock(&ldata->atomic_read_lock);
if (b - buf)
@@ -2402,7 +2388,6 @@ break_out:
static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
poll_table *wait)
{
- struct n_tty_data *ldata = tty->disc_data;
unsigned int mask = 0;
poll_wait(file, &tty->read_wait, wait);
@@ -2415,12 +2400,6 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
mask |= POLLPRI | POLLIN | POLLRDNORM;
if (tty_hung_up_p(file))
mask |= POLLHUP;
- if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
- if (MIN_CHAR(tty) && !TIME_CHAR(tty))
- ldata->minimum_to_wake = MIN_CHAR(tty);
- else
- ldata->minimum_to_wake = 1;
- }
if (tty->ops->write && !tty_is_writelocked(tty) &&
tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
tty_write_room(tty) > 0)
@@ -2471,14 +2450,6 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
static void n_tty_fasync(struct tty_struct *tty, int on)
{
- struct n_tty_data *ldata = tty->disc_data;
-
- if (!waitqueue_active(&tty->read_wait)) {
- if (on)
- ldata->minimum_to_wake = 1;
- else if (!tty->fasync)
- ldata->minimum_to_wake = N_TTY_BUF_SIZE;
- }
}
static void n_tty_closing(struct tty_struct *tty)
--
2.6.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 0/6] More n_tty fixes Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
[PATCH 6/6] n_tty: Remove tty count checks from unthrottle Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
[PATCH 4/6] tty: Fix ioctl(FIOASYNC) on hungup file Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
[PATCH 3/6] tty: Add fasync() hung up file operation Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
[PATCH 1/6] n_tty: Always wake up read()/poll() if new input Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
Re: [PATCH 1/6] n_tty: Always wake up read()/poll() if new input Johannes Stezenbach <js@sig21.net> - 2015-12-13 15:50 +0100
Re: [PATCH 1/6] n_tty: Always wake up read()/poll() if new input Peter Hurley <peter@hurleysoftware.com> - 2015-12-13 21:00 +0100
[PATCH 2/6] tty, n_tty: Remove fasync() ldisc notification Peter Hurley <peter@hurleysoftware.com> - 2015-12-12 23:20 +0100
csiph-web