When checking if a task can preempt, see if it can preempt on its current CPU first and stop there if it can instead of looking for the latest deadline CPU to improve slightly CPU cache effects. If we've decided a task is to preempt on another CPU in try_preempt, set the task's CPU to the new CPU in anticipation to prevent the preemption failing when the future CPU is checking the task in earliest_deadline_task. This should prevent rescheduling that fails to switch to the preempting task in non-interactive mode though it means waking tasks are treated differently to descheduled running tasks. -ck --- kernel/sched/bfs.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) Index: linux-4.6.2-ck2/kernel/sched/bfs.c =================================================================== --- linux-4.6.2-ck2.orig/kernel/sched/bfs.c +++ linux-4.6.2-ck2/kernel/sched/bfs.c @@ -1379,8 +1379,19 @@ static void try_preempt(struct task_stru else return; + /* See if this task can preempt the task on the current CPU first. */ + cpu = cpu_of(this_rq); + if (cpumask_test_cpu(cpu, &tmp)) { + if (smt_should_schedule(p, cpu) && can_preempt(p, this_rq->rq_prio, this_rq->rq_deadline)) { + resched_curr(this_rq); + return; + } + cpumask_clear_cpu(cpu, &tmp); + } + highest_prio = latest_deadline = 0; + /* Now look for the CPU with the latest deadline */ for_each_cpu(cpu, &tmp) { struct rq *rq; int rq_prio; @@ -1404,8 +1415,17 @@ static void try_preempt(struct task_stru if (!smt_should_schedule(p, cpu)) return; #endif - if (can_preempt(p, highest_prio, highest_prio_rq->rq_deadline)) + if (can_preempt(p, highest_prio, latest_deadline)) { + /* + * If we have decided this task should preempt this CPU, + * set the task's CPU to match so there is no discrepancy + * in earliest_deadline_task which biases away tasks with + * a different CPU set. This means waking tasks are + * treated differently to rescheduling tasks. + */ + set_task_cpu(p, cpu); resched_curr(highest_prio_rq); + } } } static int __set_cpus_allowed_ptr(struct task_struct *p,