Skip to contentSkip to conversation

scheduler changes for v3.6

GIT PULL Ingo Molnar 1 participant 1 message Jul 25, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
index 6ab6aa2..c598126 100644
@@ -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
index 668f66b..838320f 100644
@@ -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
index 9e65eff..b806b82 100644
@@ -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
index 4a1f493..fd9436a 100644
@@ -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
index 55844f2..c35a1a7 100644
@@ -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 */