scheduler changes for v3.6
Subsystems (3)
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: 8323f26ce3425460769605a6aece7a174edaa7d1 sched: Fix race in task_group()
The biggest change is a performance improvement on SMP systems:
| 4 socket 40 core + SMT Westmere box, single 30 sec tbench | runs, higher is better: | | clients 1 2 4 8 16 32 64 128 |.......................................................................... | pre 30 41 118 645 3769 6214 12233 14312 | post 299 603 1211 2418 4697 6847 11606 14557 | | A nice increase in performance.
which speedup is particularly noticeable on heavily interacting few-tasks workloads, so the changes should help desktop-style Xorg workloads and interactivity as well, on multi-core CPUs.
There are also cpuset suspend behavior fixes/restructuring and various smaller tweaks.
( I had to rebase the pending scheduler tree recently, as the
work in progress NUMA scheduling changes from Peter Zijlstra were still too raw for v3.6. This was hopefully a rare, one-off event. )
Thanks,
Ingo
------------------>
Mike Galbraith (1):
sched: Improve scalability via 'CPU buddies', which withstand random perturbations
Peter Zijlstra (2):
sched/x86: Remove broken power estimation
sched: Fix race in task_group()
Prashanth Nageshappa (2):
sched: Reorder 'struct lb_env' members to reduce its size
sched: Reset loop counters if all tasks are pinned and we need to redo load balance
Srivatsa S. Bhat (4):
CPU hotplug, cpusets, suspend: Don't modify cpusets during suspend/resume cpusets, hotplug: Implement cpuset tree traversal in a helper function cpusets, hotplug: Restructure functions that are invoked during hotplug
cpusets: Remove/update outdated comments
Srivatsa Vaddagiri (1):
sched: Improve balance_cpu() to consider other cpus in its group as target of (pinned) task
arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/sched.c | 55 ------------------ include/linux/cpuset.h | 4 +- include/linux/init_task.h | 12 +++- include/linux/sched.h | 6 +- kernel/cpuset.c | 130 ++++++++++++++++++++++++++++++------------ kernel/sched/core.c | 92 +++++++++++++++++++++++++++--- kernel/sched/fair.c | 113 +++++++++++++++++++++++++++--------- kernel/sched/sched.h | 23 ++++---- 9 files changed, 291 insertions(+), 146 deletions(-) delete mode 100644 arch/x86/kernel/cpu/sched.c
arch/x86/kernel/cpu/Makefile +1 -1
@@ -14,7 +14,7 @@ CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o -obj-y += vmware.o hypervisor.o sched.o mshyperv.o +obj-y += vmware.o hypervisor.o mshyperv.o obj-y += rdrand.o obj-y += match.o
arch/x86/kernel/cpu/sched.c deleted +0 -55
55 lines not on this page · raw message
include/linux/cpuset.h +2 -2
@@ -20,7 +20,7 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */extern int cpuset_init (void );extern void cpuset_init_smp (void ); -extern void cpuset_update_active_cpus (void ); +extern void cpuset_update_active_cpus (bool cpu_online);extern void cpuset_cpus_allowed (struct task_struct *p,struct cpumask *mask);extern void cpuset_cpus_allowed_fallback (struct task_struct *p);extern nodemask_t cpuset_mems_allowed (struct task_struct *p);
@@ -124,7 +124,7 @@ static inline void set_mems_allowed(nodemask_t nodemask)static inline int cpuset_init (void ) {return 0 ; }static inline void cpuset_init_smp (void ) {} -static inline void cpuset_update_active_cpus (void ) +static inline void cpuset_update_active_cpus (bool cpu_online) {partition_sched_domains (1 ,NULL ,NULL ); }
include/linux/init_task.h +11 -1
@@ -123,8 +123,17 @@ extern struct group_info init_groups;extern struct cred init_cred; +extern struct task_group root_task_group; + +#ifdef CONFIG_CGROUP_SCHED +# define INIT_CGROUP_SCHED (tsk) \ + .sched_task_group = &root_task_group, +#else +# define INIT_CGROUP_SCHED (tsk) +#endif +#ifdef CONFIG_PERF_EVENTS -# define INIT_PERF_EVENTS (tsk) \ +# define INIT_PERF_EVENTS (tsk) \ .perf_event_mutex = \ __MUTEX_INITIALIZER(tsk.perf_event_mutex), \ .perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list),
@@ -161,6 +170,7 @@ extern struct cred init_cred; }, \ .tasks = LIST_HEAD_INIT(tsk.tasks), \ INIT_PUSHABLE_TASKS(tsk) \ +INIT_CGROUP_SCHED (tsk) \ .ptraced = LIST_HEAD_INIT(tsk.ptraced), \ .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \ .real_parent = &tsk, \
include/linux/sched.h +5 -1
@@ -949,6 +949,7 @@ struct sched_domain {unsigned int smt_gain;int flags;/* See SD_* */ int level; +int idle_buddy;/* cpu assigned to select_idle_sibling() */ /* Runtime fields. */ unsigned long last_balance;/* init to jiffies. units in jiffies */
@@ -1244,6 +1245,9 @@ struct task_struct {const struct sched_class *sched_class;struct sched_entity se;struct sched_rt_entity rt; +#ifdef CONFIG_CGROUP_SCHED +struct task_group *sched_task_group; +#endif #ifdef CONFIG_PREEMPT_NOTIFIERS /* list of struct preempt_notifier: */
@@ -2723,7 +2727,7 @@ extern int sched_group_set_rt_period(struct task_group *tg,extern long sched_group_rt_period (struct task_group *tg);extern int sched_rt_can_attach (struct task_group *tg,struct task_struct *tsk);#endif -#endif +#endif /* CONFIG_CGROUP_SCHED */ extern int task_can_switch_user (struct user_struct *up,struct task_struct *tsk);
kernel/cpuset.c +92 -38
192 lines not on this page · raw message
kernel/sched/core.c +84 -8
151 lines not on this page · raw message
kernel/sched/fair.c +86 -27
193 lines not on this page · raw message
kernel/sched/sched.h +10 -13
@@ -538,22 +538,19 @@ extern int group_balance_cpu(struct sched_group *sg);/* * Return the group to which this tasks belongs. * -* We use task_subsys_state_check() and extend the RCU verification with -* pi->lock and rq->lock because cpu_cgroup_attach() holds those locks for each -* task it moves into the cgroup. Therefore by holding either of those locks, -* we pin the task to the current cgroup. +* We cannot use task_subsys_state() and friends because the cgroup +* subsystem changes that value before the cgroup_subsys::attach() method +* is called, therefore we cannot pin it and might observe the wrong value. +* +* The same is true for autogroup's p->signal->autogroup->tg, the autogroup +* core changes this before calling sched_move_task(). +* +* Instead we use a 'copy' which is updated from sched_move_task() while +* holding both task_struct::pi_lock and rq::lock. */ static inline struct task_group *task_group (struct task_struct *p) { -struct task_group *tg; -struct cgroup_subsys_state *css; - - css =task_subsys_state_check (p, cpu_cgroup_subsys_id, -lockdep_is_held (&p->pi_lock) || -lockdep_is_held (&task_rq (p)->lock)); - tg = container_of(css, struct task_group, css); - -return autogroup_task_group (p, tg); +return p->sched_task_group; }/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */