From fd933786d81cc9cff5eecb9ba4be2119921f2531 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Thu, 26 May 2022 17:40:25 -0700 Subject: [PATCH] libprocessgroup: Handle temporarily non-empty group removal failure Cgroup removal fails with EBUSY if there are active processes or threads still alive in the cgroup. Occasionally a thread or a process might be stuck in an interruptible sleep and take some time during exit. In such cases attempts to remove the cgroup it belongs to will fail. This results in occasional leftover cgroups. These empty unused cgroups consume memory. Ensure RemoveProcessGroup always retries and increase the retries to keep trying for 2 secs before giving up. In majority of cases only a few retries are needed but in rare cases a thread can be blocked for longer time, therefore the number of retries is set large enough to cover them. Bug: 233319780 Signed-off-by: Suren Baghdasaryan Change-Id: I2e4bb1f7b7e19c904c85faea7bbabbfdef9c8125 --- libprocessgroup/processgroup.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp index 267e62c67..51c810e98 100644 --- a/libprocessgroup/processgroup.cpp +++ b/libprocessgroup/processgroup.cpp @@ -187,10 +187,6 @@ static int RemoveProcessGroup(const char* cgroup, uid_t uid, int pid, unsigned i auto uid_pid_path = ConvertUidPidToPath(cgroup, uid, pid); auto uid_path = ConvertUidToPath(cgroup, uid); - if (retries == 0) { - retries = 1; - } - while (retries--) { ret = rmdir(uid_pid_path.c_str()); if (!ret || errno != EBUSY) break; @@ -463,12 +459,13 @@ static int KillProcessGroup(uid_t uid, int initialPid, int signal, int retries, << " in " << static_cast(ms) << "ms"; } - int err = RemoveProcessGroup(cgroup, uid, initialPid, retries); + // 400 retries correspond to 2 secs max timeout + int err = RemoveProcessGroup(cgroup, uid, initialPid, 400); if (isMemoryCgroupSupported() && UsePerAppMemcg()) { std::string memcg_apps_path; if (CgroupGetMemcgAppsPath(&memcg_apps_path) && - RemoveProcessGroup(memcg_apps_path.c_str(), uid, initialPid, retries) < 0) { + RemoveProcessGroup(memcg_apps_path.c_str(), uid, initialPid, 400) < 0) { return -1; } }