summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2021-09-03 18:06:24 +0200
committerMartijn Coenen <maco@google.com>2021-09-24 09:09:19 +0200
commit3b2091fab363c13bf2b1dde89a0eef097985c619 (patch)
tree88a6c66224cc4cf53a5eff54fc4cabdbd2d68905
parent4095348d8f6d5472289eecebe03ecd667684c247 (diff)
downloadnative-3b2091fab363c13bf2b1dde89a0eef097985c619.tar.gz
Repeat proxy limit callbacks if we keep going above the limit.
When we hit the high watermark for number of live proxies in a process, we call a callback with the offending UID. ActivityManagerService will then kill all processes belonging to this UID. The proxy limit callback is only "re-armed" when the number of proxies for that UID drops below a certain value again. However, because the proxies beloging to the now dead processes will only be removed when the GC next runs, and restarted processes may start adding new proxies in the mean time, we may actually never drop below the lower threshold again, and never fire the callback again, despite an ever-increasing amount of proxies. To prevent this, repeatedly fire the limit callback every time that we go another # of high watermark proxies over the limit. This, in combination with a GC in the framework, should make sure that we regularly kill and clean up these processes. Bug: 198340142 Test: Manual Change-Id: I8d877d409863fdae9cffd43709b647d0c1edb440 Merged-In: I8d877d409863fdae9cffd43709b647d0c1edb440
-rw-r--r--libs/binder/BpBinder.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 1dcb94c80f..6471aa6d6b 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -36,7 +36,8 @@ namespace android {
// ---------------------------------------------------------------------------
Mutex BpBinder::sTrackingLock;
-std::unordered_map<int32_t,uint32_t> BpBinder::sTrackingMap;
+std::unordered_map<int32_t, uint32_t> BpBinder::sTrackingMap;
+std::unordered_map<int32_t, uint32_t> sLastLimitCallbackMap;
int BpBinder::sNumTrackedUids = 0;
std::atomic_bool BpBinder::sCountByUidEnabled(false);
binder_proxy_limit_callback BpBinder::sLimitCallback;
@@ -117,12 +118,24 @@ sp<BpBinder> BpBinder::create(int32_t handle) {
if (sBinderProxyThrottleCreate) {
return nullptr;
}
+ trackedValue = trackedValue & COUNTING_VALUE_MASK;
+ uint32_t lastLimitCallbackAt = sLastLimitCallbackMap[trackedUid];
+
+ if (trackedValue > lastLimitCallbackAt &&
+ (trackedValue - lastLimitCallbackAt > sBinderProxyCountHighWatermark)) {
+ ALOGE("Still too many binder proxy objects sent to uid %d from uid %d (%d proxies "
+ "held)",
+ getuid(), trackedUid, trackedValue);
+ if (sLimitCallback) sLimitCallback(trackedUid);
+ sLastLimitCallbackMap[trackedUid] = trackedValue;
+ }
} else {
if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
getuid(), trackedUid, trackedValue);
sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
if (sLimitCallback) sLimitCallback(trackedUid);
+ sLastLimitCallbackMap[trackedUid] = trackedValue & COUNTING_VALUE_MASK;
if (sBinderProxyThrottleCreate) {
ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
" count drops below %d",
@@ -452,8 +465,9 @@ BpBinder::~BpBinder()
((trackedValue & COUNTING_VALUE_MASK) <= sBinderProxyCountLowWatermark)
)) {
ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
- getuid(), mTrackedUid, sBinderProxyCountLowWatermark);
+ getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
+ sLastLimitCallbackMap.erase(mTrackedUid);
}
if (--sTrackingMap[mTrackedUid] == 0) {
sTrackingMap.erase(mTrackedUid);