|
20 | 20 |
|
21 | 21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
22 | 22 |
|
| 23 | +#include <linux/cacheinfo.h> |
23 | 24 | #include <linux/cpu.h>
|
24 | 25 | #include <linux/fs.h>
|
25 | 26 | #include <linux/sysfs.h>
|
@@ -1016,6 +1017,78 @@ static ssize_t rdtgroup_mode_write(struct kernfs_open_file *of,
|
1016 | 1017 | return ret ?: nbytes;
|
1017 | 1018 | }
|
1018 | 1019 |
|
| 1020 | +/** |
| 1021 | + * rdtgroup_cbm_to_size - Translate CBM to size in bytes |
| 1022 | + * @r: RDT resource to which @d belongs. |
| 1023 | + * @d: RDT domain instance. |
| 1024 | + * @cbm: bitmask for which the size should be computed. |
| 1025 | + * |
| 1026 | + * The bitmask provided associated with the RDT domain instance @d will be |
| 1027 | + * translated into how many bytes it represents. The size in bytes is |
| 1028 | + * computed by first dividing the total cache size by the CBM length to |
| 1029 | + * determine how many bytes each bit in the bitmask represents. The result |
| 1030 | + * is multiplied with the number of bits set in the bitmask. |
| 1031 | + */ |
| 1032 | +unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, |
| 1033 | + struct rdt_domain *d, u32 cbm) |
| 1034 | +{ |
| 1035 | + struct cpu_cacheinfo *ci; |
| 1036 | + unsigned int size = 0; |
| 1037 | + int num_b, i; |
| 1038 | + |
| 1039 | + num_b = bitmap_weight((unsigned long *)&cbm, r->cache.cbm_len); |
| 1040 | + ci = get_cpu_cacheinfo(cpumask_any(&d->cpu_mask)); |
| 1041 | + for (i = 0; i < ci->num_leaves; i++) { |
| 1042 | + if (ci->info_list[i].level == r->cache_level) { |
| 1043 | + size = ci->info_list[i].size / r->cache.cbm_len * num_b; |
| 1044 | + break; |
| 1045 | + } |
| 1046 | + } |
| 1047 | + |
| 1048 | + return size; |
| 1049 | +} |
| 1050 | + |
| 1051 | +/** |
| 1052 | + * rdtgroup_size_show - Display size in bytes of allocated regions |
| 1053 | + * |
| 1054 | + * The "size" file mirrors the layout of the "schemata" file, printing the |
| 1055 | + * size in bytes of each region instead of the capacity bitmask. |
| 1056 | + * |
| 1057 | + */ |
| 1058 | +static int rdtgroup_size_show(struct kernfs_open_file *of, |
| 1059 | + struct seq_file *s, void *v) |
| 1060 | +{ |
| 1061 | + struct rdtgroup *rdtgrp; |
| 1062 | + struct rdt_resource *r; |
| 1063 | + struct rdt_domain *d; |
| 1064 | + unsigned int size; |
| 1065 | + bool sep = false; |
| 1066 | + u32 cbm; |
| 1067 | + |
| 1068 | + rdtgrp = rdtgroup_kn_lock_live(of->kn); |
| 1069 | + if (!rdtgrp) { |
| 1070 | + rdtgroup_kn_unlock(of->kn); |
| 1071 | + return -ENOENT; |
| 1072 | + } |
| 1073 | + |
| 1074 | + for_each_alloc_enabled_rdt_resource(r) { |
| 1075 | + seq_printf(s, "%*s:", max_name_width, r->name); |
| 1076 | + list_for_each_entry(d, &r->domains, list) { |
| 1077 | + if (sep) |
| 1078 | + seq_putc(s, ';'); |
| 1079 | + cbm = d->ctrl_val[rdtgrp->closid]; |
| 1080 | + size = rdtgroup_cbm_to_size(r, d, cbm); |
| 1081 | + seq_printf(s, "%d=%u", d->id, size); |
| 1082 | + sep = true; |
| 1083 | + } |
| 1084 | + seq_putc(s, '\n'); |
| 1085 | + } |
| 1086 | + |
| 1087 | + rdtgroup_kn_unlock(of->kn); |
| 1088 | + |
| 1089 | + return 0; |
| 1090 | +} |
| 1091 | + |
1019 | 1092 | /* rdtgroup information files for one cache resource. */
|
1020 | 1093 | static struct rftype res_common_files[] = {
|
1021 | 1094 | {
|
@@ -1144,6 +1217,14 @@ static struct rftype res_common_files[] = {
|
1144 | 1217 | .seq_show = rdtgroup_mode_show,
|
1145 | 1218 | .fflags = RF_CTRL_BASE,
|
1146 | 1219 | },
|
| 1220 | + { |
| 1221 | + .name = "size", |
| 1222 | + .mode = 0444, |
| 1223 | + .kf_ops = &rdtgroup_kf_single_ops, |
| 1224 | + .seq_show = rdtgroup_size_show, |
| 1225 | + .fflags = RF_CTRL_BASE, |
| 1226 | + }, |
| 1227 | + |
1147 | 1228 | };
|
1148 | 1229 |
|
1149 | 1230 | static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
|
|
0 commit comments