Skip to content

Commit 37263ba

Browse files
liupeng17KAGA-KOKO
authored andcommitted
tick/nohz: Remove duplicate between lowres and highres handlers
tick_nohz_lowres_handler() does the same work as tick_nohz_highres_handler() plus the clockevent device reprogramming, so make the former reuse the latter and rename it accordingly. Signed-off-by: Peng Liu <liupeng17@lenovo.com> Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240225225508.11587-3-frederic@kernel.org
1 parent ffb7e01 commit 37263ba

File tree

1 file changed

+36
-60
lines changed

1 file changed

+36
-60
lines changed

kernel/time/tick-sched.c

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,40 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
255255
update_process_times(user_mode(regs));
256256
profile_tick(CPU_PROFILING);
257257
}
258+
259+
/*
260+
* We rearm the timer until we get disabled by the idle code.
261+
* Called with interrupts disabled.
262+
*/
263+
static enum hrtimer_restart tick_nohz_handler(struct hrtimer *timer)
264+
{
265+
struct tick_sched *ts = container_of(timer, struct tick_sched, sched_timer);
266+
struct pt_regs *regs = get_irq_regs();
267+
ktime_t now = ktime_get();
268+
269+
tick_sched_do_timer(ts, now);
270+
271+
/*
272+
* Do not call when we are not in IRQ context and have
273+
* no valid 'regs' pointer
274+
*/
275+
if (regs)
276+
tick_sched_handle(ts, regs);
277+
else
278+
ts->next_tick = 0;
279+
280+
/*
281+
* In dynticks mode, tick reprogram is deferred:
282+
* - to the idle task if in dynticks-idle
283+
* - to IRQ exit if in full-dynticks.
284+
*/
285+
if (unlikely(ts->tick_stopped))
286+
return HRTIMER_NORESTART;
287+
288+
hrtimer_forward(timer, now, TICK_NSEC);
289+
290+
return HRTIMER_RESTART;
291+
}
258292
#endif
259293

260294
#ifdef CONFIG_NO_HZ_FULL
@@ -1429,31 +1463,15 @@ void tick_nohz_idle_exit(void)
14291463
* at the clockevent level. hrtimer can't be used instead, because its
14301464
* infrastructure actually relies on the tick itself as a backend in
14311465
* low-resolution mode (see hrtimer_run_queues()).
1432-
*
1433-
* This low-resolution handler still makes use of some hrtimer APIs meanwhile
1434-
* for convenience with expiration calculation and forwarding.
14351466
*/
14361467
static void tick_nohz_lowres_handler(struct clock_event_device *dev)
14371468
{
14381469
struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
1439-
struct pt_regs *regs = get_irq_regs();
1440-
ktime_t now = ktime_get();
14411470

14421471
dev->next_event = KTIME_MAX;
14431472

1444-
tick_sched_do_timer(ts, now);
1445-
tick_sched_handle(ts, regs);
1446-
1447-
/*
1448-
* In dynticks mode, tick reprogram is deferred:
1449-
* - to the idle task if in dynticks-idle
1450-
* - to IRQ exit if in full-dynticks.
1451-
*/
1452-
if (likely(!ts->tick_stopped)) {
1453-
hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
1473+
if (likely(tick_nohz_handler(&ts->sched_timer) == HRTIMER_RESTART))
14541474
tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
1455-
}
1456-
14571475
}
14581476

14591477
static inline void tick_nohz_activate(struct tick_sched *ts, int mode)
@@ -1522,48 +1540,6 @@ void tick_irq_enter(void)
15221540
tick_nohz_irq_enter();
15231541
}
15241542

1525-
/*
1526-
* High resolution timer specific code
1527-
*/
1528-
#ifdef CONFIG_HIGH_RES_TIMERS
1529-
/*
1530-
* We rearm the timer until we get disabled by the idle code.
1531-
* Called with interrupts disabled.
1532-
*/
1533-
static enum hrtimer_restart tick_nohz_highres_handler(struct hrtimer *timer)
1534-
{
1535-
struct tick_sched *ts =
1536-
container_of(timer, struct tick_sched, sched_timer);
1537-
struct pt_regs *regs = get_irq_regs();
1538-
ktime_t now = ktime_get();
1539-
1540-
tick_sched_do_timer(ts, now);
1541-
1542-
/*
1543-
* Do not call when we are not in IRQ context and have
1544-
* no valid 'regs' pointer
1545-
*/
1546-
if (regs)
1547-
tick_sched_handle(ts, regs);
1548-
else
1549-
ts->next_tick = 0;
1550-
1551-
/*
1552-
* In dynticks mode, tick reprogram is deferred:
1553-
* - to the idle task if in dynticks-idle
1554-
* - to IRQ exit if in full-dynticks.
1555-
*/
1556-
if (unlikely(ts->tick_stopped))
1557-
return HRTIMER_NORESTART;
1558-
1559-
hrtimer_forward(timer, now, TICK_NSEC);
1560-
1561-
return HRTIMER_RESTART;
1562-
}
1563-
#else
1564-
#define tick_nohz_highres_handler NULL
1565-
#endif /* CONFIG_HIGH_RES_TIMERS */
1566-
15671543
#if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
15681544
static int sched_skew_tick;
15691545

@@ -1587,7 +1563,7 @@ void tick_setup_sched_timer(int mode)
15871563
hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
15881564

15891565
if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && mode == NOHZ_MODE_HIGHRES)
1590-
ts->sched_timer.function = tick_nohz_highres_handler;
1566+
ts->sched_timer.function = tick_nohz_handler;
15911567

15921568
/* Get the next period (per-CPU) */
15931569
hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());

0 commit comments

Comments
 (0)