From f8c0ce62776d8eebb911ad9070181961c9f8877a Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Mon, 23 Nov 2020 10:55:18 +0800 Subject: [PATCH 2415/2944] alinux: x86: cpuinfo: Add cpuinfo support for rich container to #31381921 Make /proc/cpuinfo container aware. E.g. cpuset.cpus is 4-7, then it will show as the faked cpu0~cpu3 from the rich container. Reviewed-by: Alex Shi Reviewed-by: Michael Wang Signed-off-by: Xunlei Pang --- arch/x86/kernel/cpu/proc.c | 32 ++++++++++++++++++--------- include/linux/pid_namespace.h | 12 +++++++++++ include/linux/sched.h | 13 +++++++++++ init/Kconfig | 14 ++++++++++++ kernel/sched/cpuacct.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 2c8522a..c861b3c 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -11,14 +11,22 @@ * Get CPU information for use by the procfs. */ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, - unsigned int cpu) + unsigned int cpu, unsigned int index, + bool rich_container, unsigned int total) { #ifdef CONFIG_SMP - seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); - seq_printf(m, "siblings\t: %d\n", - cpumask_weight(topology_core_cpumask(cpu))); - seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); - seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); + if (rich_container) { + seq_puts(m, "physical id\t: 0\n"); + seq_printf(m, "siblings\t: %d\n", total); + seq_printf(m, "core id\t\t: %d\n", index); + seq_printf(m, "cpu cores\t: %d\n", total); + } else { + seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); + seq_printf(m, "siblings\t: %d\n", + cpumask_weight(topology_core_cpumask(cpu))); + seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); + seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); + } seq_printf(m, "apicid\t\t: %d\n", c->apicid); seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid); #endif @@ -57,16 +65,20 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) static int show_cpuinfo(struct seq_file *m, void *v) { struct cpuinfo_x86 *c = v; - unsigned int cpu; + unsigned int cpu, index, total; int i; + bool rich_container = false; + + index = cpu = c->cpu_index; + if (check_rich_container(cpu, &index, &rich_container, &total)) + return 0; - cpu = c->cpu_index; seq_printf(m, "processor\t: %u\n" "vendor_id\t: %s\n" "cpu family\t: %d\n" "model\t\t: %u\n" "model name\t: %s\n", - cpu, + index, c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown", c->x86, c->x86_model, @@ -94,7 +106,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (c->x86_cache_size) seq_printf(m, "cache size\t: %u KB\n", c->x86_cache_size); - show_cpuinfo_core(m, c, cpu); + show_cpuinfo_core(m, c, cpu, index, rich_container, total); show_cpuinfo_misc(m, c); seq_puts(m, "flags\t\t:"); diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 49538b1..9a956a4 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -100,4 +100,16 @@ static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) void pidhash_init(void); void pid_idr_init(void); +#ifdef CONFIG_RICH_CONTAINER +static inline bool in_rich_container(struct task_struct *tsk) +{ + return (task_active_pid_ns(tsk) != &init_pid_ns) && child_cpuacct(tsk); +} +#else +static inline bool in_rich_container(struct task_struct *tsk) +{ + return false; +} +#endif + #endif /* _LINUX_PID_NS_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index f8cdc76..adc53a2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2006,4 +2006,17 @@ struct cpuacct_usage_result { u64 steal, iowait, idle, guest, guest_nice; }; +#ifdef CONFIG_RICH_CONTAINER +bool child_cpuacct(struct task_struct *tsk); +bool check_rich_container(unsigned int cpu, unsigned int *index, + bool *rich_container, unsigned int *total); + +#else +static inline bool check_rich_container(unsigned int cpu, unsigned int *index, + bool *rich_container, unsigned int *total) +{ + return false; +} +#endif + #endif diff --git a/init/Kconfig b/init/Kconfig index 41d1c24..2880f9a 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -908,6 +908,20 @@ config SCHED_SLI Note CPU usage requires cpuacct and cpu cgroup subsys to be mounted together to take effect. +config RICH_CONTAINER + bool "Alibaba rich container" + depends on CGROUP_CPUACCT + depends on CFS_BANDWIDTH + depends on CPUSETS + default n + help + Make containers feel like VMs. Change the following interface + to reflect the information from containers, like: + "/proc/cpuinfo", "/proc/meminfo", "/sys/devices/system/cpu/online". + Then tools(i.e. top, free) can work in containers as in VMs. + Note that it requires "cpu,cpuacct,cpuset" shared v1 hierarchy to + work properly. + config CGROUP_CPUACCT bool "Simple CPU accounting controller" help diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c index a2e1f7b..f388162 100644 --- a/kernel/sched/cpuacct.c +++ b/kernel/sched/cpuacct.c @@ -1149,3 +1149,53 @@ static int __init cgroup_v1_psi_init(void) late_initcall_sync(cgroup_v1_psi_init); #endif + +#ifdef CONFIG_RICH_CONTAINER +bool child_cpuacct(struct task_struct *tsk) +{ + struct cpuacct *ca = task_ca(tsk); + + if (ca && ca != &root_cpuacct) + return true; + + return false; +} + +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; + bool in_rich; + int i, id = 0; + + rcu_read_lock(); + in_rich = in_rich_container(current); + rcu_read_unlock(); + if (!in_rich) + return false; + + *rich_container = true; + + read_lock(&tasklist_lock); + init_tsk = task_active_pid_ns(current)->child_reaper; + get_task_struct(init_tsk); + read_unlock(&tasklist_lock); + cpuset_cpus_allowed(init_tsk, &cpuset_allowed); + put_task_struct(init_tsk); + + *total = cpumask_weight(&cpuset_allowed); + if (cpumask_test_cpu(cpu, &cpuset_allowed)) { + for_each_cpu(i, &cpuset_allowed) { + if (i == cpu) + break; + id++; + } + *index = id; + return false; + } + + /* Hide this cpu in the container */ + return true; +} +#endif -- 1.8.3.1