Re: [RFC PATCH 05/11] sched: Split scheduler execution context
From: Joel Fernandes
Date: Fri Oct 14 2022 - 13:01:52 EST
Hi,
Just on the yield bits (my opinion):
On Mon, Oct 3, 2022 at 5:45 PM Connor O'Brien <connoro@xxxxxxxxxx> wrote:
>
> From: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
>
> Lets define the scheduling context as all the scheduler state in
> task_struct and the execution context as all state required to run the
> task.
>
> Currently both are intertwined in task_struct. We want to logically
> split these such that we can run the execution context of one task
> with the scheduling context of another.
>
> To this purpose introduce rq::proxy to point to the task_struct used
> for scheduler state and preserve rq::curr to denote the execution
> context.
>
> XXX connoro: A couple cases here may need more discussion:
> - sched_yield() and yield_to(): whether we call the sched_class
> methods for rq->curr or rq->proxy, there seem to be cases where
> proxy exec could cause a yielding mutex owner to run again
> immediately. How much of a concern is this?
A task chosen to run again after calling yield is not unprecedented.
>From sched_yield manpage:
"If the calling thread is the only thread in the highest priority list
at that time, it will continue to run after a call to sched_yield()."
[...]
> @@ -8276,6 +8300,11 @@ static void do_sched_yield(void)
> rq = this_rq_lock_irq(&rf);
>
> schedstat_inc(rq->yld_count);
> + /*
> + * XXX how about proxy exec?
> + * If a task currently proxied by some other task yields, should we
> + * apply the proxy or the current yield "behaviour" ?
> + */
> current->sched_class->yield_task(rq);
I think we should keep it simple and keep the existing yield behavior.
If there was no priority inversion, and lock owner called yield, why
should it behave any differently?
>
> preempt_disable();
> @@ -8625,6 +8654,10 @@ EXPORT_SYMBOL(yield);
> */
> int __sched yield_to(struct task_struct *p, bool preempt)
> {
> + /*
> + * XXX what about current being proxied?
> + * Should we use proxy->sched_class methods in this case?
> + */
> struct task_struct *curr = current;
> struct rq *rq, *p_rq;
> unsigned long flags;
Ditto.
> @@ -8984,7 +9017,7 @@ void __init init_idle(struct task_struct *idle, int cpu)
[...]
Thanks,
- Joel