From nobody Sat Sep 27 21:20:23 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8FE732126B for ; Thu, 25 Sep 2025 20:04:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758830654; cv=none; b=TLXbWcSvCEMSDTKN7t4mpl3MKbiHWk8U0Rsh+Fkmk851FMmb52pdA6gTNlmqhvaRAqglw8zCIv7xkBZMDEGkIoQJ+F2WXis+VASOGoBT8BkJzL5WBabmlTBd2j0xhCY9V5veyUT4iKlwQAT3rJ8o3S/BMgmNpZA4m+LeZh6AOek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758830654; c=relaxed/simple; bh=twEWUzV9QVJG19A6MjLSnqqgXcexWoT8KTf5Py27uuU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dn9ojNDV9lR9qvQbjOihvZKFr/GoD87StdJw95Bvx/SyueKin6U+8T/YIS4YMOtAJmuvQQukhbYzNz74ri8BUjh/D5YJrNkgkreGWVrVwZkukD/S5yPJ5MpIhAO7b3NcK+shAipPCVviflj/209wQ/kQw7Mp+3aGp1TLNXGmInw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=KHyKYARs; arc=none smtp.client-ip=198.175.65.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="KHyKYARs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1758830652; x=1790366652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=twEWUzV9QVJG19A6MjLSnqqgXcexWoT8KTf5Py27uuU=; b=KHyKYARsHCHT1jXLFJcIgOLfkauHoVt7XszhhF//u8IeKTgdZZD05ml0 /FT880hmS/o7KdEPqkPq3obBP2R2qcS48mqpBf3Q4kwrVv8aw/zSJWK2X PBzx1Z3NvIo1TF3v4n/pVffTsSu65wjtaWuR0QHSNkOcOzaavv8LYoQmu XsephTFWA/QB6vNh0y34svHAcqZCzcOyNzWmQciLReLFQdNRvg6qEvIzp a7WXpND3iXCpUi+vLXSpKpuH3sYltI6NuW7WazNmoT5ZgN2yAoyIZylqN czWo6eLAnU8Sf64rSp/z3VSlJOUBmxaga8w4L91zqdaTRoapmUo4VMX+q Q==; X-CSE-ConnectionGUID: dEV3vWYPR7Wl4snitHB2OQ== X-CSE-MsgGUID: JGzWAmbSRr6sXQHE1xQReg== X-IronPort-AV: E=McAfee;i="6800,10657,11531"; a="61074211" X-IronPort-AV: E=Sophos;i="6.17,312,1747724400"; d="scan'208";a="61074211" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2025 13:04:08 -0700 X-CSE-ConnectionGUID: rBgxTjO7QK6dr7S2F3BQLQ== X-CSE-MsgGUID: 9TT6mFhTTvyYphXDum+m5Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,293,1751266800"; d="scan'208";a="177003630" Received: from inaky-mobl1.amr.corp.intel.com (HELO agluck-desk3.intel.com) ([10.124.220.206]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2025 13:04:07 -0700 From: Tony Luck To: Fenghua Yu , Reinette Chatre , Maciej Wieczor-Retman , Peter Newman , James Morse , Babu Moger , Drew Fustini , Dave Martin , Chen Yu Cc: x86@kernel.org, linux-kernel@vger.kernel.org, patches@lists.linux.dev, Tony Luck Subject: [PATCH v11 10/31] x86,fs/resctrl: Handle events that can be read from any CPU Date: Thu, 25 Sep 2025 13:03:04 -0700 Message-ID: <20250925200328.64155-11-tony.luck@intel.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925200328.64155-1-tony.luck@intel.com> References: <20250925200328.64155-1-tony.luck@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" resctrl assumes that monitor events can only be read from a CPU in the cpumask_t set of each domain. This is true for x86 events accessed with an MSR interface, but may not be true for other access methods such as MMIO. Add a flag to struct mon_evt, settable by architecture code, to indicate there are no restrictions on which CPU can read that event. Bypass all the smp_call*() code for events that can be read on any CPU and call mon_event_count() directly from mon_event_read(). Simplify CPU checking in __mon_event_count() with a helper. Signed-off-by: Tony Luck --- include/linux/resctrl.h | 2 +- fs/resctrl/internal.h | 2 ++ arch/x86/kernel/cpu/resctrl/core.c | 6 ++--- fs/resctrl/ctrlmondata.c | 6 +++++ fs/resctrl/monitor.c | 43 ++++++++++++++++++++++-------- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 66569662efee..22edd8d131d8 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -409,7 +409,7 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *r); u32 resctrl_arch_system_num_rmid_idx(void); int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid); =20 -void resctrl_enable_mon_event(enum resctrl_event_id eventid); +void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu); =20 bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid); =20 diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h index 12a2ab7e3c9b..40b76eaa33d0 100644 --- a/fs/resctrl/internal.h +++ b/fs/resctrl/internal.h @@ -61,6 +61,7 @@ static inline struct rdt_fs_context *rdt_fc2context(struc= t fs_context *fc) * READS_TO_REMOTE_MEM) being tracked by @evtid. * Only valid if @evtid is an MBM event. * @configurable: true if the event is configurable + * @any_cpu: true if the event can be read from any CPU * @enabled: true if the event is enabled */ struct mon_evt { @@ -69,6 +70,7 @@ struct mon_evt { char *name; u32 evt_cfg; bool configurable; + bool any_cpu; bool enabled; }; =20 diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resct= rl/core.c index 4762790c6e62..8db941fef7a0 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -889,15 +889,15 @@ static __init bool get_rdt_mon_resources(void) bool ret =3D false; =20 if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) { - resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID); + resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false); ret =3D true; } if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) { - resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID); + resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false); ret =3D true; } if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) { - resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID); + resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID, false); ret =3D true; } if (rdt_cpu_has(X86_FEATURE_ABMC)) diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c index 77602563cb1f..fbf55e61445c 100644 --- a/fs/resctrl/ctrlmondata.c +++ b/fs/resctrl/ctrlmondata.c @@ -574,6 +574,11 @@ void mon_event_read(struct rmid_read *rr, struct rdt_r= esource *r, } } =20 + if (evt->any_cpu) { + mon_event_count(rr); + goto out_ctx_free; + } + cpu =3D cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU); =20 /* @@ -587,6 +592,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_re= source *r, else smp_call_on_cpu(cpu, smp_mon_event_count, rr, false); =20 +out_ctx_free: if (rr->arch_mon_ctx) resctrl_arch_mon_ctx_free(r, evt->evtid, rr->arch_mon_ctx); } diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index ee08ffbacc2b..6f8a9b5a2f6b 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -413,9 +413,33 @@ static void mbm_cntr_free(struct rdt_l3_mon_domain *d,= int cntr_id) memset(&d->cntr_cfg[cntr_id], 0, sizeof(*d->cntr_cfg)); } =20 +/* + * Called from preemptible context via a direct call of mon_event_count() = for + * events that can be read on any CPU. + * Called from preemptible but non-migratable process context (mon_event_c= ount() + * via smp_call_on_cpu()) OR non-preemptible context (mon_event_count() via + * smp_call_function_any()) for events that need to be read on a specific = CPU. + */ +static bool cpu_on_correct_domain(struct rmid_read *rr) +{ + int cpu; + + /* Any CPU is OK for this event */ + if (rr->evt->any_cpu) + return true; + + cpu =3D smp_processor_id(); + + /* Single domain. Must be on a CPU in that domain. */ + if (rr->hdr) + return cpumask_test_cpu(cpu, &rr->hdr->cpu_mask); + + /* Summing domains that share a cache, must be on a CPU for that cache. */ + return cpumask_test_cpu(cpu, &rr->ci->shared_cpu_map); +} + static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr) { - int cpu =3D smp_processor_id(); u32 closid =3D rdtgrp->closid; u32 rmid =3D rdtgrp->mon.rmid; struct rdt_l3_mon_domain *d; @@ -424,6 +448,9 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, s= truct rmid_read *rr) int err, ret; u64 tval =3D 0; =20 + if (!cpu_on_correct_domain(rr)) + return -EINVAL; + if (!domain_header_is_valid(rr->hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3)) return -EINVAL; d =3D container_of(rr->hdr, struct rdt_l3_mon_domain, hdr); @@ -448,9 +475,6 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, s= truct rmid_read *rr) } =20 if (rr->hdr) { - /* Reading a single domain, must be on a CPU in that domain. */ - if (!cpumask_test_cpu(cpu, &rr->hdr->cpu_mask)) - return -EINVAL; if (rr->is_mbm_cntr) rr->err =3D resctrl_arch_cntr_read(rr->r, rr->hdr, closid, rmid, cntr_i= d, rr->evt->evtid, &tval); @@ -465,10 +489,6 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, = struct rmid_read *rr) return 0; } =20 - /* Summing domains that share a cache, must be on a CPU for that cache. */ - if (!cpumask_test_cpu(cpu, &rr->ci->shared_cpu_map)) - return -EINVAL; - /* * Legacy files must report the sum of an event across all * domains that share the same L3 cache instance. @@ -957,7 +977,7 @@ struct mon_evt mon_event_all[QOS_NUM_EVENTS] =3D { }, }; =20 -void resctrl_enable_mon_event(enum resctrl_event_id eventid) +void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu) { if (WARN_ON_ONCE(eventid < QOS_FIRST_EVENT || eventid >=3D QOS_NUM_EVENTS= )) return; @@ -966,6 +986,7 @@ void resctrl_enable_mon_event(enum resctrl_event_id eve= ntid) return; } =20 + mon_event_all[eventid].any_cpu =3D any_cpu; mon_event_all[eventid].enabled =3D true; } =20 @@ -1791,9 +1812,9 @@ int resctrl_l3_mon_resource_init(void) =20 if (r->mon.mbm_cntr_assignable) { if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID)) - resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID); + resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false); if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID)) - resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID); + resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID, false); mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg =3D r->mon.mbm_cfg_mask; mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg =3D r->mon.mbm_cfg_mask= & (READS_TO_LOCAL_MEM | --=20 2.51.0