From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 7BFA3224F3 for ; Sun, 2 Aug 2026 16:13:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687206; cv=none; b=NdkmzDOoJCzL77uzvTCUm+J1YTSRx1nNvEuWPZjDv55N4p0AjsayF3fR9S0omWn9aY/0FsMewd9dxmbXxKOta11QyaDCnCV61HFISgFbzT336n8pgObS5p5LbypyJ9K85aq0fxxDy61EFv5lYSxZZGKRDnIzhRe8elUI0tsvRxo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687206; c=relaxed/simple; bh=r8iS9Ot75lTVYQxmx6NYSQeVFAT+z1mRp7g/U2NqbdA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oneFdmyH13P3cTYcsp87tN7Yojo3bd7fKtgXXpu9+zUiOiUYmez6cP/0+dm3eBn7fD4FK0YQvPgi88GLDZrxwopzGRmKd1wrgBKQgognnqSgPsDQ8tbiXKu6ARowakmxBTv3ixAmAtcD1NByOcBhepvNkDHc5EabIub5x2uJdZI= 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=msBCc+OX; arc=none smtp.client-ip=192.198.163.15 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="msBCc+OX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785687205; x=1817223205; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r8iS9Ot75lTVYQxmx6NYSQeVFAT+z1mRp7g/U2NqbdA=; b=msBCc+OXckWj26t9llZeq3PcmzWz3U8Jgqa2YY+vOXGPEixcI+Uuyji+ X/3EOBqnrqQ31/X6AZUYjJ8WnnKDgHHAdRLwIGNBVijPuRQFe0bFaJCsL +4Raig7jbZ7OtIaHU7MyGA8OWbREUSIRaFROk+WmLEgAfxconAo50DCkt 00lsc/qYOGYHnTWPOuyjMAG4gy4JlT3nFWTKdHvYoxiVyDmt3DShGY+Wk PftSPPhZVhpKcsOadRk4D6p4PAP14vwAcd9xNeTd0iXtzfWKsCmR3BicY wM76bRvgveHhWQ7XrJPOdgRrdIlATuDggWA55zhMB8OPNI7FQX5AqjeX9 Q==; X-CSE-ConnectionGUID: ngbJDC3TTFuQTxGAtfEaWA== X-CSE-MsgGUID: YSuJ5ihIRdiucMxmzJ3TNg== X-IronPort-AV: E=McAfee;i="6800,10657,11863"; a="86361188" X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="86361188" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2026 09:13:24 -0700 X-CSE-ConnectionGUID: o18cZYP2SKCzlunLS/f5kg== X-CSE-MsgGUID: lhb6xcbdR9m0zqxjtoDOEQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="264483962" Received: from chenyu-dev.sh.intel.com ([10.239.62.107]) by orviesa003.jf.intel.com with ESMTP; 02 Aug 2026 09:13:21 -0700 From: Chen Yu To: Reinette Chatre , Tony Luck Cc: Ben Horgan , "James Morse" , Dave Martin , Babu Moger , Fenghua Yu , Borislav Petkov , Thomas Gleixner , "Dave Hansen" , Peter Newman , chen.yu@linux.dev, x86@kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 04/31] x86/resctrl: Attach ACPI ERDT information to L3 mon domain on CPU online Date: Mon, 3 Aug 2026 00:03:39 +0800 Message-Id: <801d71817536e67c85efc384505fac816c20827f.1785680802.git.yu.c.chen@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Reading LLC occupancy counters via MMIO requires the per-domain ERDT information, parsed earlier from the ACPI ERDT table, to be reachable from the resctrl L3 monitoring domain. Nothing links the two yet, so the monitoring code cannot locate the MMIO registers of a domain. ERDT and CPUID enumerate CPU-to-L3-domain membership independently: CPUID leaf 4 describes the L3 cache topology, while the firmware CACD sub-table lists the CPUs of each ERDT domain. Both views must agree on a CPU's L3 domain for that CPU to be monitored safely. When a CPU comes online, validate that firmware and CPUID agree on its L3 domain before adding it to a resctrl monitoring domain. Exclude the CPU from all monitoring domains on a mismatch because a topology inconsistency between ERDT and CPUID indicates a firmware defect that makes the CPU's domain placement unreliable for any resource. Otherwise attach the matching ERDT domain information to the L3 monitoring domain so that later code can read monitoring data via ERDT and its sub-tables. Suggested-by: Reinette Chatre Tested-by: Hongyu Ning Signed-off-by: Chen Yu --- arch/x86/kernel/cpu/resctrl/core.c | 11 ++++- arch/x86/kernel/cpu/resctrl/erdt.c | 66 ++++++++++++++++++++++++++ arch/x86/kernel/cpu/resctrl/internal.h | 5 ++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index e6f501c6782d..4e2922ec1dda 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -705,6 +705,9 @@ static void domain_add_cpu_mon(int cpu, struct rdt_resource *r) return; } + if (!erdt_cpu_valid(cpu)) + return; + hdr = resctrl_find_domain(&r->mon_domains, id, &add_pos); if (hdr) cpumask_set_cpu(cpu, &hdr->cpu_mask); @@ -714,8 +717,14 @@ static void domain_add_cpu_mon(int cpu, struct rdt_resource *r) /* Update the mbm_assign_mode state for the CPU if supported */ if (r->mon.mbm_cntr_assignable) resctrl_arch_mbm_cntr_assign_set_one(r); - if (!hdr) + if (!hdr) { l3_mon_domain_setup(cpu, id, r, add_pos); + hdr = resctrl_find_domain(&r->mon_domains, id, NULL); + } + + if (hdr) + erdt_l3_mon_domain_setup(cpu, hdr); + break; case RDT_RESOURCE_PERF_PKG: if (!hdr) diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c index 8998cae47090..6257869d0db2 100644 --- a/arch/x86/kernel/cpu/resctrl/erdt.c +++ b/arch/x86/kernel/cpu/resctrl/erdt.c @@ -207,6 +207,72 @@ static __init bool parse_rmdd_table(struct acpi_subtbl_hdr_16 *rmdd_hdr) return false; } +bool erdt_cpu_valid(int cpu) +{ + struct erdt_domain_info *d; + int dom_id; + + if (!erdt_enabled) + return true; + + dom_id = get_cpu_cacheinfo_id(cpu, RESCTRL_L3_CACHE); + if (dom_id < 0) + return true; + + /* + * Find the erdt_domain_info that contains this CPU, + * check if all CPUs in erdt_domain_info's cpumask + * have the same id(L3 id). + * + * For example, erdt_domain_info reports: + * domain0: CPU0, CPU2, domain1: CPU1, CPU3 + * rdt_domain_hdr reports: + * domain0: CPU0, CPU1, domain1: CPU2, CPU3 + * As a result, CPU1, CPU2 should not be covered by resctrl. + */ + list_for_each_entry(d, &domain_info_list, entry) { + + if (cpumask_test_cpu(cpu, &d->cpu_mask)) { + if (d->dom_id == -1) { + d->dom_id = dom_id; + } else if (d->dom_id != dom_id) { + pr_warn(FW_BUG "CPU%d's id=%d not equal to CACD domain(%*pbl) id=%d, skip this CPU\n", + cpu, dom_id, cpumask_pr_args(&d->cpu_mask), d->dom_id); + + return false; + } + + return true; + } + } + + pr_warn(FW_BUG "Cannot find CACD domain for CPU%d\n", cpu); + return false; +} + +/* + * Associate ERDT table information with this domain. + */ +void erdt_l3_mon_domain_setup(int cpu, struct rdt_domain_hdr *hdr) +{ + struct rdt_hw_l3_mon_domain *hw_dom; + struct erdt_domain_info *d; + + if (!erdt_enabled) + return; + + hw_dom = resctrl_to_arch_mon_dom(container_of(hdr, struct rdt_l3_mon_domain, hdr)); + + list_for_each_entry(d, &domain_info_list, entry) { + if (cpumask_test_cpu(cpu, &d->cpu_mask)) { + /* Assign the ERDT information to hw_dom */ + if (!hw_dom->d_info) + hw_dom->d_info = d; + return; + } + } +} + void erdt_exit(void) { struct erdt_domain_info *d, *tmp; diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index 95e971c934e6..d6e82eb570a3 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -132,14 +132,19 @@ struct rdt_hw_ctrl_domain { * @arch_mbm_states: Per-event pointer to the MBM event's saved state. * An MBM event's state is an array of struct arch_mbm_state * indexed by RMID on x86. + * @d_info: ERDT table information of this domain * * Members of this structure are accessed via helpers that provide abstraction. */ struct rdt_hw_l3_mon_domain { struct rdt_l3_mon_domain d_resctrl; struct arch_mbm_state *arch_mbm_states[QOS_NUM_L3_MBM_EVENTS]; + const struct erdt_domain_info *d_info; }; +bool erdt_cpu_valid(int cpu); +void erdt_l3_mon_domain_setup(int cpu, struct rdt_domain_hdr *hdr); + static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r) { return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl); -- 2.43.0