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

Commit 7d2da2c2 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Run a GC after killing a UID due to binder proxy limit.

After we hit the per-UID proxy limit and kill the originating process,
there's actually no guarantee that the proxies to the (now dead)
processes are cleaned up immediately; if the processes get restarted and
start accumulating proxies again, we may go over the global proxy limit
(25k with this CL). Do a GC to make sure we clean them up.

Note that the GC here might not actually clean up all the proxies,
because the binder reference decrements will come in asynchronously; but
if new processes belonging to the UID keep adding proxies, we will get
another callback here, and run the GC again - this time cleaning up the
old proxies. Because of this potential delay, an app may temporarily
have many more outstanding proxies than the high watermark, so also
increase the global proxy limit to 25k proxies.

Bug: 198340142
Test: Manual
Change-Id: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b
Merged-In: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b
parent 938b7d01
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public final class BinderProxy implements IBinder {
        private static final int MAIN_INDEX_SIZE = 1 <<  LOG_MAIN_INDEX_SIZE;
        private static final int MAIN_INDEX_MASK = MAIN_INDEX_SIZE - 1;
        // Debuggable builds will throw an AssertionError if the number of map entries exceeds:
        private static final int CRASH_AT_SIZE = 20_000;
        private static final int CRASH_AT_SIZE = 25_000;

        /**
         * We next warn when we exceed this bucket size.
+11 −0
Original line number Diff line number Diff line
@@ -7736,6 +7736,17 @@ public class ActivityManagerService extends IActivityManager.Stub
                        } else {
                            killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
                                    "Too many Binders sent to SYSTEM");
                            // We need to run a GC here, because killing the processes involved
                            // actually isn't guaranteed to free up the proxies; in fact, if the
                            // GC doesn't run for a long time, we may even exceed the global
                            // proxy limit for a process (20000), resulting in system_server itself
                            // being killed.
                            // Note that the GC here might not actually clean up all the proxies,
                            // because the binder reference decrements will come in asynchronously;
                            // but if new processes belonging to the UID keep adding proxies, we
                            // will get another callback here, and run the GC again - this time
                            // cleaning up the old proxies.
                            VMRuntime.getRuntime().requestConcurrentGC();
                        }
                    }, mHandler);
            t.traceEnd(); // setBinderProxies