]> git.baikalelectronics.ru Git - kernel.git/commit
locking/rwsem-spinlock: Fix EINTR branch in __down_write_common()
authorKirill Tkhai <ktkhai@virtuozzo.com>
Fri, 16 Jun 2017 13:44:34 +0000 (16:44 +0300)
committerIngo Molnar <mingo@kernel.org>
Wed, 5 Jul 2017 10:26:29 +0000 (12:26 +0200)
commitcf6ad018295fca4e921cfc36892335a0b45c2387
treee9a18f3565fa002ddc6b23a86a10f92eb8d86d81
parent2d2a932190d48e00846679caccf785a5bac64dce
locking/rwsem-spinlock: Fix EINTR branch in __down_write_common()

If a writer could been woken up, the above branch

if (sem->count == 0)
break;

would have moved us to taking the sem. So, it's
not the time to wake a writer now, and only readers
are allowed now. Thus, 0 must be passed to __rwsem_do_wake().

Next, __rwsem_do_wake() wakes readers unconditionally.
But we mustn't do that if the sem is owned by writer
in the moment. Otherwise, writer and reader own the sem
the same time, which leads to memory corruption in
callers.

rwsem-xadd.c does not need that, as:

  1) the similar check is made lockless there,
  2) in __rwsem_mark_wake::try_reader_grant we test,

that sem is not owned by writer.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: <stable@vger.kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Niklas Cassel <niklas.cassel@axis.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 7e6f401a5a3f "locking/rwsem: Fix down_write_killable() for CONFIG_RWSEM_GENERIC_SPINLOCK=y"
Link: http://lkml.kernel.org/r/149762063282.19811.9129615532201147826.stgit@localhost.localdomain
Signed-off-by: Ingo Molnar <mingo@kernel.org>
kernel/locking/rwsem-spinlock.c