[PATCH] sched: Proxy yields to donor tasks

Fernand Sieber posted 1 patch 1 month, 1 week ago
kernel/sched/deadline.c | 2 +-
kernel/sched/ext.c      | 4 ++--
kernel/sched/fair.c     | 2 +-
kernel/sched/rt.c       | 2 +-
kernel/sched/syscalls.c | 5 +++--
5 files changed, 8 insertions(+), 7 deletions(-)
[PATCH] sched: Proxy yields to donor tasks
Posted by Fernand Sieber 1 month, 1 week ago
When executing a task in proxy context, handle yields as if they were
requested by the donor task.

This avoids scenario like proxy task yielding, pick next task selecting the
same previous blocked donor, running the proxy task again, etc.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Fernand Sieber <sieberf@amazon.com>
---
 kernel/sched/deadline.c | 2 +-
 kernel/sched/ext.c      | 4 ++--
 kernel/sched/fair.c     | 2 +-
 kernel/sched/rt.c       | 2 +-
 kernel/sched/syscalls.c | 5 +++--
 5 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 7b7671060bf9..c4402542ef44 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2143,7 +2143,7 @@ static void yield_task_dl(struct rq *rq)
 	 * it and the bandwidth timer will wake it up and will give it
 	 * new scheduling parameters (thanks to dl_yielded=1).
 	 */
-	rq->curr->dl.dl_yielded = 1;
+	rq->donor->dl.dl_yielded = 1;
 
 	update_rq_clock(rq);
 	update_curr_dl(rq);
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index ecb251e883ea..7e0fcfdc06a2 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -1474,7 +1474,7 @@ static bool dequeue_task_scx(struct rq *rq, struct task_struct *p, int deq_flags
 static void yield_task_scx(struct rq *rq)
 {
 	struct scx_sched *sch = scx_root;
-	struct task_struct *p = rq->curr;
+	struct task_struct *p = rq->donor;
 
 	if (SCX_HAS_OP(sch, yield))
 		SCX_CALL_OP_2TASKS_RET(sch, SCX_KF_REST, yield, rq, p, NULL);
@@ -1485,7 +1485,7 @@ static void yield_task_scx(struct rq *rq)
 static bool yield_to_task_scx(struct rq *rq, struct task_struct *to)
 {
 	struct scx_sched *sch = scx_root;
-	struct task_struct *from = rq->curr;
+	struct task_struct *from = rq->donor;
 
 	if (SCX_HAS_OP(sch, yield))
 		return SCX_CALL_OP_2TASKS_RET(sch, SCX_KF_REST, yield, rq,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 25970dbbb279..aa58c73b0f79 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8993,7 +8993,7 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, struct t
  */
 static void yield_task_fair(struct rq *rq)
 {
-	struct task_struct *curr = rq->curr;
+	struct task_struct *curr = rq->donor;
 	struct cfs_rq *cfs_rq = task_cfs_rq(curr);
 	struct sched_entity *se = &curr->se;
 
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 7936d4333731..fb07dcfc60a2 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1490,7 +1490,7 @@ static void requeue_task_rt(struct rq *rq, struct task_struct *p, int head)
 
 static void yield_task_rt(struct rq *rq)
 {
-	requeue_task_rt(rq, rq->curr, 0);
+	requeue_task_rt(rq, rq->donor, 0);
 }
 
 static int find_lowest_rq(struct task_struct *task);
diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
index 77ae87f36e84..bf360a6fbb80 100644
--- a/kernel/sched/syscalls.c
+++ b/kernel/sched/syscalls.c
@@ -1351,7 +1351,7 @@ static void do_sched_yield(void)
 	rq = this_rq_lock_irq(&rf);
 
 	schedstat_inc(rq->yld_count);
-	current->sched_class->yield_task(rq);
+	rq->donor->sched_class->yield_task(rq);
 
 	preempt_disable();
 	rq_unlock_irq(rq, &rf);
@@ -1420,12 +1420,13 @@ EXPORT_SYMBOL(yield);
  */
 int __sched yield_to(struct task_struct *p, bool preempt)
 {
-	struct task_struct *curr = current;
+	struct task_struct *curr;
 	struct rq *rq, *p_rq;
 	int yielded = 0;
 
 	scoped_guard (raw_spinlock_irqsave, &p->pi_lock) {
 		rq = this_rq();
+		curr = rq->donor;
 
 again:
 		p_rq = task_rq(p);
-- 
2.43.0




Amazon Development Centre (South Africa) (Proprietary) Limited
29 Gogosoa Street, Observatory, Cape Town, Western Cape, 7925, South Africa
Registration Number: 2004 / 034463 / 07
Re: [PATCH] sched: Proxy yields to donor tasks
Posted by kernel test robot 1 month, 1 week ago
Hi Fernand,

kernel test robot noticed the following build warnings:

[auto build test WARNING on tip/sched/core]
[also build test WARNING on linus/master v6.18-rc4 next-20251107]
[cannot apply to peterz-queue/sched/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Fernand-Sieber/sched-Proxy-yields-to-donor-tasks/20251106-184337
base:   tip/sched/core
patch link:    https://lore.kernel.org/r/20251106104022.195157-1-sieberf%40amazon.com
patch subject: [PATCH] sched: Proxy yields to donor tasks
config: arm64-randconfig-r131-20251107 (https://download.01.org/0day-ci/archive/20251107/202511071431.9PLsHNo5-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 9.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251107/202511071431.9PLsHNo5-lkp@intel.com/reproduce)

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
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511071431.9PLsHNo5-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   kernel/sched/fair.c:1167:49: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *running @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/fair.c:1167:49: sparse:     expected struct task_struct *running
   kernel/sched/fair.c:1167:49: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/fair.c:1201:33: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct sched_entity *se @@     got struct sched_entity [noderef] __rcu * @@
   kernel/sched/fair.c:1201:33: sparse:     expected struct sched_entity *se
   kernel/sched/fair.c:1201:33: sparse:     got struct sched_entity [noderef] __rcu *
   kernel/sched/fair.c:1259:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sched_entity const *se @@     got struct sched_entity [noderef] __rcu * @@
   kernel/sched/fair.c:1259:34: sparse:     expected struct sched_entity const *se
   kernel/sched/fair.c:1259:34: sparse:     got struct sched_entity [noderef] __rcu *
   kernel/sched/fair.c:12848:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:12848:9: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/fair.c:12848:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c:7012:58: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/fair.c:7012:58: sparse:     expected struct task_struct *p
   kernel/sched/fair.c:7012:58: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/fair.c:6072:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/fair.c:6072:22: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/fair.c:6072:22: sparse:    struct task_struct *
   kernel/sched/fair.c:8397:20: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:8397:20: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/fair.c:8397:20: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c:8601:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] tmp @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:8601:9: sparse:     expected struct sched_domain *[assigned] tmp
   kernel/sched/fair.c:8601:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c:8734:39: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *donor @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/fair.c:8734:39: sparse:     expected struct task_struct *donor
   kernel/sched/fair.c:8734:39: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/fair.c:8766:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/fair.c:8766:37: sparse:     expected struct task_struct *tsk
   kernel/sched/fair.c:8766:37: sparse:     got struct task_struct [noderef] __rcu *curr
>> kernel/sched/fair.c:8983:38: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *curr @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/fair.c:8983:38: sparse:     expected struct task_struct *curr
   kernel/sched/fair.c:8983:38: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/fair.c:10020:40: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sched_domain *child @@     got struct sched_domain [noderef] __rcu *child @@
   kernel/sched/fair.c:10020:40: sparse:     expected struct sched_domain *child
   kernel/sched/fair.c:10020:40: sparse:     got struct sched_domain [noderef] __rcu *child
   kernel/sched/fair.c:10648:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/fair.c:10648:22: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/fair.c:10648:22: sparse:    struct task_struct *
   kernel/sched/fair.c:12093:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:12093:9: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/fair.c:12093:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c:11743:44: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct sched_domain *sd_parent @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:11743:44: sparse:     expected struct sched_domain *sd_parent
   kernel/sched/fair.c:11743:44: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c:12208:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/fair.c:12208:9: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/fair.c:12208:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/fair.c: note: in included file:
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2625:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2625:9: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2625:9: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
--
   kernel/sched/rt.c:976:39: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/rt.c:1493:31: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/rt.c:1493:31: sparse:     expected struct task_struct *p
   kernel/sched/rt.c:1493:31: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/rt.c:1809:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/rt.c:1809:9: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/rt.c:1809:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/rt.c:1512:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *curr @@     got struct task_struct [noderef] __rcu * @@
   kernel/sched/rt.c:1512:14: sparse:     expected struct task_struct *curr
   kernel/sched/rt.c:1512:14: sparse:     got struct task_struct [noderef] __rcu *
   kernel/sched/rt.c:1513:15: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *donor @@     got struct task_struct [noderef] __rcu * @@
   kernel/sched/rt.c:1513:15: sparse:     expected struct task_struct *donor
   kernel/sched/rt.c:1513:15: sparse:     got struct task_struct [noderef] __rcu *
   kernel/sched/rt.c:1574:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/rt.c:1574:45: sparse:     expected struct task_struct *p
   kernel/sched/rt.c:1574:45: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/rt.c:1616:39: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *donor @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/rt.c:1616:39: sparse:     expected struct task_struct *donor
   kernel/sched/rt.c:1616:39: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/rt.c:1635:64: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/rt.c:1635:64: sparse:     expected struct task_struct *tsk
   kernel/sched/rt.c:1635:64: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/rt.c:1976:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *task @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/rt.c:1976:40: sparse:     expected struct task_struct *task
   kernel/sched/rt.c:1976:40: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/rt.c:1999:13: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/rt.c:1999:13: sparse:    struct task_struct *
   kernel/sched/rt.c:1999:13: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/rt.c:2345:54: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/rt.c:2345:54: sparse:     expected struct task_struct *tsk
   kernel/sched/rt.c:2345:54: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/rt.c:2347:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/rt.c:2347:40: sparse:     expected struct task_struct *p
   kernel/sched/rt.c:2347:40: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/rt.c:2347:62: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/rt.c:2347:62: sparse:     expected struct task_struct *p
   kernel/sched/rt.c:2347:62: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/build_policy.c: note: in included file:
   kernel/sched/deadline.c:2677:23: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/deadline.c:2677:23: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:2677:23: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/deadline.c:2687:13: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/deadline.c:2687:13: sparse:    struct task_struct *
   kernel/sched/deadline.c:2687:13: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/deadline.c:2793:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/deadline.c:2793:25: sparse:    struct task_struct *
   kernel/sched/deadline.c:2793:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/deadline.c:2295:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct sched_dl_entity const *b @@     got struct sched_dl_entity [noderef] __rcu * @@
   kernel/sched/deadline.c:2295:42: sparse:     expected struct sched_dl_entity const *b
   kernel/sched/deadline.c:2295:42: sparse:     got struct sched_dl_entity [noderef] __rcu *
   kernel/sched/deadline.c:2305:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/deadline.c:2305:38: sparse:     expected struct task_struct *tsk
   kernel/sched/deadline.c:2305:38: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/deadline.c:1194:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/deadline.c:1194:39: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:1194:39: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/deadline.c:1194:85: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct sched_dl_entity const *b @@     got struct sched_dl_entity [noderef] __rcu * @@
   kernel/sched/deadline.c:1194:85: sparse:     expected struct sched_dl_entity const *b
   kernel/sched/deadline.c:1194:85: sparse:     got struct sched_dl_entity [noderef] __rcu *
   kernel/sched/deadline.c:1292:23: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/deadline.c:1292:23: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:1292:23: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/deadline.c:1590:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/deadline.c:1590:31: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:1590:31: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/deadline.c:1590:70: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct sched_dl_entity const *b @@     got struct sched_dl_entity [noderef] __rcu * @@
   kernel/sched/deadline.c:1590:70: sparse:     expected struct sched_dl_entity const *b
   kernel/sched/deadline.c:1590:70: sparse:     got struct sched_dl_entity [noderef] __rcu *
   kernel/sched/deadline.c:1703:39: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected struct task_struct *donor @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/deadline.c:1703:39: sparse:     expected struct task_struct *donor
   kernel/sched/deadline.c:1703:39: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/deadline.c:2513:9: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct sched_domain *[assigned] sd @@     got struct sched_domain [noderef] __rcu *parent @@
   kernel/sched/deadline.c:2513:9: sparse:     expected struct sched_domain *[assigned] sd
   kernel/sched/deadline.c:2513:9: sparse:     got struct sched_domain [noderef] __rcu *parent
   kernel/sched/deadline.c:2181:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *curr @@     got struct task_struct [noderef] __rcu * @@
   kernel/sched/deadline.c:2181:14: sparse:     expected struct task_struct *curr
   kernel/sched/deadline.c:2181:14: sparse:     got struct task_struct [noderef] __rcu *
   kernel/sched/deadline.c:2182:15: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *donor @@     got struct task_struct [noderef] __rcu * @@
   kernel/sched/deadline.c:2182:15: sparse:     expected struct task_struct *donor
   kernel/sched/deadline.c:2182:15: sparse:     got struct task_struct [noderef] __rcu *
   kernel/sched/deadline.c:2257:43: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/deadline.c:2257:43: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:2257:43: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/deadline.c:2838:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *tsk @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/deadline.c:2838:38: sparse:     expected struct task_struct *tsk
   kernel/sched/deadline.c:2838:38: sparse:     got struct task_struct [noderef] __rcu *curr
   kernel/sched/deadline.c:2840:23: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/deadline.c:2840:23: sparse:     expected struct task_struct *p
   kernel/sched/deadline.c:2840:23: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/deadline.c:2842:44: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct sched_dl_entity const *b @@     got struct sched_dl_entity [noderef] __rcu * @@
   kernel/sched/deadline.c:2842:44: sparse:     expected struct sched_dl_entity const *b
   kernel/sched/deadline.c:2842:44: sparse:     got struct sched_dl_entity [noderef] __rcu *
   kernel/sched/deadline.c:3036:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/deadline.c:3036:23: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/deadline.c:3036:23: sparse:    struct task_struct *
   kernel/sched/deadline.c:3083:32: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p @@     got struct task_struct [noderef] __rcu *curr @@
   kernel/sched/build_policy.c: note: in included file:
   kernel/sched/syscalls.c:185:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/syscalls.c:185:22: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/syscalls.c:185:22: sparse:    struct task_struct *
>> kernel/sched/syscalls.c:1397:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *curr @@     got struct task_struct [noderef] __rcu *donor @@
   kernel/sched/syscalls.c:1397:22: sparse:     expected struct task_struct *curr
   kernel/sched/syscalls.c:1397:22: sparse:     got struct task_struct [noderef] __rcu *donor
   kernel/sched/build_policy.c: note: in included file:
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2281:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2281:25: sparse:    struct task_struct *
   kernel/sched/sched.h:2292:26: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct [noderef] __rcu *
   kernel/sched/sched.h:2292:26: sparse:    struct task_struct *
   kernel/sched/build_policy.c: note: in included file:
   kernel/sched/syscalls.c:1257:6: sparse: sparse: context imbalance in 'sched_getaffinity' - wrong count at exit
   kernel/sched/syscalls.c:1322:11: sparse: sparse: dereference of noderef expression
   kernel/sched/build_policy.c: note: in included file:
   kernel/sched/rt.c:1659:15: sparse: sparse: dereference of noderef expression

vim +8983 kernel/sched/fair.c

  8977	
  8978	/*
  8979	 * sched_yield() is very simple
  8980	 */
  8981	static void yield_task_fair(struct rq *rq)
  8982	{
> 8983		struct task_struct *curr = rq->donor;
  8984		struct cfs_rq *cfs_rq = task_cfs_rq(curr);
  8985		struct sched_entity *se = &curr->se;
  8986	
  8987		/*
  8988		 * Are we the only task in the tree?
  8989		 */
  8990		if (unlikely(rq->nr_running == 1))
  8991			return;
  8992	
  8993		clear_buddies(cfs_rq, se);
  8994	
  8995		update_rq_clock(rq);
  8996		/*
  8997		 * Update run-time statistics of the 'current'.
  8998		 */
  8999		update_curr(cfs_rq);
  9000		/*
  9001		 * Tell update_rq_clock() that we've just updated,
  9002		 * so we don't do microscopic update in schedule()
  9003		 * and double the fastpath cost.
  9004		 */
  9005		rq_clock_skip_update(rq);
  9006	
  9007		/*
  9008		 * Forfeit the remaining vruntime, only if the entity is eligible. This
  9009		 * condition is necessary because in core scheduling we prefer to run
  9010		 * ineligible tasks rather than force idling. If this happens we may
  9011		 * end up in a loop where the core scheduler picks the yielding task,
  9012		 * which yields immediately again; without the condition the vruntime
  9013		 * ends up quickly running away.
  9014		 */
  9015		if (entity_eligible(cfs_rq, se)) {
  9016			se->vruntime = se->deadline;
  9017			se->deadline += calc_delta_fair(se->slice, se);
  9018			update_min_vruntime(cfs_rq);
  9019		}
  9020	}
  9021	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] sched: Proxy yields to donor tasks
Posted by Fernand Sieber 1 month, 1 week ago
On Thu, Nov 07, 2025 at 02:31:16PM +0800, kernel test robot wrote:
> sparse warnings: (new ones prefixed by >>)
>
>>> kernel/sched/rt.c:529:55: sparse: warning: incorrect type in initializer (different address spaces)
>>> kernel/sched/rt.c:976:39: sparse: warning: incorrect type in initializer (different address spaces)

Thank you for the report.

The warnings occur because my patch changes scheduler yield functions from
accessing rq->curr to rq->donor, both of which have identical __rcu annotations.
These are pre-existing annotation issues in the scheduler code, which has been
directly accessing RCU-annotated pointers without proper dereferencing, relying
on runqueue lock protection instead.

If we do want to address these sparse warnings, I can make modifications like:

-               curr = rq->donor;
+               curr = rcu_dereference_protected(rq->donor, lockdep_is_held(&rq->__lock));

This would have zero runtime overhead while satisfying sparse's RCU checking.

Peter, let me know if these warnings should be addressed.

Thanks,
Fernand



Amazon Development Centre (South Africa) (Proprietary) Limited
29 Gogosoa Street, Observatory, Cape Town, Western Cape, 7925, South Africa
Registration Number: 2004 / 034463 / 07
Re: [PATCH] sched: Proxy yields to donor tasks
Posted by Peter Zijlstra 1 month, 1 week ago
On Fri, Nov 07, 2025 at 10:12:53AM +0200, Fernand Sieber wrote:
> On Thu, Nov 07, 2025 at 02:31:16PM +0800, kernel test robot wrote:
> > sparse warnings: (new ones prefixed by >>)
> >
> >>> kernel/sched/rt.c:529:55: sparse: warning: incorrect type in initializer (different address spaces)
> >>> kernel/sched/rt.c:976:39: sparse: warning: incorrect type in initializer (different address spaces)
> 
> Thank you for the report.
> 
> The warnings occur because my patch changes scheduler yield functions from
> accessing rq->curr to rq->donor, both of which have identical __rcu annotations.
> These are pre-existing annotation issues in the scheduler code, which has been
> directly accessing RCU-annotated pointers without proper dereferencing, relying
> on runqueue lock protection instead.
> 
> If we do want to address these sparse warnings, I can make modifications like:
> 
> -               curr = rq->donor;
> +               curr = rcu_dereference_protected(rq->donor, lockdep_is_held(&rq->__lock));
> 
> This would have zero runtime overhead while satisfying sparse's RCU checking.
> 
> Peter, let me know if these warnings should be addressed.

Nah, I'm happy to ignore them to retain readable code :-)
Re: [PATCH] sched: Proxy yields to donor tasks
Posted by Peter Zijlstra 1 month, 1 week ago
On Thu, Nov 06, 2025 at 12:40:10PM +0200, Fernand Sieber wrote:
> When executing a task in proxy context, handle yields as if they were
> requested by the donor task.

I'll modify this to say it matches the traditional PI semantics.

> This avoids scenario like proxy task yielding, pick next task selecting the
> same previous blocked donor, running the proxy task again, etc.
> 
> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Fernand Sieber <sieberf@amazon.com>

Thanks, I'll add:

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202510211205.1e0f5223-lkp@intel.com

Also, for now proxy and ext are mutually exclusive, but yeah, might as
convert that one now too. At some point someone will have to go through
all that.
[tip: sched/core] sched/proxy: Yield the donor task
Posted by tip-bot2 for Fernand Sieber 1 month, 1 week ago
The following commit has been merged into the sched/core branch of tip:

Commit-ID:     127b90315ca07ccad2618db7ba950a63e3b32d22
Gitweb:        https://git.kernel.org/tip/127b90315ca07ccad2618db7ba950a63e3b32d22
Author:        Fernand Sieber <sieberf@amazon.com>
AuthorDate:    Thu, 06 Nov 2025 12:40:10 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 11 Nov 2025 12:33:36 +01:00

sched/proxy: Yield the donor task

When executing a task in proxy context, handle yields as if they were
requested by the donor task. This matches the traditional PI semantics
of yield() as well.

This avoids scenario like proxy task yielding, pick next task selecting the
same previous blocked donor, running the proxy task again, etc.

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202510211205.1e0f5223-lkp@intel.com
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Fernand Sieber <sieberf@amazon.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251106104022.195157-1-sieberf@amazon.com
---
 kernel/sched/deadline.c | 2 +-
 kernel/sched/ext.c      | 4 ++--
 kernel/sched/fair.c     | 2 +-
 kernel/sched/rt.c       | 2 +-
 kernel/sched/syscalls.c | 5 +++--
 5 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 6b8a928..13112c6 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2143,7 +2143,7 @@ static void yield_task_dl(struct rq *rq)
 	 * it and the bandwidth timer will wake it up and will give it
 	 * new scheduling parameters (thanks to dl_yielded=1).
 	 */
-	rq->curr->dl.dl_yielded = 1;
+	rq->donor->dl.dl_yielded = 1;
 
 	update_rq_clock(rq);
 	update_curr_dl(rq);
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index b063444..224b72c 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -1474,7 +1474,7 @@ static bool dequeue_task_scx(struct rq *rq, struct task_struct *p, int deq_flags
 static void yield_task_scx(struct rq *rq)
 {
 	struct scx_sched *sch = scx_root;
-	struct task_struct *p = rq->curr;
+	struct task_struct *p = rq->donor;
 
 	if (SCX_HAS_OP(sch, yield))
 		SCX_CALL_OP_2TASKS_RET(sch, SCX_KF_REST, yield, rq, p, NULL);
@@ -1485,7 +1485,7 @@ static void yield_task_scx(struct rq *rq)
 static bool yield_to_task_scx(struct rq *rq, struct task_struct *to)
 {
 	struct scx_sched *sch = scx_root;
-	struct task_struct *from = rq->curr;
+	struct task_struct *from = rq->donor;
 
 	if (SCX_HAS_OP(sch, yield))
 		return SCX_CALL_OP_2TASKS_RET(sch, SCX_KF_REST, yield, rq,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 273e287..f1d8eb3 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8980,7 +8980,7 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, struct t
  */
 static void yield_task_fair(struct rq *rq)
 {
-	struct task_struct *curr = rq->curr;
+	struct task_struct *curr = rq->donor;
 	struct cfs_rq *cfs_rq = task_cfs_rq(curr);
 	struct sched_entity *se = &curr->se;
 
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 1fd97f2..f1867fe 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1490,7 +1490,7 @@ static void requeue_task_rt(struct rq *rq, struct task_struct *p, int head)
 
 static void yield_task_rt(struct rq *rq)
 {
-	requeue_task_rt(rq, rq->curr, 0);
+	requeue_task_rt(rq, rq->donor, 0);
 }
 
 static int find_lowest_rq(struct task_struct *task);
diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
index 8f0f603..8078791 100644
--- a/kernel/sched/syscalls.c
+++ b/kernel/sched/syscalls.c
@@ -1319,7 +1319,7 @@ static void do_sched_yield(void)
 	rq = this_rq_lock_irq(&rf);
 
 	schedstat_inc(rq->yld_count);
-	current->sched_class->yield_task(rq);
+	rq->donor->sched_class->yield_task(rq);
 
 	preempt_disable();
 	rq_unlock_irq(rq, &rf);
@@ -1388,12 +1388,13 @@ EXPORT_SYMBOL(yield);
  */
 int __sched yield_to(struct task_struct *p, bool preempt)
 {
-	struct task_struct *curr = current;
+	struct task_struct *curr;
 	struct rq *rq, *p_rq;
 	int yielded = 0;
 
 	scoped_guard (raw_spinlock_irqsave, &p->pi_lock) {
 		rq = this_rq();
+		curr = rq->donor;
 
 again:
 		p_rq = task_rq(p);