Skip to content

Commit a1d028b

Browse files
dlezcanoIngo Molnar
authored andcommitted
sched/idle: Add more comments to the code
The idle main function is a complex and a critical function. Added more comments to the code. Signed-off-by: Daniel Lezcano <[email protected]> Acked-by: Nicolas Pitre <[email protected]> Signed-off-by: Peter Zijlstra <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 8ca3c64 commit a1d028b

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

kernel/sched/idle.c

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,49 @@ static int cpuidle_idle_call(void)
7676
int next_state, entered_state, ret;
7777
bool broadcast;
7878

79+
/*
80+
* Check if the idle task must be rescheduled. If it is the
81+
* case, exit the function after re-enabling the local irq and
82+
* set again the polling flag
83+
*/
7984
if (current_clr_polling_and_test()) {
8085
local_irq_enable();
8186
__current_set_polling();
8287
return 0;
8388
}
8489

90+
/*
91+
* During the idle period, stop measuring the disabled irqs
92+
* critical sections latencies
93+
*/
8594
stop_critical_timings();
95+
96+
/*
97+
* Tell the RCU framework we are entering an idle section,
98+
* so no more rcu read side critical sections and one more
99+
* step to the grace period
100+
*/
86101
rcu_idle_enter();
87102

103+
/*
104+
* Check if the cpuidle framework is ready, otherwise fallback
105+
* to the default arch specific idle method
106+
*/
88107
ret = cpuidle_enabled(drv, dev);
89108

90109
if (!ret) {
91-
/* ask the governor for the next state */
110+
/*
111+
* Ask the governor to choose an idle state it thinks
112+
* it is convenient to go to. There is *always* a
113+
* convenient idle state
114+
*/
92115
next_state = cpuidle_select(drv, dev);
93116

117+
/*
118+
* The idle task must be scheduled, it is pointless to
119+
* go to idle, just update no idle residency and get
120+
* out of this function
121+
*/
94122
if (current_clr_polling_and_test()) {
95123
dev->last_residency = 0;
96124
entered_state = next_state;
@@ -100,13 +128,29 @@ static int cpuidle_idle_call(void)
100128
CPUIDLE_FLAG_TIMER_STOP);
101129

102130
if (broadcast)
131+
/*
132+
* Tell the time framework to switch
133+
* to a broadcast timer because our
134+
* local timer will be shutdown. If a
135+
* local timer is used from another
136+
* cpu as a broadcast timer, this call
137+
* may fail if it is not available
138+
*/
103139
ret = clockevents_notify(
104140
CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
105141
&dev->cpu);
106142

107143
if (!ret) {
108144
trace_cpu_idle_rcuidle(next_state, dev->cpu);
109145

146+
/*
147+
* Enter the idle state previously
148+
* returned by the governor
149+
* decision. This function will block
150+
* until an interrupt occurs and will
151+
* take care of re-enabling the local
152+
* interrupts
153+
*/
110154
entered_state = cpuidle_enter(drv, dev,
111155
next_state);
112156

@@ -118,17 +162,28 @@ static int cpuidle_idle_call(void)
118162
CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
119163
&dev->cpu);
120164

121-
/* give the governor an opportunity to reflect on the outcome */
165+
/*
166+
* Give the governor an opportunity to reflect on the
167+
* outcome
168+
*/
122169
cpuidle_reflect(dev, entered_state);
123170
}
124171
}
125172
}
126173

174+
/*
175+
* We can't use the cpuidle framework, let's use the default
176+
* idle routine
177+
*/
127178
if (ret)
128179
arch_cpu_idle();
129180

130181
__current_set_polling();
131182

183+
/*
184+
* It is up to the idle functions to enable back the local
185+
* interrupt
186+
*/
132187
if (WARN_ON_ONCE(irqs_disabled()))
133188
local_irq_enable();
134189

0 commit comments

Comments
 (0)