regulator: cpr-regulator: fix race condition in CPU hotplug callback
Fix a race condition which occurs when setting the voltage corner
of a cpr-regulator device from both the regulator framework and
the CPU hotplug paths simultaneously. This issue was introduced
by this change: 48ba32f0eb1a452e2e6f3d7477bdf5288e32b43d -
"regulator: cpr-regulator: add online CPUs based voltage
adjustment support"
This race condition can cause crashes due to undervolting on
boards which define per-online-core target quotient or initial
voltage adjustments when the following events occur:
0. Initial state: regulator at corner X
(i.e. cpr_vreg->corner = X)
1. cpr_regulator_set_voltage() called from the regulator
framework path for corner Y where Y > X
2. cpr_regulator_cpu_callback() is executed and reads
cpr_vreg->corner finding its value equal to X
3. cpr_regulator_cpu_callback() calls
cpr_regulator_set_voltage() to set corner X (this is
blocked waiting on the mutex)
4. cpr_regulator_set_voltage() call from the regulator
framework path finishes setting corner Y and releases the mutex
5. cpr_regulator_set_voltage() call from hotplug path begins
switching to corner X
6. cpr_regulator_set_voltage() call from hotplug path
finishes switching to corner X
7. The voltage for corner X is insufficient for the processor
frequency which requested corner Y leading to a crash
(likely from an L2 cache bit flip)
Correct this race condition by taking the mutex lock before
accessing any cpr_vreg struct members in
cpr_regulator_cpu_callback().
Change-Id: I019f0246f068be8eeabe8b24dc5e7bd67ef5d2dd
Signed-off-by:
David Collins <collinsd@codeaurora.org>
Loading
Please register or sign in to comment