I use model checker find a issue of robust and pi futex. On below situation, the owner can't find something in pi_state_list, while the requester will be blocked, never be awaked.
CPU0 CPU1 futex_lock_pi /*some cs code*/ futex_lock_pi futex_lock_pi_atomic ... newval = uval | FUTEX_WAITERS; ret = lock_pi_update_atomic(uaddr, uval, newval); ... attach_to_pi_owner .... p = find_get_task_by_vpid(pid); if (!p) return handle_exit_race(uaddr, uval, NULL); .... raw_spin_lock_irq(&p->pi_lock); .... pi_state = alloc_pi_state(); .... do_exit->mm_release if (unlikely(tsk->robust_list)) { exit_robust_list(tsk); tsk->robust_list = NULL; } if (unlikely(!list_empty(&tsk->pi_state_list))) exit_pi_state_list(tsk); /*WILL MISS*/ list_add(&pi_state->list, &p->pi_state_list); WILL BLOCKED, NEVER WAKEUP! Signed-off-by: Yunfeng Cui <cui.yunf...@zte.com.cn> Reviewed-by: Bo Wang <wang.bo...@zte.com.cn> Reviewed-by: Yi Wang <wang.y...@zte.com.cn> --- kernel/fork.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 53e780748fe3..58b90f21dac4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1277,15 +1277,16 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) if (unlikely(tsk->robust_list)) { exit_robust_list(tsk); tsk->robust_list = NULL; + /*Check pi_state_list of task on pi_lock be acquired*/ + exit_pi_state_list(tsk); } #ifdef CONFIG_COMPAT if (unlikely(tsk->compat_robust_list)) { compat_exit_robust_list(tsk); tsk->compat_robust_list = NULL; + exit_pi_state_list(tsk); } #endif - if (unlikely(!list_empty(&tsk->pi_state_list))) - exit_pi_state_list(tsk); #endif uprobe_free_utask(tsk); -- 2.15.2