<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/linux.git/drivers/tty/tty_ldsem.c, branch v4.4.283</title>
<subtitle>Linux Kernel
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v4.4.283</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v4.4.283'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/'/>
<updated>2019-08-25T08:52:51Z</updated>
<entry>
<title>tty/ldsem, locking/rwsem: Add missing ACQUIRE to read_failed sleep loop</title>
<updated>2019-08-25T08:52:51Z</updated>
<author>
<name>Peter Zijlstra</name>
<email>peterz@infradead.org</email>
</author>
<published>2019-07-18T13:03:15Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=cef88692293d07f1fa090e3c497b849dfcc1e4f4'/>
<id>urn:sha1:cef88692293d07f1fa090e3c497b849dfcc1e4f4</id>
<content type='text'>
[ Upstream commit 952041a8639a7a3a73a2b6573cb8aa8518bc39f8 ]

While reviewing rwsem down_slowpath, Will noticed ldsem had a copy of
a bug we just found for rwsem.

  X = 0;

  CPU0			CPU1

  rwsem_down_read()
    for (;;) {
      set_current_state(TASK_UNINTERRUPTIBLE);

                        X = 1;
                        rwsem_up_write();
                          rwsem_mark_wake()
                            atomic_long_add(adjustment, &amp;sem-&gt;count);
                            smp_store_release(&amp;waiter-&gt;task, NULL);

      if (!waiter.task)
        break;

      ...
    }

  r = X;

Allows 'r == 0'.

Reported-by: Will Deacon &lt;will@kernel.org&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Acked-by: Will Deacon &lt;will@kernel.org&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Cc: Peter Zijlstra &lt;peterz@infradead.org&gt;
Cc: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Fixes: 4898e640caf0 ("tty: Add timed, writer-prioritized rw semaphore")
Signed-off-by: Ingo Molnar &lt;mingo@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>tty/ldsem: Wake up readers after timed out down_write()</title>
<updated>2019-01-26T08:42:45Z</updated>
<author>
<name>Dmitry Safonov</name>
<email>dima@arista.com</email>
</author>
<published>2018-11-01T00:24:46Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=d93216e51e19c2a53bf76db0e9ac61fffc30b831'/>
<id>urn:sha1:d93216e51e19c2a53bf76db0e9ac61fffc30b831</id>
<content type='text'>
commit 231f8fd0cca078bd4396dd7e380db813ac5736e2 upstream.

ldsem_down_read() will sleep if there is pending writer in the queue.
If the writer times out, readers in the queue should be woken up,
otherwise they may miss a chance to acquire the semaphore until the last
active reader will do ldsem_up_read().

There was a couple of reports where there was one active reader and
other readers soft locked up:
  Showing all locks held in the system:
  2 locks held by khungtaskd/17:
   #0:  (rcu_read_lock){......}, at: watchdog+0x124/0x6d1
   #1:  (tasklist_lock){.+.+..}, at: debug_show_all_locks+0x72/0x2d3
  2 locks held by askfirst/123:
   #0:  (&amp;tty-&gt;ldisc_sem){.+.+.+}, at: ldsem_down_read+0x46/0x58
   #1:  (&amp;ldata-&gt;atomic_read_lock){+.+...}, at: n_tty_read+0x115/0xbe4

Prevent readers wait for active readers to release ldisc semaphore.

Link: lkml.kernel.org/r/20171121132855.ajdv4k6swzhvktl6@wfg-t540p.sh.intel.com
Link: lkml.kernel.org/r/20180907045041.GF1110@shao2-debian
Cc: Jiri Slaby &lt;jslaby@suse.com&gt;
Cc: Peter Zijlstra &lt;peterz@infradead.org&gt;
Cc: stable@vger.kernel.org
Reported-by: kernel test robot &lt;rong.a.chen@intel.com&gt;
Signed-off-by: Dmitry Safonov &lt;dima@arista.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>tty: tty_ldsem.c: move assignment out of if () block</title>
<updated>2015-05-10T17:04:18Z</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2015-04-30T09:22:18Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=f9ce5ccfd97a61ed318eb52cbb358f1aa826d82f'/>
<id>urn:sha1:f9ce5ccfd97a61ed318eb52cbb358f1aa826d82f</id>
<content type='text'>
We should not be doing assignments within an if () block
so fix up the code to not do this.

change was created using Coccinelle.

CC: Jiri Slaby &lt;jslaby@suse.cz&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>lockdep: Make held_lock-&gt;check and "int check" argument bool</title>
<updated>2014-02-09T20:18:54Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-01-20T18:20:06Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=fb9edbe98493fcd9df66de926ae9157cbe0e4dcd'/>
<id>urn:sha1:fb9edbe98493fcd9df66de926ae9157cbe0e4dcd</id>
<content type='text'>
The "int check" argument of lock_acquire() and held_lock-&gt;check are
misleading. This is actually a boolean: 2 means "true", everything
else is "false".

And there is no need to pass 1 or 0 to lock_acquire() depending on
CONFIG_PROVE_LOCKING, __lock_acquire() checks prove_locking at the
start and clears "check" if !CONFIG_PROVE_LOCKING.

Note: probably we can simply kill this member/arg. The only explicit
user of check =&gt; 0 is rcu_lock_acquire(), perhaps we can change it to
use lock_acquire(trylock =&gt;, read =&gt; 2). __lockdep_no_validate means
check =&gt; 0 implicitly, but we can change validate_chain() to check
hlock-&gt;instance-&gt;key instead. Not to mention it would be nice to get
rid of lockdep_set_novalidate_class().

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Cc: Dave Jones &lt;davej@redhat.com&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Paul McKenney &lt;paulmck@linux.vnet.ibm.com&gt;
Cc: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Cc: Alan Stern &lt;stern@rowland.harvard.edu&gt;
Cc: Sasha Levin &lt;sasha.levin@oracle.com&gt;
Signed-off-by: Peter Zijlstra &lt;peterz@infradead.org&gt;
Link: http://lkml.kernel.org/r/20140120182006.GA26495@redhat.com
Signed-off-by: Ingo Molnar &lt;mingo@kernel.org&gt;
</content>
</entry>
<entry>
<title>tty: Fix hang at ldsem_down_read()</title>
<updated>2013-12-17T00:55:43Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-12-12T02:11:58Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=cf872776fc84128bb779ce2b83a37c884c3203ae'/>
<id>urn:sha1:cf872776fc84128bb779ce2b83a37c884c3203ae</id>
<content type='text'>
When a controlling tty is being hung up and the hang up is
waiting for a just-signalled tty reader or writer to exit, and a new tty
reader/writer tries to acquire an ldisc reference concurrently with the
ldisc reference release from the signalled reader/writer, the hangup
can hang. The new reader/writer is sleeping in ldsem_down_read() and the
hangup is sleeping in ldsem_down_write() [1].

The new reader/writer fails to wakeup the waiting hangup because the
wrong lock count value is checked (the old lock count rather than the new
lock count) to see if the lock is unowned.

Change helper function to return the new lock count if the cmpxchg was
successful; document this behavior.

[1] edited dmesg log from reporter

SysRq : Show Blocked State
  task                        PC stack   pid father
systemd         D ffff88040c4f0000     0     1      0 0x00000000
 ffff88040c49fbe0 0000000000000046 ffff88040c4a0000 ffff88040c49ffd8
 00000000001d3980 00000000001d3980 ffff88040c4a0000 ffff88040593d840
 ffff88040c49fb40 ffffffff810a4cc0 0000000000000006 0000000000000023
Call Trace:
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff817a6649&gt;] schedule+0x24/0x5e
 [&lt;ffffffff817a588b&gt;] schedule_timeout+0x15b/0x1ec
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff817aa691&gt;] ? _raw_spin_unlock_irq+0x24/0x26
 [&lt;ffffffff817aa10c&gt;] down_read_failed+0xe3/0x1b9
 [&lt;ffffffff817aa26d&gt;] ldsem_down_read+0x8b/0xa5
 [&lt;ffffffff8142b5ca&gt;] ? tty_ldisc_ref_wait+0x1b/0x44
 [&lt;ffffffff8142b5ca&gt;] tty_ldisc_ref_wait+0x1b/0x44
 [&lt;ffffffff81423f5b&gt;] tty_write+0x7d/0x28a
 [&lt;ffffffff814241f5&gt;] redirected_tty_write+0x8d/0x98
 [&lt;ffffffff81424168&gt;] ? tty_write+0x28a/0x28a
 [&lt;ffffffff8115d03f&gt;] do_loop_readv_writev+0x56/0x79
 [&lt;ffffffff8115e604&gt;] do_readv_writev+0x1b0/0x1ff
 [&lt;ffffffff8116ea0b&gt;] ? do_vfs_ioctl+0x32a/0x489
 [&lt;ffffffff81167d9d&gt;] ? final_putname+0x1d/0x3a
 [&lt;ffffffff8115e6c7&gt;] vfs_writev+0x2e/0x49
 [&lt;ffffffff8115e7d3&gt;] SyS_writev+0x47/0xaa
 [&lt;ffffffff817ab822&gt;] system_call_fastpath+0x16/0x1b
bash            D ffffffff81c104c0     0  5469   5302 0x00000082
 ffff8800cf817ac0 0000000000000046 ffff8804086b22a0 ffff8800cf817fd8
 00000000001d3980 00000000001d3980 ffff8804086b22a0 ffff8800cf817a48
 000000000000b9a0 ffff8800cf817a78 ffffffff81004675 ffff8800cf817a44
Call Trace:
 [&lt;ffffffff81004675&gt;] ? dump_trace+0x165/0x29c
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff8100edda&gt;] ? save_stack_trace+0x26/0x41
 [&lt;ffffffff817a6649&gt;] schedule+0x24/0x5e
 [&lt;ffffffff817a588b&gt;] schedule_timeout+0x15b/0x1ec
 [&lt;ffffffff810a4cc0&gt;] ? sched_clock_cpu+0x9f/0xe4
 [&lt;ffffffff817a9f03&gt;] ? down_write_failed+0xa3/0x1c9
 [&lt;ffffffff817aa691&gt;] ? _raw_spin_unlock_irq+0x24/0x26
 [&lt;ffffffff817a9f0b&gt;] down_write_failed+0xab/0x1c9
 [&lt;ffffffff817aa300&gt;] ldsem_down_write+0x79/0xb1
 [&lt;ffffffff817aada3&gt;] ? tty_ldisc_lock_pair_timeout+0xa5/0xd9
 [&lt;ffffffff817aada3&gt;] tty_ldisc_lock_pair_timeout+0xa5/0xd9
 [&lt;ffffffff8142bf33&gt;] tty_ldisc_hangup+0xc4/0x218
 [&lt;ffffffff81423ab3&gt;] __tty_hangup+0x2e2/0x3ed
 [&lt;ffffffff81424a76&gt;] disassociate_ctty+0x63/0x226
 [&lt;ffffffff81078aa7&gt;] do_exit+0x79f/0xa11
 [&lt;ffffffff81086bdb&gt;] ? get_signal_to_deliver+0x206/0x62f
 [&lt;ffffffff810b4bfb&gt;] ? lock_release_holdtime.part.8+0xf/0x16e
 [&lt;ffffffff81079b05&gt;] do_group_exit+0x47/0xb5
 [&lt;ffffffff81086c16&gt;] get_signal_to_deliver+0x241/0x62f
 [&lt;ffffffff810020a7&gt;] do_signal+0x43/0x59d
 [&lt;ffffffff810f2af7&gt;] ? __audit_syscall_exit+0x21a/0x2a8
 [&lt;ffffffff810b4bfb&gt;] ? lock_release_holdtime.part.8+0xf/0x16e
 [&lt;ffffffff81002655&gt;] do_notify_resume+0x54/0x6c
 [&lt;ffffffff817abaf8&gt;] int_signal+0x12/0x17

Reported-by: Sami Farin &lt;sami.farin@gmail.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # 3.12.x
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Add timed, writer-prioritized rw semaphore</title>
<updated>2013-05-20T19:30:32Z</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2013-04-16T10:15:50Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=4898e640caf03fdbaf2122d5a33949bf3e4a5b34'/>
<id>urn:sha1:4898e640caf03fdbaf2122d5a33949bf3e4a5b34</id>
<content type='text'>
The semantics of a rw semaphore are almost ideally suited
for tty line discipline lifetime management;  multiple active
threads obtain "references" (read locks) while performing i/o
to prevent the loss or change of the current line discipline
(write lock).

Unfortunately, the existing rw_semaphore is ill-suited in other
ways;
1) TIOCSETD ioctl (change line discipline) expects to return an
   error if the line discipline cannot be exclusively locked within
   5 secs. Lock wait timeouts are not supported by rwsem.
2) A tty hangup is expected to halt and scrap pending i/o, so
   exclusive locking must be prioritized.
   Writer priority is not supported by rwsem.

Add ld_semaphore which implements these requirements in a
semantically similar way to rw_semaphore.

Writer priority is handled by separate wait lists for readers and
writers. Pending write waits are priortized before existing read
waits and prevent further read locks.

Wait timeouts are trivially added, but obviously change the lock
semantics as lock attempts can fail (but only due to timeout).

This implementation incorporates the write-lock stealing work of
Michel Lespinasse &lt;walken@google.com&gt;.

Cc: Michel Lespinasse &lt;walken@google.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
