<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/tty/n_tty.c, branch v3.11</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>n_tty: Buffer work should not reschedule itself</title>
<updated>2013-06-17T19:55:30+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-06-15T11:28:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7879a9f9fd4ff4a88b3c51f4ab6718dc7f86ed86'/>
<id>7879a9f9fd4ff4a88b3c51f4ab6718dc7f86ed86</id>
<content type='text'>
Although the driver-side input path must update the available
buffer space, it should not reschedule itself. If space is still
available and the flip buffers are not empty, flush_to_ldisc()
will loop again.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Although the driver-side input path must update the available
buffer space, it should not reschedule itself. If space is still
available and the flip buffers are not empty, flush_to_ldisc()
will loop again.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Fix unsafe update of available buffer space</title>
<updated>2013-06-17T19:55:30+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-06-15T11:28:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b84830527645dfe7b7a5cc03518e3c791b4ee9e0'/>
<id>b84830527645dfe7b7a5cc03518e3c791b4ee9e0</id>
<content type='text'>
receive_room is used to control the amount of data the flip
buffer work can push to the read buffer. This update is unsafe:

  CPU 0                        |  CPU 1
                               |
                               | n_tty_read()
                               |   n_tty_set_room()
                               |     left = &lt;calc of space&gt;
n_tty_receive_buf()            |
  &lt;push data to buffer&gt;        |
  n_tty_set_room()             |
    left = &lt;calc of space&gt;     |
    tty-&gt;receive_room = left   |
                               |     tty-&gt;receive_room = left

receive_room is now updated with a stale calculation of the
available buffer space, and the subsequent work loop will likely
overwrite unread data in the input buffer.

Update receive_room atomically with the calculation of the
available buffer space.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
receive_room is used to control the amount of data the flip
buffer work can push to the read buffer. This update is unsafe:

  CPU 0                        |  CPU 1
                               |
                               | n_tty_read()
                               |   n_tty_set_room()
                               |     left = &lt;calc of space&gt;
n_tty_receive_buf()            |
  &lt;push data to buffer&gt;        |
  n_tty_set_room()             |
    left = &lt;calc of space&gt;     |
    tty-&gt;receive_room = left   |
                               |     tty-&gt;receive_room = left

receive_room is now updated with a stale calculation of the
available buffer space, and the subsequent work loop will likely
overwrite unread data in the input buffer.

Update receive_room atomically with the calculation of the
available buffer space.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Untangle read completion variables</title>
<updated>2013-06-17T19:55:19+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-06-15T11:28:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a6e54319a7499bf754efb3a2cb2f5d4901ccbcff'/>
<id>a6e54319a7499bf754efb3a2cb2f5d4901ccbcff</id>
<content type='text'>
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Encapsulate minimum_to_wake within N_TTY</title>
<updated>2013-06-17T19:55:11+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-06-15T11:28:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=f6c8dbe6e50c6e5121d7b6644718207daa008221'/>
<id>f6c8dbe6e50c6e5121d7b6644718207daa008221</id>
<content type='text'>
minimum_to_wake is unique to N_TTY processing, and belongs in
per-ldisc data.

Add the ldisc method, ldisc_ops::fasync(), to notify line disciplines
when signal-driven I/O is enabled or disabled. When enabled for N_TTY
(by fcntl(F_SETFL, O_ASYNC)), blocking reader/polls will be woken
for any readable input. When disabled, blocking reader/polls are not
woken until the read buffer is full.

Canonical mode (L_ICANON(tty), n_tty_data::icanon) is not affected by
the minimum_to_wake setting.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
minimum_to_wake is unique to N_TTY processing, and belongs in
per-ldisc data.

Add the ldisc method, ldisc_ops::fasync(), to notify line disciplines
when signal-driven I/O is enabled or disabled. When enabled for N_TTY
(by fcntl(F_SETFL, O_ASYNC)), blocking reader/polls will be woken
for any readable input. When disabled, blocking reader/polls are not
woken until the read buffer is full.

Canonical mode (L_ICANON(tty), n_tty_data::icanon) is not affected by
the minimum_to_wake setting.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge 3.10-rc3 into tty-next</title>
<updated>2013-05-27T01:57:53+00:00</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2013-05-27T01:57:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=8095e4e81b4bc38eef7e0be99f9ecc744eaa1683'/>
<id>8095e4e81b4bc38eef7e0be99f9ecc744eaa1683</id>
<content type='text'>
We want these fixes.

Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We want these fixes.

Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>TTY: Fix tty miss restart after we turn off flow-control</title>
<updated>2013-05-20T19:15:59+00:00</updated>
<author>
<name>Wang YanQing</name>
<email>udknight@gmail.com</email>
</author>
<published>2013-05-09T06:16:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=dab73b4eb9ef924a2b90dab84e539076d82b256f'/>
<id>dab73b4eb9ef924a2b90dab84e539076d82b256f</id>
<content type='text'>
I meet emacs hang in start if I do the operation below:
  1: echo 3 &gt; /proc/sys/vm/drop_caches
  2: emacs BigFile
  3: Press CTRL-S follow 2 immediately

Then emacs hang on, CTRL-Q can't resume, the terminal
hang on, you can do nothing with this terminal except
close it.

The reason is before emacs takeover control the tty,
we use CTRL-S to XOFF it. Then when emacs takeover the
control, it may don't use the flow-control, so emacs hang.
This patch fix it.

This patch will fix a kind of strange tty relation hang problem,
I believe I meet it with vim in ssh, and also see below bug report:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=465823

Signed-off-by: Wang YanQing &lt;udknight@gmail.com&gt;
Cc: stable &lt;stable@vger.kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I meet emacs hang in start if I do the operation below:
  1: echo 3 &gt; /proc/sys/vm/drop_caches
  2: emacs BigFile
  3: Press CTRL-S follow 2 immediately

Then emacs hang on, CTRL-Q can't resume, the terminal
hang on, you can do nothing with this terminal except
close it.

The reason is before emacs takeover control the tty,
we use CTRL-S to XOFF it. Then when emacs takeover the
control, it may don't use the flow-control, so emacs hang.
This patch fix it.

This patch will fix a kind of strange tty relation hang problem,
I believe I meet it with vim in ssh, and also see below bug report:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=465823

Signed-off-by: Wang YanQing &lt;udknight@gmail.com&gt;
Cc: stable &lt;stable@vger.kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tty: Remove TTY_HW_COOK_IN/OUT</title>
<updated>2013-05-20T19:12:40+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-05-17T16:49:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=582f55907d3f6cb762af20b56478bf25ef96430e'/>
<id>582f55907d3f6cb762af20b56478bf25ef96430e</id>
<content type='text'>
No in-tree tty driver supports cooked mode in hardware; remove.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
No in-tree tty driver supports cooked mode in hardware; remove.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Fully initialize ldisc before restarting buffer work</title>
<updated>2013-03-18T23:44:01+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-03-11T20:44:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b66f4fa509153ca9d313075806d5c6425dfa43c5'/>
<id>b66f4fa509153ca9d313075806d5c6425dfa43c5</id>
<content type='text'>
Buffer work may already be pending when the n_tty ldisc is re-opened,
eg., when setting the ldisc (via TIOCSETD ioctl) and when hanging up
the tty. Since n_tty_set_room() may restart buffer work, first ensure
the ldisc is completely initialized.

Factor n_tty_set_room() out of reset_buffer_flags() (only 2 callers)
and reorganize n_tty_open() to set termios last; buffer work will
be restarted there if necessary, after the char_map is properly
initialized.

Fixes this WARNING:

[  549.561769] ------------[ cut here ]------------
[  549.598755] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0xff/0x130()
[  549.604058] scheduling buffer work for halted ldisc
[  549.607741] Pid: 9417, comm: trinity-child28 Tainted: G      D W 3.7.0-next-20121217-sasha-00023-g8689ef9 #219
[  549.652580] Call Trace:
[  549.662754]  [&lt;ffffffff81c432cf&gt;] ? n_tty_set_room+0xff/0x130
[  549.665458]  [&lt;ffffffff8110cae7&gt;] warn_slowpath_common+0x87/0xb0
[  549.668257]  [&lt;ffffffff8110cb71&gt;] warn_slowpath_fmt+0x41/0x50
[  549.671007]  [&lt;ffffffff81c432cf&gt;] n_tty_set_room+0xff/0x130
[  549.673268]  [&lt;ffffffff81c44597&gt;] reset_buffer_flags+0x137/0x150
[  549.675607]  [&lt;ffffffff81c45b71&gt;] n_tty_open+0x131/0x1c0
[  549.677699]  [&lt;ffffffff81c47824&gt;] tty_ldisc_open.isra.5+0x54/0x70
[  549.680147]  [&lt;ffffffff81c482bf&gt;] tty_ldisc_hangup+0x11f/0x1e0
[  549.682409]  [&lt;ffffffff81c3fa17&gt;] __tty_hangup+0x137/0x440
[  549.684634]  [&lt;ffffffff81c3fd49&gt;] tty_vhangup+0x9/0x10
[  549.686443]  [&lt;ffffffff81c4a42c&gt;] pty_close+0x14c/0x160
[  549.688446]  [&lt;ffffffff81c41225&gt;] tty_release+0xd5/0x490
[  549.690460]  [&lt;ffffffff8127d8a2&gt;] __fput+0x122/0x250
[  549.692577]  [&lt;ffffffff8127d9d9&gt;] ____fput+0x9/0x10
[  549.694534]  [&lt;ffffffff811348c2&gt;] task_work_run+0xb2/0xf0
[  549.696349]  [&lt;ffffffff81113c6d&gt;] do_exit+0x36d/0x580
[  549.698286]  [&lt;ffffffff8107d964&gt;] ? syscall_trace_enter+0x24/0x2e0
[  549.702729]  [&lt;ffffffff81113f4a&gt;] do_group_exit+0x8a/0xc0
[  549.706775]  [&lt;ffffffff81113f92&gt;] sys_exit_group+0x12/0x20
[  549.711088]  [&lt;ffffffff83cfab18&gt;] tracesys+0xe1/0xe6
[  549.728001] ---[ end trace 73eb41728f11f87e ]---

Reported-by: Sasha Levin &lt;levinsasha928@gmail.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Buffer work may already be pending when the n_tty ldisc is re-opened,
eg., when setting the ldisc (via TIOCSETD ioctl) and when hanging up
the tty. Since n_tty_set_room() may restart buffer work, first ensure
the ldisc is completely initialized.

Factor n_tty_set_room() out of reset_buffer_flags() (only 2 callers)
and reorganize n_tty_open() to set termios last; buffer work will
be restarted there if necessary, after the char_map is properly
initialized.

Fixes this WARNING:

[  549.561769] ------------[ cut here ]------------
[  549.598755] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0xff/0x130()
[  549.604058] scheduling buffer work for halted ldisc
[  549.607741] Pid: 9417, comm: trinity-child28 Tainted: G      D W 3.7.0-next-20121217-sasha-00023-g8689ef9 #219
[  549.652580] Call Trace:
[  549.662754]  [&lt;ffffffff81c432cf&gt;] ? n_tty_set_room+0xff/0x130
[  549.665458]  [&lt;ffffffff8110cae7&gt;] warn_slowpath_common+0x87/0xb0
[  549.668257]  [&lt;ffffffff8110cb71&gt;] warn_slowpath_fmt+0x41/0x50
[  549.671007]  [&lt;ffffffff81c432cf&gt;] n_tty_set_room+0xff/0x130
[  549.673268]  [&lt;ffffffff81c44597&gt;] reset_buffer_flags+0x137/0x150
[  549.675607]  [&lt;ffffffff81c45b71&gt;] n_tty_open+0x131/0x1c0
[  549.677699]  [&lt;ffffffff81c47824&gt;] tty_ldisc_open.isra.5+0x54/0x70
[  549.680147]  [&lt;ffffffff81c482bf&gt;] tty_ldisc_hangup+0x11f/0x1e0
[  549.682409]  [&lt;ffffffff81c3fa17&gt;] __tty_hangup+0x137/0x440
[  549.684634]  [&lt;ffffffff81c3fd49&gt;] tty_vhangup+0x9/0x10
[  549.686443]  [&lt;ffffffff81c4a42c&gt;] pty_close+0x14c/0x160
[  549.688446]  [&lt;ffffffff81c41225&gt;] tty_release+0xd5/0x490
[  549.690460]  [&lt;ffffffff8127d8a2&gt;] __fput+0x122/0x250
[  549.692577]  [&lt;ffffffff8127d9d9&gt;] ____fput+0x9/0x10
[  549.694534]  [&lt;ffffffff811348c2&gt;] task_work_run+0xb2/0xf0
[  549.696349]  [&lt;ffffffff81113c6d&gt;] do_exit+0x36d/0x580
[  549.698286]  [&lt;ffffffff8107d964&gt;] ? syscall_trace_enter+0x24/0x2e0
[  549.702729]  [&lt;ffffffff81113f4a&gt;] do_group_exit+0x8a/0xc0
[  549.706775]  [&lt;ffffffff81113f92&gt;] sys_exit_group+0x12/0x20
[  549.711088]  [&lt;ffffffff83cfab18&gt;] tracesys+0xe1/0xe6
[  549.728001] ---[ end trace 73eb41728f11f87e ]---

Reported-by: Sasha Levin &lt;levinsasha928@gmail.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Correct unthrottle-with-buffer-flush comments</title>
<updated>2013-03-18T23:38:58+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-03-11T20:44:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=25518c68b334aa977d857dd71dd53f694ffb11e8'/>
<id>25518c68b334aa977d857dd71dd53f694ffb11e8</id>
<content type='text'>
The driver is no longer unthrottled on buffer reset, so remove
comments that claim it is.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The driver is no longer unthrottled on buffer reset, so remove
comments that claim it is.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Don't flush buffer when closing ldisc</title>
<updated>2013-03-18T23:32:46+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-03-11T20:44:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=79901317ce80c43a0249ccc6e3fea9d0968e159e'/>
<id>79901317ce80c43a0249ccc6e3fea9d0968e159e</id>
<content type='text'>
A buffer flush is both undesirable and unnecessary when the ldisc
is closing. A buffer flush performs the following:
 1. resets ldisc data fields to their initial state
 2. resets tty-&gt;receive_room to indicate more data can be sent
 3. schedules buffer work to receive more data
 4. signals a buffer flush has happened to linked pty in packet mode

Since the ldisc has been halted and the tty may soon be destructed,
buffer work must not be scheduled as that work might access
an invalid tty and ldisc state. Also, the ldisc read buffer is about
to be freed, so that's pointless.

Resetting the ldisc data fields is pointless as well since that
structure is about to be freed.

Resetting tty-&gt;receive_room is unnecessary, as it will be properly
reset if a new ldisc is reopened. Besides, resetting the original
receive_room value would be wrong since the read buffer will be
gone.

Since the packet mode flush is observable from userspace, this
behavior has been preserved.

The test jig originally authored by Ilya Zykov &lt;ilya@ilyx.ru&gt; and
signed off by him is included below. The test jig prompts the
following warnings which this patch fixes.

[   38.051111] ------------[ cut here ]------------
[   38.052113] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room.part.6+0x8b/0xa0()
[   38.053916] Hardware name: Bochs
[   38.054819] Modules linked in: netconsole configfs bnep rfcomm bluetooth parport_pc ppdev snd_hda_intel snd_hda_codec
snd_hwdep snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq psmouse snd_timer serio_raw mac_hid snd_seq_device
snd microcode lp parport virtio_balloon soundcore i2c_piix4 snd_page_alloc floppy 8139too 8139cp
[   38.059704] Pid: 1564, comm: pty_kill Tainted: G        W    3.7.0-next-20121130+ttydebug-xeon #20121130+ttydebug
[   38.061578] Call Trace:
[   38.062491]  [&lt;ffffffff81058b4f&gt;] warn_slowpath_common+0x7f/0xc0
[   38.063448]  [&lt;ffffffff81058baa&gt;] warn_slowpath_null+0x1a/0x20
[   38.064439]  [&lt;ffffffff8142dc2b&gt;] n_tty_set_room.part.6+0x8b/0xa0
[   38.065381]  [&lt;ffffffff8142dc82&gt;] n_tty_set_room+0x42/0x80
[   38.066323]  [&lt;ffffffff8142e6f2&gt;] reset_buffer_flags+0x102/0x160
[   38.077508]  [&lt;ffffffff8142e76d&gt;] n_tty_flush_buffer+0x1d/0x90
[   38.078782]  [&lt;ffffffff81046569&gt;] ? default_spin_lock_flags+0x9/0x10
[   38.079734]  [&lt;ffffffff8142e804&gt;] n_tty_close+0x24/0x60
[   38.080730]  [&lt;ffffffff81431b61&gt;] tty_ldisc_close.isra.2+0x41/0x60
[   38.081680]  [&lt;ffffffff81431bbb&gt;] tty_ldisc_kill+0x3b/0x80
[   38.082618]  [&lt;ffffffff81432a07&gt;] tty_ldisc_release+0x77/0xe0
[   38.083549]  [&lt;ffffffff8142b781&gt;] tty_release+0x451/0x4d0
[   38.084525]  [&lt;ffffffff811950be&gt;] __fput+0xae/0x230
[   38.085472]  [&lt;ffffffff8119524e&gt;] ____fput+0xe/0x10
[   38.086401]  [&lt;ffffffff8107aa88&gt;] task_work_run+0xc8/0xf0
[   38.087334]  [&lt;ffffffff8105ea56&gt;] do_exit+0x196/0x4b0
[   38.088304]  [&lt;ffffffff8106c77b&gt;] ? __dequeue_signal+0x6b/0xb0
[   38.089240]  [&lt;ffffffff8105ef34&gt;] do_group_exit+0x44/0xa0
[   38.090182]  [&lt;ffffffff8106f43d&gt;] get_signal_to_deliver+0x20d/0x4e0
[   38.091125]  [&lt;ffffffff81016979&gt;] do_signal+0x29/0x130
[   38.092096]  [&lt;ffffffff81431a9e&gt;] ? tty_ldisc_deref+0xe/0x10
[   38.093030]  [&lt;ffffffff8142a317&gt;] ? tty_write+0xb7/0xf0
[   38.093976]  [&lt;ffffffff81193f53&gt;] ? vfs_write+0xb3/0x180
[   38.094904]  [&lt;ffffffff81016b20&gt;] do_notify_resume+0x80/0xc0
[   38.095830]  [&lt;ffffffff81700492&gt;] int_signal+0x12/0x17
[   38.096788] ---[ end trace 5f6f7a9651cd999b ]---

[ 2730.570602] ------------[ cut here ]------------
[ 2730.572130] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0x107/0x140()
[ 2730.574904] scheduling buffer work for halted ldisc
[ 2730.578303] Pid: 9691, comm: trinity-child15 Tainted: G        W 3.7.0-rc8-next-20121205-sasha-00023-g59f0d85 #207
[ 2730.588694] Call Trace:
[ 2730.590486]  [&lt;ffffffff81c41d77&gt;] ? n_tty_set_room+0x107/0x140
[ 2730.592559]  [&lt;ffffffff8110c827&gt;] warn_slowpath_common+0x87/0xb0
[ 2730.595317]  [&lt;ffffffff8110c8b1&gt;] warn_slowpath_fmt+0x41/0x50
[ 2730.599186]  [&lt;ffffffff81c41d77&gt;] n_tty_set_room+0x107/0x140
[ 2730.603141]  [&lt;ffffffff81c42fe7&gt;] reset_buffer_flags+0x137/0x150
[ 2730.607166]  [&lt;ffffffff81c43018&gt;] n_tty_flush_buffer+0x18/0x90
[ 2730.610123]  [&lt;ffffffff81c430af&gt;] n_tty_close+0x1f/0x60
[ 2730.612068]  [&lt;ffffffff81c461f2&gt;] tty_ldisc_close.isra.4+0x52/0x60
[ 2730.614078]  [&lt;ffffffff81c462ab&gt;] tty_ldisc_reinit+0x3b/0x70
[ 2730.615891]  [&lt;ffffffff81c46db2&gt;] tty_ldisc_hangup+0x102/0x1e0
[ 2730.617780]  [&lt;ffffffff81c3e537&gt;] __tty_hangup+0x137/0x440
[ 2730.619547]  [&lt;ffffffff81c3e869&gt;] tty_vhangup+0x9/0x10
[ 2730.621266]  [&lt;ffffffff81c48f1c&gt;] pty_close+0x14c/0x160
[ 2730.622952]  [&lt;ffffffff81c3fd45&gt;] tty_release+0xd5/0x490
[ 2730.624674]  [&lt;ffffffff8127fbe2&gt;] __fput+0x122/0x250
[ 2730.626195]  [&lt;ffffffff8127fd19&gt;] ____fput+0x9/0x10
[ 2730.627758]  [&lt;ffffffff81134602&gt;] task_work_run+0xb2/0xf0
[ 2730.629491]  [&lt;ffffffff811139ad&gt;] do_exit+0x36d/0x580
[ 2730.631159]  [&lt;ffffffff81113c8a&gt;] do_group_exit+0x8a/0xc0
[ 2730.632819]  [&lt;ffffffff81127351&gt;] get_signal_to_deliver+0x501/0x5b0
[ 2730.634758]  [&lt;ffffffff8106de34&gt;] do_signal+0x24/0x100
[ 2730.636412]  [&lt;ffffffff81204865&gt;] ? user_exit+0xa5/0xd0
[ 2730.638078]  [&lt;ffffffff81183cd8&gt;] ? trace_hardirqs_on_caller+0x118/0x140
[ 2730.640279]  [&lt;ffffffff81183d0d&gt;] ? trace_hardirqs_on+0xd/0x10
[ 2730.642164]  [&lt;ffffffff8106df78&gt;] do_notify_resume+0x48/0xa0
[ 2730.643966]  [&lt;ffffffff83cdff6a&gt;] int_signal+0x12/0x17
[ 2730.645672] ---[ end trace a40d53149c07fce0 ]---

/*
 * pty_thrash.c
 *
 * Based on original test jig by Ilya Zykov &lt;ilya@ilyx.ru&gt;
 *
 * Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
 * Signed-off-by: Ilya Zykov &lt;ilya@ilyx.ru&gt;
 */

static int fd;

static void error_exit(char *f, ...)
{
        va_list va;

        va_start(va, f);
        vprintf(f, va);
        printf(": %s\n", strerror(errno));
        va_end(va);

        if (fd &gt;= 0)
                close(fd);

        exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
        int parent;
        char pts_name[24];
        int ptn, unlock;

        while (1) {

                fd = open("/dev/ptmx", O_RDWR);
                if (fd &lt; 0)
                        error_exit("opening pty master");
                unlock = 0;
                if (ioctl(fd, TIOCSPTLCK, &amp;unlock) &lt; 0)
                        error_exit("unlocking pty pair");
                if (ioctl(fd, TIOCGPTN, &amp;ptn) &lt; 0)
                        error_exit("getting pty #");
                snprintf(pts_name, sizeof(pts_name), "/dev/pts/%d", ptn);

                child_id = fork();
                if (child_id == -1)
                        error_exit("forking child");

                if (parent) {
                        int err, id, status;
                        char buf[128];
                        int n;

                        n = read(fd, buf, sizeof(buf));
                        if (n &lt; 0)
                                error_exit("master reading");
                        printf("%.*s\n", n-1, buf);

                        close(fd);

                        err = kill(child_id, SIGKILL);
                        if (err &lt; 0)
                                error_exit("killing child");
                        id = waitpid(child_id, &amp;status, 0);
                        if (id &lt; 0 || id != child_id)
                                error_exit("waiting for child");

                } else { /* Child */

                        close(fd);
                        printf("Test cycle on slave pty %s\n", pts_name);
                        fd = open(pts_name, O_RDWR);
                        if (fd &lt; 0)
                                error_exit("opening pty slave");

                        while (1) {
                                char pattern[] = "test\n";
                                if (write(fd, pattern, strlen(pattern)) &lt; 0)
                                        error_exit("slave writing");
                        }

                }
        }

        /* never gets here */
        return 0;
}

Reported-by: Sasha Levin &lt;levinsasha928@gmail.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A buffer flush is both undesirable and unnecessary when the ldisc
is closing. A buffer flush performs the following:
 1. resets ldisc data fields to their initial state
 2. resets tty-&gt;receive_room to indicate more data can be sent
 3. schedules buffer work to receive more data
 4. signals a buffer flush has happened to linked pty in packet mode

Since the ldisc has been halted and the tty may soon be destructed,
buffer work must not be scheduled as that work might access
an invalid tty and ldisc state. Also, the ldisc read buffer is about
to be freed, so that's pointless.

Resetting the ldisc data fields is pointless as well since that
structure is about to be freed.

Resetting tty-&gt;receive_room is unnecessary, as it will be properly
reset if a new ldisc is reopened. Besides, resetting the original
receive_room value would be wrong since the read buffer will be
gone.

Since the packet mode flush is observable from userspace, this
behavior has been preserved.

The test jig originally authored by Ilya Zykov &lt;ilya@ilyx.ru&gt; and
signed off by him is included below. The test jig prompts the
following warnings which this patch fixes.

[   38.051111] ------------[ cut here ]------------
[   38.052113] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room.part.6+0x8b/0xa0()
[   38.053916] Hardware name: Bochs
[   38.054819] Modules linked in: netconsole configfs bnep rfcomm bluetooth parport_pc ppdev snd_hda_intel snd_hda_codec
snd_hwdep snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq psmouse snd_timer serio_raw mac_hid snd_seq_device
snd microcode lp parport virtio_balloon soundcore i2c_piix4 snd_page_alloc floppy 8139too 8139cp
[   38.059704] Pid: 1564, comm: pty_kill Tainted: G        W    3.7.0-next-20121130+ttydebug-xeon #20121130+ttydebug
[   38.061578] Call Trace:
[   38.062491]  [&lt;ffffffff81058b4f&gt;] warn_slowpath_common+0x7f/0xc0
[   38.063448]  [&lt;ffffffff81058baa&gt;] warn_slowpath_null+0x1a/0x20
[   38.064439]  [&lt;ffffffff8142dc2b&gt;] n_tty_set_room.part.6+0x8b/0xa0
[   38.065381]  [&lt;ffffffff8142dc82&gt;] n_tty_set_room+0x42/0x80
[   38.066323]  [&lt;ffffffff8142e6f2&gt;] reset_buffer_flags+0x102/0x160
[   38.077508]  [&lt;ffffffff8142e76d&gt;] n_tty_flush_buffer+0x1d/0x90
[   38.078782]  [&lt;ffffffff81046569&gt;] ? default_spin_lock_flags+0x9/0x10
[   38.079734]  [&lt;ffffffff8142e804&gt;] n_tty_close+0x24/0x60
[   38.080730]  [&lt;ffffffff81431b61&gt;] tty_ldisc_close.isra.2+0x41/0x60
[   38.081680]  [&lt;ffffffff81431bbb&gt;] tty_ldisc_kill+0x3b/0x80
[   38.082618]  [&lt;ffffffff81432a07&gt;] tty_ldisc_release+0x77/0xe0
[   38.083549]  [&lt;ffffffff8142b781&gt;] tty_release+0x451/0x4d0
[   38.084525]  [&lt;ffffffff811950be&gt;] __fput+0xae/0x230
[   38.085472]  [&lt;ffffffff8119524e&gt;] ____fput+0xe/0x10
[   38.086401]  [&lt;ffffffff8107aa88&gt;] task_work_run+0xc8/0xf0
[   38.087334]  [&lt;ffffffff8105ea56&gt;] do_exit+0x196/0x4b0
[   38.088304]  [&lt;ffffffff8106c77b&gt;] ? __dequeue_signal+0x6b/0xb0
[   38.089240]  [&lt;ffffffff8105ef34&gt;] do_group_exit+0x44/0xa0
[   38.090182]  [&lt;ffffffff8106f43d&gt;] get_signal_to_deliver+0x20d/0x4e0
[   38.091125]  [&lt;ffffffff81016979&gt;] do_signal+0x29/0x130
[   38.092096]  [&lt;ffffffff81431a9e&gt;] ? tty_ldisc_deref+0xe/0x10
[   38.093030]  [&lt;ffffffff8142a317&gt;] ? tty_write+0xb7/0xf0
[   38.093976]  [&lt;ffffffff81193f53&gt;] ? vfs_write+0xb3/0x180
[   38.094904]  [&lt;ffffffff81016b20&gt;] do_notify_resume+0x80/0xc0
[   38.095830]  [&lt;ffffffff81700492&gt;] int_signal+0x12/0x17
[   38.096788] ---[ end trace 5f6f7a9651cd999b ]---

[ 2730.570602] ------------[ cut here ]------------
[ 2730.572130] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0x107/0x140()
[ 2730.574904] scheduling buffer work for halted ldisc
[ 2730.578303] Pid: 9691, comm: trinity-child15 Tainted: G        W 3.7.0-rc8-next-20121205-sasha-00023-g59f0d85 #207
[ 2730.588694] Call Trace:
[ 2730.590486]  [&lt;ffffffff81c41d77&gt;] ? n_tty_set_room+0x107/0x140
[ 2730.592559]  [&lt;ffffffff8110c827&gt;] warn_slowpath_common+0x87/0xb0
[ 2730.595317]  [&lt;ffffffff8110c8b1&gt;] warn_slowpath_fmt+0x41/0x50
[ 2730.599186]  [&lt;ffffffff81c41d77&gt;] n_tty_set_room+0x107/0x140
[ 2730.603141]  [&lt;ffffffff81c42fe7&gt;] reset_buffer_flags+0x137/0x150
[ 2730.607166]  [&lt;ffffffff81c43018&gt;] n_tty_flush_buffer+0x18/0x90
[ 2730.610123]  [&lt;ffffffff81c430af&gt;] n_tty_close+0x1f/0x60
[ 2730.612068]  [&lt;ffffffff81c461f2&gt;] tty_ldisc_close.isra.4+0x52/0x60
[ 2730.614078]  [&lt;ffffffff81c462ab&gt;] tty_ldisc_reinit+0x3b/0x70
[ 2730.615891]  [&lt;ffffffff81c46db2&gt;] tty_ldisc_hangup+0x102/0x1e0
[ 2730.617780]  [&lt;ffffffff81c3e537&gt;] __tty_hangup+0x137/0x440
[ 2730.619547]  [&lt;ffffffff81c3e869&gt;] tty_vhangup+0x9/0x10
[ 2730.621266]  [&lt;ffffffff81c48f1c&gt;] pty_close+0x14c/0x160
[ 2730.622952]  [&lt;ffffffff81c3fd45&gt;] tty_release+0xd5/0x490
[ 2730.624674]  [&lt;ffffffff8127fbe2&gt;] __fput+0x122/0x250
[ 2730.626195]  [&lt;ffffffff8127fd19&gt;] ____fput+0x9/0x10
[ 2730.627758]  [&lt;ffffffff81134602&gt;] task_work_run+0xb2/0xf0
[ 2730.629491]  [&lt;ffffffff811139ad&gt;] do_exit+0x36d/0x580
[ 2730.631159]  [&lt;ffffffff81113c8a&gt;] do_group_exit+0x8a/0xc0
[ 2730.632819]  [&lt;ffffffff81127351&gt;] get_signal_to_deliver+0x501/0x5b0
[ 2730.634758]  [&lt;ffffffff8106de34&gt;] do_signal+0x24/0x100
[ 2730.636412]  [&lt;ffffffff81204865&gt;] ? user_exit+0xa5/0xd0
[ 2730.638078]  [&lt;ffffffff81183cd8&gt;] ? trace_hardirqs_on_caller+0x118/0x140
[ 2730.640279]  [&lt;ffffffff81183d0d&gt;] ? trace_hardirqs_on+0xd/0x10
[ 2730.642164]  [&lt;ffffffff8106df78&gt;] do_notify_resume+0x48/0xa0
[ 2730.643966]  [&lt;ffffffff83cdff6a&gt;] int_signal+0x12/0x17
[ 2730.645672] ---[ end trace a40d53149c07fce0 ]---

/*
 * pty_thrash.c
 *
 * Based on original test jig by Ilya Zykov &lt;ilya@ilyx.ru&gt;
 *
 * Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
 * Signed-off-by: Ilya Zykov &lt;ilya@ilyx.ru&gt;
 */

static int fd;

static void error_exit(char *f, ...)
{
        va_list va;

        va_start(va, f);
        vprintf(f, va);
        printf(": %s\n", strerror(errno));
        va_end(va);

        if (fd &gt;= 0)
                close(fd);

        exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
        int parent;
        char pts_name[24];
        int ptn, unlock;

        while (1) {

                fd = open("/dev/ptmx", O_RDWR);
                if (fd &lt; 0)
                        error_exit("opening pty master");
                unlock = 0;
                if (ioctl(fd, TIOCSPTLCK, &amp;unlock) &lt; 0)
                        error_exit("unlocking pty pair");
                if (ioctl(fd, TIOCGPTN, &amp;ptn) &lt; 0)
                        error_exit("getting pty #");
                snprintf(pts_name, sizeof(pts_name), "/dev/pts/%d", ptn);

                child_id = fork();
                if (child_id == -1)
                        error_exit("forking child");

                if (parent) {
                        int err, id, status;
                        char buf[128];
                        int n;

                        n = read(fd, buf, sizeof(buf));
                        if (n &lt; 0)
                                error_exit("master reading");
                        printf("%.*s\n", n-1, buf);

                        close(fd);

                        err = kill(child_id, SIGKILL);
                        if (err &lt; 0)
                                error_exit("killing child");
                        id = waitpid(child_id, &amp;status, 0);
                        if (id &lt; 0 || id != child_id)
                                error_exit("waiting for child");

                } else { /* Child */

                        close(fd);
                        printf("Test cycle on slave pty %s\n", pts_name);
                        fd = open(pts_name, O_RDWR);
                        if (fd &lt; 0)
                                error_exit("opening pty slave");

                        while (1) {
                                char pattern[] = "test\n";
                                if (write(fd, pattern, strlen(pattern)) &lt; 0)
                                        error_exit("slave writing");
                        }

                }
        }

        /* never gets here */
        return 0;
}

Reported-by: Sasha Levin &lt;levinsasha928@gmail.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
