Re: [PATCH 1/2] sched_ext: Add lazy preemption support
From: Tejun Heo
Date: Sun Sep 13 2026 - 12:50:38 EST
Hello, Andrea.
This mostly looks fine to me, but the kick path changes could be simpler.
On Fri, Sep 11, 2026 at 09:56:53PM +0200, Andrea Righi wrote:
> + if ((sch->ops.flags & SCX_OPS_LAZY_SLICE_EXPIRY) &&
> + !scx_bypassing(sch, cpu_of(rq)))
> + resched_curr_lazy(rq);
Could lazy slice expiry be a per-task flag, with the ops flag providing the
default? That would let a scheduler choose immediate or lazy expiry for
individual tasks. BPF should be able to override the default in either
direction, with bypass still forcing immediate rescheduling.
There's also a NO_HZ_FULL corner case. If a remote target is running with
SCX_SLICE_INF and its tick stopped, resched_curr_lazy() sends no IPI, and
clearing the slice doesn't restart the tick. sched_tick_remote() calls
task_tick_scx() directly, bypassing the lazy-to-immediate promotion in
sched_tick(). With lazy expiry enabled, it keeps requesting lazy
rescheduling. That leaves delivery dependent on another interrupt, such as
the deadline server timer. Both the kick and enqueue paths need to arrange
progress for a tick-stopped target.
> + if (preempt)
> + cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt);
> + if (preempt_lazy)
> + cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt_lazy);
Why not clear both masks where cpus_to_preempt was previously cleared,
including the skipped-kick path? There's no need for the additional
conditions here.
> + if (unlikely((flags & SCX_KICK_PREEMPT) && (flags & SCX_KICK_PREEMPT_LAZY))) {
> + scx_error(sch, "SCX_KICK_PREEMPT and SCX_KICK_PREEMPT_LAZY cannot be combined");
> + return;
> + }
> + if (unlikely((flags & SCX_KICK_PREEMPT_LAZY) && (flags & SCX_KICK_WAIT))) {
> + scx_error(sch, "SCX_KICK_PREEMPT_LAZY cannot be used with SCX_KICK_WAIT");
> + return;
> + }
Do we need to reject all these combinations? PREEMPT should win over
PREEMPT_LAZY, as it does when separate calls request both. WAIT can force
immediate rescheduling. A plain kick combined with lazy preemption should
still clear the slice and reschedule immediately.
> + if (!cpumask_test_cpu(cpu, pcpu->cpus_to_preempt))
> + cpumask_set_cpu(cpu, pcpu->cpus_to_preempt_lazy);
[ ... ]
> + cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt_lazy);
Can we just accumulate the requested bits and resolve precedence in
kick_one_cpu()? That would remove both the guard against cpus_to_preempt and
the clearing of cpus_to_preempt_lazy.
Thanks.
--
tejun