Skip to contentSkip to conversation

scheduler changes for v3.10

GIT PULL Ingo Molnar 3 participants 6 messages Apr 30, 2013

Subsystems (9)
x86 Library code MM core Scheduler +5 more subsystems
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: 25f55d9d01ad7a7ad248fd5af1d22675ffd202c5 sched: Fix init NOHZ_IDLE flag

The main changes in this development cycle were:

- full dynticks preparatory work by Frederic Weisbecker

- factor out the cpu time accounting code better, by Li Zefan

- multi-CPU load balancer cleanups and improvements by Joonsoo Kim

- various smaller fixes and cleanups

Thanks,

Ingo

------------------>
Andrei Epure (3):
sched: Spelling fix
sched: Fix variable name misnomer, add comments
sched: Document task_struct::personality field

Frederic Weisbecker (7):
context_tracking: Move exception handling to generic code
context_tracking: Restore correct previous context state on exception exit
context_tracking: Restore preempted context state after preempt_schedule_irq()
cputime: Dynamically scale cputime for full dynticks accounting
context_tracking: Enable probes by default for selftesting
math64: New div64_u64_rem helper
sched: Lower chances of cputime scaling overflow

Ingo Molnar (1):
sched/cpuacct/UML: Fix header file dependency bug on the UML build

Joonsoo Kim (6):
sched: Change position of resched_cpu() in load_balance()
sched: Explicitly cpu_idle_type checking in rebalance_domains()
sched: Don't consider other cpus in our group in case of NEWLY_IDLE
sched: Move up affinity check to mitigate useless redoing overhead
sched: Rename load_balance_tmpmask to load_balance_mask
sched: Prevent to re-select dst-cpu in load_balance()

Li Zefan (22):
sched: Remove some dummy functions
sched: Remove test_sd_parent()
sched: Move SCHED_LOAD_SHIFT macros to kernel/sched/sched.h
sched: Move struct sched_group to kernel/sched/sched.h
sched: Move wake flags to kernel/sched/sched.h
sched: Move struct sched_class to kernel/sched/sched.h
sched: Make default_scale_freq_power() static
sched: Move group scheduling functions out of include/linux/sched.h
sched: Remove double declaration of root_task_group
sched: Fix update_group_power() prototype placement to fix build warning when !CONFIG_SMP
sched: Split cpuacct code out of core.c
sched: Split cpuacct code out of sched.h
sched/cpuacct: Add cpuacct_init()
sched/cpuacct: Add cpuacct_acount_field()
sched/cpuacct: Remove redundant NULL checks in cpuacct_charge() sched/cpuacct: Remove redundant NULL checks in cpuacct_acount_field() sched/cpuacct: Clean up cpuacct.h
sched/cpuacct: Allocate per_cpu cpuusage for root cpuacct statically sched/cpuacct: Initialize root cpuacct earlier
sched/cpuacct: Initialize cpuacct subsystem earlier
sched/cpuacct: No need to check subsys active state
cgroup: Kill subsys.active flag

Libin (1):
sched: Fix comment in rebalance_domains()

Peter Zijlstra (1):
sched/tracing: Allow tracing the preemption decision on wakeup

Vincent Guittot (2):
sched: Fix wrong rq's runnable_avg update with rt tasks
sched: Fix init NOHZ_IDLE flag

Viresh Kumar (1):
sched: Fix typo inside comment

Zhang Hang (1):
sched: Simplify can_migrate_task()

 arch/x86/include/asm/context_tracking.h |  21 ---
 arch/x86/kernel/kvm.c                   |   8 +-
 arch/x86/kernel/traps.c                 |  68 +++++---
 arch/x86/mm/fault.c                     |   8 +-
 include/linux/cgroup.h                  |   1 -
 include/linux/context_tracking.h        |  24 ++-
 include/linux/math64.h                  |  19 +-
 include/linux/sched.h                   | 204 +---------------------
 init/Kconfig                            |   1 +
 kernel/cgroup.c                         |   3 -
 kernel/fork.c                           |   2 +-
 kernel/sched/Makefile                   |   1 +
 kernel/sched/core.c                     | 254 ++-------------------------
 kernel/sched/cpuacct.c                  | 296 ++++++++++++++++++++++++++++++++
 kernel/sched/cpuacct.h                  |  17 ++
 kernel/sched/cputime.c                  | 214 ++++++++++++-----------
 kernel/sched/fair.c                     | 148 +++++++++-------
 kernel/sched/idle_task.c                |  16 ++
 kernel/sched/sched.h                    | 219 +++++++++++++++++------
 lib/div64.c                             |  19 +-
 20 files changed, 834 insertions(+), 709 deletions(-)
 create mode 100644 kernel/sched/cpuacct.c
 create mode 100644 kernel/sched/cpuacct.h
arch/x86/include/asm/context_tracking.h +0 -21
index 1616562..1fe4970 100644
@@ -1,31 +1,10 @@
 #ifndef _ASM_X86_CONTEXT_TRACKING_H
 #define _ASM_X86_CONTEXT_TRACKING_H
 
-#ifndef __ASSEMBLY__
-#include <linux/context_tracking.h>
-#include <asm/ptrace.h>
-
-static inline void exception_enter(struct pt_regs *regs)
-{
-	user_exit();
-}
-
-static inline void exception_exit(struct pt_regs *regs)
-{
-#ifdef CONFIG_CONTEXT_TRACKING
-	if (user_mode(regs))
-		user_enter();
-#endif
-}
-
-#else /* __ASSEMBLY__ */
-
 #ifdef CONFIG_CONTEXT_TRACKING
 # define SCHEDULE_USER call schedule_user
 #else
 # define SCHEDULE_USER call schedule
 #endif
 
-#endif /* !__ASSEMBLY__ */
-
 #endif
arch/x86/kernel/kvm.c +5 -3
index b686a90..cd6d9a5 100644
@@ -20,6 +20,7 @@
  *   Authors: Anthony Liguori <[email protected]>
  */
 
+#include <linux/context_tracking.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kvm_para.h>
@@ -43,7 +44,6 @@
 #include <asm/apicdef.h>
 #include <asm/hypervisor.h>
 #include <asm/kvm_guest.h>
-#include <asm/context_tracking.h>
 
 static int kvmapf = 1;
 
@@ -254,16 +254,18 @@ EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason);
 dotraplinkage void __kprobes
 do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
 {
+	enum ctx_state prev_state;
+
 	switch (kvm_read_and_reset_pf_reason()) {
 	default:
 		do_page_fault(regs, error_code);
 		break;
 	case KVM_PV_REASON_PAGE_NOT_PRESENT:
 		/* page is swapped out by the host. */
-		exception_enter(regs);
+		prev_state = exception_enter();
 		exit_idle();
 		kvm_async_pf_task_wait((u32)read_cr2());
-		exception_exit(regs);
+		exception_exit(prev_state);
 		break;
 	case KVM_PV_REASON_PAGE_READY:
 		rcu_irq_enter();
arch/x86/kernel/traps.c +42 -26

216 lines not on this page · raw message

arch/x86/mm/fault.c +5 -3
index 2b97525..fa8c02d 100644
@@ -13,12 +13,12 @@
 #include <linux/perf_event.h>		/* perf_sw_event		*/
 #include <linux/hugetlb.h>		/* hstate_index_to_shift	*/
 #include <linux/prefetch.h>		/* prefetchw			*/
+#include <linux/context_tracking.h>	/* exception_enter(), ...	*/
 
 #include <asm/traps.h>			/* dotraplinkage, ...		*/
 #include <asm/pgalloc.h>		/* pgd_*(), ...			*/
 #include <asm/kmemcheck.h>		/* kmemcheck_*(), ...		*/
 #include <asm/fixmap.h>			/* VSYSCALL_START		*/
-#include <asm/context_tracking.h>	/* exception_enter(), ...	*/
 
 /*
  * Page fault error code bits:
@@ -1222,7 +1222,9 @@ good_area:
 dotraplinkage void __kprobes
 do_page_fault(struct pt_regs *regs, unsigned long error_code)
 {
-	exception_enter(regs);
+	enum ctx_state prev_state;
+
+	prev_state = exception_enter();
 	__do_page_fault(regs, error_code);
-	exception_exit(regs);
+	exception_exit(prev_state);
 }
include/linux/cgroup.h +0 -1
index 900af59..95c02c0 100644
@@ -458,7 +458,6 @@ struct cgroup_subsys {
 	void (*bind)(struct cgroup *root);
 
 	int subsys_id;
-	int active;
 	int disabled;
 	int early_init;
 	/*
include/linux/context_tracking.h +22 -2
index b28d161..365f4a6 100644
@@ -1,9 +1,9 @@
 #ifndef _LINUX_CONTEXT_TRACKING_H
 #define _LINUX_CONTEXT_TRACKING_H
 
-#ifdef CONFIG_CONTEXT_TRACKING
 #include <linux/sched.h>
 #include <linux/percpu.h>
+#include <asm/ptrace.h>
 
 struct context_tracking {
 	/*
@@ -13,12 +13,13 @@ struct context_tracking {
 	 * may be further optimized using static keys.
 	 */
 	bool active;
-	enum {
+	enum ctx_state {
 		IN_KERNEL = 0,
 		IN_USER,
 	} state;
 };
 
+#ifdef CONFIG_CONTEXT_TRACKING
 DECLARE_PER_CPU(struct context_tracking, context_tracking);
 
 static inline bool context_tracking_in_user(void)
@@ -33,12 +34,31 @@ static inline bool context_tracking_active(void)
 
 extern void user_enter(void);
 extern void user_exit(void);
+
+static inline enum ctx_state exception_enter(void)
+{
+	enum ctx_state prev_ctx;
+
+	prev_ctx = this_cpu_read(context_tracking.state);
+	user_exit();
+
+	return prev_ctx;
+}
+
+static inline void exception_exit(enum ctx_state prev_ctx)
+{
+	if (prev_ctx == IN_USER)
+		user_enter();
+}
+
 extern void context_tracking_task_switch(struct task_struct *prev,
 					 struct task_struct *next);
 #else
 static inline bool context_tracking_in_user(void) { return false; }
 static inline void user_enter(void) { }
 static inline void user_exit(void) { }
+static inline enum ctx_state exception_enter(void) { return 0; }
+static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline void context_tracking_task_switch(struct task_struct *prev,
 						struct task_struct *next) { }
 #endif /* !CONFIG_CONTEXT_TRACKING */
include/linux/math64.h +18 -1
index b8ba855..931a619 100644
@@ -30,6 +30,15 @@ static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
 }
 
 /**
+ * div64_u64_rem - unsigned 64bit divide with 64bit divisor
+ */
+static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
+{
+	*remainder = dividend % divisor;
+	return dividend / divisor;
+}
+
+/**
  * div64_u64 - unsigned 64bit divide with 64bit divisor
  */
 static inline u64 div64_u64(u64 dividend, u64 divisor)
@@ -61,8 +70,16 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
 #endif
 
+#ifndef div64_u64_rem
+extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder);
+#endif
+
 #ifndef div64_u64
-extern u64 div64_u64(u64 dividend, u64 divisor);
+static inline u64 div64_u64(u64 dividend, u64 divisor)
+{
+	u64 remainder;
+	return div64_u64_rem(dividend, divisor, &remainder);
+}
 #endif
 
 #ifndef div64_s64
include/linux/sched.h +9 -195

272 lines not on this page · raw message

init/Kconfig +1 -0
index 22616cd..8a1dac2 100644
@@ -509,6 +509,7 @@ config RCU_USER_QS
 config CONTEXT_TRACKING_FORCE
 	bool "Force context tracking"
 	depends on CONTEXT_TRACKING
+	default CONTEXT_TRACKING
 	help
 	  Probe on user/kernel boundaries by default in order to
 	  test the features that rely on it such as userspace RCU extended
kernel/cgroup.c +0 -3
index a32f943..5c46281 100644
@@ -4468,7 +4468,6 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
 	 * need to invoke fork callbacks here. */
 	BUG_ON(!list_empty(&init_task.tasks));
 
-	ss->active = 1;
 	BUG_ON(online_css(ss, dummytop));
 
 	mutex_unlock(&cgroup_mutex);
@@ -4573,7 +4572,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 	}
 	write_unlock(&css_set_lock);
 
-	ss->active = 1;
 	ret = online_css(ss, dummytop);
 	if (ret)
 		goto err_unload;
@@ -4614,7 +4612,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 	mutex_lock(&cgroup_mutex);
 
 	offline_css(ss, dummytop);
-	ss->active = 0;
 
 	if (ss->use_id)
 		idr_destroy(&ss->idr);
kernel/fork.c +1 -1
index 8d932b1..f3146ed 100644
@@ -1230,7 +1230,7 @@ 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
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 	p->prev_cputime.utime = p->prev_cputime.stime = 0;
 #endif
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
kernel/sched/Makefile +1 -0
index f06d249..deaf90e 100644
@@ -16,3 +16,4 @@ obj-$(CONFIG_SMP) += cpupri.o
 obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
 obj-$(CONFIG_SCHEDSTATS) += stats.o
 obj-$(CONFIG_SCHED_DEBUG) += debug.o
+obj-$(CONFIG_CGROUP_CPUACCT) += cpuacct.o
kernel/sched/core.c +18 -236

341 lines not on this page · raw message

kernel/sched/cpuacct.c new file +296 -0

296 lines not on this page · raw message

kernel/sched/cpuacct.h new file +17 -0
new file mode 100644
index 0000000..ed60562
@@ -0,0 +1,17 @@
+#ifdef CONFIG_CGROUP_CPUACCT
+
+extern void cpuacct_charge(struct task_struct *tsk, u64 cputime);
+extern void cpuacct_account_field(struct task_struct *p, int index, u64 val);
+
+#else
+
+static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime)
+{
+}
+
+static inline void
+cpuacct_account_field(struct task_struct *p, int index, u64 val)
+{
+}
+
+#endif
kernel/sched/cputime.c +113 -101

268 lines not on this page · raw message

kernel/sched/fair.c +90 -58

327 lines not on this page · raw message

kernel/sched/idle_task.c +16 -0
index b6baf37..b8ce773 100644
@@ -13,6 +13,16 @@ select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
 {
 	return task_cpu(p); /* IDLE tasks as never migrated */
 }
+
+static void pre_schedule_idle(struct rq *rq, struct task_struct *prev)
+{
+	idle_exit_fair(rq);
+}
+
+static void post_schedule_idle(struct rq *rq)
+{
+	idle_enter_fair(rq);
+}
 #endif /* CONFIG_SMP */
 /*
  * Idle tasks are unconditionally rescheduled:
@@ -25,6 +35,10 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl
 static struct task_struct *pick_next_task_idle(struct rq *rq)
 {
 	schedstat_inc(rq, sched_goidle);
+#ifdef CONFIG_SMP
+	/* Trigger the post schedule to do an idle_enter for CFS */
+	rq->post_schedule = 1;
+#endif
 	return rq->idle;
 }
 
@@ -86,6 +100,8 @@ const struct sched_class idle_sched_class = {
 
 #ifdef CONFIG_SMP
 	.select_task_rq		= select_task_rq_idle,
+	.pre_schedule		= pre_schedule_idle,
+	.post_schedule		= post_schedule_idle,
 #endif
 
 	.set_curr_task          = set_curr_task_idle,
kernel/sched/sched.h +167 -52

290 lines not on this page · raw message

lib/div64.c +13 -6
index a163b6c..3af5728 100644
@@ -79,9 +79,10 @@ EXPORT_SYMBOL(div_s64_rem);
 #endif
 
 /**
- * div64_u64 - unsigned 64bit divide with 64bit divisor
+ * div64_u64_rem - unsigned 64bit divide with 64bit divisor and 64bit remainder
  * @dividend:	64bit dividend
  * @divisor:	64bit divisor
+ * @remainder:  64bit remainder
  *
  * This implementation is a modified version of the algorithm proposed
  * by the book 'Hacker's Delight'.  The original source and full proof
@@ -89,27 +90,33 @@ EXPORT_SYMBOL(div_s64_rem);
  *
  * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt'
  */
-#ifndef div64_u64
-u64 div64_u64(u64 dividend, u64 divisor)
+#ifndef div64_u64_rem
+u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
 {
 	u32 high = divisor >> 32;
 	u64 quot;
 
 	if (high == 0) {
-		quot = div_u64(dividend, divisor);
+		u32 rem32;
+		quot = div_u64_rem(dividend, divisor, &rem32);
+		*remainder = rem32;
 	} else {
 		int n = 1 + fls(high);
 		quot = div_u64(dividend >> n, divisor >> n);
 
 		if (quot != 0)
 			quot--;
-		if ((dividend - quot * divisor) >= divisor)
+
+		*remainder = dividend - quot * divisor;
+		if (*remainder >= divisor) {
 			quot++;
+			*remainder -= divisor;
+		}
 	}
 
 	return quot;
 }
-EXPORT_SYMBOL(div64_u64);
+EXPORT_SYMBOL(div64_u64_rem);
 #endif
 
 /**
#1 lore raw
Quoted 6 lines · Ingo Molnar

Please pull the latest sched-core-for-linus git tree from:

The main changes in this development cycle were:

- full dynticks preparatory work by Frederic Weisbecker

Why does this have the crappy cputime scaling overflow code, when we had a long thread about how to do it right *without* any 64-bit divides, including a quality-tested patch?

This still has the garbage "div64_u64_rem()" crap which actually SLOWS DOWN 32-bit code even when not used (becuse it makes "div64_u64()" calculate it even when unnecessary.

WTF happened here? I and others spent efforts so that we wouldn't need this kind of crap.

Linus

#2 lore raw
Quoted 12 lines · Linus Torvalds
Quoted 6 lines · Ingo Molnar

Please pull the latest sched-core-for-linus git tree from:

The main changes in this development cycle were:

- full dynticks preparatory work by Frederic Weisbecker

Why does this have the crappy cputime scaling overflow code, when we had a long thread about how to do it right *without* any 64-bit divides, including a quality-tested patch?

Quoted 6 lines

This still has the garbage "div64_u64_rem()" crap which actually SLOWS DOWN 32-bit code even when not used (becuse it makes "div64_u64()" calculate it even when unnecessary.

WTF happened here? I and others spent efforts so that we wouldn't need this kind of crap.

I'm sorry, I was on vacations and has some other work to do, so I didn't send patches in timely manner. I just posted them today.

Stanislaw

#3 lore raw
Quoted 17 lines · Stanislaw Gruszka
Quoted 16 lines · Linus Torvalds
Quoted 6 lines · Ingo Molnar

Please pull the latest sched-core-for-linus git tree from:

The main changes in this development cycle were:

- full dynticks preparatory work by Frederic Weisbecker

Why does this have the crappy cputime scaling overflow code, when we had a long thread about how to do it right *without* any 64-bit divides, including a quality-tested patch?

This still has the garbage "div64_u64_rem()" crap which actually SLOWS DOWN 32-bit code even when not used (becuse it makes "div64_u64()" calculate it even when unnecessary.

Quoted 5 lines
Quoted 2 lines

WTF happened here? I and others spent efforts so that we wouldn't need this kind of crap.

I'm sorry, I was on vacations and has some other work to do, so I didn't send patches in timely manner. I just posted them today.

Linus, would you like me to revert d9a3c9823a2e and re-send the pull request?

I intended to queue up Stanislaw's fixes in sched/urgent as the real solution, but they arrived earlier today and are too fresh.

Thanks,

Ingo

#4 lore raw
Quoted 3 lines · Ingo Molnar

Linus, would you like me to revert d9a3c9823a2e and re-send the pull request?

I took the pull request, but I'd like to see the non-64-bit divide version before the merge window ends. And with no more div_rem users I think we should at least double-check that the new div64_u64() (that uses the new div64_u64_rem) isn't noticeably slower than the old one. If it is, we should revert that new (and then unused) div64 code too.

Linus

#5 lore raw
Quoted 7 lines · Linus Torvalds
Quoted 3 lines · Ingo Molnar

Linus, would you like me to revert d9a3c9823a2e and re-send the pull request?

I took the pull request, but I'd like to see the non-64-bit divide version before the merge window ends. [...]

Yeah, wanted to apply it later today or tomorrow, and push it to you this week - well before the end of the merge window.

Quoted 4 lines

[...] And with no more div_rem users I think we should at least double-check that the new div64_u64() (that uses the new div64_u64_rem) isn't noticeably slower than the old one. If it is, we should revert that new (and then unused) div64 code too.

Correct, this is what Stanislaw's series from earlier today does:

[PATCH -tip 1/4] sched: Avoid cputime scaling overflow [PATCH -tip 2/4] sched: Do not account bogus utime [PATCH -tip 3/4] sched: Avoid prev->stime underflow [PATCH -tip 4/4] Revert "math64: New div64_u64_rem helper"

so it gets rid of the div64_u64_rem() bits as well.

Thanks,

Ingo