Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fs/resctrl: Add event configuration directory under info/L3_MON/

The "mbm_event" counter assignment mode allows the user to assign a hardware
counter to an RMID, event pair and monitor the bandwidth as long as it is
assigned. The user can specify the memory transaction(s) for the counter to
track.

When this mode is supported, the /sys/fs/resctrl/info/L3_MON/event_configs
directory contains a sub-directory for each MBM event that can be assigned to
a counter. The MBM event sub-directory contains a file named "event_filter"
that is used to view and modify which memory transactions the MBM event is
configured with.

Create /sys/fs/resctrl/info/L3_MON/event_configs directory on resctrl mount
and pre-populate it with directories for the two existing MBM events:
mbm_total_bytes and mbm_local_bytes. Create the "event_filter" file within
each MBM event directory with the needed *show() that displays the memory
transactions with which the MBM event is configured.

Example:
$ mount -t resctrl resctrl /sys/fs/resctrl
$ cd /sys/fs/resctrl/
$ cat info/L3_MON/event_configs/mbm_total_bytes/event_filter
local_reads,remote_reads,local_non_temporal_writes,
remote_non_temporal_writes,local_reads_slow_memory,
remote_reads_slow_memory,dirty_victim_writes_all

$ cat info/L3_MON/event_configs/mbm_local_bytes/event_filter
local_reads,local_non_temporal_writes,local_reads_slow_memory

Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lore.kernel.org/cover.1757108044.git.babu.moger@amd.com

authored by

Babu Moger and committed by
Borislav Petkov (AMD)
ea274cbe 159f36cd

+153 -2
+33
Documentation/filesystems/resctrl.rst
··· 310 310 # cat /sys/fs/resctrl/info/L3_MON/available_mbm_cntrs 311 311 0=30;1=30 312 312 313 + "event_configs": 314 + Directory that exists when "mbm_event" counter assignment mode is supported. 315 + Contains a sub-directory for each MBM event that can be assigned to a counter. 316 + 317 + Two MBM events are supported by default: mbm_local_bytes and mbm_total_bytes. 318 + Each MBM event's sub-directory contains a file named "event_filter" that is 319 + used to view and modify which memory transactions the MBM event is configured 320 + with. The file is accessible only when "mbm_event" counter assignment mode is 321 + enabled. 322 + 323 + List of memory transaction types supported: 324 + 325 + ========================== ======================================================== 326 + Name Description 327 + ========================== ======================================================== 328 + dirty_victim_writes_all Dirty Victims from the QOS domain to all types of memory 329 + remote_reads_slow_memory Reads to slow memory in the non-local NUMA domain 330 + local_reads_slow_memory Reads to slow memory in the local NUMA domain 331 + remote_non_temporal_writes Non-temporal writes to non-local NUMA domain 332 + local_non_temporal_writes Non-temporal writes to local NUMA domain 333 + remote_reads Reads to memory in the non-local NUMA domain 334 + local_reads Reads to memory in the local NUMA domain 335 + ========================== ======================================================== 336 + 337 + For example:: 338 + 339 + # cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_total_bytes/event_filter 340 + local_reads,remote_reads,local_non_temporal_writes,remote_non_temporal_writes, 341 + local_reads_slow_memory,remote_reads_slow_memory,dirty_victim_writes_all 342 + 343 + # cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_local_bytes/event_filter 344 + local_reads,local_non_temporal_writes,local_reads_slow_memory 345 + 313 346 "max_threshold_occupancy": 314 347 Read/write file provides the largest value (in 315 348 bytes) at which a previously used LLC_occupancy
+4
fs/resctrl/internal.h
··· 241 241 242 242 #define RFTYPE_DEBUG BIT(10) 243 243 244 + #define RFTYPE_ASSIGN_CONFIG BIT(11) 245 + 244 246 #define RFTYPE_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL) 245 247 246 248 #define RFTYPE_MON_INFO (RFTYPE_INFO | RFTYPE_MON) ··· 404 402 void rdtgroup_assign_cntrs(struct rdtgroup *rdtgrp); 405 403 406 404 void rdtgroup_unassign_cntrs(struct rdtgroup *rdtgrp); 405 + 406 + int event_filter_show(struct kernfs_open_file *of, struct seq_file *seq, void *v); 407 407 408 408 #ifdef CONFIG_RESCTRL_FS_PSEUDO_LOCK 409 409 int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
+56
fs/resctrl/monitor.c
··· 972 972 return mon_event_all[evtid].evt_cfg; 973 973 } 974 974 975 + /** 976 + * struct mbm_transaction - Memory transaction an MBM event can be configured with. 977 + * @name: Name of memory transaction (read, write ...). 978 + * @val: The bit (eg. READS_TO_LOCAL_MEM or READS_TO_REMOTE_MEM) used to 979 + * represent the memory transaction within an event's configuration. 980 + */ 981 + struct mbm_transaction { 982 + char name[32]; 983 + u32 val; 984 + }; 985 + 986 + /* Decoded values for each type of memory transaction. */ 987 + static struct mbm_transaction mbm_transactions[NUM_MBM_TRANSACTIONS] = { 988 + {"local_reads", READS_TO_LOCAL_MEM}, 989 + {"remote_reads", READS_TO_REMOTE_MEM}, 990 + {"local_non_temporal_writes", NON_TEMP_WRITE_TO_LOCAL_MEM}, 991 + {"remote_non_temporal_writes", NON_TEMP_WRITE_TO_REMOTE_MEM}, 992 + {"local_reads_slow_memory", READS_TO_LOCAL_S_MEM}, 993 + {"remote_reads_slow_memory", READS_TO_REMOTE_S_MEM}, 994 + {"dirty_victim_writes_all", DIRTY_VICTIMS_TO_ALL_MEM}, 995 + }; 996 + 997 + int event_filter_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) 998 + { 999 + struct mon_evt *mevt = rdt_kn_parent_priv(of->kn); 1000 + struct rdt_resource *r; 1001 + bool sep = false; 1002 + int ret = 0, i; 1003 + 1004 + mutex_lock(&rdtgroup_mutex); 1005 + rdt_last_cmd_clear(); 1006 + 1007 + r = resctrl_arch_get_resource(mevt->rid); 1008 + if (!resctrl_arch_mbm_cntr_assign_enabled(r)) { 1009 + rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n"); 1010 + ret = -EINVAL; 1011 + goto out_unlock; 1012 + } 1013 + 1014 + for (i = 0; i < NUM_MBM_TRANSACTIONS; i++) { 1015 + if (mevt->evt_cfg & mbm_transactions[i].val) { 1016 + if (sep) 1017 + seq_putc(seq, ','); 1018 + seq_printf(seq, "%s", mbm_transactions[i].name); 1019 + sep = true; 1020 + } 1021 + } 1022 + seq_putc(seq, '\n'); 1023 + 1024 + out_unlock: 1025 + mutex_unlock(&rdtgroup_mutex); 1026 + 1027 + return ret; 1028 + } 1029 + 975 1030 /* 976 1031 * rdtgroup_assign_cntr() - Assign/unassign the counter ID for the event, RMID 977 1032 * pair in the domain. ··· 1342 1287 RFTYPE_MON_INFO | RFTYPE_RES_CACHE); 1343 1288 resctrl_file_fflags_init("available_mbm_cntrs", 1344 1289 RFTYPE_MON_INFO | RFTYPE_RES_CACHE); 1290 + resctrl_file_fflags_init("event_filter", RFTYPE_ASSIGN_CONFIG); 1345 1291 } 1346 1292 1347 1293 return 0;
+57 -2
fs/resctrl/rdtgroup.c
··· 1924 1924 .write = mbm_local_bytes_config_write, 1925 1925 }, 1926 1926 { 1927 + .name = "event_filter", 1928 + .mode = 0444, 1929 + .kf_ops = &rdtgroup_kf_single_ops, 1930 + .seq_show = event_filter_show, 1931 + }, 1932 + { 1927 1933 .name = "mbm_assign_mode", 1928 1934 .mode = 0444, 1929 1935 .kf_ops = &rdtgroup_kf_single_ops, ··· 2189 2183 return ret; 2190 2184 } 2191 2185 2186 + static int resctrl_mkdir_event_configs(struct rdt_resource *r, struct kernfs_node *l3_mon_kn) 2187 + { 2188 + struct kernfs_node *kn_subdir, *kn_subdir2; 2189 + struct mon_evt *mevt; 2190 + int ret; 2191 + 2192 + kn_subdir = kernfs_create_dir(l3_mon_kn, "event_configs", l3_mon_kn->mode, NULL); 2193 + if (IS_ERR(kn_subdir)) 2194 + return PTR_ERR(kn_subdir); 2195 + 2196 + ret = rdtgroup_kn_set_ugid(kn_subdir); 2197 + if (ret) 2198 + return ret; 2199 + 2200 + for_each_mon_event(mevt) { 2201 + if (mevt->rid != r->rid || !mevt->enabled || !resctrl_is_mbm_event(mevt->evtid)) 2202 + continue; 2203 + 2204 + kn_subdir2 = kernfs_create_dir(kn_subdir, mevt->name, kn_subdir->mode, mevt); 2205 + if (IS_ERR(kn_subdir2)) { 2206 + ret = PTR_ERR(kn_subdir2); 2207 + goto out; 2208 + } 2209 + 2210 + ret = rdtgroup_kn_set_ugid(kn_subdir2); 2211 + if (ret) 2212 + goto out; 2213 + 2214 + ret = rdtgroup_add_files(kn_subdir2, RFTYPE_ASSIGN_CONFIG); 2215 + if (ret) 2216 + break; 2217 + } 2218 + 2219 + out: 2220 + return ret; 2221 + } 2222 + 2192 2223 static int rdtgroup_mkdir_info_resdir(void *priv, char *name, 2193 2224 unsigned long fflags) 2194 2225 { 2195 2226 struct kernfs_node *kn_subdir; 2227 + struct rdt_resource *r; 2196 2228 int ret; 2197 2229 2198 2230 kn_subdir = kernfs_create_dir(kn_info, name, ··· 2243 2199 return ret; 2244 2200 2245 2201 ret = rdtgroup_add_files(kn_subdir, fflags); 2246 - if (!ret) 2247 - kernfs_activate(kn_subdir); 2202 + if (ret) 2203 + return ret; 2204 + 2205 + if ((fflags & RFTYPE_MON_INFO) == RFTYPE_MON_INFO) { 2206 + r = priv; 2207 + if (r->mon.mbm_cntr_assignable) { 2208 + ret = resctrl_mkdir_event_configs(r, kn_subdir); 2209 + if (ret) 2210 + return ret; 2211 + } 2212 + } 2213 + 2214 + kernfs_activate(kn_subdir); 2248 2215 2249 2216 return ret; 2250 2217 }
+3
include/linux/resctrl_types.h
··· 34 34 /* Max event bits supported */ 35 35 #define MAX_EVT_CONFIG_BITS GENMASK(6, 0) 36 36 37 + /* Number of memory transactions that an MBM event can be configured with */ 38 + #define NUM_MBM_TRANSACTIONS 7 39 + 37 40 /* Event IDs */ 38 41 enum resctrl_event_id { 39 42 /* Must match value of first event below */