@@ -255,6 +255,40 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
255
255
update_process_times (user_mode (regs ));
256
256
profile_tick (CPU_PROFILING );
257
257
}
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
+ }
258
292
#endif
259
293
260
294
#ifdef CONFIG_NO_HZ_FULL
@@ -1429,31 +1463,15 @@ void tick_nohz_idle_exit(void)
1429
1463
* at the clockevent level. hrtimer can't be used instead, because its
1430
1464
* infrastructure actually relies on the tick itself as a backend in
1431
1465
* 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.
1435
1466
*/
1436
1467
static void tick_nohz_lowres_handler (struct clock_event_device * dev )
1437
1468
{
1438
1469
struct tick_sched * ts = this_cpu_ptr (& tick_cpu_sched );
1439
- struct pt_regs * regs = get_irq_regs ();
1440
- ktime_t now = ktime_get ();
1441
1470
1442
1471
dev -> next_event = KTIME_MAX ;
1443
1472
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 ))
1454
1474
tick_program_event (hrtimer_get_expires (& ts -> sched_timer ), 1 );
1455
- }
1456
-
1457
1475
}
1458
1476
1459
1477
static inline void tick_nohz_activate (struct tick_sched * ts , int mode )
@@ -1522,48 +1540,6 @@ void tick_irq_enter(void)
1522
1540
tick_nohz_irq_enter ();
1523
1541
}
1524
1542
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
-
1567
1543
#if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
1568
1544
static int sched_skew_tick ;
1569
1545
@@ -1587,7 +1563,7 @@ void tick_setup_sched_timer(int mode)
1587
1563
hrtimer_init (& ts -> sched_timer , CLOCK_MONOTONIC , HRTIMER_MODE_ABS_HARD );
1588
1564
1589
1565
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 ;
1591
1567
1592
1568
/* Get the next period (per-CPU) */
1593
1569
hrtimer_set_expires (& ts -> sched_timer , tick_init_jiffy_update ());
0 commit comments