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:
parent
8b45f30e76
commit
f52d7ef05a
|
@ -696,17 +696,34 @@ static inline bool got_nohz_idle_kick(void)
|
||||||
#endif /* CONFIG_NO_HZ_COMMON */
|
#endif /* CONFIG_NO_HZ_COMMON */
|
||||||
|
|
||||||
#ifdef CONFIG_NO_HZ_FULL
|
#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)
|
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 */
|
/* Make sure rq->nr_running update is visible after the IPI */
|
||||||
smp_rmb();
|
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 false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -226,7 +226,12 @@ void __tick_nohz_full_check(void)
|
||||||
|
|
||||||
static void nohz_full_kick_work_func(struct irq_work *work)
|
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();
|
__tick_nohz_full_check();
|
||||||
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
|
static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
|
||||||
|
|
Loading…
Reference in New Issue