diff options
| author | 2019-02-19 09:57:32 -0800 | |
|---|---|---|
| committer | 2019-04-04 15:34:43 +0000 | |
| commit | d78542bb5215db104a015b61048b4f9d68a96d7b (patch) | |
| tree | ab8e4df5a0568ff4e6f81d8291faa4cc82287297 | |
| parent | dd07ae579c291a2b6ffe09bd576fd908eb9e5ddd (diff) | |
Fix for NetworkStats/Telephony deadlock
Call into NetworkStatsService to update uid foreground
state without the NPMS lock held. Both calls are from
the handler thread, so no sequencing issues.
Bug: 123274986
Bug: 74007921
Test: atest CtsHostsideNetworkTests
Change-Id: I9e8449e5a75db616e646f55c930ff82982fc9083
| -rw-r--r-- | services/core/java/com/android/server/net/NetworkPolicyManagerService.java | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index af58b195a491..c6f6c50a308d 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -3515,10 +3515,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** * Process state of UID changed; if needed, will trigger * {@link #updateRulesForDataUsageRestrictionsUL(int)} and - * {@link #updateRulesForPowerRestrictionsUL(int)} + * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated. */ @GuardedBy("mUidRulesFirstLock") - private void updateUidStateUL(int uid, int uidState) { + private boolean updateUidStateUL(int uid, int uidState) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL"); try { final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); @@ -3537,15 +3537,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } updateRulesForPowerRestrictionsUL(uid); } - updateNetworkStats(uid, isUidStateForeground(uidState)); + return true; } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } + return false; } @GuardedBy("mUidRulesFirstLock") - private void removeUidStateUL(int uid) { + private boolean removeUidStateUL(int uid) { final int index = mUidState.indexOfKey(uid); if (index >= 0) { final int oldUidState = mUidState.valueAt(index); @@ -3560,9 +3561,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForRestrictPowerUL(uid); } updateRulesForPowerRestrictionsUL(uid); - updateNetworkStats(uid, false); + return true; } } + return false; } // adjust stats accounting based on foreground status @@ -4552,21 +4554,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } - }; void handleUidChanged(int uid, int procState, long procStateSeq) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); try { + boolean updated; synchronized (mUidRulesFirstLock) { // We received a uid state change callback, add it to the history so that it // will be useful for debugging. mLogger.uidStateChanged(uid, procState, procStateSeq); // Now update the network policy rules as per the updated uid state. - updateUidStateUL(uid, procState); + updated = updateUidStateUL(uid, procState); // Updating the network rules is done, so notify AMS about this. mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); } + // Do this without the lock held. handleUidChanged() and handleUidGone() are + // called from the handler, so there's no multi-threading issue. + if (updated) { + updateNetworkStats(uid, isUidStateForeground(procState)); + } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } @@ -4575,8 +4582,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { void handleUidGone(int uid) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); try { + boolean updated; synchronized (mUidRulesFirstLock) { - removeUidStateUL(uid); + updated = removeUidStateUL(uid); + } + // Do this without the lock held. handleUidChanged() and handleUidGone() are + // called from the handler, so there's no multi-threading issue. + if (updated) { + updateNetworkStats(uid, false); } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); |