KernelWakelockReader: provide class level lock when updates staleStats
As the wakelock version number is defined as static to provide consistent versioning across objects, class level static lock should be implemented to prevent racing conditions. To trigger the racing condition, update statsd's stats pulling logic locally to repeatably requesting wakelock stats then wakeup the phone to trigger BatteryStats update routine. The racing condition is 100% reproducible under the setup. The patch has been verified with the setup, and the racing is no longer seen. See more reproduce details in the linked bug. Bug: 173539101 Test: manual Change-Id: I386afa2f2ecd8678e71ece978da4a9950b21ca4d
This commit is contained in:
@@ -78,13 +78,16 @@ public class KernelWakelockReader {
|
||||
boolean useSystemSuspend = (new File(sSysClassWakeupDir)).exists();
|
||||
|
||||
if (useSystemSuspend) {
|
||||
// Get both kernel and native wakelock stats from SystemSuspend
|
||||
updateVersion(staleStats);
|
||||
if (getWakelockStatsFromSystemSuspend(staleStats) == null) {
|
||||
Slog.w(TAG, "Failed to get wakelock stats from SystemSuspend");
|
||||
return null;
|
||||
// static read/write lock protection for sKernelWakelockUpdateVersion
|
||||
synchronized (KernelWakelockReader.class) {
|
||||
// Get both kernel and native wakelock stats from SystemSuspend
|
||||
updateVersion(staleStats);
|
||||
if (getWakelockStatsFromSystemSuspend(staleStats) == null) {
|
||||
Slog.w(TAG, "Failed to get wakelock stats from SystemSuspend");
|
||||
return null;
|
||||
}
|
||||
return removeOldStats(staleStats);
|
||||
}
|
||||
return removeOldStats(staleStats);
|
||||
} else {
|
||||
Arrays.fill(mKernelWakelockBuffer, (byte) 0);
|
||||
int len = 0;
|
||||
@@ -141,14 +144,17 @@ public class KernelWakelockReader {
|
||||
}
|
||||
}
|
||||
|
||||
updateVersion(staleStats);
|
||||
// Get native wakelock stats from SystemSuspend
|
||||
if (getWakelockStatsFromSystemSuspend(staleStats) == null) {
|
||||
Slog.w(TAG, "Failed to get Native wakelock stats from SystemSuspend");
|
||||
// static read/write lock protection for sKernelWakelockUpdateVersion
|
||||
synchronized (KernelWakelockReader.class) {
|
||||
updateVersion(staleStats);
|
||||
// Get native wakelock stats from SystemSuspend
|
||||
if (getWakelockStatsFromSystemSuspend(staleStats) == null) {
|
||||
Slog.w(TAG, "Failed to get Native wakelock stats from SystemSuspend");
|
||||
}
|
||||
// Get kernel wakelock stats
|
||||
parseProcWakelocks(mKernelWakelockBuffer, len, wakeup_sources, staleStats);
|
||||
return removeOldStats(staleStats);
|
||||
}
|
||||
// Get kernel wakelock stats
|
||||
parseProcWakelocks(mKernelWakelockBuffer, len, wakeup_sources, staleStats);
|
||||
return removeOldStats(staleStats);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user