Thread (7 messages) 7 messages, 1 author, 2015-05-20
DORMANTno replies

[PATCH RT] rt, nohz_full: fix nohz_full for PREEMPT_RT_FULL

From: Steven Rostedt <rostedt@goodmis.org>
Date: 2015-05-20 02:58:55
Also in: lkml
Subsystem: nohz, dynticks support, scheduler, the rest · Maintainers: Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar, Thomas Gleixner, Peter Zijlstra, Juri Lelli, Vincent Guittot, Linus Torvalds

I'm adding this to the next 3.12-rt release.

-- Steve

From 239f9f7716c6a2b466fcbb605fa0102de483c116 Mon Sep 17 00:00:00 2001
From: Mike Galbraith <redacted>
Date: Sat, 11 Apr 2015 15:15:59 +0200
Subject: [PATCH] rt, nohz_full: fix nohz_full for PREEMPT_RT_FULL

A task being ticked and trying to shut the tick down will fail due
to having just awakened ksoftirqd, subtract it from nr_running.

Signed-off-by: Mike Galbraith <redacted>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/sched/core.c      | 29 +++++++++++++++++++++++------
 kernel/time/tick-sched.c |  5 +++++
 2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index af7418b7d212..76873807655a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -696,17 +696,34 @@ static inline bool got_nohz_idle_kick(void)
 #endif /* CONFIG_NO_HZ_COMMON */
 
 #ifdef CONFIG_NO_HZ_FULL
+
+static int ksoftirqd_running(void)
+{
+	struct task_struct *softirqd;
+
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL))
+		return 0;
+	softirqd = this_cpu_ksoftirqd();
+	if (softirqd && softirqd->on_rq)
+		return 1;
+	return 0;
+}
+
 bool sched_can_stop_tick(void)
 {
-       struct rq *rq;
+	struct rq *rq;
 
-       rq = this_rq();
+	rq = this_rq();
 
-       /* Make sure rq->nr_running update is visible after the IPI */
-       smp_rmb();
+	/* Make sure rq->nr_running update is visible after the IPI */
+	smp_rmb();
 
-       /* More than one running task need preemption */
-       if (rq->nr_running > 1)
+	/*
+	 * More than one running task need preemption
+	 *
+	 * NOTE, RT: if ksoftirqd is awake, subtract it.
+	 */
+	if (rq->nr_running - ksoftirqd_running() > 1)
                return false;
 
        return true;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 2cfd4c740042..3238cfbfbeeb 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -221,7 +221,12 @@ void __tick_nohz_full_check(void)
 
 static void nohz_full_kick_work_func(struct irq_work *work)
 {
+	unsigned long flags;
+
+	/* ksoftirqd processes sirqs with interrupts enabled */
+	local_irq_save(flags);
 	__tick_nohz_full_check();
+	local_irq_restore(flags);
 }
 
 static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
-- 
2.1.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help