aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2017-09-25 19:39:33 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-09-27 06:10:10 -0400
commit9b3a7fd0f5fb583a8fdda678e8a87dff1717f7f3 (patch)
tree21157e2dc7f1d2e0c8eda0f349b77e7b24ddaa1f
parente19b205be43d11bff638cad4487008c48d21c103 (diff)
x86/intel_rdt: Add framework for better RDT UI diagnostics
Commands are given to the resctrl file system by making/removing directories, or by writing to files. When something goes wrong the user is generally left wondering why they got: bash: echo: write error: Invalid argument Add a new file "last_cmd_status" to the "info" directory that will give the user some better clues on what went wrong. Provide functions to clear and update last_cmd_status which check that we hold the rdtgroup_mutex. [ tglx: Made last_cmd_status static and folded back the hunk from patch 3 which replaces the open coded access to last_cmd_status with the accessor function ] Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Vikas Shivappa <vikas.shivappa@intel.com> Cc: Boris Petkov <bp@suse.de> Cc: Reinette Chatre <reinette.chatre@intel.com> Link: https://lkml.kernel.org/r/edc4e0e9741eee89bba569f0021b1b2662fd9508.1506382469.git.tony.luck@intel.com
-rw-r--r--arch/x86/kernel/cpu/intel_rdt.h7
-rw-r--r--arch/x86/kernel/cpu/intel_rdt_rdtgroup.c56
2 files changed, 63 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index ebaddaeef023..9d3148d88ec8 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -126,12 +126,15 @@ struct rdtgroup {
126#define RFTYPE_BASE BIT(1) 126#define RFTYPE_BASE BIT(1)
127#define RF_CTRLSHIFT 4 127#define RF_CTRLSHIFT 4
128#define RF_MONSHIFT 5 128#define RF_MONSHIFT 5
129#define RF_TOPSHIFT 6
129#define RFTYPE_CTRL BIT(RF_CTRLSHIFT) 130#define RFTYPE_CTRL BIT(RF_CTRLSHIFT)
130#define RFTYPE_MON BIT(RF_MONSHIFT) 131#define RFTYPE_MON BIT(RF_MONSHIFT)
132#define RFTYPE_TOP BIT(RF_TOPSHIFT)
131#define RFTYPE_RES_CACHE BIT(8) 133#define RFTYPE_RES_CACHE BIT(8)
132#define RFTYPE_RES_MB BIT(9) 134#define RFTYPE_RES_MB BIT(9)
133#define RF_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL) 135#define RF_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL)
134#define RF_MON_INFO (RFTYPE_INFO | RFTYPE_MON) 136#define RF_MON_INFO (RFTYPE_INFO | RFTYPE_MON)
137#define RF_TOP_INFO (RFTYPE_INFO | RFTYPE_TOP)
135#define RF_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL) 138#define RF_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL)
136 139
137/* List of all resource groups */ 140/* List of all resource groups */
@@ -408,6 +411,10 @@ union cpuid_0x10_x_edx {
408 unsigned int full; 411 unsigned int full;
409}; 412};
410 413
414void rdt_last_cmd_clear(void);
415void rdt_last_cmd_puts(const char *s);
416void rdt_last_cmd_printf(const char *fmt, ...);
417
411void rdt_ctrl_update(void *arg); 418void rdt_ctrl_update(void *arg);
412struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); 419struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
413void rdtgroup_kn_unlock(struct kernfs_node *kn); 420void rdtgroup_kn_unlock(struct kernfs_node *kn);
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index a869d4a073c5..68103513130b 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -24,6 +24,7 @@
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/sysfs.h> 25#include <linux/sysfs.h>
26#include <linux/kernfs.h> 26#include <linux/kernfs.h>
27#include <linux/seq_buf.h>
27#include <linux/seq_file.h> 28#include <linux/seq_file.h>
28#include <linux/sched/signal.h> 29#include <linux/sched/signal.h>
29#include <linux/sched/task.h> 30#include <linux/sched/task.h>
@@ -51,6 +52,31 @@ static struct kernfs_node *kn_mongrp;
51/* Kernel fs node for "mon_data" directory under root */ 52/* Kernel fs node for "mon_data" directory under root */
52static struct kernfs_node *kn_mondata; 53static struct kernfs_node *kn_mondata;
53 54
55static struct seq_buf last_cmd_status;
56static char last_cmd_status_buf[512];
57
58void rdt_last_cmd_clear(void)
59{
60 lockdep_assert_held(&rdtgroup_mutex);
61 seq_buf_clear(&last_cmd_status);
62}
63
64void rdt_last_cmd_puts(const char *s)
65{
66 lockdep_assert_held(&rdtgroup_mutex);
67 seq_buf_puts(&last_cmd_status, s);
68}
69
70void rdt_last_cmd_printf(const char *fmt, ...)
71{
72 va_list ap;
73
74 va_start(ap, fmt);
75 lockdep_assert_held(&rdtgroup_mutex);
76 seq_buf_vprintf(&last_cmd_status, fmt, ap);
77 va_end(ap);
78}
79
54/* 80/*
55 * Trivial allocator for CLOSIDs. Since h/w only supports a small number, 81 * Trivial allocator for CLOSIDs. Since h/w only supports a small number,
56 * we can keep a bitmap of free CLOSIDs in a single integer. 82 * we can keep a bitmap of free CLOSIDs in a single integer.
@@ -569,6 +595,21 @@ static int rdtgroup_tasks_show(struct kernfs_open_file *of,
569 return ret; 595 return ret;
570} 596}
571 597
598static int rdt_last_cmd_status_show(struct kernfs_open_file *of,
599 struct seq_file *seq, void *v)
600{
601 int len;
602
603 mutex_lock(&rdtgroup_mutex);
604 len = seq_buf_used(&last_cmd_status);
605 if (len)
606 seq_printf(seq, "%.*s", len, last_cmd_status_buf);
607 else
608 seq_puts(seq, "ok\n");
609 mutex_unlock(&rdtgroup_mutex);
610 return 0;
611}
612
572static int rdt_num_closids_show(struct kernfs_open_file *of, 613static int rdt_num_closids_show(struct kernfs_open_file *of,
573 struct seq_file *seq, void *v) 614 struct seq_file *seq, void *v)
574{ 615{
@@ -686,6 +727,13 @@ static ssize_t max_threshold_occ_write(struct kernfs_open_file *of,
686/* rdtgroup information files for one cache resource. */ 727/* rdtgroup information files for one cache resource. */
687static struct rftype res_common_files[] = { 728static struct rftype res_common_files[] = {
688 { 729 {
730 .name = "last_cmd_status",
731 .mode = 0444,
732 .kf_ops = &rdtgroup_kf_single_ops,
733 .seq_show = rdt_last_cmd_status_show,
734 .fflags = RF_TOP_INFO,
735 },
736 {
689 .name = "num_closids", 737 .name = "num_closids",
690 .mode = 0444, 738 .mode = 0444,
691 .kf_ops = &rdtgroup_kf_single_ops, 739 .kf_ops = &rdtgroup_kf_single_ops,
@@ -855,6 +903,10 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
855 return PTR_ERR(kn_info); 903 return PTR_ERR(kn_info);
856 kernfs_get(kn_info); 904 kernfs_get(kn_info);
857 905
906 ret = rdtgroup_add_files(kn_info, RF_TOP_INFO);
907 if (ret)
908 goto out_destroy;
909
858 for_each_alloc_enabled_rdt_resource(r) { 910 for_each_alloc_enabled_rdt_resource(r) {
859 fflags = r->fflags | RF_CTRL_INFO; 911 fflags = r->fflags | RF_CTRL_INFO;
860 ret = rdtgroup_mkdir_info_resdir(r, r->name, fflags); 912 ret = rdtgroup_mkdir_info_resdir(r, r->name, fflags);
@@ -1156,6 +1208,7 @@ out_info:
1156out_cdp: 1208out_cdp:
1157 cdp_disable(); 1209 cdp_disable();
1158out: 1210out:
1211 rdt_last_cmd_clear();
1159 mutex_unlock(&rdtgroup_mutex); 1212 mutex_unlock(&rdtgroup_mutex);
1160 1213
1161 return dentry; 1214 return dentry;
@@ -1902,6 +1955,9 @@ int __init rdtgroup_init(void)
1902{ 1955{
1903 int ret = 0; 1956 int ret = 0;
1904 1957
1958 seq_buf_init(&last_cmd_status, last_cmd_status_buf,
1959 sizeof(last_cmd_status_buf));
1960
1905 ret = rdtgroup_setup_root(); 1961 ret = rdtgroup_setup_root();
1906 if (ret) 1962 if (ret)
1907 return ret; 1963 return ret;