Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0208449c authored by Connor O'Brien's avatar Connor O'Brien
Browse files

Defer UID data removal until after reading is finished



Removing UID data inside readDelta() callbacks causes deadlocks when
BPF data is used. Instead, build a list of UIDs to remove but defer
deletion until after readDelta() returns.

Bug: 177011744
Test: atest FrameworksCoreTests:com.android.internal.os.BatteryStatsCpuTimesTest
Change-Id: I41881571f6955a47186797f2d9db9c7594740c6b
Merged-In: I38e037b89e71b0cb1ba01374189ba8b7af01d632
Signed-off-by: default avatarConnor O'Brien <connoro@google.com>
parent 95d5d13b
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -11876,16 +11876,17 @@ public class BatteryStatsImpl extends BatteryStats {
        final int numClusters = mPowerProfile.getNumCpuClusters();
        mWakeLockAllocationsUs = null;
        final long startTimeMs = mClocks.uptimeMillis();
        final List<Integer> uidsToRemove = new ArrayList<>();
        mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
            uid = mapUid(uid);
            if (Process.isIsolated(uid)) {
                mCpuUidFreqTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid);
                return;
            }
            if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid);
                mCpuUidFreqTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                return;
            }
            final Uid u = getUidStatsLocked(uid);
@@ -11944,6 +11945,9 @@ public class BatteryStatsImpl extends BatteryStats {
                }
            }
        });
        for (int uid : uidsToRemove) {
            mCpuUidFreqTimeReader.removeUid(uid);
        }
        final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
        if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
@@ -11989,21 +11993,25 @@ public class BatteryStatsImpl extends BatteryStats {
    @VisibleForTesting
    public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
        final long startTimeMs = mClocks.uptimeMillis();
        final List<Integer> uidsToRemove = new ArrayList<>();
        mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
            uid = mapUid(uid);
            if (Process.isIsolated(uid)) {
                mCpuUidActiveTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid);
                return;
            }
            if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                Slog.w(TAG, "Got active times for an invalid user's uid " + uid);
                mCpuUidActiveTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                return;
            }
            final Uid u = getUidStatsLocked(uid);
            u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery);
        });
        for (int uid : uidsToRemove) {
            mCpuUidActiveTimeReader.removeUid(uid);
        }
        final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
        if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
@@ -12018,21 +12026,25 @@ public class BatteryStatsImpl extends BatteryStats {
    @VisibleForTesting
    public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
        final long startTimeMs = mClocks.uptimeMillis();
        final List<Integer> uidsToRemove = new ArrayList<>();
        mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
            uid = mapUid(uid);
            if (Process.isIsolated(uid)) {
                mCpuUidClusterTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid);
                return;
            }
            if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid);
                mCpuUidClusterTimeReader.removeUid(uid);
                uidsToRemove.add(uid);
                return;
            }
            final Uid u = getUidStatsLocked(uid);
            u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery);
        });
        for (int uid : uidsToRemove) {
            mCpuUidClusterTimeReader.removeUid(uid);
        }
        final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
        if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {