From 4dbc0b194539d367bdacaad67e80aa7659397353 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Mon, 23 Nov 2020 12:15:51 +0800 Subject: [PATCH 2420/2944] alinux: pidns: Introduce rich container scenario to #31381921 For k8s, multpile containers share one pid_namespace, the child reaper lives in one special "pause" container amongst. Then we should use current other than the child reaper to get the information, thus it deserves a runtime interface. Introduce "/proc/sys/kernel/rich_container_source": - 0 means to use cgroups of "current" by default. - 1 means to use cgroups of "child reaper". Reviewed-by: Alex Shi Acked-by: Michael Wang Signed-off-by: Xunlei Pang --- drivers/base/cpu.c | 14 +++++++------- fs/proc/meminfo.c | 10 +++++----- include/linux/pid_namespace.h | 14 ++++++++++++++ kernel/pid_namespace.c | 1 + kernel/sched/cpuacct.c | 10 +++++----- kernel/sysctl.c | 10 ++++++++++ 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 5cf2ca0..73f588e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -213,28 +213,28 @@ static ssize_t show_cpus_attr(struct device *dev, { struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr); struct cpumask cpuset_allowed; - struct task_struct *init_tsk; + struct task_struct *scenario; bool rich_container; rcu_read_lock(); rich_container = in_rich_container(current); if (rich_container) { read_lock(&tasklist_lock); - init_tsk = task_active_pid_ns(current)->child_reaper; - get_task_struct(init_tsk); + scenario = rich_container_get_scenario(); + get_task_struct(scenario); read_unlock(&tasklist_lock); } else { - init_tsk = NULL; + scenario = NULL; } rcu_read_unlock(); if (rich_container && !strcmp(attr->attr.name, "online")) - cpuset_cpus_allowed(init_tsk, &cpuset_allowed); + cpuset_cpus_allowed(scenario, &cpuset_allowed); else cpumask_copy(&cpuset_allowed, ca->map); - if (init_tsk) - put_task_struct(init_tsk); + if (scenario) + put_task_struct(scenario); return cpumap_print_to_pagebuf(true, buf, &cpuset_allowed); } diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 71d006c..fc3d79e 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -43,7 +43,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) #ifdef CONFIG_MEMCG rcu_read_lock(); if (in_rich_container(current)) { - struct task_struct *init_tsk; + struct task_struct *scenario; /* * current may be in a subcgroup, use reaper instead. @@ -51,16 +51,16 @@ static int meminfo_proc_show(struct seq_file *m, void *v) * top group. */ read_lock(&tasklist_lock); - init_tsk = task_active_pid_ns(current)->child_reaper; - get_task_struct(init_tsk); + scenario = rich_container_get_scenario(); + get_task_struct(scenario); read_unlock(&tasklist_lock); - memcg = mem_cgroup_from_task(init_tsk); + memcg = mem_cgroup_from_task(scenario); if (mem_cgroup_is_root(memcg)) memcg = NULL; else css_get(&memcg->css); - put_task_struct(init_tsk); + put_task_struct(scenario); } rcu_read_unlock(); #endif diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index e558345..4d3751a 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -102,6 +102,7 @@ static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) #ifdef CONFIG_RICH_CONTAINER extern int sysctl_rich_container_enable; +extern int sysctl_rich_container_source; static inline bool in_rich_container(struct task_struct *tsk) { if (sysctl_rich_container_enable == 0) @@ -109,11 +110,24 @@ static inline bool in_rich_container(struct task_struct *tsk) return (task_active_pid_ns(tsk) != &init_pid_ns) && child_cpuacct(tsk); } + +static inline struct task_struct *rich_container_get_scenario(void) +{ + if (sysctl_rich_container_source == 1) + return task_active_pid_ns(current)->child_reaper; + + return current; +} #else static inline bool in_rich_container(struct task_struct *tsk) { return false; } + +static inline struct task_struct *rich_container_get_scenario(void) +{ + return NULL; +} #endif #endif /* _LINUX_PID_NS_H */ diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 435eb0a..bf5e30f 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -25,6 +25,7 @@ #ifdef CONFIG_RICH_CONTAINER int sysctl_rich_container_enable; +int sysctl_rich_container_source; /* 0 - current; 1 - child_reaper */ #endif static DEFINE_MUTEX(pid_caches_mutex); diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c index f388162..1abe417 100644 --- a/kernel/sched/cpuacct.c +++ b/kernel/sched/cpuacct.c @@ -1165,7 +1165,7 @@ bool check_rich_container(unsigned int cpu, unsigned int *index, bool *rich_container, unsigned int *total) { struct cpumask cpuset_allowed; - struct task_struct *init_tsk; + struct task_struct *scenario; bool in_rich; int i, id = 0; @@ -1178,11 +1178,11 @@ bool check_rich_container(unsigned int cpu, unsigned int *index, *rich_container = true; read_lock(&tasklist_lock); - init_tsk = task_active_pid_ns(current)->child_reaper; - get_task_struct(init_tsk); + scenario = rich_container_get_scenario(); + get_task_struct(scenario); read_unlock(&tasklist_lock); - cpuset_cpus_allowed(init_tsk, &cpuset_allowed); - put_task_struct(init_tsk); + cpuset_cpus_allowed(scenario, &cpuset_allowed); + put_task_struct(scenario); *total = cpumask_weight(&cpuset_allowed); if (cpumask_test_cpu(cpu, &cpuset_allowed)) { diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 608d481..363cfea 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1303,6 +1303,16 @@ static int sysrq_sysctl_handler(struct ctl_table *table, int write, .extra1 = &zero, .extra2 = &one, }, + { + .procname = "rich_container_source", + .data = &sysctl_rich_container_source, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, + #endif { } }; -- 1.8.3.1