[RFC 3/4] Disable scheduler tick when we are running SCHED_FIFO tasks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch is disabling the scheduler tick to go off when there is a task
with SCHED_FIFO policy running. Since these tasks are not timesliced anyway
we only care about timers, softirqs and such stuff just like when we disable
the tick during idle periods.

Signed-off-by: Jan Blunck <jblunck@xxxxxxx>
---
 kernel/sched_rt.c        |   23 +++++++++++++++++++++++
 kernel/softirq.c         |    5 +++++
 kernel/time/tick-sched.c |    7 ++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 8afb953..3879ca1 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1095,6 +1095,13 @@ static struct task_struct *pick_next_task_rt(struct rq *rq)
 	rq->post_schedule = has_pushable_tasks(rq);
 #endif
 
+	if (p) {
+		/* Disable sched_tick in post_schedule later */
+		if (unlikely(rt_task(p)) && !(p->flags & PF_KTHREAD) &&
+			(p->policy == SCHED_FIFO))
+			rq->post_schedule = 1;
+	}
+
 	return p;
 }
 
@@ -1475,11 +1482,27 @@ static void pre_schedule_rt(struct rq *rq, struct task_struct *prev)
 	/* Try to pull RT tasks here if we lower this rq's prio */
 	if (unlikely(rt_task(prev)) && rq->rt.highest_prio.curr > prev->prio)
 		pull_rt_task(rq);
+
+	/* Enable sched_tick again before we schedule */
+	if (unlikely(rt_task(prev)) && !(prev->flags & PF_KTHREAD) &&
+		(prev->policy == SCHED_FIFO)) {
+		tick_nohz_restart_sched_tick();
+
+		/* Disable tick in post_schedule if we don't switch */
+		rq->post_schedule = 1;
+	}
 }
 
 static void post_schedule_rt(struct rq *rq)
 {
 	push_rt_tasks(rq);
+
+	/* Disable tick if we are a FIFO task */
+	if (unlikely(rt_task(rq->curr)) &&
+	    unlikely(!local_softirq_pending()) &&
+	    !(rq->curr->flags & PF_KTHREAD) &&
+	    (rq->curr->policy == SCHED_FIFO))
+		tick_nohz_stop_sched_tick(1);
 }
 
 /*
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 07b4f1b..ff05f6a 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -307,6 +307,11 @@ void irq_exit(void)
 	/* Make sure that timer wheel updates are propagated */
 	if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
 		tick_nohz_stop_sched_tick(0);
+
+	/* Disable tick if the current task is FIFO */
+	if (unlikely(rt_task(current) && !(current->flags & PF_KTHREAD) &&
+			current->policy == SCHED_FIFO))
+		tick_nohz_stop_sched_tick(1);
 #endif
 	preempt_enable_no_resched();
 }
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 81b7398..567110d 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -520,9 +520,10 @@ void tick_nohz_restart_sched_tick(void)
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 	unsigned long ticks;
 #endif
+	unsigned long flags;
 	ktime_t now;
 
-	local_irq_disable();
+	local_irq_save(flags);
 	if (ts->idle_active || (ts->inidle && ts->tick_stopped))
 		now = ktime_get();
 
@@ -531,7 +532,7 @@ void tick_nohz_restart_sched_tick(void)
 
 	if (!ts->inidle || !ts->tick_stopped) {
 		ts->inidle = 0;
-		local_irq_enable();
+		local_irq_restore(flags);
 		return;
 	}
 
@@ -567,7 +568,7 @@ void tick_nohz_restart_sched_tick(void)
 
 	tick_nohz_restart(ts, now);
 
-	local_irq_enable();
+	local_irq_restore(flags);
 }
 
 static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now)
-- 
1.6.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux