|
@@ -714,6 +714,78 @@ static int rdt_shareable_bits_show(struct kernfs_open_file *of,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * rdt_bit_usage_show - Display current usage of resources
|
|
|
+ *
|
|
|
+ * A domain is a shared resource that can now be allocated differently. Here
|
|
|
+ * we display the current regions of the domain as an annotated bitmask.
|
|
|
+ * For each domain of this resource its allocation bitmask
|
|
|
+ * is annotated as below to indicate the current usage of the corresponding bit:
|
|
|
+ * 0 - currently unused
|
|
|
+ * X - currently available for sharing and used by software and hardware
|
|
|
+ * H - currently used by hardware only but available for software use
|
|
|
+ * S - currently used and shareable by software only
|
|
|
+ * E - currently used exclusively by one resource group
|
|
|
+ */
|
|
|
+static int rdt_bit_usage_show(struct kernfs_open_file *of,
|
|
|
+ struct seq_file *seq, void *v)
|
|
|
+{
|
|
|
+ struct rdt_resource *r = of->kn->parent->priv;
|
|
|
+ u32 sw_shareable, hw_shareable, exclusive;
|
|
|
+ struct rdt_domain *dom;
|
|
|
+ int i, hwb, swb, excl;
|
|
|
+ enum rdtgrp_mode mode;
|
|
|
+ bool sep = false;
|
|
|
+ u32 *ctrl;
|
|
|
+
|
|
|
+ mutex_lock(&rdtgroup_mutex);
|
|
|
+ hw_shareable = r->cache.shareable_bits;
|
|
|
+ list_for_each_entry(dom, &r->domains, list) {
|
|
|
+ if (sep)
|
|
|
+ seq_putc(seq, ';');
|
|
|
+ ctrl = dom->ctrl_val;
|
|
|
+ sw_shareable = 0;
|
|
|
+ exclusive = 0;
|
|
|
+ seq_printf(seq, "%d=", dom->id);
|
|
|
+ for (i = 0; i < r->num_closid; i++, ctrl++) {
|
|
|
+ if (!closid_allocated(i))
|
|
|
+ continue;
|
|
|
+ mode = rdtgroup_mode_by_closid(i);
|
|
|
+ switch (mode) {
|
|
|
+ case RDT_MODE_SHAREABLE:
|
|
|
+ sw_shareable |= *ctrl;
|
|
|
+ break;
|
|
|
+ case RDT_MODE_EXCLUSIVE:
|
|
|
+ exclusive |= *ctrl;
|
|
|
+ break;
|
|
|
+ case RDT_NUM_MODES:
|
|
|
+ WARN(1,
|
|
|
+ "invalid mode for closid %d\n", i);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (i = r->cache.cbm_len - 1; i >= 0; i--) {
|
|
|
+ hwb = test_bit(i, (unsigned long *)&hw_shareable);
|
|
|
+ swb = test_bit(i, (unsigned long *)&sw_shareable);
|
|
|
+ excl = test_bit(i, (unsigned long *)&exclusive);
|
|
|
+ if (hwb && swb)
|
|
|
+ seq_putc(seq, 'X');
|
|
|
+ else if (hwb && !swb)
|
|
|
+ seq_putc(seq, 'H');
|
|
|
+ else if (!hwb && swb)
|
|
|
+ seq_putc(seq, 'S');
|
|
|
+ else if (excl)
|
|
|
+ seq_putc(seq, 'E');
|
|
|
+ else /* Unused bits remain */
|
|
|
+ seq_putc(seq, '0');
|
|
|
+ }
|
|
|
+ sep = true;
|
|
|
+ }
|
|
|
+ seq_putc(seq, '\n');
|
|
|
+ mutex_unlock(&rdtgroup_mutex);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int rdt_min_bw_show(struct kernfs_open_file *of,
|
|
|
struct seq_file *seq, void *v)
|
|
|
{
|
|
@@ -995,6 +1067,13 @@ static struct rftype res_common_files[] = {
|
|
|
.seq_show = rdt_shareable_bits_show,
|
|
|
.fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE,
|
|
|
},
|
|
|
+ {
|
|
|
+ .name = "bit_usage",
|
|
|
+ .mode = 0444,
|
|
|
+ .kf_ops = &rdtgroup_kf_single_ops,
|
|
|
+ .seq_show = rdt_bit_usage_show,
|
|
|
+ .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE,
|
|
|
+ },
|
|
|
{
|
|
|
.name = "min_bandwidth",
|
|
|
.mode = 0444,
|