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 <umgwanakikbuti@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
Mike Galbraith 2015-04-11 15:15:59 +02:00 committed by Alibek Omarov
parent 8b45f30e76
commit f52d7ef05a
2 changed files with 28 additions and 6 deletions

View File

@ -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;

View File

@ -226,7 +226,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) = {