From 7a7b5f89d96f514a0754957debeca3c6936bc580 Mon Sep 17 00:00:00 2001 From: mazhenhua Date: Wed, 10 Nov 2021 11:16:06 +0800 Subject: [PATCH] ANDROID: locking/rwsem: only clean RWSEM_FLAG_HANDOFF when already set sem->count will be negative after writer is killed if flag RWSEM_FLAG_HANDOFF is not set, we shouldn't clean again CPU2 CPU4 task A[reader] task B[writer] down_read_killable[locked] sem->count=0x100 down_write_killable sem->count=0x102[wlist not empty] up_read count=0x2 sig kill received down_read_killable sem->count=0x102[wlist not empty] goto branch out_nolock: list_del(&waiter.list); wait list is empty sem->count-RWSEM_FLAG_HANDOFF sem->count=0xFE list_empty(&sem->wait_list) is TRUE sem->count andnot RWSEM_FLAG_WAITERS sem->count=0xFC up_read sem->count-=0x100 sem->count=0xFFFFFFFFFFFFFFFC DEBUG_RWSEMS_WARN_ON(tmp < 0, sem); Bug: 204595609 Link: https://lore.kernel.org/all/a630a9aa-8c66-31c9-21a0-3d30bde2c9df@redhat.com/T/ Signed-off-by: mazhenhua Change-Id: Ife64c179335d74768a3d68e402c72d10148f3e7e --- kernel/locking/rwsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index e0505b9b8a31..7b0d64f0d550 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -1287,7 +1287,7 @@ out_nolock: list_del(&waiter.list); if (unlikely(wstate == WRITER_HANDOFF)) - atomic_long_add(-RWSEM_FLAG_HANDOFF, &sem->count); + atomic_long_andnot(RWSEM_FLAG_HANDOFF, &sem->count); if (list_empty(&sem->wait_list)) atomic_long_andnot(RWSEM_FLAG_WAITERS, &sem->count);