@@ -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 */
14361467static 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
14591477static 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
15681544static 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