From fbbe339f72ed97e63907ea52a8bd41e0c2f8db63 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 1 May 2023 08:27:18 +0100 Subject: [PATCH] sched: schedule() no longer switches threads when preempt_count > 0 --- sched/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sched/core.c b/sched/core.c index 63d21ad..73011f5 100644 --- a/sched/core.c +++ b/sched/core.c @@ -70,6 +70,8 @@ void context_switch(struct thread *old, struct thread *new) void __schedule(enum sched_mode mode) { + ml_int_disable(); + struct cpu_data *this_cpu = get_this_cpu(); struct runqueue *rq = &this_cpu->c_rq; @@ -78,6 +80,10 @@ void __schedule(enum sched_mode mode) unsigned long flags; rq_lock(rq, &flags); + /* subtrace one to compensate for the fact that get_this_cpu() + increases preempt_count */ + int preempt = READ_ONCE(this_cpu->c_preempt_count) - 1; + put_cpu(this_cpu); struct thread *prev = rq->rq_cur; @@ -86,6 +92,11 @@ void __schedule(enum sched_mode mode) prev->tr_quantum_cycles = 0; } + if (preempt > 0) { + rq_unlock(rq, flags); + return; + } + enum thread_state prev_state = READ_ONCE(prev->tr_state); if ((mode == SCHED_IRQ || prev_state == THREAD_READY) && prev != rq->rq_idle) { @@ -108,6 +119,8 @@ void __schedule(enum sched_mode mode) if (prev != next) { context_switch(prev, next); } + + ml_int_enable(); } void schedule(enum sched_mode mode)