Message ID | 20191122095833.20861-1-yu.c.chen@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v4] x86/resctrl: Add task resctrl information display | expand |
On Fri, Nov 22, 2019 at 05:58:33PM +0800, Chen Yu wrote: > Monitoring tools that want to find out which resctrl control > and monitor groups a task belongs to must currently read > the "tasks" file in every group until they locate the process > ID. > > Add an additional file /proc/{pid}/resctrl to provide this > information. > --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c > +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c > + seq_printf(s, "/%s", rdtg->kn->name); > + list_for_each_entry(crg, &rdtg->mon.crdtgrp_list, > + mon.crdtgrp_list) { > + if (tsk->rmid != crg->mon.rmid) > + continue; > + seq_printf(s, "%smon_groups/%s", > + rdtg == &rdtgroup_default ? "" : "/", > + crg->kn->name); > + break; > + } > + seq_puts(s, "\n"); This should be seq_putc(). > --- /dev/null > +++ b/include/linux/resctrl.h > @@ -0,0 +1,16 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef _RESCTRL_H > +#define _RESCTRL_H > + > +#ifdef CONFIG_PROC_CPU_RESCTRL > + > +#include <linux/proc_fs.h> Forward declaring stuff should be more than enough. > +int proc_resctrl_show(struct seq_file *m, > + struct pid_namespace *ns, > + struct pid *pid, > + struct task_struct *tsk); > + > +#endif > + > +#endif /* _RESCTRL_H */
Hi Alexey, thanks for looking at this patch. On Sun, Nov 24, 2019 at 04:25:13PM +0300, Alexey Dobriyan wrote: > On Fri, Nov 22, 2019 at 05:58:33PM +0800, Chen Yu wrote: > > Monitoring tools that want to find out which resctrl control > > and monitor groups a task belongs to must currently read > > the "tasks" file in every group until they locate the process > > ID. > > > > Add an additional file /proc/{pid}/resctrl to provide this > > information. > > > --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c > > +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c > > > + seq_printf(s, "/%s", rdtg->kn->name); > > + list_for_each_entry(crg, &rdtg->mon.crdtgrp_list, > > + mon.crdtgrp_list) { > > + if (tsk->rmid != crg->mon.rmid) > > + continue; > > + seq_printf(s, "%smon_groups/%s", > > + rdtg == &rdtgroup_default ? "" : "/", > > + crg->kn->name); > > + break; > > + } > > + seq_puts(s, "\n"); > > This should be seq_putc(). > > Okay, changed in next version. > > --- /dev/null > > +++ b/include/linux/resctrl.h > > @@ -0,0 +1,16 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +#ifndef _RESCTRL_H > > +#define _RESCTRL_H > > + > > +#ifdef CONFIG_PROC_CPU_RESCTRL > > + > > +#include <linux/proc_fs.h> > > Forward declaring stuff should be more than enough. > Okay, deleted in next version. Then after removing this header, the .c files(besides proc/fs/base.c) who include resctrl.h should be responsible to import corresondling headers themselves. Thanks, Chenyu > > +int proc_resctrl_show(struct seq_file *m, > > + struct pid_namespace *ns, > > + struct pid *pid, > > + struct task_struct *tsk); > > + > > +#endif > > + > > +#endif /* _RESCTRL_H */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8ef85139553f..252364d18887 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -455,6 +455,7 @@ config X86_CPU_RESCTRL bool "x86 CPU resource control support" depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD) select KERNFS + select PROC_CPU_RESCTRL if PROC_FS help Enable x86 CPU resource control support. diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 2e3b06d6bbc6..f8898fe3e85c 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -725,6 +725,84 @@ static int rdtgroup_tasks_show(struct kernfs_open_file *of, return ret; } +#ifdef CONFIG_PROC_CPU_RESCTRL + +/* + * A task can only be part of one control + * group and of one monitoring group which + * is associated to that control group. + * So one line is simple and clear enough: + * + * 1) "" + * Resctrl is not available. + * + * 2) "/" + * Task is part of the root group, and it is + * not associated to any monitoring group. + * + * 3) "/mon_groups/mon0" + * Task is part of the root group and monitoring + * group mon0. + * + * 4) "/group0" + * Task is part of control group group0, and it is + * not associated to any monitoring group. + * + * 5) "/group0/mon_groups/mon1" + * Task is part of control group group0 and monitoring + * group mon1. + */ +int proc_resctrl_show(struct seq_file *s, struct pid_namespace *ns, + struct pid *pid, struct task_struct *tsk) +{ + struct rdtgroup *rdtg; + int ret = 0; + + mutex_lock(&rdtgroup_mutex); + + /* Return empty if resctrl has not been mounted. */ + if (!static_branch_unlikely(&rdt_enable_key)) + goto unlock; + + list_for_each_entry(rdtg, &rdt_all_groups, rdtgroup_list) { + struct rdtgroup *crg; + + /* + * Task information is only relevant for shareable + * and exclusive groups. + */ + if (rdtg->mode != RDT_MODE_SHAREABLE && + rdtg->mode != RDT_MODE_EXCLUSIVE) + continue; + + if (rdtg->closid != tsk->closid) + continue; + + seq_printf(s, "/%s", rdtg->kn->name); + list_for_each_entry(crg, &rdtg->mon.crdtgrp_list, + mon.crdtgrp_list) { + if (tsk->rmid != crg->mon.rmid) + continue; + seq_printf(s, "%smon_groups/%s", + rdtg == &rdtgroup_default ? "" : "/", + crg->kn->name); + break; + } + seq_puts(s, "\n"); + goto unlock; + } + /* + * The above search should succeed. Otherwise return + * with an error. + */ + ret = -ENOENT; +unlock: + mutex_unlock(&rdtgroup_mutex); + + return ret; +} +#endif + static int rdt_last_cmd_status_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index cb5629bd5fff..ae96a339d24d 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig @@ -103,3 +103,7 @@ config PROC_CHILDREN config PROC_PID_ARCH_STATUS def_bool n depends on PROC_FS + +config PROC_CPU_RESCTRL + def_bool n + depends on PROC_FS diff --git a/fs/proc/base.c b/fs/proc/base.c index ebea9501afb8..0e4b8bf2b986 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -94,6 +94,7 @@ #include <linux/sched/debug.h> #include <linux/sched/stat.h> #include <linux/posix-timers.h> +#include <linux/resctrl.h> #include <trace/events/oom.h> #include "internal.h" #include "fd.h" @@ -3060,6 +3061,9 @@ static const struct pid_entry tgid_base_stuff[] = { #endif #ifdef CONFIG_CGROUPS ONE("cgroup", S_IRUGO, proc_cgroup_show), +#endif +#ifdef CONFIG_PROC_CPU_RESCTRL + ONE("resctrl", S_IRUGO, proc_resctrl_show), #endif ONE("oom_score", S_IRUGO, proc_oom_score), REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), @@ -3460,6 +3464,9 @@ static const struct pid_entry tid_base_stuff[] = { #endif #ifdef CONFIG_CGROUPS ONE("cgroup", S_IRUGO, proc_cgroup_show), +#endif +#ifdef CONFIG_PROC_CPU_RESCTRL + ONE("resctrl", S_IRUGO, proc_resctrl_show), #endif ONE("oom_score", S_IRUGO, proc_oom_score), REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h new file mode 100644 index 000000000000..50b147784d55 --- /dev/null +++ b/include/linux/resctrl.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _RESCTRL_H +#define _RESCTRL_H + +#ifdef CONFIG_PROC_CPU_RESCTRL + +#include <linux/proc_fs.h> + +int proc_resctrl_show(struct seq_file *m, + struct pid_namespace *ns, + struct pid *pid, + struct task_struct *tsk); + +#endif + +#endif /* _RESCTRL_H */