sched: schedule() no longer switches threads when preempt_count > 0
This commit is contained in:
13
sched/core.c
13
sched/core.c
@@ -70,6 +70,8 @@ void context_switch(struct thread *old, struct thread *new)
|
|||||||
|
|
||||||
void __schedule(enum sched_mode mode)
|
void __schedule(enum sched_mode mode)
|
||||||
{
|
{
|
||||||
|
ml_int_disable();
|
||||||
|
|
||||||
struct cpu_data *this_cpu = get_this_cpu();
|
struct cpu_data *this_cpu = get_this_cpu();
|
||||||
struct runqueue *rq = &this_cpu->c_rq;
|
struct runqueue *rq = &this_cpu->c_rq;
|
||||||
|
|
||||||
@@ -78,6 +80,10 @@ void __schedule(enum sched_mode mode)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
rq_lock(rq, &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);
|
put_cpu(this_cpu);
|
||||||
|
|
||||||
struct thread *prev = rq->rq_cur;
|
struct thread *prev = rq->rq_cur;
|
||||||
@@ -86,6 +92,11 @@ void __schedule(enum sched_mode mode)
|
|||||||
prev->tr_quantum_cycles = 0;
|
prev->tr_quantum_cycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preempt > 0) {
|
||||||
|
rq_unlock(rq, flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
enum thread_state prev_state = READ_ONCE(prev->tr_state);
|
enum thread_state prev_state = READ_ONCE(prev->tr_state);
|
||||||
|
|
||||||
if ((mode == SCHED_IRQ || prev_state == THREAD_READY) && prev != rq->rq_idle) {
|
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) {
|
if (prev != next) {
|
||||||
context_switch(prev, next);
|
context_switch(prev, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ml_int_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedule(enum sched_mode mode)
|
void schedule(enum sched_mode mode)
|
||||||
|
|||||||
Reference in New Issue
Block a user