[RFC PATCH 15/17] x86/resctrl: Add status files to info/PKG_MON

Tony Luck posted 17 patches 11 months, 1 week ago
There is a newer version of this series
[RFC PATCH 15/17] x86/resctrl: Add status files to info/PKG_MON
Posted by Tony Luck 11 months, 1 week ago
Each of the package event groups includes status about the number
of missed events and timestamps (from a 25 MHz clock) on last time
an update was missed and last time an update was processed.

Add a three info files to report per-aggregator values of these
status values.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
 arch/x86/kernel/cpu/resctrl/internal.h  | 13 ++++
 arch/x86/kernel/cpu/resctrl/intel_pmt.c | 92 ++++++++++++++++++++++---
 arch/x86/kernel/cpu/resctrl/rdtgroup.c  | 22 +++++-
 3 files changed, 117 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 068a47b015e7..5f3656e938ed 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -321,6 +321,7 @@ struct rdtgroup {
 #define RFTYPE_CTRL_INFO		(RFTYPE_INFO | RFTYPE_CTRL)
 #define RFTYPE_MON_INFO			(RFTYPE_INFO | RFTYPE_MON)
 #define RFTYPE_TOP_INFO			(RFTYPE_INFO | RFTYPE_TOP)
+#define RFTYPE_PKG_INFO			(RFTYPE_INFO | RFTYPE_RES_PKG)
 #define RFTYPE_CTRL_BASE		(RFTYPE_BASE | RFTYPE_CTRL)
 #define RFTYPE_MON_BASE			(RFTYPE_BASE | RFTYPE_MON)
 
@@ -642,6 +643,12 @@ int rdt_get_intel_pmt_mon_config(void);
 int rdtgroup_intel_pmt_data_show(struct seq_file *m, struct rdt_resource *r,
 				 int domid, struct rdtgroup *rdtgrp, u32 evtid,
 				 struct rmid_read *rr);
+int rdtgroup_last_update_show(struct kernfs_open_file *of,
+			      struct seq_file *seq, void *v);
+int rdtgroup_overflows_show(struct kernfs_open_file *of,
+			    struct seq_file *seq, void *v);
+int rdtgroup_overflow_timestamp_show(struct kernfs_open_file *of,
+				     struct seq_file *seq, void *v);
 void rdt_get_intel_pmt_mount(void);
 void setup_intel_pmt_mon_domain(int cpu, int id, struct rdt_resource *r, struct list_head *add_pos);
 void rdt_intel_pmt_exit(void);
@@ -650,6 +657,12 @@ static inline int rdt_get_intel_pmt_mon_config(void) { return 0; }
 static inline int rdtgroup_intel_pmt_data_show(struct seq_file *m, struct rdt_resource *r,
 					       int domid, struct rdtgroup *rdtgrp, u32 evtid,
 					       struct rmid_read *rr) { return 0; }
+static inline int rdtgroup_last_update_show(struct kernfs_open_file *of,
+					    struct seq_file *seq, void *v) { return 0; };
+static inline int rdtgroup_overflows_show(struct kernfs_open_file *of,
+					  struct seq_file *seq, void *v) { return 0; };
+static inline int rdtgroup_overflow_timestamp_show(struct kernfs_open_file *of,
+						   struct seq_file *seq, void *v) { return 0; };
 static inline void rdt_get_intel_pmt_mount(void) { }
 static inline void setup_intel_pmt_mon_domain(int cpu, int id, struct rdt_resource *r,
 					      struct list_head *add_pos) { }
diff --git a/arch/x86/kernel/cpu/resctrl/intel_pmt.c b/arch/x86/kernel/cpu/resctrl/intel_pmt.c
index 4067aacd9d80..e89130387387 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_pmt.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_pmt.c
@@ -321,25 +321,37 @@ void setup_intel_pmt_mon_domain(int cpu, int id, struct rdt_resource *r, struct
 		mkdir_mondata_subdir_allrdtgrp(r, &hw_dom->hdr);
 }
 
+enum ops {
+	DO_SUM_EVENT,
+	DO_PRINTVALS
+};
+
 #define VALID_BIT	BIT_ULL(63)
 #define DATA_BITS	GENMASK_ULL(62, 0)
 
-static u64 scan_pmt_devs(int package, int guid, int offset)
+static u64 scan_pmt_devs(struct seq_file *m, int package, int guid, int offset, enum ops op)
 {
-	u64 rval, val;
+	u64 rval = 0, val;
+	char *sep = "";
 	int ndev = 0;
 
-	rval = 0;
-
 	for (int i = 0; i < pkg_info[package].count; i++) {
 		if (pkg_info[package].regions[i].guid != guid)
 			continue;
 		ndev++;
 		val = readq(pkg_info[package].regions[i].addr + offset);
 
-		if (!(val & VALID_BIT))
-			return ~0ull;
-		rval += val & DATA_BITS;
+		switch (op) {
+		case DO_SUM_EVENT:
+			if (!(val & VALID_BIT))
+				return ~0ull;
+			rval += val & DATA_BITS;
+			break;
+		case DO_PRINTVALS:
+			seq_printf(m, "%s0x%llx", sep, val);
+			sep = ",";
+			break;
+		}
 	}
 
 	return ndev ? rval : ~0ull;
@@ -377,7 +389,7 @@ int rdtgroup_intel_pmt_data_show(struct seq_file *m, struct rdt_resource *r,
 	offset = rdtgrp->mon.rmid * EVT_STRIDE(evtid);
 	offset += EVT_OFFSET(evtid);
 
-	val = scan_pmt_devs(domid, EVT_GUID(evtid), offset);
+	val = scan_pmt_devs(m, domid, EVT_GUID(evtid), offset, DO_SUM_EVENT);
 	if (val == ~0ull) {
 		seq_puts(m, "unavailable\n");
 		return 0;
@@ -388,7 +400,7 @@ int rdtgroup_intel_pmt_data_show(struct seq_file *m, struct rdt_resource *r,
 		list_for_each_entry(entry, head, mon.crdtgrp_list) {
 			offset = entry->mon.rmid * EVT_STRIDE(evtid);
 			offset += EVT_OFFSET(evtid);
-			cval = scan_pmt_devs(domid, EVT_GUID(evtid), offset);
+			cval = scan_pmt_devs(m, domid, EVT_GUID(evtid), offset, DO_SUM_EVENT);
 			if (cval == ~0ull) {
 				seq_puts(m, "unavailable\n");
 				return 0;
@@ -408,3 +420,65 @@ int rdtgroup_intel_pmt_data_show(struct seq_file *m, struct rdt_resource *r,
 
 	return 0;
 }
+
+static void status_show(struct seq_file *seq, char *name, int guid, int offset)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_INTEL_PMT].r_resctrl;
+	struct rdt_mon_domain *d;
+	char *sep = "";
+
+	seq_printf(seq, "%s: ", name);
+
+	cpus_read_lock();
+	list_for_each_entry(d, &r->mon_domains, hdr.list) {
+		seq_printf(seq, "%s%d=[", sep, d->hdr.id);
+		scan_pmt_devs(seq, d->hdr.id, guid, offset, DO_PRINTVALS);
+		seq_puts(seq, "]");
+		sep = ";";
+	}
+	cpus_read_unlock();
+
+	seq_puts(seq, "\n");
+}
+
+int rdtgroup_last_update_show(struct kernfs_open_file *of,
+			      struct seq_file *seq, void *v)
+{
+	struct telem_entry **t;
+
+	for (t = telem_entry; *t; t++) {
+		if (!(*t)->active)
+			continue;
+		status_show(seq, (*t)->name, (*t)->guid, (*t)->last_update_tstamp_off);
+	}
+
+	return 0;
+}
+
+int rdtgroup_overflows_show(struct kernfs_open_file *of,
+			    struct seq_file *seq, void *v)
+{
+	struct telem_entry **t;
+
+	for (t = telem_entry; *t; t++) {
+		if (!(*t)->active)
+			continue;
+		status_show(seq, (*t)->name, (*t)->guid, (*t)->overflow_counter_off);
+	}
+
+	return 0;
+}
+
+int rdtgroup_overflow_timestamp_show(struct kernfs_open_file *of,
+				     struct seq_file *seq, void *v)
+{
+	struct telem_entry **t;
+
+	for (t = telem_entry; *t; t++) {
+		if (!(*t)->active)
+			continue;
+		status_show(seq, (*t)->name, (*t)->guid, (*t)->last_overflow_tstamp_off);
+	}
+
+	return 0;
+}
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 93da2e4f7fec..635c17042f7a 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -1986,7 +1986,27 @@ static struct rftype res_common_files[] = {
 		.seq_show	= rdtgroup_closid_show,
 		.fflags		= RFTYPE_CTRL_BASE | RFTYPE_DEBUG,
 	},
-
+	{
+		.name		= "last_update",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_last_update_show,
+		.fflags		= RFTYPE_PKG_INFO,
+	},
+	{
+		.name		= "overflows",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_overflows_show,
+		.fflags		= RFTYPE_PKG_INFO,
+	},
+	{
+		.name		= "overflow_timestamp",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_overflow_timestamp_show,
+		.fflags		= RFTYPE_PKG_INFO,
+	},
 };
 
 static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
-- 
2.48.1