hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT
--------------------------------
To support the MB monitoring feature, provide mbm_total_bytes interface under the resctrl fs to monitor the MATA memory bandwidth.
In fact, resctrl does not mandate that MBM should work in the mode of free running, so even if the number of monitor instances doesn't meet the number of resctrl has control/monitor groups, it will not affect the monitoring function.
Fixes: dc2005d467b3 ("untested: arm_mpam: resctrl: Add support for mbm counters") Signed-off-by: Zeng Heng zengheng4@huawei.com --- arch/x86/kernel/cpu/resctrl/monitor.c | 53 +++++++++++++++++++ drivers/platform/mpam/mpam_resctrl.c | 76 ++++++++++++++++++++++++--- fs/resctrl/internal.h | 15 ------ fs/resctrl/monitor.c | 47 +---------------- include/linux/resctrl.h | 17 ++++++ 5 files changed, 139 insertions(+), 69 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index 54cf311b6de4..9bb08920985b 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -267,3 +267,56 @@ void __init intel_rdt_mbm_apply_quirk(void) mbm_cf_rmidthreshold = mbm_cf_table[cf_index].rmidthreshold; mbm_cf = mbm_cf_table[cf_index].cf; } + +static struct mon_evt llc_occupancy_event = { + .name = "llc_occupancy", + .evtid = QOS_L3_OCCUP_EVENT_ID, +}; + +static struct mon_evt mbm_total_event = { + .name = "mbm_total_bytes", + .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, +}; + +static struct mon_evt mbm_local_event = { + .name = "mbm_local_bytes", + .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, +}; + +/* + * Initialize the event list for the resource. + * + * Note that MBM events are also part of RDT_RESOURCE_L3 resource + * because as per the SDM the total and local memory bandwidth + * are enumerated as part of L3 monitoring. + */ +static void l3_mon_evt_init(struct rdt_resource *r) +{ + INIT_LIST_HEAD(&r->evt_list); + + if (resctrl_arch_is_llc_occupancy_enabled()) + list_add_tail(&llc_occupancy_event.list, &r->evt_list); + if (resctrl_arch_is_mbm_total_enabled()) + list_add_tail(&mbm_total_event.list, &r->evt_list); + if (resctrl_arch_is_mbm_local_enabled()) + list_add_tail(&mbm_local_event.list, &r->evt_list); +} + +static int resctrl_arch_mon_resource_init(void) +{ + struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3); + int ret; + + l3_mon_evt_init(r); + + if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { + mbm_total_event.configurable = true; + mbm_config_rftype_init("mbm_total_bytes_config"); + } + if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID)) { + mbm_local_event.configurable = true; + mbm_config_rftype_init("mbm_local_bytes_config"); + } + + return 0; +} diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 38e53c46a9ec..035232198541 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -473,14 +473,6 @@ static bool class_has_usable_mbwu(struct mpam_class *class) if (!mpam_has_feature(mpam_feat_msmon_mbwu, cprops)) return false;
- /* - * resctrl expects the bandwidth counters to be free running, - * which means we need as many monitors as resctrl has - * control/monitor groups. - */ - if (cprops->num_mbwu_mon < resctrl_arch_system_num_rmid_idx()) - return false; - return (mpam_partid_max > 1) || (mpam_pmg_max != 0); }
@@ -1199,6 +1191,74 @@ int mpam_resctrl_offline_cpu(unsigned int cpu) return 0; }
+static struct mon_evt llc_occupancy_event = { + .name = "llc_occupancy", + .evtid = QOS_L3_OCCUP_EVENT_ID, +}; + +static struct mon_evt mbm_total_event = { + .name = "mbm_total_bytes", + .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, +}; + +static struct mon_evt mbm_local_event = { + .name = "mbm_local_bytes", + .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, +}; + +/* + * Initialize the event list for the resource. + * + * Note that MBM events are also part of RDT_RESOURCE_L3 resource + * because as per the SDM the total and local memory bandwidth + * are enumerated as part of L3 monitoring. + */ +static void l3_mon_evt_init(struct rdt_resource *r) +{ + INIT_LIST_HEAD(&r->evt_list); + + if ((r->rid == RDT_RESOURCE_L3) && + resctrl_arch_is_llc_occupancy_enabled()) { + list_add_tail(&llc_occupancy_event.list, &r->evt_list); + + if (resctrl_arch_is_mbm_local_enabled()) + list_add_tail(&mbm_local_event.list, &r->evt_list); + } + + if ((r->rid == RDT_RESOURCE_MBA) && + resctrl_arch_is_mbm_total_enabled()) + list_add_tail(&mbm_total_event.list, &r->evt_list); +} + +static int __resctrl_mon_resource_init(enum resctrl_res_level res) +{ + struct rdt_resource *r = resctrl_arch_get_resource(res); + + if (!r->mon_capable) + return 0; + + l3_mon_evt_init(r); + + if ((r->rid == RDT_RESOURCE_MBA) && + resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { + mbm_total_event.configurable = true; + mbm_config_rftype_init("mbm_total_bytes_config"); + } + if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID)) { + mbm_local_event.configurable = true; + mbm_config_rftype_init("mbm_local_bytes_config"); + } + + return 0; +} + +int resctrl_arch_mon_resource_init(void) +{ + __resctrl_mon_resource_init(RDT_RESOURCE_L3); + __resctrl_mon_resource_init(RDT_RESOURCE_MBA); + return 0; +} + static int __init __cacheinfo_ready(void) { cacheinfo_ready = true; diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h index 7a6f46b4edd0..fb620beba958 100644 --- a/fs/resctrl/internal.h +++ b/fs/resctrl/internal.h @@ -66,20 +66,6 @@ static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc) return container_of(kfc, struct rdt_fs_context, kfc); }
-/** - * struct mon_evt - Entry in the event list of a resource - * @evtid: event id - * @name: name of the event - * @configurable: true if the event is configurable - * @list: entry in &rdt_resource->evt_list - */ -struct mon_evt { - enum resctrl_event_id evtid; - char *name; - bool configurable; - struct list_head list; -}; - /** * union mon_data_bits - Monitoring details for each event file * @priv: Used to store monitoring event data in @u @@ -306,7 +292,6 @@ void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms, void cqm_handle_limbo(struct work_struct *work); bool has_busy_rmid(struct rdt_domain *d); void __check_limbo(struct rdt_domain *d, bool force_free); -void mbm_config_rftype_init(const char *config); void rdt_staged_configs_clear(void); int resctrl_find_cleanest_closid(void);
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index 68401ca0827a..7d824dc8fa90 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -791,40 +791,6 @@ static void dom_data_exit(struct rdt_resource *r) mutex_unlock(&rdtgroup_mutex); }
-static struct mon_evt llc_occupancy_event = { - .name = "llc_occupancy", - .evtid = QOS_L3_OCCUP_EVENT_ID, -}; - -static struct mon_evt mbm_total_event = { - .name = "mbm_total_bytes", - .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, -}; - -static struct mon_evt mbm_local_event = { - .name = "mbm_local_bytes", - .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, -}; - -/* - * Initialize the event list for the resource. - * - * Note that MBM events are also part of RDT_RESOURCE_L3 resource - * because as per the SDM the total and local memory bandwidth - * are enumerated as part of L3 monitoring. - */ -static void l3_mon_evt_init(struct rdt_resource *r) -{ - INIT_LIST_HEAD(&r->evt_list); - - if (resctrl_arch_is_llc_occupancy_enabled()) - list_add_tail(&llc_occupancy_event.list, &r->evt_list); - if (resctrl_arch_is_mbm_total_enabled()) - list_add_tail(&mbm_total_event.list, &r->evt_list); - if (resctrl_arch_is_mbm_local_enabled()) - list_add_tail(&mbm_local_event.list, &r->evt_list); -} - int resctrl_mon_resource_init(void) { struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3); @@ -837,18 +803,7 @@ int resctrl_mon_resource_init(void) if (ret) return ret;
- l3_mon_evt_init(r); - - if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { - mbm_total_event.configurable = true; - mbm_config_rftype_init("mbm_total_bytes_config"); - } - if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID)) { - mbm_local_event.configurable = true; - mbm_config_rftype_init("mbm_local_bytes_config"); - } - - return 0; + return resctrl_arch_mon_resource_init(); }
void resctrl_mon_resource_exit(void) diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index f4aeccd78afb..edc7264a8369 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -254,6 +254,20 @@ struct resctrl_mon_config_info { int err; };
+/** + * struct mon_evt - Entry in the event list of a resource + * @evtid: event id + * @name: name of the event + * @configurable: true if the event is configurable + * @list: entry in &rdt_resource->evt_list + */ +struct mon_evt { + enum resctrl_event_id evtid; + char *name; + bool configurable; + struct list_head list; +}; + /* * Update and re-load this CPUs defaults. Called via IPI, takes a pointer to * struct resctrl_cpu_sync, or NULL. @@ -405,4 +419,7 @@ extern unsigned int resctrl_rmid_realloc_limit; int resctrl_init(void); void resctrl_exit(void);
+int resctrl_arch_mon_resource_init(void); +void mbm_config_rftype_init(const char *config); + #endif /* _RESCTRL_H */