kernel/sched/core.c:6702 find_proxy_task() warn: inconsistent returns '&mutex->wait_lock'.
kernel test robot <[email protected]>
| Newsgroups | dev.linux.lists.oe-kbuild |
|---|---|
| Message-ID | <[email protected]> |
BCC: [email protected] CC: [email protected] CC: [email protected] TO: John Stultz <[email protected]> CC: Peter Zijlstra <[email protected]> CC: K Prateek Nayak <[email protected]> tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: fce2dfa773ced15f27dd27cd0b482a7473cdcf2a commit: 56f4b24267a643b0b9ab73f09feaaabfee5a37ae sched: Fix modifying donor->blocked on without proper locking date: 4 months ago :::::: branch date: 15 hours ago :::::: commit date: 4 months ago config: s390-randconfig-r073-20260717 (https://download.01.org/0day-ci/archive/20260717/[email protected]/config) compiler: s390-linux-gcc (GCC) 8.5.0 smatch: v0.5.0-9185-gbcc58b9c If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Fixes: 56f4b24267a6 ("sched: Fix modifying donor->blocked on without proper locking") | Reported-by: kernel test robot <[email protected]> | Reported-by: Dan Carpenter <[email protected]> | Closes: https://lore.kernel.org/r/[email protected]/ smatch warnings: kernel/sched/core.c:6702 find_proxy_task() warn: inconsistent returns '&mutex->wait_lock'. kernel/sched/core.c:6702 find_proxy_task() warn: inconsistent returns '&p->blocked_lock'. vim +6702 kernel/sched/core.c be41bde4c3a86d John Stultz 2025-07-12 6575 be41bde4c3a86d John Stultz 2025-07-12 6576 /* 7de9d4f946383f Peter Zijlstra 2025-07-12 6577 * Find runnable lock owner to proxy for mutex blocked donor 7de9d4f946383f Peter Zijlstra 2025-07-12 6578 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6579 * Follow the blocked-on relation: 7de9d4f946383f Peter Zijlstra 2025-07-12 6580 * task->blocked_on -> mutex->owner -> task... 7de9d4f946383f Peter Zijlstra 2025-07-12 6581 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6582 * Lock order: 7de9d4f946383f Peter Zijlstra 2025-07-12 6583 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6584 * p->pi_lock 7de9d4f946383f Peter Zijlstra 2025-07-12 6585 * rq->lock 7de9d4f946383f Peter Zijlstra 2025-07-12 6586 * mutex->wait_lock fa4a1ff8ab235a John Stultz 2026-03-24 6587 * p->blocked_lock 7de9d4f946383f Peter Zijlstra 2025-07-12 6588 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6589 * Returns the task that is going to be used as execution context (the one 7de9d4f946383f Peter Zijlstra 2025-07-12 6590 * that is actually going to be run on cpu_of(rq)). be41bde4c3a86d John Stultz 2025-07-12 6591 */ be41bde4c3a86d John Stultz 2025-07-12 6592 static struct task_struct * be41bde4c3a86d John Stultz 2025-07-12 6593 find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) be41bde4c3a86d John Stultz 2025-07-12 6594 { 56f4b24267a643 John Stultz 2026-03-24 6595 enum { FOUND, DEACTIVATE_DONOR } action = FOUND; 7de9d4f946383f Peter Zijlstra 2025-07-12 6596 struct task_struct *owner = NULL; 7de9d4f946383f Peter Zijlstra 2025-07-12 6597 int this_cpu = cpu_of(rq); 7de9d4f946383f Peter Zijlstra 2025-07-12 6598 struct task_struct *p; be41bde4c3a86d John Stultz 2025-07-12 6599 struct mutex *mutex; be41bde4c3a86d John Stultz 2025-07-12 6600 7de9d4f946383f Peter Zijlstra 2025-07-12 6601 /* Follow blocked_on chain. */ 37341ec573da7c John Stultz 2026-03-24 6602 for (p = donor; (mutex = p->blocked_on); p = owner) { be41bde4c3a86d John Stultz 2025-07-12 6603 /* be41bde4c3a86d John Stultz 2025-07-12 6604 * By taking mutex->wait_lock we hold off concurrent mutex_unlock() be41bde4c3a86d John Stultz 2025-07-12 6605 * and ensure @owner sticks around. be41bde4c3a86d John Stultz 2025-07-12 6606 */ be41bde4c3a86d John Stultz 2025-07-12 6607 guard(raw_spinlock)(&mutex->wait_lock); fa4a1ff8ab235a John Stultz 2026-03-24 6608 guard(raw_spinlock)(&p->blocked_lock); be41bde4c3a86d John Stultz 2025-07-12 6609 fa4a1ff8ab235a John Stultz 2026-03-24 6610 /* Check again that p is blocked with blocked_lock held */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6611 if (mutex != __get_task_blocked_on(p)) { be41bde4c3a86d John Stultz 2025-07-12 6612 /* be41bde4c3a86d John Stultz 2025-07-12 6613 * Something changed in the blocked_on chain and be41bde4c3a86d John Stultz 2025-07-12 6614 * we don't know if only at this level. So, let's be41bde4c3a86d John Stultz 2025-07-12 6615 * just bail out completely and let __schedule() be41bde4c3a86d John Stultz 2025-07-12 6616 * figure things out (pick_again loop). be41bde4c3a86d John Stultz 2025-07-12 6617 */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6618 return NULL; 7de9d4f946383f Peter Zijlstra 2025-07-12 6619 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6620 7de9d4f946383f Peter Zijlstra 2025-07-12 6621 owner = __mutex_owner(mutex); 7de9d4f946383f Peter Zijlstra 2025-07-12 6622 if (!owner) { 7de9d4f946383f Peter Zijlstra 2025-07-12 6623 __clear_task_blocked_on(p, mutex); 7de9d4f946383f Peter Zijlstra 2025-07-12 6624 return p; 7de9d4f946383f Peter Zijlstra 2025-07-12 6625 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6626 7de9d4f946383f Peter Zijlstra 2025-07-12 6627 if (!READ_ONCE(owner->on_rq) || owner->se.sched_delayed) { 7de9d4f946383f Peter Zijlstra 2025-07-12 6628 /* XXX Don't handle blocked owners/delayed dequeue yet */ 56f4b24267a643 John Stultz 2026-03-24 6629 action = DEACTIVATE_DONOR; 56f4b24267a643 John Stultz 2026-03-24 6630 break; be41bde4c3a86d John Stultz 2025-07-12 6631 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6632 7de9d4f946383f Peter Zijlstra 2025-07-12 6633 if (task_cpu(owner) != this_cpu) { 7de9d4f946383f Peter Zijlstra 2025-07-12 6634 /* XXX Don't handle migrations yet */ 56f4b24267a643 John Stultz 2026-03-24 6635 action = DEACTIVATE_DONOR; 56f4b24267a643 John Stultz 2026-03-24 6636 break; be41bde4c3a86d John Stultz 2025-07-12 6637 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6638 7de9d4f946383f Peter Zijlstra 2025-07-12 6639 if (task_on_rq_migrating(owner)) { 7de9d4f946383f Peter Zijlstra 2025-07-12 6640 /* 7de9d4f946383f Peter Zijlstra 2025-07-12 6641 * One of the chain of mutex owners is currently migrating to this 7de9d4f946383f Peter Zijlstra 2025-07-12 6642 * CPU, but has not yet been enqueued because we are holding the 7de9d4f946383f Peter Zijlstra 2025-07-12 6643 * rq lock. As a simple solution, just schedule rq->idle to give 7de9d4f946383f Peter Zijlstra 2025-07-12 6644 * the migration a chance to complete. Much like the migrate_task 7de9d4f946383f Peter Zijlstra 2025-07-12 6645 * case we should end up back in find_proxy_task(), this time 7de9d4f946383f Peter Zijlstra 2025-07-12 6646 * hopefully with all relevant tasks already enqueued. 7de9d4f946383f Peter Zijlstra 2025-07-12 6647 */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6648 return proxy_resched_idle(rq); 7de9d4f946383f Peter Zijlstra 2025-07-12 6649 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6650 7de9d4f946383f Peter Zijlstra 2025-07-12 6651 /* 7de9d4f946383f Peter Zijlstra 2025-07-12 6652 * Its possible to race where after we check owner->on_rq 7de9d4f946383f Peter Zijlstra 2025-07-12 6653 * but before we check (owner_cpu != this_cpu) that the 7de9d4f946383f Peter Zijlstra 2025-07-12 6654 * task on another cpu was migrated back to this cpu. In 7de9d4f946383f Peter Zijlstra 2025-07-12 6655 * that case it could slip by our checks. So double check 7de9d4f946383f Peter Zijlstra 2025-07-12 6656 * we are still on this cpu and not migrating. If we get 7de9d4f946383f Peter Zijlstra 2025-07-12 6657 * inconsistent results, try again. 7de9d4f946383f Peter Zijlstra 2025-07-12 6658 */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6659 if (!task_on_rq_queued(owner) || task_cpu(owner) != this_cpu) 7de9d4f946383f Peter Zijlstra 2025-07-12 6660 return NULL; 7de9d4f946383f Peter Zijlstra 2025-07-12 6661 7de9d4f946383f Peter Zijlstra 2025-07-12 6662 if (owner == p) { 7de9d4f946383f Peter Zijlstra 2025-07-12 6663 /* 7de9d4f946383f Peter Zijlstra 2025-07-12 6664 * It's possible we interleave with mutex_unlock like: 7de9d4f946383f Peter Zijlstra 2025-07-12 6665 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6666 * lock(&rq->lock); 7de9d4f946383f Peter Zijlstra 2025-07-12 6667 * find_proxy_task() 7de9d4f946383f Peter Zijlstra 2025-07-12 6668 * mutex_unlock() 7de9d4f946383f Peter Zijlstra 2025-07-12 6669 * lock(&wait_lock); 7de9d4f946383f Peter Zijlstra 2025-07-12 6670 * donor(owner) = current->blocked_donor; 7de9d4f946383f Peter Zijlstra 2025-07-12 6671 * unlock(&wait_lock); 7de9d4f946383f Peter Zijlstra 2025-07-12 6672 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6673 * wake_up_q(); 7de9d4f946383f Peter Zijlstra 2025-07-12 6674 * ... 7de9d4f946383f Peter Zijlstra 2025-07-12 6675 * ttwu_runnable() 7de9d4f946383f Peter Zijlstra 2025-07-12 6676 * __task_rq_lock() 7de9d4f946383f Peter Zijlstra 2025-07-12 6677 * lock(&wait_lock); 7de9d4f946383f Peter Zijlstra 2025-07-12 6678 * owner == p 7de9d4f946383f Peter Zijlstra 2025-07-12 6679 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6680 * Which leaves us to finish the ttwu_runnable() and make it go. 7de9d4f946383f Peter Zijlstra 2025-07-12 6681 * 7de9d4f946383f Peter Zijlstra 2025-07-12 6682 * So schedule rq->idle so that ttwu_runnable() can get the rq 7de9d4f946383f Peter Zijlstra 2025-07-12 6683 * lock and mark owner as running. 7de9d4f946383f Peter Zijlstra 2025-07-12 6684 */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6685 return proxy_resched_idle(rq); 7de9d4f946383f Peter Zijlstra 2025-07-12 6686 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6687 /* 7de9d4f946383f Peter Zijlstra 2025-07-12 6688 * OK, now we're absolutely sure @owner is on this 7de9d4f946383f Peter Zijlstra 2025-07-12 6689 * rq, therefore holding @rq->lock is sufficient to 7de9d4f946383f Peter Zijlstra 2025-07-12 6690 * guarantee its existence, as per ttwu_remote(). 7de9d4f946383f Peter Zijlstra 2025-07-12 6691 */ 7de9d4f946383f Peter Zijlstra 2025-07-12 6692 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6693 56f4b24267a643 John Stultz 2026-03-24 6694 /* Handle actions we need to do outside of the guard() scope */ 56f4b24267a643 John Stultz 2026-03-24 6695 switch (action) { 56f4b24267a643 John Stultz 2026-03-24 6696 case DEACTIVATE_DONOR: 56f4b24267a643 John Stultz 2026-03-24 6697 return proxy_deactivate(rq, donor); 56f4b24267a643 John Stultz 2026-03-24 6698 case FOUND: 56f4b24267a643 John Stultz 2026-03-24 6699 /* fallthrough */; 56f4b24267a643 John Stultz 2026-03-24 6700 } 7de9d4f946383f Peter Zijlstra 2025-07-12 6701 WARN_ON_ONCE(owner && !owner->on_rq); 7de9d4f946383f Peter Zijlstra 2025-07-12 @6702 return owner; 7de9d4f946383f Peter Zijlstra 2025-07-12 6703 } be41bde4c3a86d John Stultz 2025-07-12 6704 #else /* SCHED_PROXY_EXEC */ be41bde4c3a86d John Stultz 2025-07-12 6705 static struct task_struct * be41bde4c3a86d John Stultz 2025-07-12 6706 find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) be41bde4c3a86d John Stultz 2025-07-12 6707 { be41bde4c3a86d John Stultz 2025-07-12 6708 WARN_ONCE(1, "This should never be called in the !SCHED_PROXY_EXEC case\n"); be41bde4c3a86d John Stultz 2025-07-12 6709 return donor; be41bde4c3a86d John Stultz 2025-07-12 6710 } be41bde4c3a86d John Stultz 2025-07-12 6711 #endif /* SCHED_PROXY_EXEC */ be41bde4c3a86d John Stultz 2025-07-12 6712 :::::: The code at line 6702 was first introduced by commit :::::: 7de9d4f946383f48ec393b6e9ad0c20e49e174e7 sched: Start blocked_on chain processing in find_proxy_task() :::::: TO: Peter Zijlstra <[email protected]> :::::: CC: Peter Zijlstra <[email protected]> -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki