[PATCH v2] hrtimer: Fix is_hard/is_soft both false with missing HARD/SOFT flag

guoqi0226 posted 1 patch 3 weeks, 1 day ago
kernel/time/hrtimer.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
[PATCH v2] hrtimer: Fix is_hard/is_soft both false with missing HARD/SOFT flag
Posted by guoqi0226 3 weeks, 1 day ago
When hrtimer mode is only ABS/REL (e.g. HRTIMER_MODE_ABS) with no explicit
SOFT/HARD flag, and CONFIG_PREEMPT_RT is disabled, both timer->is_hard and
is_soft become false, violating the hard/soft exclusive design rule.

Enforce correct hard/soft timer via effective_mode:
- Enable softtimer when CONFIG_PREEMPT_RT is enabled and no HARD flag
- Add HRTIMER_MODE_HARD to effective_mode when
  CONFIG_PREEMPT_RT is disabled (e.g. HRTIMER_MODE_ABS)
- Compute timer->is_hard as !!(effective_mode & HRTIMER_MODE_HARD)

This ensures exactly one of is_hard/is_soft is true.

Signed-off-by: guoqi0226 <guoqi0226@163.com>
---
 kernel/time/hrtimer.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 860af7a58428..1709fccc8720 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1618,6 +1618,7 @@ static void __hrtimer_setup(struct hrtimer *timer,
 {
 	bool softtimer = !!(mode & HRTIMER_MODE_SOFT);
 	struct hrtimer_cpu_base *cpu_base;
+	enum hrtimer_mode effective_mode = mode;
 	int base;
 
 	/*
@@ -1628,6 +1629,9 @@ static void __hrtimer_setup(struct hrtimer *timer,
 	 */
 	if (IS_ENABLED(CONFIG_PREEMPT_RT) && !(mode & HRTIMER_MODE_HARD))
 		softtimer = true;
+	else if (!IS_ENABLED(CONFIG_PREEMPT_RT) && !(mode & HRTIMER_MODE_HARD) &&
+		 !(mode & HRTIMER_MODE_SOFT))
+		effective_mode |= HRTIMER_MODE_HARD;
 
 	memset(timer, 0, sizeof(struct hrtimer));
 
@@ -1644,7 +1648,7 @@ static void __hrtimer_setup(struct hrtimer *timer,
 	base = softtimer ? HRTIMER_MAX_CLOCK_BASES / 2 : 0;
 	base += hrtimer_clockid_to_base(clock_id);
 	timer->is_soft = softtimer;
-	timer->is_hard = !!(mode & HRTIMER_MODE_HARD);
+	timer->is_hard = !!(effective_mode & HRTIMER_MODE_HARD);
 	timer->base = &cpu_base->clock_base[base];
 	timerqueue_init(&timer->node);
 
-- 
2.25.1
Re: [PATCH v2] hrtimer: Fix is_hard/is_soft both false with missing HARD/SOFT flag
Posted by Sebastian Andrzej Siewior 3 weeks ago
On 2026-03-15 14:30:09 [+0800], guoqi0226 wrote:
> When hrtimer mode is only ABS/REL (e.g. HRTIMER_MODE_ABS) with no explicit
> SOFT/HARD flag, and CONFIG_PREEMPT_RT is disabled, both timer->is_hard and
> is_soft become false, violating the hard/soft exclusive design rule.
> 
> Enforce correct hard/soft timer via effective_mode:
> - Enable softtimer when CONFIG_PREEMPT_RT is enabled and no HARD flag
> - Add HRTIMER_MODE_HARD to effective_mode when
>   CONFIG_PREEMPT_RT is disabled (e.g. HRTIMER_MODE_ABS)
> - Compute timer->is_hard as !!(effective_mode & HRTIMER_MODE_HARD)
> 
> This ensures exactly one of is_hard/is_soft is true.

How and where is this a problem?

> Signed-off-by: guoqi0226 <guoqi0226@163.com>

Sebastian