summaryrefslogtreecommitdiffstats
path: root/kernel/locking/rwsem.c
diff options
context:
space:
mode:
authorWaiman Long <longman@redhat.com>2020-01-15 10:43:36 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-23 08:22:37 +0100
commit710d9fd2f48bdd7e9944ea58d2205934951e7336 (patch)
treeb7dc252113c72096a452987a8e8ef7b782966053 /kernel/locking/rwsem.c
parent4e80eb337cb403bfef3f65b26020dd6a11bda1d8 (diff)
downloadlinux-stable-710d9fd2f48bdd7e9944ea58d2205934951e7336.tar.gz
linux-stable-710d9fd2f48bdd7e9944ea58d2205934951e7336.tar.bz2
linux-stable-710d9fd2f48bdd7e9944ea58d2205934951e7336.zip
locking/rwsem: Fix kernel crash when spinning on RWSEM_OWNER_UNKNOWN
commit 39e7234f00bc93613c086ae42d852d5f4147120a upstream. The commit 91d2a812dfb9 ("locking/rwsem: Make handoff writer optimistically spin on owner") will allow a recently woken up waiting writer to spin on the owner. Unfortunately, if the owner happens to be RWSEM_OWNER_UNKNOWN, the code will incorrectly spin on it leading to a kernel crash. This is fixed by passing the proper non-spinnable bits to rwsem_spin_on_owner() so that RWSEM_OWNER_UNKNOWN will be treated as a non-spinnable target. Fixes: 91d2a812dfb9 ("locking/rwsem: Make handoff writer optimistically spin on owner") Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Christoph Hellwig <hch@lst.de> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20200115154336.8679-1-longman@redhat.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/locking/rwsem.c')
-rw-r--r--kernel/locking/rwsem.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index eef04551eae7..baafa1dd9fcc 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -1226,8 +1226,8 @@ wait:
* In this case, we attempt to acquire the lock again
* without sleeping.
*/
- if ((wstate == WRITER_HANDOFF) &&
- (rwsem_spin_on_owner(sem, 0) == OWNER_NULL))
+ if (wstate == WRITER_HANDOFF &&
+ rwsem_spin_on_owner(sem, RWSEM_NONSPINNABLE) == OWNER_NULL)
goto trylock_again;
/* Block until there are no active lockers. */