Skip to content

Commit

Permalink
sched/features: Distinguish between NORMAL and DEADLINE hrtick
Browse files Browse the repository at this point in the history
The HRTICK feature has traditionally been servicing configurations that
need precise preemptions point for NORMAL tasks. More recently, the
feature has been extended to also service DEADLINE tasks with stringent
runtime enforcement needs (e.g., runtime < 1ms with HZ=1000).

Enabling HRTICK sched feature currently enables the additional timer and
task tick for both classes, which might introduced undesired overhead
for no additional benefit if one needed it only for one of the cases.

Separate HRTICK sched feature in two (and leave the traditional case
name unmodified) so that it can be selectively enabled when needed.

With:

  $ echo HRTICK > /sys/kernel/debug/sched_features

the NORMAL/fair hrtick gets enabled.

With:

  $ echo HRTICK_DL > /sys/kernel/debug/sched_features

the DEADLINE hrtick gets enabled.

Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com>
Signed-off-by: Daniel Bristot de Oliveira <bristot@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20210208073554.14629-3-juri.lelli@redhat.com
  • Loading branch information
Juri Lelli authored and Ingo Molnar committed Feb 17, 2021
1 parent 156ec6f commit e0ee463
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 7 deletions.
2 changes: 1 addition & 1 deletion kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4969,7 +4969,7 @@ static void __sched notrace __schedule(bool preempt)

schedule_debug(prev, preempt);

if (sched_feat(HRTICK))
if (sched_feat(HRTICK) || sched_feat(HRTICK_DL))
hrtick_clear(rq);

local_irq_disable();
Expand Down
4 changes: 2 additions & 2 deletions kernel/sched/deadline.c
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first)
if (!first)
return;

if (hrtick_enabled(rq))
if (hrtick_enabled_dl(rq))
start_hrtick_dl(rq, p);

if (rq->curr->sched_class != &dl_sched_class)
Expand Down Expand Up @@ -1895,7 +1895,7 @@ static void task_tick_dl(struct rq *rq, struct task_struct *p, int queued)
* not being the leftmost task anymore. In that case NEED_RESCHED will
* be set and schedule() will start a new hrtick for the next task.
*/
if (hrtick_enabled(rq) && queued && p->dl.runtime > 0 &&
if (hrtick_enabled_dl(rq) && queued && p->dl.runtime > 0 &&
is_leftmost(p, &rq->dl))
start_hrtick_dl(rq, p);
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -5429,7 +5429,7 @@ static void hrtick_update(struct rq *rq)
{
struct task_struct *curr = rq->curr;

if (!hrtick_enabled(rq) || curr->sched_class != &fair_sched_class)
if (!hrtick_enabled_fair(rq) || curr->sched_class != &fair_sched_class)
return;

if (cfs_rq_of(&curr->se)->nr_running < sched_nr_latency)
Expand Down Expand Up @@ -7116,7 +7116,7 @@ done: __maybe_unused;
list_move(&p->se.group_node, &rq->cfs_tasks);
#endif

if (hrtick_enabled(rq))
if (hrtick_enabled_fair(rq))
hrtick_start_fair(rq, p);

update_misfit_status(p, rq);
Expand Down
1 change: 1 addition & 0 deletions kernel/sched/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SCHED_FEAT(CACHE_HOT_BUDDY, true)
SCHED_FEAT(WAKEUP_PREEMPTION, true)

SCHED_FEAT(HRTICK, false)
SCHED_FEAT(HRTICK_DL, false)
SCHED_FEAT(DOUBLE_TICK, false)

/*
Expand Down
26 changes: 24 additions & 2 deletions kernel/sched/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -2105,17 +2105,39 @@ extern const_debug unsigned int sysctl_sched_migration_cost;
*/
static inline int hrtick_enabled(struct rq *rq)
{
if (!sched_feat(HRTICK))
return 0;
if (!cpu_active(cpu_of(rq)))
return 0;
return hrtimer_is_hres_active(&rq->hrtick_timer);
}

static inline int hrtick_enabled_fair(struct rq *rq)
{
if (!sched_feat(HRTICK))
return 0;
return hrtick_enabled(rq);
}

static inline int hrtick_enabled_dl(struct rq *rq)
{
if (!sched_feat(HRTICK_DL))
return 0;
return hrtick_enabled(rq);
}

void hrtick_start(struct rq *rq, u64 delay);

#else

static inline int hrtick_enabled_fair(struct rq *rq)
{
return 0;
}

static inline int hrtick_enabled_dl(struct rq *rq)
{
return 0;
}

static inline int hrtick_enabled(struct rq *rq)
{
return 0;
Expand Down

0 comments on commit e0ee463

Please sign in to comment.