scheduler updates for v4.6
Subsystems (15)
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: f9c904b7613b8b4c85b10cd6b33ad41b2843fa9d sched/cputime: Fix steal_account_process_tick() to always return jiffies
The main changes in this cycle are:
- Make schedstats a runtime tunable (disabled by default) and optimize it via static keys. As most distributions enable CONFIG_SCHEDSTATS=y due to its instrumentation value, this is a nice performance enhancement. (Mel Gorman)
- Implement 'simple waitqueues' (swait): these are just pure waitqueues without any of the more complex features of full-blown waitqueues (callbacks, wake flags, wake keys, etc.). Simple waitqueues have less memory overhead and are faster.
Use simple waitqueues in the RCU code (in 4 different places) and for handling KVM vCPU wakeups.
(Peter Zijlstra, Daniel Wagner, Thomas Gleixner, Paul Gortmaker, Marcelo Tosatti)
- sched/numa enhancements (Rik van Riel)
- NOHZ performance enhancements (Rik van Riel)
- Various sched/deadline enhancements (Steven Rostedt)
- Various fixes (Peter Zijlstra)
- ... and a number of other fixes, cleanups and smaller enhancements.
Thanks,
Ingo
------------------>
Byungchul Park (2):
sched/core: Remove dead statement in __schedule() sched/fair: Avoid using decay_load_missed() with a negative value
Chris Friesen (1):
sched/cputime: Fix steal_account_process_tick() to always return jiffies
Daniel Wagner (2):
kbuild: Add option to turn incompatible pointer check into error
rcu: Do not call rcu_nocb_gp_cleanup() while holding rnp->lock
Dongsheng Yang (1):
sched/core: Remove duplicated sched_group_set_shares() prototype
Frederic Weisbecker (1):
sched/fair: Consolidate nohz CPU load update code
Ingo Molnar (1):
Revert "kbuild: Add option to turn incompatible pointer check into error"
Luca Abeni (1):
sched/deadline: Remove dl_new from struct sched_dl_entity
Marcelo Tosatti (1):
KVM: Use simple waitqueue for vcpu->wq
Mel Gorman (1):
sched/debug: Make schedstats a runtime tunable that is disabled by default
Paul Gortmaker (1):
rcu: Use simple wait queues where possible in rcutree
Peter Zijlstra (4):
sched/cgroup: Fix cgroup entity load tracking tear-down sched/deadline: Always calculate end of period on sched_yield() sched/rt: Fix PI handling vs. sched_setscheduler() sched/deadline: Remove superfluous call to switched_to_dl()
Peter Zijlstra (Intel) (1):
wait.[ch]: Introduce the simple waitqueue (swait) implementation
Prarit Bhargava (1):
sched/isolcpus: Output warning when the 'isolcpus=' kernel parameter is invalid
Rik van Riel (5):
sched/numa: Spread memory according to CPU and memory use sched, time: Remove non-power-of-two divides from __acct_update_integrals() acct, time: Change indentation in __acct_update_integrals() time, acct: Drop irq save & restore from __acct_update_integrals() sched, time: Switch VIRT_CPU_ACCOUNTING_GEN to jiffy granularity
Sebastian Andrzej Siewior (1):
sched/debug: Fix preempt_disable_ip recording for preempt_disable()
Stafford Horne (1):
sched/wait: Fix wait_event_freezable() documentation
Steven Rostedt (1):
sched/rt: Kick RT bandwidth timer immediately on start up
Steven Rostedt (Red Hat) (3):
sched/debug: Move the /sys/kernel/debug/sched_features file setup into debug.c sched/debug: Move sched_domain_sysctl to debug.c
sched/debug: Add deadline scheduler bandwidth ratio to /proc/sched_debug
Documentation/kernel-parameters.txt | 5 + Documentation/sysctl/kernel.txt | 8 + arch/arm/kvm/arm.c | 8 +- arch/arm/kvm/psci.c | 4 +- arch/mips/kvm/mips.c | 8 +- arch/powerpc/include/asm/kvm_host.h | 4 +- arch/powerpc/kvm/book3s_hv.c | 23 +- arch/s390/include/asm/kvm_host.h | 2 +- arch/s390/kvm/interrupt.c | 4 +- arch/x86/kvm/lapic.c | 6 +- include/linux/ftrace.h | 12 + include/linux/kvm_host.h | 5 +- include/linux/latencytop.h | 3 + include/linux/sched.h | 14 +- include/linux/sched/sysctl.h | 4 + include/linux/swait.h | 172 ++++++++++++++ include/linux/wait.h | 2 +- kernel/latencytop.c | 14 +- kernel/profile.c | 1 + kernel/rcu/tree.c | 24 +- kernel/rcu/tree.h | 12 +- kernel/rcu/tree_plugin.h | 32 ++- kernel/sched/Makefile | 2 +- kernel/sched/core.c | 449 ++++++++---------------------------- kernel/sched/cputime.c | 53 +++-- kernel/sched/deadline.c | 60 +++-- kernel/sched/debug.c | 415 +++++++++++++++++++++++++++++---- kernel/sched/fair.c | 297 ++++++++++++++---------- kernel/sched/rt.c | 96 +++++--- kernel/sched/sched.h | 53 ++++- kernel/sched/stats.h | 8 +- kernel/sched/swait.c | 123 ++++++++++ kernel/softirq.c | 4 +- kernel/sysctl.c | 13 +- kernel/tsacct.c | 54 +++-- virt/kvm/async_pf.c | 4 +- virt/kvm/kvm_main.c | 17 +- 37 files changed, 1300 insertions(+), 715 deletions(-) create mode 100644 include/linux/swait.h create mode 100644 kernel/sched/swait.c
Documentation/kernel-parameters.txt +5 -0
@@ -3528,6 +3528,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sched_debug [KNL] Enables verbose scheduler debug messages. + schedstats= [KNL,X86] Enable or disable scheduled statistics. + Allowed values are enable and disable. This feature + incurs a small amount of overhead in the scheduler + but is useful for debugging and performance tuning. + skew_tick= [KNL] Offset the periodic timer tick per cpu to mitigate xtime_lock contention on larger systems, and/or RCU lock contention on all systems with CONFIG_MAXSMP set.
Documentation/sysctl/kernel.txt +8 -0
@@ -760,6 +760,14 @@ rtsig-nr shows the number of RT signals currently queued. ============================================================== +sched_schedstats: + +Enables/disables scheduler statistics. Enabling this feature +incurs a small amount of overhead in the scheduler but is +useful for debugging and performance tuning. + +============================================================== + sg-big-buff: This file shows the size of the generic SCSI (sg) buffer.
arch/arm/kvm/arm.c +4 -4
@@ -506,18 +506,18 @@ static void kvm_arm_resume_guest(struct kvm *kvm)struct kvm_vcpu *vcpu;kvm_for_each_vcpu (i, vcpu, kvm) { -wait_queue_head_t *wq =kvm_arch_vcpu_wq (vcpu); +struct swait_queue_head *wq =kvm_arch_vcpu_wq (vcpu); vcpu->arch.pause = false; -wake_up_interruptible (wq); +swake_up (wq); } }static void vcpu_sleep (struct kvm_vcpu *vcpu) { -wait_queue_head_t *wq =kvm_arch_vcpu_wq (vcpu); +struct swait_queue_head *wq =kvm_arch_vcpu_wq (vcpu); -wait_event_interruptible (*wq, ((!vcpu->arch.power_off) && +swait_event_interruptible (*wq, ((!vcpu->arch.power_off) && (!vcpu->arch.pause))); }
arch/arm/kvm/psci.c +2 -2
@@ -70,7 +70,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) {struct kvm *kvm = source_vcpu->kvm;struct kvm_vcpu *vcpu =NULL ; -wait_queue_head_t *wq; +struct swait_queue_head *wq;unsigned long cpu_id;unsigned long context_id;phys_addr_t target_pc;
@@ -119,7 +119,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)smp_mb ();/* Make sure the above is visible */ wq =kvm_arch_vcpu_wq (vcpu); -wake_up_interruptible (wq); +swake_up (wq);return PSCI_RET_SUCCESS ; }
arch/mips/kvm/mips.c +4 -4
@@ -445,8 +445,8 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, dvcpu->arch.wait =0 ; -if (waitqueue_active (&dvcpu->wq)) -wake_up_interruptible (&dvcpu->wq); +if (swait_active (&dvcpu->wq)) +swake_up (&dvcpu->wq);return 0 ; }
@@ -1174,8 +1174,8 @@ static void kvm_mips_comparecount_func(unsigned long data) kvm_mips_callbacks->queue_timer_int (vcpu); vcpu->arch.wait =0 ; -if (waitqueue_active (&vcpu->wq)) -wake_up_interruptible (&vcpu->wq); +if (swait_active (&vcpu->wq)) +swake_up (&vcpu->wq); }/* low level hrtimer wake routine */
arch/powerpc/include/asm/kvm_host.h +2 -2
@@ -289,7 +289,7 @@ struct kvmppc_vcore {struct list_head runnable_threads;struct list_head preempt_list;spinlock_t lock; -wait_queue_head_t wq; +struct swait_queue_head wq;spinlock_t stoltb_lock;/* protects stolen_tb and preempt_tb */ u64 stolen_tb;u64 preempt_tb;
@@ -629,7 +629,7 @@ struct kvm_vcpu_arch {u8 prodded;u32 last_inst; -wait_queue_head_t *wqp; +struct swait_queue_head *wqp;struct kvmppc_vcore *vcore;int ret;int trap;
arch/powerpc/kvm/book3s_hv.c +11 -12
@@ -114,11 +114,11 @@ static bool kvmppc_ipi_thread(int cpu)static void kvmppc_fast_vcpu_kick_hv (struct kvm_vcpu *vcpu) {int cpu; -wait_queue_head_t *wqp; +struct swait_queue_head *wqp; wqp =kvm_arch_vcpu_wq (vcpu); -if (waitqueue_active (wqp)) { -wake_up_interruptible (wqp); +if (swait_active (wqp)) { +swake_up (wqp); ++vcpu->stat.halt_wakeup; }
@@ -701,8 +701,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) tvcpu->arch.prodded =1 ;smp_mb ();if (vcpu->arch.ceded) { -if (waitqueue_active (&vcpu->wq)) { -wake_up_interruptible (&vcpu->wq); +if (swait_active (&vcpu->wq)) { +swake_up (&vcpu->wq); vcpu->stat.halt_wakeup++; } }
@@ -1459,7 +1459,7 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core)INIT_LIST_HEAD (&vcore->runnable_threads);spin_lock_init (&vcore->lock);spin_lock_init (&vcore->stoltb_lock); -init_waitqueue_head (&vcore->wq); +init_swait_queue_head (&vcore->wq); vcore->preempt_tb =TB_NIL ; vcore->lpcr = kvm->arch.lpcr; vcore->first_vcpuid = core * threads_per_subcore;
@@ -2531,10 +2531,9 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) {struct kvm_vcpu *vcpu;int do_sleep =1 ; +DECLARE_SWAITQUEUE (wait); -DEFINE_WAIT (wait); - -prepare_to_wait (&vc->wq, &wait,TASK_INTERRUPTIBLE ); +prepare_to_swait (&vc->wq, &wait,TASK_INTERRUPTIBLE );/* * Check one last time for pending exceptions and ceded state after
@@ -2548,7 +2547,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) }if (!do_sleep) { -finish_wait (&vc->wq, &wait); +finish_swait (&vc->wq, &wait);return ; }
@@ -2556,7 +2555,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)trace_kvmppc_vcore_blocked (vc,0 );spin_unlock (&vc->lock);schedule (); -finish_wait (&vc->wq, &wait); +finish_swait (&vc->wq, &wait);spin_lock (&vc->lock); vc->vcore_state =VCORE_INACTIVE ;trace_kvmppc_vcore_blocked (vc,1 );
@@ -2612,7 +2611,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)kvmppc_start_thread (vcpu, vc);trace_kvm_guest_enter (vcpu); }else if (vc->vcore_state ==VCORE_SLEEPING ) { -wake_up (&vc->wq); +swake_up (&vc->wq); } }
arch/s390/include/asm/kvm_host.h +1 -1
@@ -467,7 +467,7 @@ struct kvm_s390_irq_payload {struct kvm_s390_local_interrupt {spinlock_t lock;struct kvm_s390_float_interrupt *float_int; -wait_queue_head_t *wq; +struct swait_queue_head *wq;atomic_t *cpuflags; DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS);struct kvm_s390_irq_payload irq;
arch/s390/kvm/interrupt.c +2 -2
@@ -966,13 +966,13 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)void kvm_s390_vcpu_wakeup (struct kvm_vcpu *vcpu) { -if (waitqueue_active (&vcpu->wq)) { +if (swait_active (&vcpu->wq)) {/* * The vcpu gave up the cpu voluntarily, mark it as a good * yield-candidate. */ vcpu->preempted = true; -wake_up_interruptible (&vcpu->wq); +swake_up (&vcpu->wq); vcpu->stat.halt_wakeup++; } }
arch/x86/kvm/lapic.c +3 -3
@@ -1195,7 +1195,7 @@ static void apic_update_lvtt(struct kvm_lapic *apic)static void apic_timer_expired (struct kvm_lapic *apic) {struct kvm_vcpu *vcpu = apic->vcpu; -wait_queue_head_t *q = &vcpu->wq; +struct swait_queue_head *q = &vcpu->wq;struct kvm_timer *ktimer = &apic->lapic_timer;if (atomic_read (&apic->lapic_timer.pending))
@@ -1204,8 +1204,8 @@ static void apic_timer_expired(struct kvm_lapic *apic)atomic_inc (&apic->lapic_timer.pending);kvm_set_pending_timer (vcpu); -if (waitqueue_active (q)) -wake_up_interruptible (q); +if (swait_active (q)) +swake_up (q);if (apic_lvtt_tscdeadline (apic)) ktimer->expired_tscdeadline = ktimer->tscdeadline;
include/linux/ftrace.h +12 -0
@@ -713,6 +713,18 @@ static inline void __ftrace_enabled_restore(int enabled)#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6)) +static inline unsigned long get_lock_parent_ip (void ) +{ +unsigned long addr =CALLER_ADDR0 ; + +if (!in_lock_functions (addr)) +return addr; + addr =CALLER_ADDR1 ; +if (!in_lock_functions (addr)) +return addr; +return CALLER_ADDR2 ; +} +#ifdef CONFIG_IRQSOFF_TRACER extern void time_hardirqs_on (unsigned long a0,unsigned long a1);extern void time_hardirqs_off (unsigned long a0,unsigned long a1);
include/linux/kvm_host.h +3 -2
@@ -25,6 +25,7 @@#include <linux/irqflags.h> #include <linux/context_tracking.h> #include <linux/irqbypass.h> +#include <linux/swait.h> #include <asm/signal.h> #include <linux/kvm.h>
@@ -218,7 +219,7 @@ struct kvm_vcpu {int fpu_active;int guest_fpu_loaded, guest_xcr0_loaded;unsigned char fpu_counter; -wait_queue_head_t wq; +struct swait_queue_head wq;struct pid *pid;int sigset_active;sigset_t sigset;
@@ -782,7 +783,7 @@ static inline bool kvm_arch_has_assigned_device(struct kvm *kvm) }#endif -static inline wait_queue_head_t *kvm_arch_vcpu_wq (struct kvm_vcpu *vcpu) +static inline struct swait_queue_head *kvm_arch_vcpu_wq (struct kvm_vcpu *vcpu) {#ifdef __KVM_HAVE_ARCH_WQPreturn vcpu->arch.wqp;
include/linux/latencytop.h +3 -0
@@ -37,6 +37,9 @@ account_scheduler_latency(struct task_struct *task, int usecs, int inter)void clear_all_latency_tracing (struct task_struct *p); +extern int sysctl_latencytop (struct ctl_table *table,int write, +void __user *buffer,size_t *lenp,loff_t *ppos); +#else static inline void
include/linux/sched.h +7 -7
@@ -182,8 +182,6 @@ extern void update_cpu_load_nohz(int active);static inline void update_cpu_load_nohz (int active) { }#endif -extern unsigned long get_parent_ip (unsigned long addr); -extern void dump_cpu_task (int cpu);struct seq_file ;
@@ -920,6 +918,10 @@ static inline int sched_info_on(void)#endif } +#ifdef CONFIG_SCHEDSTATS +void force_schedstat_enabled (void ); +#endif +enum cpu_idle_type {CPU_IDLE ,CPU_NOT_IDLE ,
@@ -1289,6 +1291,8 @@ struct sched_rt_entity {unsigned long timeout;unsigned long watchdog_stamp;unsigned int time_slice; +unsigned short on_rq; +unsigned short on_list;struct sched_rt_entity *back;#ifdef CONFIG_RT_GROUP_SCHED
@@ -1329,10 +1333,6 @@ struct sched_dl_entity {* task has to wait for a replenishment to be performed at the * next firing of dl_timer. * -* @dl_new tells if a new instance arrived. If so we must -* start executing it with full runtime and reset its absolute -* deadline; -* * @dl_boosted tells if we are boosted due to DI. If so we are * outside bandwidth enforcement mechanism (but only until we * exit the critical section);
@@ -1340,7 +1340,7 @@ struct sched_dl_entity {* @dl_yielded tells if task gave up the cpu before consuming * all its available runtime during the last job. */ -int dl_throttled, dl_new, dl_boosted, dl_yielded; +int dl_throttled, dl_boosted, dl_yielded;/* * Bandwidth enforcement timer. Each -deadline task has its
include/linux/sched/sysctl.h +4 -0
@@ -95,4 +95,8 @@ extern int sysctl_numa_balancing(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +extern int sysctl_schedstats (struct ctl_table *table,int write, +void __user *buffer,size_t *lenp, +loff_t *ppos); +#endif /* _SCHED_SYSCTL_H */
include/linux/swait.h new file +172 -0
172 lines not on this page · raw message
include/linux/wait.h +1 -1
@@ -338,7 +338,7 @@ do { \ schedule(); try_to_freeze())/** -* wait_event - sleep (or freeze) until a condition gets true +* wait_event_freezable - sleep (or freeze) until a condition gets true * @wq: the waitqueue to wait on * @condition: a C expression for the event to wait for *
kernel/latencytop.c +13 -1
@@ -47,12 +47,12 @@* of times) */ -#include <linux/latencytop.h> #include <linux/kallsyms.h> #include <linux/seq_file.h> #include <linux/notifier.h> #include <linux/spinlock.h> #include <linux/proc_fs.h> +#include <linux/latencytop.h> #include <linux/export.h> #include <linux/sched.h> #include <linux/list.h>
@@ -289,4 +289,16 @@ static int __init init_lstats_procfs(void)proc_create ("latency_stats" ,0644 ,NULL , &lstats_fops);return 0 ; } + +int sysctl_latencytop (struct ctl_table *table,int write, +void __user *buffer,size_t *lenp,loff_t *ppos) +{ +int err; + + err =proc_dointvec (table, write, buffer, lenp, ppos); +if (latencytop_enabled) +force_schedstat_enabled (); + +return err; +}device_initcall (init_lstats_procfs);
kernel/profile.c +1 -0
@@ -59,6 +59,7 @@ int profile_setup(char *str)if (!strncmp (str, sleepstr,strlen (sleepstr))) {#ifdef CONFIG_SCHEDSTATS +force_schedstat_enabled (); prof_on =SLEEP_PROFILING ;if (str[strlen (sleepstr)] ==',' ) str +=strlen (sleepstr) +1 ;
kernel/rcu/tree.c +13 -11
@@ -1614,7 +1614,6 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)int needmore;struct rcu_data *rdp =this_cpu_ptr (rsp->rda); -rcu_nocb_gp_cleanup (rsp, rnp); rnp->need_future_gp[c &0x1 ] =0 ; needmore = rnp->need_future_gp[(c +1 ) &0x1 ]; trace_rcu_future_gp(rnp, rdp, c,
@@ -1635,7 +1634,7 @@ static void rcu_gp_kthread_wake(struct rcu_state *rsp) !READ_ONCE (rsp->gp_flags) || !rsp->gp_kthread) return; -wake_up (&rsp->gp_wq); +swake_up (&rsp->gp_wq); }/*
@@ -2010,6 +2009,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)int nocb =0 ;struct rcu_data *rdp;struct rcu_node *rnp =rcu_get_root (rsp); +struct swait_queue_head *sq;WRITE_ONCE (rsp->gp_activity, jiffies);raw_spin_lock_irq_rcu_node (rnp);
@@ -2046,7 +2046,9 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) needgp =__note_gp_changes (rsp, rnp, rdp) || needgp;/* smp_mb() provided by prior unlock-lock pair. */ nocb +=rcu_future_gp_cleanup (rsp, rnp); + sq =rcu_nocb_gp_get (rnp);raw_spin_unlock_irq (&rnp->lock); +rcu_nocb_gp_cleanup (sq);cond_resched_rcu_qs ();WRITE_ONCE (rsp->gp_activity, jiffies);rcu_gp_slow (rsp, gp_cleanup_delay);
@@ -2092,7 +2094,7 @@ static int __noreturn rcu_gp_kthread(void *arg)READ_ONCE (rsp->gpnum), TPS("reqwait")); rsp->gp_state =RCU_GP_WAIT_GPS ; -wait_event_interruptible (rsp->gp_wq, +swait_event_interruptible (rsp->gp_wq,READ_ONCE (rsp->gp_flags) &RCU_GP_FLAG_INIT ); rsp->gp_state =RCU_GP_DONE_GPS ;
@@ -2122,7 +2124,7 @@ static int __noreturn rcu_gp_kthread(void *arg)READ_ONCE (rsp->gpnum), TPS("fqswait")); rsp->gp_state =RCU_GP_WAIT_FQS ; - ret =wait_event_interruptible_timeout (rsp->gp_wq, + ret =swait_event_interruptible_timeout (rsp->gp_wq,rcu_gp_fqs_check_wake (rsp, &gf), j); rsp->gp_state =RCU_GP_DOING_FQS ;/* Locking provides needed memory barriers. */
@@ -2246,7 +2248,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)WARN_ON_ONCE (!rcu_gp_in_progress (rsp));WRITE_ONCE (rsp->gp_flags,READ_ONCE (rsp->gp_flags) |RCU_GP_FLAG_FQS );raw_spin_unlock_irqrestore (&rcu_get_root (rsp)->lock, flags); -rcu_gp_kthread_wake (rsp); +swake_up (&rsp->gp_wq);/* Memory barrier implied by swake_up() path. */ }/*
@@ -2900,7 +2902,7 @@ static void force_quiescent_state(struct rcu_state *rsp) }WRITE_ONCE (rsp->gp_flags,READ_ONCE (rsp->gp_flags) |RCU_GP_FLAG_FQS );raw_spin_unlock_irqrestore (&rnp_old->lock, flags); -rcu_gp_kthread_wake (rsp); +swake_up (&rsp->gp_wq);/* Memory barrier implied by swake_up() path. */ }/*
@@ -3529,7 +3531,7 @@ static void __rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,raw_spin_unlock_irqrestore (&rnp->lock, flags);if (wake) {smp_mb ();/* EGP done before wake_up(). */ -wake_up (&rsp->expedited_wq); +swake_up (&rsp->expedited_wq); }break ; }
@@ -3780,7 +3782,7 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) jiffies_start = jiffies;for (;;) { - ret =wait_event_interruptible_timeout ( + ret =swait_event_timeout ( rsp->expedited_wq,sync_rcu_preempt_exp_done (rnp_root), jiffies_stall);
@@ -3788,7 +3790,7 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp)return ;if (ret <0 ) {/* Hit a signal, disable CPU stall warnings. */ -wait_event (rsp->expedited_wq, +swait_event (rsp->expedited_wq,sync_rcu_preempt_exp_done (rnp_root));return ; }
@@ -4482,8 +4484,8 @@ static void __init rcu_init_one(struct rcu_state *rsp) } } -init_waitqueue_head (&rsp->gp_wq); -init_waitqueue_head (&rsp->expedited_wq); +init_swait_queue_head (&rsp->gp_wq); +init_swait_queue_head (&rsp->expedited_wq); rnp = rsp->level[rcu_num_lvls -1 ];for_each_possible_cpu (i) {while (i > rnp->grphi)
kernel/rcu/tree.h +7 -5
@@ -27,6 +27,7 @@#include <linux/threads.h> #include <linux/cpumask.h> #include <linux/seqlock.h> +#include <linux/swait.h> #include <linux/stop_machine.h> /*
@@ -243,7 +244,7 @@ struct rcu_node {/* Refused to boost: not sure why, though. */ /* This can happen due to race conditions. */ #ifdef CONFIG_RCU_NOCB_CPU -wait_queue_head_t nocb_gp_wq[2 ]; +struct swait_queue_head nocb_gp_wq[2 ];/* Place for rcu_nocb_kthread() to wait GP. */ #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ int need_future_gp[2 ];
@@ -399,7 +400,7 @@ struct rcu_data {atomic_long_t nocb_q_count_lazy;/* invocation (all stages). */ struct rcu_head *nocb_follower_head;/* CBs ready to invoke. */ struct rcu_head **nocb_follower_tail; -wait_queue_head_t nocb_wq;/* For nocb kthreads to sleep on. */ +struct swait_queue_head nocb_wq;/* For nocb kthreads to sleep on. */ struct task_struct *nocb_kthread;int nocb_defer_wakeup;/* Defer wakeup of nocb_kthread. */
@@ -478,7 +479,7 @@ struct rcu_state {unsigned long gpnum;/* Current gp number. */ unsigned long completed;/* # of last completed gp. */ struct task_struct *gp_kthread;/* Task for grace periods. */ -wait_queue_head_t gp_wq;/* Where GP task waits. */ +struct swait_queue_head gp_wq;/* Where GP task waits. */ short gp_flags;/* Commands for GP task. */ short gp_state;/* GP kthread sleep state. */
@@ -506,7 +507,7 @@ struct rcu_state {unsigned long expedited_sequence;/* Take a ticket. */ atomic_long_t expedited_normal;/* # fallbacks to normal. */ atomic_t expedited_need_qs;/* # CPUs left to check in. */ -wait_queue_head_t expedited_wq;/* Wait for check-ins. */ +struct swait_queue_head expedited_wq;/* Wait for check-ins. */ int ncpus_snap;/* # CPUs seen last time. */ unsigned long jiffies_force_qs;/* Time at which to invoke */
@@ -621,7 +622,8 @@ static void zero_cpu_stall_ticks(struct rcu_data *rdp);static void increment_cpu_stall_ticks (void );static bool rcu_nocb_cpu_needs_barrier (struct rcu_state *rsp,int cpu);static void rcu_nocb_gp_set (struct rcu_node *rnp,int nrq); -static void rcu_nocb_gp_cleanup (struct rcu_state *rsp,struct rcu_node *rnp); +static struct swait_queue_head *rcu_nocb_gp_get (struct rcu_node *rnp); +static void rcu_nocb_gp_cleanup (struct swait_queue_head *sq);static void rcu_init_one_nocb (struct rcu_node *rnp);static bool __call_rcu_nocb (struct rcu_data *rdp,struct rcu_head *rhp,bool lazy,unsigned long flags);
kernel/rcu/tree_plugin.h +21 -11
@@ -1811,9 +1811,9 @@ early_param("rcu_nocb_poll", parse_rcu_nocb_poll);* Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended * grace period. */ -static void rcu_nocb_gp_cleanup (struct rcu_state *rsp,struct rcu_node *rnp) +static void rcu_nocb_gp_cleanup (struct swait_queue_head *sq) { -wake_up_all (&rnp->nocb_gp_wq[rnp->completed &0x1 ]); +swake_up_all (sq); }/*
@@ -1829,10 +1829,15 @@ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq) rnp->need_future_gp[(rnp->completed +1 ) &0x1 ] += nrq; } +static struct swait_queue_head *rcu_nocb_gp_get (struct rcu_node *rnp) +{ +return &rnp->nocb_gp_wq[rnp->completed &0x1 ]; +} +static void rcu_init_one_nocb (struct rcu_node *rnp) { -init_waitqueue_head (&rnp->nocb_gp_wq[0 ]); -init_waitqueue_head (&rnp->nocb_gp_wq[1 ]); +init_swait_queue_head (&rnp->nocb_gp_wq[0 ]); +init_swait_queue_head (&rnp->nocb_gp_wq[1 ]); }#ifndef CONFIG_RCU_NOCB_CPU_ALL
@@ -1857,7 +1862,7 @@ static void wake_nocb_leader(struct rcu_data *rdp, bool force)if (READ_ONCE (rdp_leader->nocb_leader_sleep) || force) {/* Prior smp_mb__after_atomic() orders against prior enqueue. */ WRITE_ONCE (rdp_leader->nocb_leader_sleep, false); -wake_up (&rdp_leader->nocb_wq); +swake_up (&rdp_leader->nocb_wq); } }
@@ -2069,7 +2074,7 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp)*/ trace_rcu_future_gp (rnp, rdp, c,TPS ("StartWait" ));for (;;) { -wait_event_interruptible ( +swait_event_interruptible ( rnp->nocb_gp_wq[c &0x1 ], (d =ULONG_CMP_GE (READ_ONCE (rnp->completed), c)));if (likely (d))
@@ -2097,7 +2102,7 @@ static void nocb_leader_wait(struct rcu_data *my_rdp)/* Wait for callbacks to appear. */ if (!rcu_nocb_poll) {trace_rcu_nocb_wake (my_rdp->rsp->name, my_rdp->cpu,"Sleep" ); -wait_event_interruptible (my_rdp->nocb_wq, +swait_event_interruptible (my_rdp->nocb_wq, !READ_ONCE (my_rdp->nocb_leader_sleep));/* Memory barrier handled by smp_mb() calls below and repoll. */ }else if (firsttime) {
@@ -2172,7 +2177,7 @@ static void nocb_leader_wait(struct rcu_data *my_rdp)* List was empty, wake up the follower. * Memory barriers supplied by atomic_long_add(). */ -wake_up (&rdp->nocb_wq); +swake_up (&rdp->nocb_wq); } }
@@ -2193,7 +2198,7 @@ static void nocb_follower_wait(struct rcu_data *rdp)if (!rcu_nocb_poll) {trace_rcu_nocb_wake (rdp->rsp->name, rdp->cpu,"FollowerSleep" ); -wait_event_interruptible (rdp->nocb_wq, +swait_event_interruptible (rdp->nocb_wq,READ_ONCE (rdp->nocb_follower_head)); }else if (firsttime) {/* Don't drown trace log with "Poll"! */
@@ -2352,7 +2357,7 @@ void __init rcu_init_nohz(void)static void __init rcu_boot_init_nocb_percpu_data (struct rcu_data *rdp) { rdp->nocb_tail = &rdp->nocb_head; -init_waitqueue_head (&rdp->nocb_wq); +init_swait_queue_head (&rdp->nocb_wq); rdp->nocb_follower_tail = &rdp->nocb_follower_head; }
@@ -2502,7 +2507,7 @@ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu)return false; } -static void rcu_nocb_gp_cleanup (struct rcu_state *rsp,struct rcu_node *rnp) +static void rcu_nocb_gp_cleanup (struct swait_queue_head *sq) { }
@@ -2510,6 +2515,11 @@ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq) { } +static struct swait_queue_head *rcu_nocb_gp_get (struct rcu_node *rnp) +{ +return NULL ; +} +static void rcu_init_one_nocb (struct rcu_node *rnp) { }
kernel/sched/Makefile +1 -1
@@ -13,7 +13,7 @@ endif obj-y += core.o loadavg.o clock.o cputime.o obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o -obj-y += wait.o completion.o idle.o +obj-y += wait.o swait.o completion.o idle.o obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o
kernel/sched/core.c +100 -349
622 lines not on this page · raw message
kernel/sched/cputime.c +30 -23
127 lines not on this page · raw message
kernel/sched/deadline.c +27 -33
133 lines not on this page · raw message
kernel/sched/debug.c +367 -48
468 lines not on this page · raw message
kernel/sched/fair.c +181 -116
542 lines not on this page · raw message
kernel/sched/rt.c +69 -27
190 lines not on this page · raw message
kernel/sched/sched.h +44 -9
92 lines not on this page · raw message
kernel/sched/stats.h +5 -3
@@ -29,9 +29,10 @@ rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)if (rq) rq->rq_sched_info.run_delay += delta; } -# define schedstat_inc (rq, field) do { (rq)->field++; } while (0) -# define schedstat_add (rq, field, amt) do { (rq)->field += (amt); } while (0) -# define schedstat_set (var, val) do { var = (val); } while (0) +# define schedstat_enabled () static_branch_unlikely(&sched_schedstats) +# define schedstat_inc (rq, field) do { if (schedstat_enabled()) { (rq)->field++; } } while (0) +# define schedstat_add (rq, field, amt) do { if (schedstat_enabled()) { (rq)->field += (amt); } } while (0) +# define schedstat_set (var, val) do { if (schedstat_enabled()) { var = (val); } } while (0)#else /* !CONFIG_SCHEDSTATS */ static inline void rq_sched_info_arrive (struct rq *rq,unsigned long long delta)
@@ -42,6 +43,7 @@ rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)static inline void rq_sched_info_depart (struct rq *rq,unsigned long long delta) {} +# define schedstat_enabled () 0# define schedstat_inc (rq, field) do { } while (0)# define schedstat_add (rq, field, amt) do { } while (0)# define schedstat_set (var, val) do { } while (0)
kernel/sched/swait.c new file +123 -0
32 lines not on this page · raw message
kernel/tsacct.c +30 -24
54 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.