Reuse mem cgroups for tracking forked PIDs.

It turns out we were using the CPU accounting
cgroups for keeping track of processes that were
forked by an app without the framework's knowledge,
so we could kill all of them reliably (see b/15313911
for context).

Since we want to use memory cgroups for other purposes,
we might as well use memory cgroups for tracking forked
PIDs if they're enabled. This also gets us automatic cleanup
of empty mem cgroups.

Also, removed old mem cgroup mount point that is no
longer used, as well as cgroup release agent code that
we're not using.

Change-Id: I69d5cc31c162ffa49ef6945755f41381e306cc8b
This commit is contained in:
Martijn Coenen 2016-01-20 16:39:16 -08:00
parent c003b515e9
commit b82bab66f3
5 changed files with 38 additions and 96 deletions

View file

@ -7,14 +7,4 @@ LOCAL_SHARED_LIBRARIES := liblog libutils
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
LOCAL_REQUIRED_MODULE := processgroup_cleanup
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := cleanup.cpp
LOCAL_MODULE := processgroup_cleanup
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_STATIC_LIBRARIES := libc libcutils
include $(BUILD_EXECUTABLE)

View file

@ -1,31 +0,0 @@
/*
* Copyright 2014 Google, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <unistd.h>
#include <sys/syslimits.h>
#include "processgroup_priv.h"
int main(int argc, char **argv)
{
char buf[PATH_MAX];
if (argc != 2)
return -1;
memcpy(buf, PROCESSGROUP_CGROUP_PATH, sizeof(PROCESSGROUP_CGROUP_PATH));
strlcat(buf, argv[1], sizeof(buf));
return rmdir(buf);
}

View file

@ -22,6 +22,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <mutex>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -35,7 +36,26 @@
#include <utils/SystemClock.h>
#include <processgroup/processgroup.h>
#include "processgroup_priv.h"
#define MEM_CGROUP_PATH "/dev/memcg/apps"
#define ACCT_CGROUP_PATH "/acct"
#define PROCESSGROUP_UID_PREFIX "uid_"
#define PROCESSGROUP_PID_PREFIX "pid_"
#define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs"
#define PROCESSGROUP_MAX_UID_LEN 11
#define PROCESSGROUP_MAX_PID_LEN 11
#define PROCESSGROUP_MAX_PATH_LEN \
((sizeof(MEM_CGROUP_PATH) > sizeof(ACCT_CGROUP_PATH) ? \
sizeof(MEM_CGROUP_PATH) : sizeof(ACCT_CGROUP_PATH)) + \
sizeof(PROCESSGROUP_UID_PREFIX) + 1 + \
PROCESSGROUP_MAX_UID_LEN + \
sizeof(PROCESSGROUP_PID_PREFIX) + 1 + \
PROCESSGROUP_MAX_PID_LEN + \
sizeof(PROCESSGROUP_CGROUP_PROCS_FILE) + \
1)
std::once_flag init_path_flag;
struct ctx {
bool initialized;
@ -45,10 +65,18 @@ struct ctx {
size_t buf_len;
};
static const char* getCgroupRootPath() {
static const char* cgroup_root_path = NULL;
std::call_once(init_path_flag, [&]() {
cgroup_root_path = access(MEM_CGROUP_PATH, W_OK) ? ACCT_CGROUP_PATH : MEM_CGROUP_PATH;
});
return cgroup_root_path;
}
static int convertUidToPath(char *path, size_t size, uid_t uid)
{
return snprintf(path, size, "%s/%s%d",
PROCESSGROUP_CGROUP_PATH,
getCgroupRootPath(),
PROCESSGROUP_UID_PREFIX,
uid);
}
@ -56,7 +84,7 @@ static int convertUidToPath(char *path, size_t size, uid_t uid)
static int convertUidPidToPath(char *path, size_t size, uid_t uid, int pid)
{
return snprintf(path, size, "%s/%s%d/%s%d",
PROCESSGROUP_CGROUP_PATH,
getCgroupRootPath(),
PROCESSGROUP_UID_PREFIX,
uid,
PROCESSGROUP_PID_PREFIX,
@ -188,9 +216,10 @@ static void removeUidProcessGroups(const char *uid_path)
void removeAllProcessGroups()
{
SLOGV("removeAllProcessGroups()");
DIR *root = opendir(PROCESSGROUP_CGROUP_PATH);
const char *cgroup_root_path = getCgroupRootPath();
DIR *root = opendir(cgroup_root_path);
if (root == NULL) {
SLOGE("failed to open %s: %s", PROCESSGROUP_CGROUP_PATH, strerror(errno));
SLOGE("failed to open %s: %s", cgroup_root_path, strerror(errno));
} else {
struct dirent cur;
struct dirent *dir;
@ -204,7 +233,7 @@ void removeAllProcessGroups()
continue;
}
snprintf(path, sizeof(path), "%s/%s", PROCESSGROUP_CGROUP_PATH, dir->d_name);
snprintf(path, sizeof(path), "%s/%s", cgroup_root_path, dir->d_name);
removeUidProcessGroups(path);
SLOGV("removing %s\n", path);
rmdir(path);

View file

@ -1,35 +0,0 @@
/*
* Copyright 2014 Google, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _PROCESSGROUP_PRIV_H_
#define _PROCESSGROUP_PRIV_H_
#define PROCESSGROUP_CGROUP_PATH "/acct"
#define PROCESSGROUP_UID_PREFIX "uid_"
#define PROCESSGROUP_PID_PREFIX "pid_"
#define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs"
#define PROCESSGROUP_MAX_UID_LEN 11
#define PROCESSGROUP_MAX_PID_LEN 11
#define PROCESSGROUP_MAX_PATH_LEN \
(sizeof(PROCESSGROUP_CGROUP_PATH) + \
sizeof(PROCESSGROUP_UID_PREFIX) + 1 + \
PROCESSGROUP_MAX_UID_LEN + \
sizeof(PROCESSGROUP_PID_PREFIX) + 1 + \
PROCESSGROUP_MAX_PID_LEN + \
sizeof(PROCESSGROUP_CGROUP_PROCS_FILE) + \
1)
#endif

View file

@ -43,19 +43,6 @@ on init
mount cgroup none /acct cpuacct
mkdir /acct/uid
# Create cgroup mount point for memory
mount tmpfs none /sys/fs/cgroup mode=0750,uid=0,gid=1000
mkdir /sys/fs/cgroup/memory 0750 root system
mount cgroup none /sys/fs/cgroup/memory memory
write /sys/fs/cgroup/memory/memory.move_charge_at_immigrate 1
chown root system /sys/fs/cgroup/memory/tasks
chmod 0660 /sys/fs/cgroup/memory/tasks
mkdir /sys/fs/cgroup/memory/sw 0750 root system
write /sys/fs/cgroup/memory/sw/memory.swappiness 100
write /sys/fs/cgroup/memory/sw/memory.move_charge_at_immigrate 1
chown root system /sys/fs/cgroup/memory/sw/tasks
chmod 0660 /sys/fs/cgroup/memory/sw/tasks
# Create energy-aware scheduler tuning nodes
mkdir /sys/fs/cgroup/stune
mount cgroup none /sys/fs/cgroup/stune schedtune
@ -95,9 +82,11 @@ on init
symlink /storage/self/primary /sdcard
symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
# memory control cgroup
# root memory control cgroup, used by lmkd
mkdir /dev/memcg 0700 root system
mount cgroup none /dev/memcg memory
# app mem cgroups, used by activity manager and lmkd
mkdir /dev/memcg/apps/ 0755 system system
write /proc/sys/kernel/panic_on_oops 1
write /proc/sys/kernel/hung_task_timeout_secs 0