x86/resctrl: Add task resctrl information display
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}/cpu_resctrl_groups to provide this information: 1) res: mon: resctrl is not available. 2) res:/ mon: Task is part of the root resctrl control group, and it is not associated to any monitor group. 3) res:/ mon:mon0 Task is part of the root resctrl control group and monitor group mon0. 4) res:group0 mon: Task is part of resctrl control group group0, and it is not associated to any monitor group. 5) res:group0 mon:mon1 Task is part of resctrl control group group0 and monitor group mon1. Signed-off-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Borislav Petkov <bp@suse.de> Tested-by: Jinshi Chen <jinshi.chen@intel.com> Link: https://lkml.kernel.org/r/20200115092851.14761-1-yu.c.chen@intel.com
This commit is contained in:
Родитель
536a0d8e79
Коммит
e79f15a459
|
@ -456,6 +456,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.
|
||||
|
||||
|
|
|
@ -729,6 +729,92 @@ 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 resctrl control group and of one monitor
|
||||
* group which is associated to that control group.
|
||||
*
|
||||
* 1) res:
|
||||
* mon:
|
||||
*
|
||||
* resctrl is not available.
|
||||
*
|
||||
* 2) res:/
|
||||
* mon:
|
||||
*
|
||||
* Task is part of the root resctrl control group, and it is not associated
|
||||
* to any monitor group.
|
||||
*
|
||||
* 3) res:/
|
||||
* mon:mon0
|
||||
*
|
||||
* Task is part of the root resctrl control group and monitor group mon0.
|
||||
*
|
||||
* 4) res:group0
|
||||
* mon:
|
||||
*
|
||||
* Task is part of resctrl control group group0, and it is not associated
|
||||
* to any monitor group.
|
||||
*
|
||||
* 5) res:group0
|
||||
* mon:mon1
|
||||
*
|
||||
* Task is part of resctrl control group group0 and monitor 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)) {
|
||||
seq_puts(s, "res:\nmon:\n");
|
||||
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, "res:%s%s\n", (rdtg == &rdtgroup_default) ? "/" : "",
|
||||
rdtg->kn->name);
|
||||
seq_puts(s, "mon:");
|
||||
list_for_each_entry(crg, &rdtg->mon.crdtgrp_list,
|
||||
mon.crdtgrp_list) {
|
||||
if (tsk->rmid != crg->mon.rmid)
|
||||
continue;
|
||||
seq_printf(s, "%s", crg->kn->name);
|
||||
break;
|
||||
}
|
||||
seq_putc(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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("cpu_resctrl_groups", 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("cpu_resctrl_groups", 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),
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _RESCTRL_H
|
||||
#define _RESCTRL_H
|
||||
|
||||
#ifdef CONFIG_PROC_CPU_RESCTRL
|
||||
|
||||
int proc_resctrl_show(struct seq_file *m,
|
||||
struct pid_namespace *ns,
|
||||
struct pid *pid,
|
||||
struct task_struct *tsk);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _RESCTRL_H */
|
Загрузка…
Ссылка в новой задаче