[PATCH OLK-6.6 0/7] fs/resctrl: Create l2 cache monitors

James Morse (2): arm64: mpam: Add cpu_pm notifier to restore MPAM sysregs arm64: mpam: Restore the expected MPAM sysregs on cpuhp Zeng Heng (5): x86/resctrl: Add a handling path of default label in get_arch_mbm_state() fs/resctrl: Create l2 cache monitors fs/resctrl: Add l2 mount option to enable L2 msc arm64/mpam: Refuse cpu offline when L2 msc is enabled arm64/mpam: Refuse to enter powerdown state after L2 msc updated arch/arm64/kernel/cpufeature.c | 6 ++ arch/arm64/kernel/mpam.c | 41 ++++++++++++++ arch/x86/include/asm/resctrl.h | 2 + arch/x86/kernel/cpu/resctrl/monitor.c | 2 + drivers/platform/mpam/mpam_devices.c | 7 ++- drivers/platform/mpam/mpam_internal.h | 2 + drivers/platform/mpam/mpam_resctrl.c | 79 +++++++++++++++++++++++++-- fs/resctrl/ctrlmondata.c | 6 ++ fs/resctrl/internal.h | 2 +- fs/resctrl/monitor.c | 14 +++++ fs/resctrl/rdtgroup.c | 33 ++++++++++- include/linux/arm_mpam.h | 2 + include/linux/resctrl.h | 5 ++ include/linux/resctrl_types.h | 10 ++++ 14 files changed, 200 insertions(+), 11 deletions(-) -- 2.25.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/16099 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/TQV... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/16099 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/TQV...

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 -------------------------------- Add a handling path of default label to the get_arch_mbm_state() to avoid compilation warnings. This patch will serve as a prerequisite patch for extending the enum resctrl_event_id. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/x86/kernel/cpu/resctrl/monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index ad3f4c790a6c..092ef09c3e37 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -134,6 +134,8 @@ static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom, return &hw_dom->arch_mbm_total[rmid]; case QOS_L3_MBM_LOCAL_EVENT_ID: return &hw_dom->arch_mbm_local[rmid]; + default: + break; } /* Never expect to get here */ -- 2.25.1

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 -------------------------------- Support MPAM to create *mon_L2_${cache_id}/l2c_occupancy* cache occupancy monitors under mon_data directory. In the other hand, RDT doesn't support L2 monitor feature. In addition, let MPAM L2 cache msc support memory bandwidth monitor feature. L2 cache msc not only has the MSMON_CSU monitor, but also has the MSMON_MBWU monitor. Now provide *mon_L2_${cache_id}/mbm_core_bytes* interface to display the value of l2c MSMON_MBWU counter. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/x86/include/asm/resctrl.h | 2 ++ drivers/platform/mpam/mpam_devices.c | 1 + drivers/platform/mpam/mpam_resctrl.c | 50 ++++++++++++++++++++++++---- fs/resctrl/monitor.c | 14 ++++++++ fs/resctrl/rdtgroup.c | 17 ++++++++-- include/linux/arm_mpam.h | 2 ++ include/linux/resctrl.h | 1 + include/linux/resctrl_types.h | 10 ++++++ 8 files changed, 88 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h index b4a0a99bde6a..406b4cf301bb 100644 --- a/arch/x86/include/asm/resctrl.h +++ b/arch/x86/include/asm/resctrl.h @@ -101,6 +101,8 @@ static inline bool resctrl_arch_is_mbm_local_enabled(void) return (rdt_mon_features & (1 << QOS_L3_MBM_LOCAL_EVENT_ID)); } +static inline bool resctrl_arch_is_mbm_core_enabled(void) { return false; } + /* * __resctrl_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR * diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 814959ac1ed2..0bafdb83db45 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -930,6 +930,7 @@ static u64 mpam_msmon_overflow_val(struct mpam_msc_ris *ris) static const struct midr_range mbwu_flowrate_list[] = { MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), MIDR_ALL_VERSIONS(MIDR_HISI_LINXICORE9100), + MIDR_ALL_VERSIONS(MIDR_HISI_HIP12), { /* sentinel */ } }; diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 0e0011a0eb03..17ecda4c7ab6 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -36,6 +36,7 @@ static bool exposed_alloc_capable; static bool exposed_mon_capable; static struct mpam_class *mbm_local_class; static struct mpam_class *mbm_total_class; +static struct mpam_class *mbm_core_class; /* * MPAM emulates CDP by setting different PARTID in the I/D fields of MPAM1_EL1. @@ -79,6 +80,11 @@ bool resctrl_arch_is_mbm_total_enabled(void) return mbm_total_class; } +bool resctrl_arch_is_mbm_core_enabled(void) +{ + return mbm_core_class; +} + bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level rid) { switch (rid) { @@ -307,6 +313,8 @@ static void *resctrl_arch_mon_ctx_alloc_no_wait(struct rdt_resource *r, case QOS_L3_OCCUP_EVENT_ID: case QOS_L3_MBM_LOCAL_EVENT_ID: case QOS_L3_MBM_TOTAL_EVENT_ID: + case QOS_L2_OCCUP_EVENT_ID: + case QOS_L2_MBM_CORE_EVENT_ID: *ret = __mon_is_rmid_idx; return ret; @@ -372,10 +380,12 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, switch (eventid) { case QOS_L3_OCCUP_EVENT_ID: + case QOS_L2_OCCUP_EVENT_ID: type = mpam_feat_msmon_csu; break; case QOS_L3_MBM_LOCAL_EVENT_ID: case QOS_L3_MBM_TOTAL_EVENT_ID: + case QOS_L2_MBM_CORE_EVENT_ID: type = mpam_feat_msmon_mbwu; break; default: @@ -524,6 +534,11 @@ bool resctrl_arch_is_llc_occupancy_enabled(void) return cache_has_usable_csu(mpam_resctrl_exports[RDT_RESOURCE_L3].class); } +bool resctrl_arch_is_l2c_occupancy_enabled(void) +{ + return cache_has_usable_csu(mpam_resctrl_exports[RDT_RESOURCE_L2].class); +} + static bool class_has_usable_mbwu(struct mpam_class *class) { struct mpam_props *cprops = &class->props; @@ -918,19 +933,23 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) * be local. If it's on the memory controller, its assumed to * be global. */ - if (has_mbwu && class->level >= 3) { - mbm_local_class = class; - r->mon_capable = true; + if (has_mbwu) { + if (class->level == 3) { + mbm_local_class = class; + r->mon_capable = true; + + } else if (class->level == 2) { + mbm_core_class = class; + r->mon_capable = true; + } } /* * CSU counters only make sense on a cache. The file is called * llc_occupancy, but its expected to the on the L3. */ - if (has_csu && class->type == MPAM_CLASS_CACHE && - class->level == 3) { + if (has_csu && class->type == MPAM_CLASS_CACHE) r->mon_capable = true; - } break; case RDT_RESOURCE_MBA: @@ -1502,6 +1521,11 @@ static struct mon_evt llc_occupancy_event = { .evtid = QOS_L3_OCCUP_EVENT_ID, }; +static struct mon_evt l2c_occupancy_event = { + .name = "l2c_occupancy", + .evtid = QOS_L2_OCCUP_EVENT_ID, +}; + static struct mon_evt mbm_total_event = { .name = "mbm_total_bytes", .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, @@ -1512,6 +1536,11 @@ static struct mon_evt mbm_local_event = { .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, }; +static struct mon_evt mbm_core_event = { + .name = "mbm_core_bytes", + .evtid = QOS_L2_MBM_CORE_EVENT_ID, +}; + /* * Initialize the event list for the resource. * @@ -1534,6 +1563,14 @@ static void l3_mon_evt_init(struct rdt_resource *r) list_add_tail(&mbm_local_event.list, &r->evt_list); } + if (r->rid == RDT_RESOURCE_L2) { + if (resctrl_arch_is_l2c_occupancy_enabled()) + list_add_tail(&l2c_occupancy_event.list, &r->evt_list); + + if (resctrl_arch_is_mbm_core_enabled()) + list_add_tail(&mbm_core_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); @@ -1542,6 +1579,7 @@ static void l3_mon_evt_init(struct rdt_resource *r) int resctrl_arch_mon_resource_init(void) { l3_mon_evt_init(resctrl_arch_get_resource(RDT_RESOURCE_L3)); + l3_mon_evt_init(resctrl_arch_get_resource(RDT_RESOURCE_L2)); l3_mon_evt_init(resctrl_arch_get_resource(RDT_RESOURCE_MBA)); if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index 7d824dc8fa90..fb60316199c4 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -595,6 +595,20 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, if (is_mba_sc(NULL)) mbm_bw_count(closid, rmid, &rr); + resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); + } + if (resctrl_arch_is_mbm_core_enabled()) { + rr.evtid = QOS_L2_MBM_CORE_EVENT_ID; + rr.val = 0; + rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid); + if (IS_ERR(rr.arch_mon_ctx)) { + pr_warn_ratelimited("Failed to allocate monitor context: %ld", + PTR_ERR(rr.arch_mon_ctx)); + return; + } + + __mon_event_count(closid, rmid, &rr); + resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); } } diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index ffb6b8930435..dffc2392e9c9 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -114,13 +114,15 @@ void rdt_staged_configs_clear(void) static bool resctrl_is_mbm_enabled(void) { return (resctrl_arch_is_mbm_total_enabled() || - resctrl_arch_is_mbm_local_enabled()); + resctrl_arch_is_mbm_local_enabled() || + resctrl_arch_is_mbm_core_enabled()); } static bool resctrl_is_mbm_event(int e) { - return (e >= QOS_L3_MBM_TOTAL_EVENT_ID && - e <= QOS_L3_MBM_LOCAL_EVENT_ID); + return (e == QOS_L3_MBM_TOTAL_EVENT_ID || + e == QOS_L3_MBM_LOCAL_EVENT_ID || + e == QOS_L2_MBM_CORE_EVENT_ID); } /* @@ -4001,6 +4003,15 @@ static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) return -ENOMEM; } } + if (resctrl_arch_is_mbm_core_enabled()) { + tsize = sizeof(*d->mbm_core); + d->mbm_core = kcalloc(idx_limit, tsize, GFP_KERNEL); + if (!d->mbm_core) { + bitmap_free(d->rmid_busy_llc); + kfree(d->mbm_core); + return -ENOMEM; + } + } return 0; } diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h index aef951595f65..3a06a8afad7c 100644 --- a/include/linux/arm_mpam.h +++ b/include/linux/arm_mpam.h @@ -64,6 +64,8 @@ static inline bool resctrl_arch_event_is_free_running(enum resctrl_event_id evt) bool resctrl_arch_alloc_capable(void); bool resctrl_arch_mon_capable(void); bool resctrl_arch_is_llc_occupancy_enabled(void); +bool resctrl_arch_is_l2c_occupancy_enabled(void); +bool resctrl_arch_is_mbm_core_enabled(void); bool resctrl_arch_is_mbm_local_enabled(void); bool resctrl_arch_is_mbm_total_enabled(void); bool resctrl_arch_would_mbm_overflow(void); diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 566a891f1e04..ba716c3c6cfb 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -113,6 +113,7 @@ struct rdt_domain { unsigned long *rmid_busy_llc; struct mbm_state *mbm_total; struct mbm_state *mbm_local; + struct mbm_state *mbm_core; struct delayed_work mbm_over; struct delayed_work cqm_limbo; int mbm_work_cpu; diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h index fd1704766c29..3d56c35877ea 100644 --- a/include/linux/resctrl_types.h +++ b/include/linux/resctrl_types.h @@ -99,11 +99,21 @@ enum resctrl_res_level { /* * Event IDs, the values match those used to program IA32_QM_EVTSEL before * reading IA32_QM_CTR on RDT systems. + * + * Monitor Event IDs, representative a variety of monitoring events: + * QOS_L3_OCCUP_EVENT_ID: L3 Cache Occupancy statistics event + * QOS_L3_MBM_TOTAL_EVENT_ID: Global Memory Bandwidth statistics event + * QOS_L3_MBM_LOCAL_EVENT_ID: L3 Cache Bandwidth statistics event + * QOS_L2_OCCUP_EVENT_ID: L2 Cache Occupancy statistics event + * QOS_L2_MBM_CORE_EVENT_ID: L2 Cache Bandwidth statistics event */ enum resctrl_event_id { QOS_L3_OCCUP_EVENT_ID = 0x01, QOS_L3_MBM_TOTAL_EVENT_ID = 0x02, QOS_L3_MBM_LOCAL_EVENT_ID = 0x03, + + QOS_L2_OCCUP_EVENT_ID, + QOS_L2_MBM_CORE_EVENT_ID, }; #endif /* __LINUX_RESCTRL_TYPES_H */ -- 2.25.1

From: James Morse <james.morse@arm.com> maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mp... -------------------------------- The MPAM system registers will be lost if the CPU is reset during PSCI's CPU_SUSPEND. Restore them. mpam_thread_switch(current) can't be used as this won't make any changes if the in-memory copy says the register already has the correct value. In reality the system register is UNKNOWN out of reset. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/arm64/kernel/mpam.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/kernel/mpam.c b/arch/arm64/kernel/mpam.c index d8891d5c59c0..d3ac3bfb5564 100644 --- a/arch/arm64/kernel/mpam.c +++ b/arch/arm64/kernel/mpam.c @@ -4,6 +4,7 @@ #include <asm/mpam.h> #include <linux/arm_mpam.h> +#include <linux/cpu_pm.h> #include <linux/jump_label.h> #include <linux/percpu.h> #include <linux/crash_dump.h> @@ -13,6 +14,32 @@ DEFINE_STATIC_KEY_FALSE(mpam_enabled); DEFINE_PER_CPU(u64, arm64_mpam_default); DEFINE_PER_CPU(u64, arm64_mpam_current); +static int mpam_pm_notifier(struct notifier_block *self, + unsigned long cmd, void *v) +{ + u64 regval; + int cpu = smp_processor_id(); + + switch (cmd) { + case CPU_PM_EXIT: + /* + * Don't use mpam_thread_switch() as the system register + * value has changed under our feet. + */ + regval = READ_ONCE(per_cpu(arm64_mpam_current, cpu)); + write_sysreg_s(0, SYS_MPAM1_EL1); + write_sysreg_s(regval, SYS_MPAM0_EL1); + + return NOTIFY_OK; + default: + return NOTIFY_DONE; + } +} + +static struct notifier_block mpam_pm_nb = { + .notifier_call = mpam_pm_notifier, +}; + static int __init arm64_mpam_register_cpus(void) { u16 partid_max; @@ -29,6 +56,7 @@ static int __init arm64_mpam_register_cpus(void) partid_max = FIELD_GET(MPAMIDR_PARTID_MAX, mpamidr); pmg_max = FIELD_GET(MPAMIDR_PMG_MAX, mpamidr); + cpu_pm_register_notifier(&mpam_pm_nb); return mpam_register_requestor(partid_max, pmg_max); } arch_initcall(arm64_mpam_register_cpus); -- 2.25.1

From: James Morse <james.morse@arm.com> maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mp... -------------------------------- When a CPU is brought online, only the MPAM1_EL1 sysreg is set. For completeness restore the MPAM0_EL1 register too. This isn't expected to cause a problem as cpuhp happens from the idle thread, which can't return to user-space. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/arm64/kernel/cpufeature.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index c49a76ad747f..38eaa358c76b 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2357,6 +2357,11 @@ static void __maybe_unused cpu_enable_mpam(const struct arm64_cpu_capabilities *entry) { u64 idr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1); + int cpu = smp_processor_id(); + u64 regval = 0; + + if (IS_ENABLED(CONFIG_ARM64_MPAM)) + regval = READ_ONCE(per_cpu(arm64_mpam_current, cpu)); /* * Initialise MPAM EL2 registers and disable EL2 traps. @@ -2373,6 +2378,7 @@ cpu_enable_mpam(const struct arm64_cpu_capabilities *entry) * been throttled to release the lock. */ write_sysreg_s(0, SYS_MPAM1_EL1); + write_sysreg_s(regval, SYS_MPAM0_EL1); } static void mpam_extra_caps(void) -- 2.25.1

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 -------------------------------- The L2 msc function interface is hidden by default, and allow to enable after adding mounting option of "-o l2" by user specified. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- fs/resctrl/ctrlmondata.c | 6 ++++++ fs/resctrl/internal.h | 1 + fs/resctrl/rdtgroup.c | 16 ++++++++++++++++ include/linux/resctrl.h | 1 + 4 files changed, 24 insertions(+) diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c index 60b422eed2c8..00132a77879d 100644 --- a/fs/resctrl/ctrlmondata.c +++ b/fs/resctrl/ctrlmondata.c @@ -307,6 +307,9 @@ static int rdtgroup_parse_resource(char *resname, char *tok, struct resctrl_schema *s; list_for_each_entry(s, &resctrl_schema_all, list) { + if (s->res->invisible) + continue; + if (!strcmp(resname, s->name) && rdtgrp->closid < s->num_closid) return parse_line(tok, s, rdtgrp); } @@ -451,6 +454,9 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, } else { closid = rdtgrp->closid; list_for_each_entry(schema, &resctrl_schema_all, list) { + if (schema->res->invisible) + continue; + if (closid < schema->num_closid) show_doms(s, schema, closid); } diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h index fb620beba958..9c6e6b8bd81a 100644 --- a/fs/resctrl/internal.h +++ b/fs/resctrl/internal.h @@ -57,6 +57,7 @@ struct rdt_fs_context { bool enable_cdpl3; bool enable_mba_mbps; bool enable_debug; + bool enable_l2; }; static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc) diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index dffc2392e9c9..70fdbaa12ba8 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -2517,6 +2517,7 @@ static void rdt_disable_ctx(void) static int rdt_enable_ctx(struct rdt_fs_context *ctx) { + struct rdt_resource *r; int ret = 0; if (ctx->enable_cdpl2) { @@ -2540,6 +2541,13 @@ static int rdt_enable_ctx(struct rdt_fs_context *ctx) if (ctx->enable_debug) resctrl_debug = true; + r = resctrl_arch_get_resource(RDT_RESOURCE_L2); + /* Only arm64 arch hides L2 resource by default */ + if (IS_ENABLED(CONFIG_ARM64_MPAM) && !ctx->enable_l2) + r->invisible = true; + else + r->invisible = false; + return 0; out_cdpl3: @@ -2762,6 +2770,7 @@ enum rdt_param { Opt_cdpl2, Opt_mba_mbps, Opt_debug, + Opt_l2, nr__rdt_params }; @@ -2770,6 +2779,7 @@ static const struct fs_parameter_spec rdt_fs_parameters[] = { fsparam_flag("cdpl2", Opt_cdpl2), fsparam_flag("mba_MBps", Opt_mba_mbps), fsparam_flag("debug", Opt_debug), + fsparam_flag("l2", Opt_l2), {} }; @@ -2798,6 +2808,9 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_debug: ctx->enable_debug = true; return 0; + case Opt_l2: + ctx->enable_l2 = true; + return 0; } return -EINVAL; @@ -3150,6 +3163,9 @@ static int mkdir_mondata_all(struct kernfs_node *parent_kn, if (!r->mon_capable) continue; + if (r->invisible) + continue; + ret = mkdir_mondata_subdir_alldom(kn, r, prgrp); if (ret) goto out_destroy; diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index ba716c3c6cfb..a59c01912a6f 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -216,6 +216,7 @@ struct rdt_resource { int rid; bool alloc_capable; bool mon_capable; + bool invisible; int num_rmid; int cache_level; struct resctrl_cache cache; -- 2.25.1

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 -------------------------------- When a CPU is brought offline, all registers of volatile msc components would loss configuration context. Because that MPAM driver refuses to set CPU offline when L2 msc is enabled. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 6 +++++- drivers/platform/mpam/mpam_internal.h | 2 ++ drivers/platform/mpam/mpam_resctrl.c | 29 +++++++++++++++++++++++++++ fs/resctrl/internal.h | 1 - include/linux/resctrl.h | 3 +++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 0bafdb83db45..85bb01e53376 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -1558,9 +1558,13 @@ static int mpam_discovery_cpu_online(unsigned int cpu) static int mpam_cpu_offline(unsigned int cpu) { - int idx; + int ret, idx; struct mpam_msc *msc; + ret = mpam_resctrl_prepare_offline(); + if (ret) + return ret; + idx = srcu_read_lock(&mpam_srcu); list_for_each_entry_rcu(msc, &mpam_all_msc, glbl_list) { if (!cpumask_test_cpu(cpu, &msc->accessibility)) diff --git a/drivers/platform/mpam/mpam_internal.h b/drivers/platform/mpam/mpam_internal.h index e9c52078edea..ff1890b3a78e 100644 --- a/drivers/platform/mpam/mpam_internal.h +++ b/drivers/platform/mpam/mpam_internal.h @@ -590,4 +590,6 @@ void mpam_resctrl_exit(void); */ #define MSMON_CAPT_EVNT_NOW BIT(0) +int mpam_resctrl_prepare_offline(void); + #endif /* MPAM_INTERNAL_H */ diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 17ecda4c7ab6..cdcadc4111e1 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -950,6 +950,14 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) */ if (has_csu && class->type == MPAM_CLASS_CACHE) r->mon_capable = true; + + /* + * The power domain of L2 cache msc is shared with the + * core's, which will cause information of the L2 msc to + * be lost when the core enter power down state. + */ + if (class->level <= 2) + r->is_volatile = true; break; case RDT_RESOURCE_MBA: @@ -1481,6 +1489,27 @@ int mpam_resctrl_online_cpu(unsigned int cpu) return 0; } +int mpam_resctrl_prepare_offline(void) +{ + struct mpam_resctrl_res *res; + int i; + + if (resctrl_mounted) { + for (i = 0; i < RDT_NUM_RESOURCES; i++) { + res = &mpam_resctrl_exports[i]; + + if (res->resctrl_res.is_volatile && + !res->resctrl_res.invisible) { + pr_info("%s is working, umount /sys/fs/resctrl first.\n", + res->resctrl_res.name); + return -EBUSY; + } + } + } + + return 0; +} + int mpam_resctrl_offline_cpu(unsigned int cpu) { int i; diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h index 9c6e6b8bd81a..839fbcf51ed2 100644 --- a/fs/resctrl/internal.h +++ b/fs/resctrl/internal.h @@ -97,7 +97,6 @@ struct rmid_read { }; extern struct list_head resctrl_schema_all; -extern bool resctrl_mounted; enum rdt_group_type { RDTCTRL_GROUP = 0, diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index a59c01912a6f..4f54c371d185 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -217,6 +217,7 @@ struct rdt_resource { bool alloc_capable; bool mon_capable; bool invisible; + bool is_volatile; int num_rmid; int cache_level; struct resctrl_cache cache; @@ -435,6 +436,8 @@ void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d); extern unsigned int resctrl_rmid_realloc_threshold; extern unsigned int resctrl_rmid_realloc_limit; +extern bool resctrl_mounted; + int resctrl_init(void); void resctrl_exit(void); -- 2.25.1

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1 -------------------------------- In case that L2 msc components lose configure context after entering cpuidle powerdown state, refuse to enter powerdown state since L2 msc specified by user. When resctrl fs is released from kernel, MPAM driver would restore all MSC partition with default values and enable cpuidle powerdown state again. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/arm64/kernel/mpam.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/mpam.c b/arch/arm64/kernel/mpam.c index d3ac3bfb5564..3f070cbab420 100644 --- a/arch/arm64/kernel/mpam.c +++ b/arch/arm64/kernel/mpam.c @@ -8,6 +8,7 @@ #include <linux/jump_label.h> #include <linux/percpu.h> #include <linux/crash_dump.h> +#include <linux/resctrl.h> DEFINE_STATIC_KEY_FALSE(arm64_mpam_has_hcr); DEFINE_STATIC_KEY_FALSE(mpam_enabled); @@ -18,9 +19,21 @@ static int mpam_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { u64 regval; - int cpu = smp_processor_id(); + struct rdt_resource *r; + int i, cpu = smp_processor_id(); switch (cmd) { + case CPU_PM_ENTER: + if (!resctrl_mounted) + return NOTIFY_OK; + + for (i = 0; i < RDT_NUM_RESOURCES; i++) { + r = resctrl_arch_get_resource(i); + if (!r->invisible && r->is_volatile) + return NOTIFY_BAD; + } + + return NOTIFY_OK; case CPU_PM_EXIT: /* * Don't use mpam_thread_switch() as the system register -- 2.25.1
participants (2)
-
patchwork bot
-
Zeng Heng