diff options
author | Tony Luck <tony.luck@intel.com> | 2017-09-25 19:39:33 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-09-27 06:10:10 -0400 |
commit | 9b3a7fd0f5fb583a8fdda678e8a87dff1717f7f3 (patch) | |
tree | 21157e2dc7f1d2e0c8eda0f349b77e7b24ddaa1f | |
parent | e19b205be43d11bff638cad4487008c48d21c103 (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.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 56 |
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 | ||
414 | void rdt_last_cmd_clear(void); | ||
415 | void rdt_last_cmd_puts(const char *s); | ||
416 | void rdt_last_cmd_printf(const char *fmt, ...); | ||
417 | |||
411 | void rdt_ctrl_update(void *arg); | 418 | void rdt_ctrl_update(void *arg); |
412 | struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); | 419 | struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); |
413 | void rdtgroup_kn_unlock(struct kernfs_node *kn); | 420 | void 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 */ |
52 | static struct kernfs_node *kn_mondata; | 53 | static struct kernfs_node *kn_mondata; |
53 | 54 | ||
55 | static struct seq_buf last_cmd_status; | ||
56 | static char last_cmd_status_buf[512]; | ||
57 | |||
58 | void rdt_last_cmd_clear(void) | ||
59 | { | ||
60 | lockdep_assert_held(&rdtgroup_mutex); | ||
61 | seq_buf_clear(&last_cmd_status); | ||
62 | } | ||
63 | |||
64 | void rdt_last_cmd_puts(const char *s) | ||
65 | { | ||
66 | lockdep_assert_held(&rdtgroup_mutex); | ||
67 | seq_buf_puts(&last_cmd_status, s); | ||
68 | } | ||
69 | |||
70 | void 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 | ||
598 | static 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 | |||
572 | static int rdt_num_closids_show(struct kernfs_open_file *of, | 613 | static 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. */ |
687 | static struct rftype res_common_files[] = { | 728 | static 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: | |||
1156 | out_cdp: | 1208 | out_cdp: |
1157 | cdp_disable(); | 1209 | cdp_disable(); |
1158 | out: | 1210 | out: |
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; |