aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-04-20 09:15:35 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-04-22 14:08:04 -0400
commitce831b38ca4920739a7a5b0c73b921da41f03718 (patch)
tree492802655004af21c748daaf08f55e14068ceb13
parent9f3660c2c1a221c886474587103c69f6034d3e4f (diff)
sched: New helper to prevent from stopping the tick in full dynticks
Provide a new helper to be called from the full dynticks engine before stopping the tick in order to make sure we don't stop it when there is more than one task running on the CPU. This way we make sure that the tick stays alive to maintain fairness. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Chris Metcalf <cmetcalf@tilera.com> Cc: Christoph Lameter <cl@linux.com> Cc: Geoff Levand <geoff@infradead.org> Cc: Gilad Ben Yossef <gilad@benyossef.com> Cc: Hakan Akkan <hakanakkan@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Kevin Hilman <khilman@linaro.org> Cc: Li Zhong <zhong@linux.vnet.ibm.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/sched.h6
-rw-r--r--kernel/sched/core.c18
2 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1ff9e0a5de27..a74adedcdd10 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1856,6 +1856,12 @@ extern void wake_up_nohz_cpu(int cpu);
1856static inline void wake_up_nohz_cpu(int cpu) { } 1856static inline void wake_up_nohz_cpu(int cpu) { }
1857#endif 1857#endif
1858 1858
1859#ifdef CONFIG_NO_HZ_FULL
1860extern bool sched_can_stop_tick(void);
1861#else
1862static inline bool sched_can_stop_tick(void) { return false; }
1863#endif
1864
1859#ifdef CONFIG_SCHED_AUTOGROUP 1865#ifdef CONFIG_SCHED_AUTOGROUP
1860extern void sched_autogroup_create_attach(struct task_struct *p); 1866extern void sched_autogroup_create_attach(struct task_struct *p);
1861extern void sched_autogroup_detach(struct task_struct *p); 1867extern void sched_autogroup_detach(struct task_struct *p);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 0f0a5b3fd62c..69f71335984f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -650,6 +650,24 @@ static inline bool got_nohz_idle_kick(void)
650 650
651#endif /* CONFIG_NO_HZ_COMMON */ 651#endif /* CONFIG_NO_HZ_COMMON */
652 652
653#ifdef CONFIG_NO_HZ_FULL
654bool sched_can_stop_tick(void)
655{
656 struct rq *rq;
657
658 rq = this_rq();
659
660 /* Make sure rq->nr_running update is visible after the IPI */
661 smp_rmb();
662
663 /* More than one running task need preemption */
664 if (rq->nr_running > 1)
665 return false;
666
667 return true;
668}
669#endif /* CONFIG_NO_HZ_FULL */
670
653void sched_avg_update(struct rq *rq) 671void sched_avg_update(struct rq *rq)
654{ 672{
655 s64 period = sched_avg_period(); 673 s64 period = sched_avg_period();