[RFC PATCH v7 25/29] sched/rt: Enable HRTICK_DL for HCBS servers.

From: Yuri Andriaccio

Date: Mon Nov 09 2026 - 11:52:29 EST


If HRTICK_DL is enabled, start hrtick timers whenever a rt-task that is served
by a rt-cgroup is ticked or enqueued for execution.

Signed-off-by: Yuri Andriaccio <yurand2000@xxxxxxxxx>
---
kernel/sched/deadline.c | 13 +++++++++++--
kernel/sched/rt.c | 30 ++++++++++++++++++++++++++++++
kernel/sched/sched.h | 1 +
3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 219493427e0b..6220d793ae91 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2841,10 +2841,20 @@ static void start_hrtick_dl(struct rq *rq, struct sched_dl_entity *dl_se)
{
hrtick_start(rq, dl_se->runtime);
}
+
+int dl_can_start_hrtick(struct rq *rq, struct sched_dl_entity *dl_se)
+{
+ return dl_se->runtime > 0 && is_leftmost(dl_se, &rq->dl);
+}
#else /* !CONFIG_SCHED_HRTICK: */
static void start_hrtick_dl(struct rq *rq, struct sched_dl_entity *dl_se)
{
}
+
+int dl_can_start_hrtick(struct rq *rq, struct sched_dl_entity *dl_se)
+{
+ return 0;
+}
#endif /* !CONFIG_SCHED_HRTICK */

/*
@@ -2975,8 +2985,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_dl(rq) && queued && p->dl.runtime > 0 &&
- is_leftmost(&p->dl, &rq->dl))
+ if (hrtick_enabled_dl(rq) && queued && dl_can_start_hrtick(rq, &p->dl))
start_hrtick_dl(rq, &p->dl);
}

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 839977b05d53..fffb6ec30e68 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1231,6 +1231,17 @@ static void wakeup_preempt_rt(struct rq *rq, struct task_struct *p, int flags)
check_preempt_equal_prio(rq, p);
}

+#ifdef CONFIG_SCHED_HRTICK
+static void start_hrtick_rt(struct rq *rq, struct sched_dl_entity *dl_se)
+{
+ hrtick_start(rq, dl_se->runtime);
+}
+#else /* !CONFIG_SCHED_HRTICK: */
+static void start_hrtick_dl(struct rq *rq, struct sched_dl_entity *dl_se)
+{
+}
+#endif /* !CONFIG_SCHED_HRTICK */
+
static inline void set_next_task_rt(struct rq *rq, struct task_struct *p, enum snt_e type)
{
struct sched_rt_entity *rt_se = &p->rt;
@@ -1258,6 +1269,12 @@ static inline void set_next_task_rt(struct rq *rq, struct task_struct *p, enum s
update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 0);

rt_queue_push_tasks(rt_rq);
+
+ if (!is_dl_group(rt_rq))
+ return;
+
+ if (hrtick_enabled_dl(rq))
+ start_hrtick_rt(rq, dl_group_of(rt_rq));
}

static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
@@ -2254,6 +2271,8 @@ static inline void watchdog(struct rq *rq, struct task_struct *p) { }
static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
{
struct sched_rt_entity *rt_se = &p->rt;
+ struct sched_dl_entity *dl_se;
+ struct rt_rq *rt_rq = rt_rq_of_se(rt_se);

update_curr_rt(rq);
update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 1);
@@ -2281,6 +2300,17 @@ static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
resched_curr(rq);
return;
}
+
+ if (!is_dl_group(rt_rq))
+ return;
+
+ /*
+ * update_curr_rt() might have resulted our dl_server to not be anymore
+ * the leftmost deadline entity, similarly to task_tick_dl.
+ */
+ dl_se = dl_group_of(rt_rq);
+ if (hrtick_enabled_dl(rq) && queued && dl_can_start_hrtick(rq, dl_se))
+ start_hrtick_rt(rq, dl_se);
}

static unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task)
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 835af319b78d..323befba5609 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -356,6 +356,7 @@ extern bool dl_param_changed(struct task_struct *p, const struct sched_attr *att
extern int dl_cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
extern int dl_bw_deactivate(int cpu);
extern s64 dl_scaled_delta_exec(struct rq *rq, struct sched_dl_entity *dl_se, s64 delta_exec);
+extern int dl_can_start_hrtick(struct rq *rq, struct sched_dl_entity *dl_se);
/*
* SCHED_DEADLINE supports servers (nested scheduling) with the following
* interface:
--
2.56.0