scheduler changes for v4.3
Subsystems (19)
Linus,
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus
# HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()
The biggest change in this cycle is the rewrite of the main SMP load balancing
metric: the CPU load/utilization. The main goal was to make the metric more precise and more representative - see the changelog of this commit for the gory details:
9d89c257dfb9 ("sched/fair: Rewrite runnable load and utilization average tracking")
It is done in a way that significantly reduces complexity of the code:
5 files changed, 249 insertions(+), 494 deletions(-)
and the performance testing results are encouraging. Nevertheless we need to keep an eye on potential regressions, since this potentially affects every SMP workload in existence.
This work comes from Yuyang Du.
Other changes:
- SCHED_DL updates. (Andrea Parri)
- Simplify architecture callbacks by removing finish_arch_switch(). (Peter Zijlstra et al)
- cputime accounting: guarantee stime + utime == rtime. (Peter Zijlstra)
- optimize idle CPU wakeups some more - inspired by Facebook server loads. (Mike Galbraith)
- stop_machine fixes and updates. (Oleg Nesterov)
- Introduce the 'trace_sched_waking' tracepoint. (Peter Zijlstra)
- sched/numa tweaks. (Srikar Dronamraju)
- misc fixes and small cleanups
Thanks,
Ingo
------------------>
Andrea Parri (2):
sched/deadline: Fix comment in push_dl_tasks() sched/deadline: Fix comment in enqueue_task_dl()
Aravind Gopalakrishnan (1):
sched/numa: Fix NUMA_DIRECT topology identification
Boqun Feng (1):
sched/fair: Clean up the __sched_period() code
Byungchul Park (2):
sched/fair: Fix a comment reflecting function name change
sched: Ensure a task has a non-normalized vruntime when returning back to CFS
Chris Metcalf (2):
sched, tile: Remove finish_arch_switch
tile: Reorganize _switch_to()
Ingo Molnar (1):
sched, sparc32: Update scheduler comments in copy_thread()
Konstantin Khlebnikov (3):
sched/preempt, xen: Use need_resched() instead of should_resched() sched/preempt, powerpc, kvm: Use need_resched() instead of should_resched() sched/preempt: Fix cond_resched_lock() and cond_resched_softirq()
Lucas Stach (1):
sched/idle: Move latency tracing stop/start calls deeper inside the idle loop
Markus Elfring (1):
sched, sysctl: Delete an unnecessary check before unregister_sysctl_table()
Mike Galbraith (1):
sched/fair: Beef up wake_wide()
Oleg Nesterov (5):
stop_machine: Move 'cpu_stopper_task' and 'stop_cpus_work' into 'struct cpu_stopper'
stop_machine: Don't do for_each_cpu() twice in queue_stop_cpus_work()
stop_machine: Unexport __stop_machine()
stop_machine: Use 'cpu_stop_fn_t' where possible
stop_machine: Remove cpu_stop_work's from list in cpu_stop_park()
Peter Zijlstra (9):
sched/cputime: Guarantee stime + utime == rtime
sched: Introduce the 'trace_sched_waking' tracepoint sched, avr32: Remove finish_arch_switch()
sched, score: Remove finish_arch_switch()
sched, sh: Fold finish_arch_switch() into switch_to()
sched: Remove finish_arch_switch()
sched: Fix a race between __kthread_bind() and sched_setaffinity()
sched: Make sched_class::set_cpus_allowed() unconditional
sched: Change the sched_class::set_cpus_allowed() calling context
Ralf Baechle (1):
sched, MIPS: Get rid of finish_arch_switch()
Srikar Dronamraju (2):
sched/numa: Prefer NUMA hotness over cache hotness
sched/numa: Consider 'imbalance_pct' when comparing loads in numa_has_capacity()
Vincent Guittot (1):
sched/fair: Implement update_blocked_averages() for CONFIG_FAIR_GROUP_SCHED=n
Will Deacon (1):
sched, arm: Remove finish_arch_switch()
Xunlei Pang (2):
sched/rt: Remove a redundant condition from task_woken_rt() sched/deadline: Remove a redundant condition from task_woken_dl()
Yuyang Du (7):
sched/fair: Avoid pulling all tasks in idle balancing sched/fair: Remove rq's runnable avg
sched/fair: Rewrite runnable load and utilization average tracking sched/fair: Init cfs_rq's sched_entity load average sched/fair: Remove task and group entity load when they are dead sched/fair: Provide runnable_load_avg back to cfs_rq sched/fair: Clean up load average references
[email protected] (1):
sched/numa: Check sched_feat(NUMA) in migrate_improves_locality()
arch/arm/include/asm/switch_to.h | 5 +- arch/avr32/include/asm/switch_to.h | 7 +- arch/mips/include/asm/switch_to.h | 48 +- arch/powerpc/kvm/book3s_hv.c | 2 +- arch/score/include/asm/switch_to.h | 2 - arch/sh/include/asm/switch_to_32.h | 8 +- arch/sparc/kernel/process_32.c | 10 +- arch/tile/include/asm/switch_to.h | 8 +- arch/tile/kernel/process.c | 5 + arch/x86/include/asm/preempt.h | 4 +- drivers/cpuidle/cpuidle.c | 4 + drivers/xen/preempt.c | 2 +- include/asm-generic/preempt.h | 5 +- include/linux/init_task.h | 10 + include/linux/kthread.h | 1 + include/linux/preempt.h | 19 +- include/linux/sched.h | 98 ++-- include/linux/stop_machine.h | 28 +- include/trace/events/sched.h | 30 +- kernel/cpu.c | 2 +- kernel/fork.c | 7 +- kernel/kthread.c | 20 +- kernel/sched/core.c | 101 +++- kernel/sched/cputime.c | 101 ++-- kernel/sched/deadline.c | 40 +- kernel/sched/debug.c | 48 +- kernel/sched/fair.c | 937 +++++++++++++++---------------------- kernel/sched/features.h | 18 +- kernel/sched/idle.c | 14 +- kernel/sched/idle_task.c | 1 + kernel/sched/rt.c | 42 +- kernel/sched/sched.h | 39 +- kernel/sched/stop_task.c | 1 + kernel/stop_machine.c | 44 +- kernel/trace/trace_sched_switch.c | 2 +- kernel/trace/trace_sched_wakeup.c | 2 +- kernel/workqueue.c | 6 +- 37 files changed, 762 insertions(+), 959 deletions(-)
arch/arm/include/asm/switch_to.h +4 -1
@@ -10,7 +10,9 @@* CPU. */ #if defined(CONFIG_PREEMPT ) && defined(CONFIG_SMP ) && defined(CONFIG_CPU_V7 ) -#define finish_arch_switch (prev) dsb(ish) +#define __complete_pending_tlbi () dsb(ish) +#else +#define __complete_pending_tlbi ()#endif /*
@@ -22,6 +24,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info#define switch_to (prev,next,last) \ do { \ + __complete_pending_tlbi(); \ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ } while (0)
arch/avr32/include/asm/switch_to.h +5 -2
@@ -15,11 +15,13 @@*/ #ifdef CONFIG_OWNERSHIP_TRACE #include <asm/ocd.h> -#define finish_arch_switch (prev) \ +#define ocd_switch (prev, next) \ do { \ ocd_write(PID, prev->pid); \ - ocd_write(PID, current->pid); \ + ocd_write(PID, next->pid); \ } while(0) +#else +#define ocd_switch (prev, next)#endif /*
@@ -38,6 +40,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct cpu_context *);#define switch_to (prev, next, last) \ do { \ + ocd_switch(prev, next); \ last = __switch_to(prev, &prev->thread.cpu_context + 1, \ &next->thread.cpu_context); \ } while (0)
arch/mips/include/asm/switch_to.h +23 -25
68 lines not on this page · raw message
arch/powerpc/kvm/book3s_hv.c +1 -1
@@ -2178,7 +2178,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) vc->runner = vcpu;if (n_ceded == vc->n_runnable) {kvmppc_vcore_blocked (vc); - }else if (should_resched ()) { + }else if (need_resched ()) { vc->vcore_state =VCORE_PREEMPT ;/* Let something else run */ cond_resched_lock (&vc->lock);
arch/score/include/asm/switch_to.h +0 -2
@@ -8,6 +8,4 @@ do { \ (last) =resume (prev, next,task_thread_info (next)); \ } while (0) -#define finish_arch_switch (prev) do {} while (0) -#endif /* _ASM_SCORE_SWITCH_TO_H */
arch/sh/include/asm/switch_to_32.h +2 -6
@@ -78,6 +78,8 @@ do { \ \if (is_dsp_enabled (prev)) \__save_dsp (prev); \ +if (is_dsp_enabled (next)) \ +__restore_dsp (next); \ \ __ts1 = (u32 *)&prev->thread.sp; \ __ts2 = (u32 *)&prev->thread.pc; \
@@ -125,10 +127,4 @@ do { \ last = __last; \ } while (0) -#define finish_arch_switch (prev) \ -do { \ - if (is_dsp_enabled(prev)) \ - __restore_dsp(prev); \ -} while (0) -#endif /* __ASM_SH_SWITCH_TO_32_H */
arch/sparc/kernel/process_32.c +5 -5
@@ -333,11 +333,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, childregs = (struct pt_regs *) (new_stack +STACKFRAME_SZ );/* -* A new process must start with interrupts closed in 2.5, -* because this is how Mingo's scheduler works (see schedule_tail -* and finish_arch_switch). If we do not do it, a timer interrupt hits -* before we unlock, attempts to re-take the rq->lock, and then we die. -* Thus, kpsr|=PSR_PIL. +* A new process must start with interrupts disabled, see schedule_tail() +* and finish_task_switch(). (If we do not do it and if a timer interrupt +* hits before we unlock and attempts to take the rq->lock, we deadlock.) +* +* Thus, kpsr |= PSR_PIL. */ ti->ksp = (unsigned long ) new_stack; p->thread.kregs = childregs;
arch/tile/include/asm/switch_to.h +3 -5
@@ -53,15 +53,13 @@ extern unsigned long get_switch_to_pc(void);* Kernel threads can check to see if they need to migrate their * stack whenever they return from a context switch; for user * threads, we defer until they are returning to user-space. +* We defer homecache migration until the runqueue lock is released. */ -#define finish_arch_switch (prev) do { \ - if (unlikely((prev)->state == TASK_DEAD)) \ - __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_EXIT | \ - ((prev)->pid << _SIM_CONTROL_OPERATOR_BITS)); \ +#define finish_arch_post_lock_switch () do { \ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_SWITCH | \ (current->pid << _SIM_CONTROL_OPERATOR_BITS)); \ if (current->mm == NULL && !kstack_hash && \ - current_thread_info()->homecache_cpu != smp_processor_id()) \ + current_thread_info()->homecache_cpu != raw_smp_processor_id()) \ homecache_migrate_kthread(); \ } while (0)
arch/tile/kernel/process.c +5 -0
@@ -446,6 +446,11 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,hardwall_switch_tasks (prev, next);#endif +/* Notify the simulator of task exit. */ +if (unlikely (prev->state ==TASK_DEAD )) +__insn_mtspr (SPR_SIM_CONTROL ,SIM_CONTROL_OS_EXIT | + (prev->pid << _SIM_CONTROL_OPERATOR_BITS)); +/* * Switch kernel SP, PC, and callee-saved registers. * In the context of the new task, return the old task pointer
arch/x86/include/asm/preempt.h +2 -2
@@ -90,9 +90,9 @@ static __always_inline bool __preempt_count_dec_and_test(void)/* * Returns true when we need to resched and can (barring IRQ state). */ -static __always_inline bool should_resched(void) +static __always_inline bool should_resched(int preempt_offset) { -return unlikely (!raw_cpu_read_4 (__preempt_count)); +return unlikely (raw_cpu_read_4 (__preempt_count) == preempt_offset); }#ifdef CONFIG_PREEMPT
drivers/cpuidle/cpuidle.c +4 -0
@@ -118,6 +118,7 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,* cpuidle mechanism enables interrupts and doing that with timekeeping * suspended is generally unsafe. */ +stop_critical_timings (); drv->states[index].enter_freeze (dev, drv, index);WARN_ON (!irqs_disabled ());/*
@@ -126,6 +127,7 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,* critical sections, so tell RCU about that. */ RCU_NONIDLE (tick_unfreeze ()); +start_critical_timings (); }/**
@@ -190,7 +192,9 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,trace_cpu_idle_rcuidle (index, dev->cpu); time_start =ktime_get (); +stop_critical_timings (); entered_state = target_state->enter (dev, drv, index); +start_critical_timings (); time_end =ktime_get ();trace_cpu_idle_rcuidle (PWR_EVENT_EXIT , dev->cpu);
drivers/xen/preempt.c +1 -1
@@ -31,7 +31,7 @@ EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); asmlinkage __visible void xen_maybe_preempt_hcall(void) {if (unlikely (__this_cpu_read (xen_in_preemptible_hcall) - &&should_resched ())) { + &&need_resched ())) {/* * Clear flag as we may be rescheduled on a different * cpu.
include/asm-generic/preempt.h +3 -2
@@ -71,9 +71,10 @@ static __always_inline bool __preempt_count_dec_and_test(void)/* * Returns true when we need to resched and can (barring IRQ state). */ -static __always_inline bool should_resched(void) +static __always_inline bool should_resched(int preempt_offset) { -return unlikely (!preempt_count () &&tif_need_resched ()); +return unlikely (preempt_count () == preempt_offset && +tif_need_resched ()); }#ifdef CONFIG_PREEMPT
include/linux/init_task.h +10 -0
@@ -32,6 +32,14 @@ extern struct fs_struct init_fs;#define INIT_CPUSET_SEQ (tsk)#endif +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE +#define INIT_PREV_CPUTIME (x) .prev_cputime = { \ + .lock = __RAW_SPIN_LOCK_UNLOCKED(x.prev_cputime.lock), \ +}, +#else +#define INIT_PREV_CPUTIME (x) +#endif +#define INIT_SIGNALS (sig) { \ .nr_threads = 1, \ .thread_head = LIST_HEAD_INIT(init_task.thread_node), \
@@ -46,6 +54,7 @@ extern struct fs_struct init_fs; .cputime_atomic = INIT_CPUTIME_ATOMIC, \ .running = 0, \ }, \ +INIT_PREV_CPUTIME (sig) \ .cred_guard_mutex = \ __MUTEX_INITIALIZER(sig.cred_guard_mutex), \ }
@@ -246,6 +255,7 @@ extern struct task_group root_task_group; INIT_TASK_RCU_TASKS(tsk) \ INIT_CPUSET_SEQ(tsk) \ INIT_RT_MUTEXES(tsk) \ + INIT_PREV_CPUTIME(tsk) \ INIT_VTIME(tsk) \ INIT_NUMA_BALANCING(tsk) \ INIT_KASAN(tsk) \
include/linux/kthread.h +1 -0
@@ -38,6 +38,7 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), })void kthread_bind (struct task_struct *k,unsigned int cpu); +void kthread_bind_mask (struct task_struct *k,const struct cpumask *mask);int kthread_stop (struct task_struct *k);bool kthread_should_stop (void );bool kthread_should_park (void );
include/linux/preempt.h +14 -5
@@ -84,13 +84,21 @@*/ #define in_nmi () (preempt_count() & NMI_MASK) +/* +* The preempt_count offset after preempt_disable(); +*/ #if defined(CONFIG_PREEMPT_COUNT ) -# define PREEMPT_DISABLE_OFFSET 1 +# define PREEMPT_DISABLE_OFFSET PREEMPT_OFFSET#else -# define PREEMPT_DISABLE_OFFSET 0 +# define PREEMPT_DISABLE_OFFSET 0#endif /* +* The preempt_count offset after spin_lock() +*/ +#define PREEMPT_LOCK_OFFSET PREEMPT_DISABLE_OFFSET + +/* * The preempt_count offset needed for things like: * * spin_lock_bh()
@@ -103,7 +111,7 @@* * Work as expected. */ -#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_DISABLE_OFFSET) +#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_LOCK_OFFSET)/* * Are we running in atomic context? WARNING: this macro cannot
@@ -124,7 +132,8 @@#if defined(CONFIG_DEBUG_PREEMPT ) || defined(CONFIG_PREEMPT_TRACER )extern void preempt_count_add (int val);extern void preempt_count_sub (int val); -#define preempt_count_dec_and_test () ({ preempt_count_sub(1); should_resched(); }) +#define preempt_count_dec_and_test () \ + ({ preempt_count_sub(1); should_resched(0); })#else #define preempt_count_add (val) __preempt_count_add(val)#define preempt_count_sub (val) __preempt_count_sub(val)
@@ -184,7 +193,7 @@ do { \#define preempt_check_resched () \ do { \ - if (should_resched()) \ + if (should_resched(0)) \ __preempt_schedule(); \ } while (0)
include/linux/sched.h +43 -55
170 lines not on this page · raw message
include/linux/stop_machine.h +5 -23
@@ -112,25 +112,13 @@ static inline int try_stop_cpus(const struct cpumask *cpumask,* * This can be thought of as a very heavy write lock, equivalent to * grabbing every spinlock in the kernel. */ -int stop_machine (int (*fn)(void *),void *data,const struct cpumask *cpus); +int stop_machine (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus); -/** -* __stop_machine: freeze the machine on all CPUs and run this function -* @fn: the function to run -* @data: the data ptr for the @fn -* @cpus: the cpus to run the @fn() on (NULL = any online cpu) -* -* Description: This is a special version of the above, which assumes cpus -* won't come or go while it's being called. Used by hotplug cpu. -*/ -int __stop_machine (int (*fn)(void *),void *data,const struct cpumask *cpus); - -int stop_machine_from_inactive_cpu (int (*fn)(void *),void *data, +int stop_machine_from_inactive_cpu (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus); -#else /* CONFIG_STOP_MACHINE && CONFIG_SMP */ -static inline int __stop_machine (int (*fn)(void *),void *data, +static inline int stop_machine (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus) {unsigned long flags;
@@ -141,16 +129,10 @@ static inline int __stop_machine(int (*fn)(void *), void *data, return ret; } -static inline int stop_machine (int (*fn)(void *),void *data, -const struct cpumask *cpus) -{ -return __stop_machine (fn, data, cpus); -} - -static inline int stop_machine_from_inactive_cpu (int (*fn)(void *),void *data, +static inline int stop_machine_from_inactive_cpu (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus) { -return __stop_machine (fn, data, cpus); +return stop_machine (fn, data, cpus); }#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */
include/trace/events/sched.h +21 -9
@@ -55,9 +55,9 @@ TRACE_EVENT(sched_kthread_stop_ret,*/ DECLARE_EVENT_CLASS(sched_wakeup_template, - TP_PROTO(struct task_struct *p, int success), + TP_PROTO(struct task_struct *p), - TP_ARGS(__perf_task(p), success), + TP_ARGS(__perf_task(p)), TP_STRUCT__entry( __array( char, comm, TASK_COMM_LEN )
@@ -71,25 +71,37 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,memcpy (__entry->comm, p->comm,TASK_COMM_LEN ); __entry->pid = p->pid; __entry->prio = p->prio; - __entry->success = success; + __entry->success =1 ;/* rudiment, kill when possible */ __entry->target_cpu =task_cpu (p); ), -TP_printk ("comm=%s pid=%d prio=%d success=%d target_cpu=%03d" , +TP_printk ("comm=%s pid=%d prio=%d target_cpu=%03d" , __entry->comm, __entry->pid, __entry->prio, - __entry->success, __entry->target_cpu) + __entry->target_cpu) ); +/* +* Tracepoint called when waking a task; this tracepoint is guaranteed to be +* called from the waking context. +*/ +DEFINE_EVENT (sched_wakeup_template, sched_waking, + TP_PROTO(struct task_struct *p), +TP_ARGS (p)); + +/* +* Tracepoint called when the task is actually woken; p->state == TASK_RUNNNG. +* It it not always called from the waking context. +*/ DEFINE_EVENT (sched_wakeup_template, sched_wakeup, - TP_PROTO(struct task_struct *p, int success), -TP_ARGS (p, success)); + TP_PROTO(struct task_struct *p), +TP_ARGS (p));/* * Tracepoint for waking up a new task: */ DEFINE_EVENT (sched_wakeup_template, sched_wakeup_new, - TP_PROTO(struct task_struct *p, int success), -TP_ARGS (p, success)); + TP_PROTO(struct task_struct *p), +TP_ARGS (p));#ifdef CREATE_TRACE_POINTS static inline long __trace_sched_switch_state (struct task_struct *p)
kernel/cpu.c +1 -1
@@ -395,7 +395,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)* So now all preempt/rcu users must observe !cpu_active(). */ - err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);
kernel/fork.c +4 -3
@@ -1067,6 +1067,7 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)rcu_assign_pointer (tsk->sighand, sig);if (!sig)return -ENOMEM ; +atomic_set (&sig->count,1 );memcpy (sig->action, current->sighand->action,sizeof (sig->action));return 0 ;
@@ -1128,6 +1129,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)init_sigpending (&sig->shared_pending);INIT_LIST_HEAD (&sig->posix_timers);seqlock_init (&sig->stats_lock); +prev_cputime_init (&sig->prev_cputime);hrtimer_init (&sig->real_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); sig->real_timer.function = it_real_fn;
@@ -1335,9 +1337,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->utime = p->stime = p->gtime =0 ; p->utimescaled = p->stimescaled =0 ; -#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE - p->prev_cputime.utime = p->prev_cputime.stime =0 ; -#endif +prev_cputime_init (&p->prev_cputime); +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN seqlock_init (&p->vtime_seqlock); p->vtime_snap =0 ;
kernel/kthread.c +17 -3
@@ -325,16 +325,30 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), }EXPORT_SYMBOL (kthread_create_on_node); -static void __kthread_bind (struct task_struct *p,unsigned int cpu,long state) +static void __kthread_bind_mask (struct task_struct *p,const struct cpumask *mask,long state) { -/* Must have done schedule() in kthread() before we set_task_cpu */ +unsigned long flags; +if (!wait_task_inactive (p, state)) {WARN_ON (1 );return ; } +/* It's safe because the task is inactive. */ -do_set_cpus_allowed (p,cpumask_of (cpu)); +raw_spin_lock_irqsave (&p->pi_lock, flags); +do_set_cpus_allowed (p, mask); p->flags |=PF_NO_SETAFFINITY ; +raw_spin_unlock_irqrestore (&p->pi_lock, flags); +} + +static void __kthread_bind (struct task_struct *p,unsigned int cpu,long state) +{ +__kthread_bind_mask (p,cpumask_of (cpu), state); +} + +void kthread_bind_mask (struct task_struct *p,const struct cpumask *mask) +{ +__kthread_bind_mask (p, mask,TASK_UNINTERRUPTIBLE ); }/**
kernel/sched/core.c +79 -22
225 lines not on this page · raw message
kernel/sched/cputime.c +60 -41
130 lines not on this page · raw message
kernel/sched/deadline.c +4 -36
@@ -953,7 +953,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)/* * Use the scheduling parameters of the top pi-waiter -* task if we have one and its (relative) deadline is +* task if we have one and its (absolute) deadline is * smaller than our one... OTW we keep our runtime and * deadline. */
@@ -1563,7 +1563,7 @@ static int push_dl_task(struct rq *rq)static void push_dl_tasks (struct rq *rq) { -/* Terminates as it moves a -deadline task */ +/* push_dl_task() will return true if it moved a -deadline task */ while (push_dl_task (rq)) ; }
@@ -1657,7 +1657,6 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p) { if (!task_running(rq, p) && !test_tsk_need_resched(rq->curr) && - has_pushable_dl_tasks(rq) && p->nr_cpus_allowed > 1 && dl_task(rq->curr) && (rq->curr->nr_cpus_allowed < 2 ||
@@ -1669,9 +1668,8 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p)static void set_cpus_allowed_dl (struct task_struct *p,const struct cpumask *new_mask) { -struct rq *rq;struct root_domain *src_rd; -int weight; +struct rq *rq;BUG_ON (!dl_task (p));
@@ -1697,37 +1695,7 @@ static void set_cpus_allowed_dl(struct task_struct *p,raw_spin_unlock (&src_dl_b->lock); } -/* -* Update only if the task is actually running (i.e., -* it is on the rq AND it is not throttled). -*/ -if (!on_dl_rq (&p->dl)) -return ; - - weight =cpumask_weight (new_mask); - -/* -* Only update if the process changes its state from whether it -* can migrate or not. -*/ -if ((p->nr_cpus_allowed >1 ) == (weight >1 )) -return ; - -/* -* The process used to be able to migrate OR it can now migrate -*/ -if (weight <=1 ) { -if (!task_current (rq, p)) -dequeue_pushable_dl_task (rq, p); -BUG_ON (!rq->dl.dl_nr_migratory); - rq->dl.dl_nr_migratory--; - }else { -if (!task_current (rq, p)) -enqueue_pushable_dl_task (rq, p); - rq->dl.dl_nr_migratory++; - } - -update_dl_migration (&rq->dl); +set_cpus_allowed_common (p, new_mask); }/* Assumes rq->lock is held */
kernel/sched/debug.c +19 -29
77 lines not on this page · raw message
kernel/sched/fair.c +373 -564
1,447 lines not on this page · raw message
kernel/sched/features.h +5 -13
@@ -79,20 +79,12 @@ SCHED_FEAT(LB_MIN, false)* numa_balancing= */ #ifdef CONFIG_NUMA_BALANCING -SCHED_FEAT (NUMA , false)/* -* NUMA_FAVOUR_HIGHER will favor moving tasks towards nodes where a -* higher number of hinting faults are recorded during active load -* balancing. +* NUMA will favor moving tasks towards nodes where a higher number of +* hinting faults are recorded during active load balancing. It will +* resist moving tasks towards nodes where a lower number of hinting +* faults have been recorded. */ -SCHED_FEAT (NUMA_FAVOUR_HIGHER , true) - -/* -* NUMA_RESIST_LOWER will resist moving tasks towards nodes where a -* lower number of hinting faults have been recorded. As this has -* the potential to prevent a task ever migrating to a new node -* due to CPU overload it is disabled by default. - */ -SCHED_FEAT(NUMA_RESIST_LOWER, false) +SCHED_FEAT(NUMA, true)#endif
kernel/sched/idle.c +5 -9
@@ -83,10 +83,13 @@ void __weak arch_cpu_idle(void)*/ void default_idle_call (void ) { -if (current_clr_polling_and_test ()) +if (current_clr_polling_and_test ()) {local_irq_enable (); -else + }else { +stop_critical_timings ();arch_cpu_idle (); +start_critical_timings (); + } } static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
@@ -141,12 +144,6 @@ static void cpuidle_idle_call(void) }/* -* During the idle period, stop measuring the disabled irqs -* critical sections latencies -*/ -stop_critical_timings (); - -/* * Tell the RCU framework we are entering an idle section, * so no more rcu read side critical sections and one more * step to the grace period
@@ -198,7 +195,6 @@ static void cpuidle_idle_call(void)local_irq_enable ();rcu_idle_exit (); -start_critical_timings (); }DEFINE_PER_CPU (bool, cpu_dead_idle);
kernel/sched/idle_task.c +1 -0
@@ -96,6 +96,7 @@ const struct sched_class idle_sched_class = {#ifdef CONFIG_SMP .select_task_rq = select_task_rq_idle, + .set_cpus_allowed = set_cpus_allowed_common, #endif .set_curr_task = set_curr_task_idle,
kernel/sched/rt.c +1 -41
60 lines not on this page · raw message
kernel/sched/sched.h +14 -25
@@ -245,7 +245,6 @@ struct task_group {#ifdef CONFIG_SMP atomic_long_t load_avg; -atomic_t runnable_avg;#endif #endif
@@ -366,27 +365,20 @@ struct cfs_rq {#ifdef CONFIG_SMP /* -* CFS Load tracking -* Under CFS, load is tracked on a per-entity basis and aggregated up. -* This allows for the description of both thread and group usage (in -* the FAIR_GROUP_SCHED case). -* runnable_load_avg is the sum of the load_avg_contrib of the -* sched_entities on the rq. -* blocked_load_avg is similar to runnable_load_avg except that its -* the blocked sched_entities on the rq. -* utilization_load_avg is the sum of the average running time of the -* sched_entities on the rq. +* CFS load tracking */ -unsigned long runnable_load_avg, blocked_load_avg, utilization_load_avg; -atomic64_t decay_counter; -u64 last_decay; -atomic_long_t removed_load; - +struct sched_avg avg; +u64 runnable_load_sum; +unsigned long runnable_load_avg;#ifdef CONFIG_FAIR_GROUP_SCHED -/* Required to track per-cpu representation of a task_group */ -u32 tg_runnable_contrib; -unsigned long tg_load_contrib; +unsigned long tg_load_avg_contrib; +#endif +atomic_long_t removed_load_avg, removed_util_avg; +#ifndef CONFIG_64BIT +u64 load_last_update_time_copy; +#endif +#ifdef CONFIG_FAIR_GROUP_SCHED /* * h_load = weight * f(tg) *
@@ -595,8 +587,6 @@ struct rq {#ifdef CONFIG_FAIR_GROUP_SCHED /* list of leaf cfs_rq on this cpu: */ struct list_head leaf_cfs_rq_list; - -struct sched_avg avg;#endif /* CONFIG_FAIR_GROUP_SCHED */ /*
@@ -1065,9 +1055,6 @@ static inline int task_on_rq_migrating(struct task_struct *p)#ifndef prepare_arch_switch# define prepare_arch_switch (next) do { } while (0)#endif -#ifndef finish_arch_switch -# define finish_arch_switch (prev) do { } while (0) -#endif #ifndef finish_arch_post_lock_switch# define finish_arch_post_lock_switch () do { } while (0)#endif
@@ -1268,6 +1255,8 @@ extern void trigger_load_balance(struct rq *rq);extern void idle_enter_fair (struct rq *this_rq);extern void idle_exit_fair (struct rq *this_rq); +extern void set_cpus_allowed_common (struct task_struct *p,const struct cpumask *new_mask); +#else static inline void idle_enter_fair (struct rq *rq) { }
@@ -1319,7 +1308,7 @@ extern void init_dl_task_timer(struct sched_dl_entity *dl_se);unsigned long to_ratio (u64 period,u64 runtime); -extern void init_task_runnable_average (struct task_struct *p); +extern void init_entity_runnable_average (struct sched_entity *se);static inline void add_nr_running (struct rq *rq,unsigned count) {
kernel/sched/stop_task.c +1 -0
@@ -123,6 +123,7 @@ const struct sched_class stop_sched_class = {#ifdef CONFIG_SMP .select_task_rq = select_task_rq_stop, + .set_cpus_allowed = set_cpus_allowed_common, #endif .set_curr_task = set_curr_task_stop,
kernel/stop_machine.c +22 -22
132 lines not on this page · raw message
kernel/trace/trace_sched_switch.c +1 -1
@@ -26,7 +26,7 @@ probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *n }static void -probe_sched_wakeup (void *ignore,struct task_struct *wakee,int success) +probe_sched_wakeup (void *ignore,struct task_struct *wakee) {if (unlikely (!sched_ref))return ;
kernel/trace/trace_sched_wakeup.c +1 -1
@@ -514,7 +514,7 @@ static void wakeup_reset(struct trace_array *tr) }static void -probe_wakeup (void *ignore,struct task_struct *p,int success) +probe_wakeup (void *ignore,struct task_struct *p) {struct trace_array_cpu *data;int cpu =smp_processor_id ();
kernel/workqueue.c +2 -4
@@ -1714,9 +1714,7 @@ static struct worker *create_worker(struct worker_pool *pool) goto fail;set_user_nice (worker->task, pool->attrs->nice); - -/* prevent userland from meddling with cpumask of workqueue workers */ - worker->task->flags |=PF_NO_SETAFFINITY ; +kthread_bind_mask (worker->task, pool->attrs->cpumask);/* successful, attach the worker to the pool */ worker_attach_to_pool (worker, pool);
@@ -3856,7 +3854,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, } wq->rescuer = rescuer; - rescuer->task->flags |=PF_NO_SETAFFINITY ; +kthread_bind_mask (rescuer->task, cpu_possible_mask);wake_up_process (rescuer->task); }
Quoted 5 lines · Ingo Molnar
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus # HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()
Linus,
your merge (commit a1d8561172f369ba) breaks booting on my machine.
I wrote down the backtrace:
map_vsyscallkvm_arch_hardware_setupmap_vsyscallkvm_initmap_vsyscalldo_one_initcallkernel_init_freeablerest_initkernel_initret_from_forkrest_init
RIP: svm_hardware_setup
Reverting your merge resolution fixes the issue:
kernel/cpu.c +1 -2
@@ -397,12 +397,11 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen)* Prevent irq alloc/free while the dying cpu reorganizes the * interrupt affinities. */ -irq_lock_sparse ();/* * So now all preempt/rcu users must observe !cpu_active(). */ - err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);
Signature · 1 line
Markus
Quoted 10 lines · Markus Trippelsdorf
Quoted 5 lines · Ingo Molnar
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus # HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()Linus,
your merge (commit
a1d8561172f369ba) breaks booting on my machine.
So I just double checked Linus's merge resolution, re-created it from scratch, and it looks correct. Furthermore, I resolved the conflict similarly in the past and this resolution had been in -tip and linux-next testing for some while.
But I noticed something weird in your revert patch:
Quoted 24 lines
I wrote down the backtrace:
map_vsyscallkvm_arch_hardware_setupmap_vsyscallkvm_initmap_vsyscalldo_one_initcallkernel_init_freeablerest_initkernel_initret_from_forkrest_initRIP: svm_hardware_setupReverting your merge resolution fixes the issue:
kernel/cpu.c +0
-0
kernel/cpu.c static int _cpu_down(unsigned int cpu, int tasks_frozen) · line 400
Quoted 4 lines
kernel/cpu.c +0
-1@@ -397,12 +397,11 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen)* Prevent irq alloc/free while the dying cpu reorganizes the * interrupt affinities. */ -irq_lock_sparse ();
So where does this chunk come from? None of the trees nor the merge resolution touches this code.
Maybe you had other changes in your tree that interfered?
That missing irq_lock_sparse() might indeed break the boot. But that's not something that got in there from Linus's tree AFAICS.
kernel/cpu.c static int _cpu_down(unsigned int cpu, int tasks_frozen) · line 407
Quoted 8 lines
kernel/cpu.c +1
-1/* * So now all preempt/rcu users must observe !cpu_active(). */ - err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);
This change cannot possibly have built on Linus's tree, as __stop_machine() got unexported, it is now internal and static to kernel/stop_machine.c...
So could you please double check your side?
Thanks,
Ingo
Quoted 69 lines · Ingo Molnar
Quoted 10 lines · Markus Trippelsdorf
Quoted 5 lines · Ingo Molnar
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus # HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()Linus,
your merge (commit
a1d8561172f369ba) breaks booting on my machine.So I just double checked Linus's merge resolution, re-created it from scratch, and it looks correct. Furthermore, I resolved the conflict similarly in the past and this resolution had been in -tip and linux-next testing for some while.
But I noticed something weird in your revert patch:
Quoted 24 lines
I wrote down the backtrace:
map_vsyscallkvm_arch_hardware_setupmap_vsyscallkvm_initmap_vsyscalldo_one_initcallkernel_init_freeablerest_initkernel_initret_from_forkrest_initRIP: svm_hardware_setupReverting your merge resolution fixes the issue:
kernel/cpu.c +0
-0kernel/cpu.c static int _cpu_down(unsigned int cpu, int tasks_frozen) · line 400
Quoted 4 lines
kernel/cpu.c +0
-1@@ -397,12 +397,11 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen)* Prevent irq alloc/free while the dying cpu reorganizes the * interrupt affinities. */ -irq_lock_sparse ();So where does this chunk come from? None of the trees nor the merge resolution touches this code.
Maybe you had other changes in your tree that interfered?
That missing
irq_lock_sparse()might indeed break the boot. But that's not something that got in there from Linus's tree AFAICS.kernel/cpu.c static int _cpu_down(unsigned int cpu, int tasks_frozen) · line 406
Quoted 8 lines
kernel/cpu.c +1
-1/* * So now all preempt/rcu users must observe !cpu_active(). */ - err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);This change cannot possibly have built on Linus's tree, as
__stop_machine()got unexported, it is now internal and static tokernel/stop_machine.c...
Quoted 1 line
So could you please double check your side?
Well, git show a1d8561172f369ba56d636df49a6b4d6d77e2123 :
commit a1d8561172f369ba56d636df49a6b4d6d77e2123
Merge: 3959df1dfb95 ff277d4250fe
Author: Linus Torvalds <[email protected]>
Date: Mon Aug 31 20:26:22 2015 -0700
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler updates from Ingo Molnar:
"The biggest change in this cycle is the rewrite of the main SMP load
balancing metric: the CPU load/utilization. The main goal was to make the metric more precise and more representative - see the changelog of this commit for the gory details:
9d89c257dfb9 ("sched/fair: Rewrite runnable load and utilization average tracking")
It is done in a way that significantly reduces complexity of the code:
5 files changed, 249 insertions(+), 494 deletions(-)
and the performance testing results are encouraging. Nevertheless we need to keep an eye on potential regressions, since this potentially affects every SMP workload in existence.
This work comes from Yuyang Du.
Other changes:
- SCHED_DL updates. (Andrea Parri)
- Simplify architecture callbacks by removing finish_arch_switch(). (Peter Zijlstra et al)
- cputime accounting: guarantee stime + utime == rtime. (Peter Zijlstra)
- optimize idle CPU wakeups some more - inspired by Facebook server loads. (Mike Galbraith)
- stop_machine fixes and updates. (Oleg Nesterov)
- Introduce the 'trace_sched_waking' tracepoint. (Peter Zijlstra)
- sched/numa tweaks. (Srikar Dronamraju)
- misc fixes and small cleanups"
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) sched/deadline: Fix comment in enqueue_task_dl()
sched/deadline: Fix comment in push_dl_tasks()
sched: Change the sched_class::set_cpus_allowed() calling context
sched: Make sched_class::set_cpus_allowed() unconditional
sched: Fix a race between __kthread_bind() and sched_setaffinity()
sched: Ensure a task has a non-normalized vruntime when returning back to CFS sched/numa: Fix NUMA_DIRECT topology identification
tile: Reorganize _switch_to()
sched, sparc32: Update scheduler comments in copy_thread()
sched: Remove finish_arch_switch()
sched, tile: Remove finish_arch_switch
sched, sh: Fold finish_arch_switch() into switch_to()
sched, score: Remove finish_arch_switch()
sched, avr32: Remove finish_arch_switch()
sched, MIPS: Get rid of finish_arch_switch()
sched, arm: Remove finish_arch_switch()
sched/fair: Clean up load average references
sched/fair: Provide runnable_load_avg back to cfs_rq
sched/fair: Remove task and group entity load when they are dead
sched/fair: Init cfs_rq's sched_entity load average
...
kernel/cpu.c +0 -0
@@@ -394,15 -392,10 +394,15 @@@ static int _cpu_down(unsigned int cpu,smpboot_park_threads (cpu);/* - * So now all preempt/rcu users must observe !cpu_active(). + * Prevent irq alloc/free while the dying cpu reorganizes the + * interrupt affinities. */ +irq_lock_sparse (); +/* + * So now all preempt/rcu users must observe !cpu_active(). + */ - err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);
Signature · 1 line
Markus
Quoted 19 lines · Markus Trippelsdorf
Well, git show
a1d8561172f369ba56d636df49a6b4d6d77e2123:commit
a1d8561172f369ba56d636df49a6b4d6d77e2123
Merge:3959df1dfb95ff277d4250fe
Author: Linus Torvalds <[email protected]>
Date: Mon Aug 31 20:26:22 2015 -0700kernel/cpu.c +0
-0@@@ -394,15 -392,10 +394,15 @@@ static int _cpu_down(unsigned int cpu,smpboot_park_threads (cpu);/* - * So now all preempt/rcu users must observe !cpu_active(). + * Prevent irq alloc/free while the dying cpu reorganizes the + * interrupt affinities. */
kernel/cpu.c
Quoted 10 lines
kernel/cpu.c +1
-1+irq_lock_sparse (); +/* + * So now all preempt/rcu users must observe !cpu_active(). + */ - err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);
So the irq_lock_sparse() change is from a commit that got merged in the last merge window, which is part of v4.2:
ce0d3c0a6fb1 ("genirq: Revert sparse irq locking around __cpu_up() and move it to x86 for now")
Could you please post the patch against Linus's latest that you have tested on your system to make it boot fine?
The one you posted cannot possibly build, because access to __stop_machine() is gone from cpu.c:
kernel/cpu.c: In function ‘_cpu_down’:kernel/cpu.c:404:2: error: implicit declaration of function ‘__stop_machine’ [-Werror=implicit-function-declaration]
err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
^
Thanks,
Ingo
Quoted 36 lines · Ingo Molnar
Quoted 19 lines · Markus Trippelsdorf
Well, git show
a1d8561172f369ba56d636df49a6b4d6d77e2123:commit
a1d8561172f369ba56d636df49a6b4d6d77e2123
Merge:3959df1dfb95ff277d4250fe
Author: Linus Torvalds <[email protected]>
Date: Mon Aug 31 20:26:22 2015 -0700kernel/cpu.c +0
-0@@@ -394,15 -392,10 +394,15 @@@ static int _cpu_down(unsigned int cpu,smpboot_park_threads (cpu);/* - * So now all preempt/rcu users must observe !cpu_active(). + * Prevent irq alloc/free while the dying cpu reorganizes the + * interrupt affinities. */ kernel/cpu.c
Quoted 10 lines
kernel/cpu.c +1
-1+irq_lock_sparse (); +/* + * So now all preempt/rcu users must observe !cpu_active(). + */ - err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);So the
irq_lock_sparse()change is from a commit that got merged in the last merge window, which is part of v4.2:
Quoted 7 lines
ce0d3c0a6fb1("genirq: Revert sparse irq locking around__cpu_up()and move it to x86 for now")Could you please post the patch against Linus's latest that you have tested on your system to make it boot fine?
The one you posted cannot possibly build, because access to
__stop_machine()is gone fromcpu.c:
As I wrote in my other reply. The boot failure is nondeterministic (boot succeeds roughly every sixth time). So the bisection and the patch is just bogus (,but the boot failure is real).
Sorry.
Signature · 1 line
Markus
Quoted 42 lines · Markus Trippelsdorf
Quoted 41 lines · Ingo Molnar
Quoted 19 lines · Markus Trippelsdorf
Well, git show
a1d8561172f369ba56d636df49a6b4d6d77e2123:commit
a1d8561172f369ba56d636df49a6b4d6d77e2123
Merge:3959df1dfb95ff277d4250fe
Author: Linus Torvalds <[email protected]>
Date: Mon Aug 31 20:26:22 2015 -0700kernel/cpu.c +0
-0@@@ -394,15 -392,10 +394,15 @@@ static int _cpu_down(unsigned int cpu,smpboot_park_threads (cpu);/* - * So now all preempt/rcu users must observe !cpu_active(). + * Prevent irq alloc/free while the dying cpu reorganizes the + * interrupt affinities. */ kernel/cpu.c
Quoted 10 lines
kernel/cpu.c +1
-1+irq_lock_sparse (); +/* + * So now all preempt/rcu users must observe !cpu_active(). + */ - err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu)); + err =stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail (CPU_DOWN_FAILED | mod, hcpu);So the
irq_lock_sparse()change is from a commit that got merged in the last merge window, which is part of v4.2:
ce0d3c0a6fb1("genirq: Revert sparse irq locking around__cpu_up()and move it to x86 for now")Could you please post the patch against Linus's latest that you have tested on your system to make it boot fine?
Quoted 8 lines
Quoted 2 lines
The one you posted cannot possibly build, because access to
__stop_machine()is gone fromcpu.c:As I wrote in my other reply. The boot failure is nondeterministic (boot succeeds roughly every sixth time). So the bisection and the patch is just bogus (,but the boot failure is real).
Sorry.
No problem. Please let us know if any of these commits does turn out to be the culprit. (Which is always a possibility.)
Thanks,
Ingo
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 10 lines · Ingo Molnar
Quoted 5 lines · Markus Trippelsdorf
As I wrote in my other reply. The boot failure is nondeterministic (boot succeeds roughly every sixth time). So the bisection and the patch is just bogus (,but the boot failure is real).
Sorry.
No problem. Please let us know if any of these commits does turn out to be the culprit. (Which is always a possibility.)
I'm pretty sure commit 3c2e7f7de3 is the culprit.
commit 3c2e7f7de3240216042b61073803b61b9b3cfb22
Author: Paolo Bonzini <[email protected]> Date: Tue Jul 7 14:32:17 2015 +0200
KVM: SVM: use NPT page attributes
I've booted ten times in a row successfully with the following patch:
arch/x86/kvm/svm.c +1 -1
@@ -989,7 +989,7 @@ static __init int svm_hardware_setup(void) }else kvm_disable_tdp (); -build_mtrr2protval (); +// build_mtrr2protval(); return 0 ; err:
Paolo, your commit causes nondeterministic boot failure on my machine. It sometimes crashes early with the following backtrace:
map_vsyscallkvm_arch_hardware_setupmap_vsyscallkvm_initmap_vsyscalldo_one_initcallkernel_init_freeablerest_initkernel_initret_from_forkrest_init
RIP: svm_hardware_setup
Signature · 1 line
Markus
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 36 lines · Markus Trippelsdorf
Quoted 10 lines · Ingo Molnar
Quoted 5 lines · Markus Trippelsdorf
As I wrote in my other reply. The boot failure is nondeterministic (boot succeeds roughly every sixth time). So the bisection and the patch is just bogus (,but the boot failure is real).
Sorry.
No problem. Please let us know if any of these commits does turn out to be the culprit. (Which is always a possibility.)
I'm pretty sure commit
3c2e7f7de3is the culprit.commit
3c2e7f7de3240216042b61073803b61b9b3cfb22Author: Paolo Bonzini <[email protected]> Date: Tue Jul 7 14:32:17 2015 +0200KVM: SVM: use NPT page attributes
I've booted ten times in a row successfully with the following patch:
arch/x86/kvm/svm.c +1
-1@@ -989,7 +989,7 @@ static __init int svm_hardware_setup(void) }else kvm_disable_tdp (); -build_mtrr2protval (); +// build_mtrr2protval(); return 0 ; err:
Quoted 3 lines
Paolo, your commit causes nondeterministic boot failure on my machine. It sometimes crashes early with the following backtrace:
Did it trigger the BUG()/BUG_ON() in mtrr2protval()/fallback_mtrr_type()? If yes, could you please print the actual value out?
BTW, you may change BUG() to WARN() to get the print info more easier.
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 3 lines · Xiao Guangrong
Did it trigger the BUG()/BUG_ON() in mtrr2protval()/fallback_mtrr_type()? If yes, could you please print the actual value out?
It is the BUG() in fallback_mtrr_type(). I changed it to a printk and it prints 1 for the value of mtrr.
MTRR_TYPE_WRCOMB 1
Signature · 1 line
Markus
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 10 lines · Markus Trippelsdorf
Quoted 3 lines · Xiao Guangrong
Did it trigger the BUG()/BUG_ON() in mtrr2protval()/fallback_mtrr_type()? If yes, could you please print the actual value out?
It is the
BUG()infallback_mtrr_type(). I changed it to a printk and it prints 1 for the value of mtrr.
MTRR_TYPE_WRCOMB1
Then I suspect pat is not enabled in your box, could you please check CONFIG_X86_PAT is selected in your .config file, pat is shown in /proc/cpuid, "nopat" kernel parameter is used, and dmesg | grep PAT.
I will post a fix if the suspect is right.
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 11 lines · Xiao Guangrong
Quoted 8 lines · Markus Trippelsdorf
Quoted 3 lines · Xiao Guangrong
Did it trigger the BUG()/BUG_ON() in mtrr2protval()/fallback_mtrr_type()? If yes, could you please print the actual value out?
It is the
BUG()infallback_mtrr_type(). I changed it to a printk and it prints 1 for the value of mtrr.
Quoted 6 lines
Quoted 2 lines
MTRR_TYPE_WRCOMB1Then I suspect pat is not enabled in your box, could you please check
CONFIG_X86_PATis selected in your .config file, pat is shown in/proc/cpuid, "nopat" kernel parameter is used, and dmesg | grep PAT.
No. PAT is of course enabled and booting is successful sometimes even with the BUG() in allback_mtrr_type(). I suspect a setup (timing) issue.
markus@x4 linux % cat .config | grep X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT
[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WT
markus@x4 linux % cat /proc/cpuinfo| grep pat
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate npt lbrv svm_lock nrip_save vmmcall
...
Signature · 1 line
Markus
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 15 lines · Markus Trippelsdorf
Quoted 14 lines · Xiao Guangrong
Quoted 10 lines · Markus Trippelsdorf
Quoted 3 lines · Xiao Guangrong
Did it trigger the BUG()/BUG_ON() in mtrr2protval()/fallback_mtrr_type()? If yes, could you please print the actual value out?
It is the
BUG()infallback_mtrr_type(). I changed it to a printk and it prints 1 for the value of mtrr.
MTRR_TYPE_WRCOMB1
Quoted 6 lines
Quoted 3 lines
Then I suspect pat is not enabled in your box, could you please check
CONFIG_X86_PATis selected in your .config file, pat is shown in/proc/cpuid, "nopat" kernel parameter is used, and dmesg | grep PAT.No. PAT is of course enabled and booting is successful sometimes even with the
BUG()inallback_mtrr_type(). I suspect a setup (timing) issue.
Thanks for your confirmation.
Quoted 5 lines
markus@x4 linux % cat .config | grep
X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WT
Strange, BP processor has already set WC to PAT1, however KVM does not read it out from PAT MSR on its local CPU.
Hmm... PAT default values do not include WC, it seems initing PAT on SP has not finished after module_init()?
Could please apply this diff and test it again?
arch/x86/kvm/svm.c +10 -0
@@ -884,6 +884,7 @@ static u8 fallback_mtrr_type(int mtrr)case MTRR_TYPE_WRPROT :return MTRR_TYPE_UC_MINUS ;default : +printk ("BUG in %s, mtrr = %d.\n" , __FUNCTION__, mtrr);BUG (); } }
@@ -907,6 +908,8 @@ static void build_mtrr2protval(void)* guest. */ rdmsrl (MSR_IA32_CR_PAT , pat); +printk ("KVM PAT: 0x%llx.\n" , pat); +for (i =0 ; i <8 ; i++) {u8 mtrr = pat >> (8 * i);
@@ -914,10 +917,17 @@ static void build_mtrr2protval(void) mtrr2protval[mtrr] =__cm_idx2pte (i); } +for (i =0 ; i <8 ; i++) +printk ("mtrr2protval[%d]:%x.\n" , i, mtrr2protval[i]); + +for (i =0 ; i <8 ; i++) {if (mtrr2protval[i] ==MTRR2PROTVAL_INVALID ) {u8 fallback =fallback_mtrr_type (i); mtrr2protval[i] = mtrr2protval[fallback]; +if (mtrr2protval[i] ==MTRR2PROTVAL_INVALID ) +printk ("BUG in %s, mtrr2protval[%d] = %x.\n" , __FUNCTION__, i, mtrr2protval[i]); +BUG_ON (mtrr2protval[i] ==MTRR2PROTVAL_INVALID ); } }
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 12 lines · Xiao Guangrong
Quoted 3 lines
No. PAT is of course enabled and booting is successful sometimes even with the
BUG()inallback_mtrr_type(). I suspect a setup (timing) issue.Thanks for your confirmation.
Quoted 5 lines
markus@x4 linux % cat .config | grep
X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WT
Quoted 7 lines
Strange, BP processor has already set WC to PAT1, however KVM does not read it out from PAT MSR on its local CPU.
Hmm... PAT default values do not include WC, it seems initing PAT on SP has not finished after
module_init()?Could please apply this diff and test it again?
(Your patch was malformed.)
[ 2.138098] kvm: Nested Virtualization enabled [ 2.138153] kvm: Nested Paging enabled [ 2.138204] KVM PAT: 0x7040600070406. [ 2.138255] mtrr2protval[0]:18. [ 2.138306] mtrr2protval[1]:ff. [ 2.138356] mtrr2protval[2]:0. [ 2.138408] mtrr2protval[3]:0. [ 2.138459] mtrr2protval[4]:8. [ 2.138510] mtrr2protval[5]:ff. [ 2.138561] mtrr2protval[6]:0. [ 2.138612] mtrr2protval[7]:10. [ 2.138662] BUG in fallback_mtrr_type, mtrr = 1.
Signature · 1 line
Markus
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 19 lines · Markus Trippelsdorf
Quoted 18 lines · Xiao Guangrong
Quoted 3 lines
No. PAT is of course enabled and booting is successful sometimes even with the
BUG()inallback_mtrr_type(). I suspect a setup (timing) issue.Thanks for your confirmation.
Quoted 5 lines
markus@x4 linux % cat .config | grep
X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WTStrange, BP processor has already set WC to PAT1, however KVM does not read it out from PAT MSR on its local CPU.
Hmm... PAT default values do not include WC, it seems initing PAT on SP has not finished after
module_init()?
Quoted 7 lines
Quoted 1 line
Could please apply this diff and test it again?
(Your patch was malformed.)
[ 2.138098] kvm: Nested Virtualization enabled [ 2.138153] kvm: Nested Paging enabled [ 2.138204] KVM PAT: 0x7040600070406.
So the PAT is the value after CPU reset, it's likely PAT is not initialized on the local CPU.
Maybe something is escaped from stop_machine() called in native_smp_cpus_done(), Ingo?
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 24 lines · Xiao Guangrong
Quoted 21 lines · Markus Trippelsdorf
Quoted 19 lines · Xiao Guangrong
Quoted 3 lines
No. PAT is of course enabled and booting is successful sometimes even with the
BUG()inallback_mtrr_type(). I suspect a setup (timing) issue.Thanks for your confirmation.
Quoted 5 lines
markus@x4 linux % cat .config | grep
X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WTStrange, BP processor has already set WC to PAT1, however KVM does not read it out from PAT MSR on its local CPU.
Hmm... PAT default values do not include WC, it seems initing PAT on SP has not finished after
module_init()?Could please apply this diff and test it again?
Quoted 8 lines
Quoted 5 lines
(Your patch was malformed.)
[ 2.138098] kvm: Nested Virtualization enabled [ 2.138153] kvm: Nested Paging enabled [ 2.138204] KVM PAT: 0x7040600070406.So the PAT is the value after CPU reset, it's likely PAT is not initialized on the local CPU.
Could it be a simple AMD/INTEL difference. I'm running a AMD CPU and I see many !use_intel() in if statements in arch/x86/kernel/cpu/mtrr/main.c...
Signature · 1 line
Markus
Re: commit 3c2e7f7de3 (KVM use NPT page attributes) causes boot failures
Quoted 31 lines · Markus Trippelsdorf
Quoted 30 lines · Xiao Guangrong
Quoted 26 lines · Markus Trippelsdorf
Quoted 12 lines · Xiao Guangrong
Quoted 3 lines
No. PAT is of course enabled and booting is successful sometimes even with the
BUG()inallback_mtrr_type(). I suspect a setup (timing) issue.Thanks for your confirmation.
Quoted 5 lines
markus@x4 linux % cat .config | grep
X86_PATCONFIG_X86_PAT=y
markus@x4 linux % dmesg | grep PAT[ 0.000000] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WC UC- WTQuoted 7 lines
Strange, BP processor has already set WC to PAT1, however KVM does not read it out from PAT MSR on its local CPU.
Hmm... PAT default values do not include WC, it seems initing PAT on SP has not finished after
module_init()?Could please apply this diff and test it again?
(Your patch was malformed.)
[ 2.138098] kvm: Nested Virtualization enabled [ 2.138153] kvm: Nested Paging enabled [ 2.138204] KVM PAT: 0x7040600070406.
Quoted 6 lines
Quoted 2 lines
So the PAT is the value after CPU reset, it's likely PAT is not initialized on the local CPU.
Could it be a simple AMD/INTEL difference. I'm running a AMD CPU and I see many !use_intel() in if statements in
arch/x86/kernel/cpu/mtrr/main.c...
#define use_intel() (mtrr_if && mtrr_if->use_intel_if == 1)
And i checked your CPU supports "mtrr" /proc/info, so it should use generic_mtrr_ops and generic_mtrr_ops.use_intel_if = 1. That means AMD CPU also use "intel" way. :)
Please refer to the initiation of "mtrr_if" in mtrr_bp_init().
Quoted 6 lines · Ingo Molnar
The one you posted cannot possibly build, because access to
__stop_machine()is gone fromcpu.c:
kernel/cpu.c: In function ‘_cpu_down’:kernel/cpu.c:404:2: error: implicit declaration of function ‘__stop_machine’ [-Werror=implicit-function-declaration]
err =__stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
Just to clear this up: It did build on my machine because it wasn't compiled at all (CONFIG_HOTPLUG_CPU is not set).
Signature · 1 line
Markus
Quoted 8 lines · Ingo Molnar
Quoted 5 lines · Markus Trippelsdorf
Quoted 4 lines · Ingo Molnar
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.gitsched-core-for-linus
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
# HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()Linus,
your merge (commit
a1d8561172f369ba) breaks booting on my machine.So could you please double check your side?
I just double checked and my git tree is clean.
But it could be that the boot failure is nondeterministic, so git bisect got off the track.
Anyway I don't have time to debug this further ATM.
Signature · 1 line
Markus
Quoted 13 lines · Markus Trippelsdorf
Quoted 12 lines · Ingo Molnar
Quoted 9 lines · Markus Trippelsdorf
Quoted 5 lines · Ingo Molnar
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus # HEAD: ff277d4250fe715b6666219b1a3423b863418794 sched/deadline: Fix comment in enqueue_task_dl()Linus,
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
your merge (commit
a1d8561172f369ba) breaks booting on my machine.So could you please double check your side?
I just double checked and my git tree is clean.
But it could be that the boot failure is nondeterministic, so git bisect got off the track.
Just to confirm. The boot failure _is_ nondeterministic. I just booted a few times in a row and it failed five times and succeeded the sixth time.
So please ignore my bisection result and the bogus patch that I've posted.
Signature · 1 line
Markus