@@ -1175,12 +1175,23 @@ void tick_nohz_idle_enter(void)
1175
1175
}
1176
1176
1177
1177
/**
1178
- * tick_nohz_irq_exit - update next tick event from interrupt exit
1178
+ * tick_nohz_irq_exit - Notify the tick about IRQ exit
1179
1179
*
1180
- * When an interrupt fires while we are idle and it doesn't cause
1181
- * a reschedule, it may still add, modify or delete a timer, enqueue
1182
- * an RCU callback, etc...
1183
- * So we need to re-calculate and reprogram the next tick event.
1180
+ * A timer may have been added/modified/deleted either by the current IRQ,
1181
+ * or by another place using this IRQ as a notification. This IRQ may have
1182
+ * also updated the RCU callback list. These events may require a
1183
+ * re-evaluation of the next tick. Depending on the context:
1184
+ *
1185
+ * 1) If the CPU is idle and no resched is pending, just proceed with idle
1186
+ * time accounting. The next tick will be re-evaluated on the next idle
1187
+ * loop iteration.
1188
+ *
1189
+ * 2) If the CPU is nohz_full:
1190
+ *
1191
+ * 2.1) If there is any tick dependency, restart the tick if stopped.
1192
+ *
1193
+ * 2.2) If there is no tick dependency, (re-)evaluate the next tick and
1194
+ * stop/update it accordingly.
1184
1195
*/
1185
1196
void tick_nohz_irq_exit (void )
1186
1197
{
@@ -1330,11 +1341,20 @@ static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)
1330
1341
}
1331
1342
1332
1343
/**
1333
- * tick_nohz_idle_exit - restart the idle tick from the idle task
1344
+ * tick_nohz_idle_exit - Update the tick upon idle task exit
1345
+ *
1346
+ * When the idle task exits, update the tick depending on the
1347
+ * following situations:
1348
+ *
1349
+ * 1) If the CPU is not in nohz_full mode (most cases), then
1350
+ * restart the tick.
1351
+ *
1352
+ * 2) If the CPU is in nohz_full mode (corner case):
1353
+ * 2.1) If the tick can be kept stopped (no tick dependencies)
1354
+ * then re-eavaluate the next tick and try to keep it stopped
1355
+ * as long as possible.
1356
+ * 2.2) If the tick has dependencies, restart the tick.
1334
1357
*
1335
- * Restart the idle tick when the CPU is woken up from idle
1336
- * This also exit the RCU extended quiescent state. The CPU
1337
- * can use RCU again after this function is called.
1338
1358
*/
1339
1359
void tick_nohz_idle_exit (void )
1340
1360
{
@@ -1364,7 +1384,13 @@ void tick_nohz_idle_exit(void)
1364
1384
}
1365
1385
1366
1386
/*
1367
- * The nohz low res interrupt handler
1387
+ * In low-resolution mode, the tick handler must be implemented directly
1388
+ * at the clockevent level. hrtimer can't be used instead because its
1389
+ * infrastructure actually relies on the tick itself as a backend in
1390
+ * low-resolution mode (see hrtimer_run_queues()).
1391
+ *
1392
+ * This low-resolution handler still makes use of some hrtimer APIs meanwhile
1393
+ * for commodity with expiration calculation and forwarding.
1368
1394
*/
1369
1395
static void tick_nohz_lowres_handler (struct clock_event_device * dev )
1370
1396
{
0 commit comments