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 <mazhenhua@xiaomi.com> Change-Id: Ife64c179335d74768a3d68e402c72d10148f3e7e
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user