Commit 127b9031 authored by Fernand Sieber's avatar Fernand Sieber Committed by Peter Zijlstra
Browse files

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: default avatarkernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202510211205.1e0f5223-lkp@intel.com


Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
Signed-off-by: default avatarFernand Sieber <sieberf@amazon.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251106104022.195157-1-sieberf@amazon.com
parent 977b9a00
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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;

+1 −1
Original line number Diff line number Diff line
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -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);