|
@@ -20,6 +20,7 @@
|
|
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
|
+#include <linux/cacheinfo.h>
|
|
|
#include <linux/cpu.h>
|
|
|
#include <linux/fs.h>
|
|
|
#include <linux/sysfs.h>
|
|
@@ -1016,6 +1017,78 @@ out:
|
|
|
return ret ?: nbytes;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * rdtgroup_cbm_to_size - Translate CBM to size in bytes
|
|
|
+ * @r: RDT resource to which @d belongs.
|
|
|
+ * @d: RDT domain instance.
|
|
|
+ * @cbm: bitmask for which the size should be computed.
|
|
|
+ *
|
|
|
+ * The bitmask provided associated with the RDT domain instance @d will be
|
|
|
+ * translated into how many bytes it represents. The size in bytes is
|
|
|
+ * computed by first dividing the total cache size by the CBM length to
|
|
|
+ * determine how many bytes each bit in the bitmask represents. The result
|
|
|
+ * is multiplied with the number of bits set in the bitmask.
|
|
|
+ */
|
|
|
+unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r,
|
|
|
+ struct rdt_domain *d, u32 cbm)
|
|
|
+{
|
|
|
+ struct cpu_cacheinfo *ci;
|
|
|
+ unsigned int size = 0;
|
|
|
+ int num_b, i;
|
|
|
+
|
|
|
+ num_b = bitmap_weight((unsigned long *)&cbm, r->cache.cbm_len);
|
|
|
+ ci = get_cpu_cacheinfo(cpumask_any(&d->cpu_mask));
|
|
|
+ for (i = 0; i < ci->num_leaves; i++) {
|
|
|
+ if (ci->info_list[i].level == r->cache_level) {
|
|
|
+ size = ci->info_list[i].size / r->cache.cbm_len * num_b;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return size;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * rdtgroup_size_show - Display size in bytes of allocated regions
|
|
|
+ *
|
|
|
+ * The "size" file mirrors the layout of the "schemata" file, printing the
|
|
|
+ * size in bytes of each region instead of the capacity bitmask.
|
|
|
+ *
|
|
|
+ */
|
|
|
+static int rdtgroup_size_show(struct kernfs_open_file *of,
|
|
|
+ struct seq_file *s, void *v)
|
|
|
+{
|
|
|
+ struct rdtgroup *rdtgrp;
|
|
|
+ struct rdt_resource *r;
|
|
|
+ struct rdt_domain *d;
|
|
|
+ unsigned int size;
|
|
|
+ bool sep = false;
|
|
|
+ u32 cbm;
|
|
|
+
|
|
|
+ rdtgrp = rdtgroup_kn_lock_live(of->kn);
|
|
|
+ if (!rdtgrp) {
|
|
|
+ rdtgroup_kn_unlock(of->kn);
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+
|
|
|
+ for_each_alloc_enabled_rdt_resource(r) {
|
|
|
+ seq_printf(s, "%*s:", max_name_width, r->name);
|
|
|
+ list_for_each_entry(d, &r->domains, list) {
|
|
|
+ if (sep)
|
|
|
+ seq_putc(s, ';');
|
|
|
+ cbm = d->ctrl_val[rdtgrp->closid];
|
|
|
+ size = rdtgroup_cbm_to_size(r, d, cbm);
|
|
|
+ seq_printf(s, "%d=%u", d->id, size);
|
|
|
+ sep = true;
|
|
|
+ }
|
|
|
+ seq_putc(s, '\n');
|
|
|
+ }
|
|
|
+
|
|
|
+ rdtgroup_kn_unlock(of->kn);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/* rdtgroup information files for one cache resource. */
|
|
|
static struct rftype res_common_files[] = {
|
|
|
{
|
|
@@ -1144,6 +1217,14 @@ static struct rftype res_common_files[] = {
|
|
|
.seq_show = rdtgroup_mode_show,
|
|
|
.fflags = RF_CTRL_BASE,
|
|
|
},
|
|
|
+ {
|
|
|
+ .name = "size",
|
|
|
+ .mode = 0444,
|
|
|
+ .kf_ops = &rdtgroup_kf_single_ops,
|
|
|
+ .seq_show = rdtgroup_size_show,
|
|
|
+ .fflags = RF_CTRL_BASE,
|
|
|
+ },
|
|
|
+
|
|
|
};
|
|
|
|
|
|
static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
|