scheduler fixes
Subsystems (2)
Linus,
Please pull the latest sched-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-urgent-for-linus
# HEAD: b7e7ade34e6188bee2e3b0d42b51d25137d9e2a5 sched/core: Fix remote wakeups
Two fixes: one for a lost wakeup, the other to fix the compiler optimizing out preempt operations on ARM64 (and possibly other non-x86 architectures).
Thanks,
Ingo
------------------>
Peter Zijlstra (2):
sched/preempt: Fix preempt_count manipulations sched/core: Fix remote wakeups
include/asm-generic/preempt.h | 4 ++-- include/linux/sched.h | 1 + kernel/sched/core.c | 18 +++++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-)
include/asm-generic/preempt.h +2 -2
@@ -7,10 +7,10 @@ static __always_inline int preempt_count(void) { -return current_thread_info ()->preempt_count; +return READ_ONCE (current_thread_info ()->preempt_count); } -static __always_inline int *preempt_count_ptr(void) +static __always_inline volatile int *preempt_count_ptr(void) {return ¤t_thread_info ()->preempt_count; }
include/linux/sched.h +1 -0
@@ -1533,6 +1533,7 @@ struct task_struct { unsigned sched_reset_on_fork:1; unsigned sched_contributes_to_load:1; unsigned sched_migrated:1; + unsigned sched_remote_wakeup:1; unsigned :0; /* force alignment to the next boundary *//* unserialized, strictly 'current' */
kernel/sched/core.c +11 -7
@@ -1768,13 +1768,15 @@ void sched_ttwu_pending(void) cookie =lockdep_pin_lock (&rq->lock);while (llist) { +int wake_flags =0 ; + p = llist_entry(llist, struct task_struct, wake_entry); llist =llist_next (llist); -/* -* See ttwu_queue(); we only call ttwu_queue_remote() when -* its a x-cpu wakeup. -*/ -ttwu_do_activate (rq, p,WF_MIGRATED , cookie); + +if (p->sched_remote_wakeup) + wake_flags =WF_MIGRATED ; + +ttwu_do_activate (rq, p, wake_flags, cookie); }lockdep_unpin_lock (&rq->lock, cookie);
@@ -1819,10 +1821,12 @@ void scheduler_ipi(void)irq_exit (); } -static void ttwu_queue_remote (struct task_struct *p,int cpu) +static void ttwu_queue_remote (struct task_struct *p,int cpu,int wake_flags) {struct rq *rq =cpu_rq (cpu); + p->sched_remote_wakeup = !!(wake_flags &WF_MIGRATED ); +if (llist_add (&p->wake_entry, &cpu_rq (cpu)->wake_list)) {if (!set_nr_if_polling (rq->idle))smp_send_reschedule (cpu);
@@ -1869,7 +1873,7 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)#if defined(CONFIG_SMP )if (sched_feat (TTWU_QUEUE ) && !cpus_share_cache (smp_processor_id (), cpu)) {sched_clock_cpu (cpu);/* sync clocks x-cpu */ -ttwu_queue_remote (p, cpu); +ttwu_queue_remote (p, cpu, wake_flags);return ; }#endif