mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
tty: Fix missed wakeup from packet mode status update
The pty master read() can miss the wake up for a packet mode status change. For example, CPU 0 | CPU 1 n_tty_read() | n_tty_packet_mode_flush() ... | . if (packet & link->ctrl_status) { | . /* no new ctrl_status ATM */ | . | spin_lock | ctrl_status |= TIOCPKT_FLUSHREAD | spin_unlock | wake_up(link->read_wait) } | set_current_state(TASK_INTERRUPTIBLE) | ... | The pty master read() will now sleep (assuming there is no input) having missed the read_wait wakeup. Set the task state before the condition test. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Reviewed-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4ed60fc257
commit
1aa1bf1115
1 changed files with 5 additions and 4 deletions
|
@ -2168,6 +2168,11 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||||
|
|
||||||
add_wait_queue(&tty->read_wait, &wait);
|
add_wait_queue(&tty->read_wait, &wait);
|
||||||
while (nr) {
|
while (nr) {
|
||||||
|
/* This statement must be first before checking for input
|
||||||
|
so that any interrupt will set the state back to
|
||||||
|
TASK_RUNNING. */
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
|
||||||
/* First test for status change. */
|
/* First test for status change. */
|
||||||
if (packet && tty->link->ctrl_status) {
|
if (packet && tty->link->ctrl_status) {
|
||||||
unsigned char cs;
|
unsigned char cs;
|
||||||
|
@ -2185,10 +2190,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||||
nr--;
|
nr--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* This statement must be first before checking for input
|
|
||||||
so that any interrupt will set the state back to
|
|
||||||
TASK_RUNNING. */
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
|
|
||||||
if (((minimum - (b - buf)) < ldata->minimum_to_wake) &&
|
if (((minimum - (b - buf)) < ldata->minimum_to_wake) &&
|
||||||
((minimum - (b - buf)) >= 1))
|
((minimum - (b - buf)) >= 1))
|
||||||
|
|
Loading…
Add table
Reference in a new issue