* [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU
@ 2024-11-28 0:22 Ricardo Neri
2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Ricardo Neri @ 2024-11-28 0:22 UTC (permalink / raw)
To: x86
Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown,
Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki,
Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui,
Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel
Hi,
This is v8 of a patchset to fix the cache sysfs interface by setting the
number of cache leaves independently for each CPU. This version merges
patches 2 and 3 from v7 into one as Borislav suggested. I also dropped
the wrappers functions I had added to access per-CPU cache info
(ci_cpu_cacheinfo).
It looked OK to me to keep the Reviewed-by and Tested-by tags collected
so far as all feedback still applies and changes were minor. I hope
reviewers are OK!
Previous versions can be found in [1], [2], [3], [4], [5], [6], and [7].
Below is the (updated) cover letter from v6 for reference:
The interface /sys/devices/system/cpu/cpuX/cache is broken (not populated)
if CPUs have different numbers of subleaves in CPUID 4. This is the case
of Intel Meteor Lake, which now is out in the world. Tools that rely on
sysfs (e.g., lstopo) fail.
Patch 2 fixes the described issue on Meteor Lake. Patch 1 deals with
prework in the cacheinfo base driver to fix issues uncovered while updating
cacheinfo for x86.
All the tests described in detail in [8] and [9] passed. This is the
summary:
* /sys/devices/system/cpu/cpuX/cache is populated in Meteor Lake.
* No inconsistencies are found in /sys/devices/system/cpu/cpuX/cache
and the tools x86info, lstopo, and lscpu.
* No splat is observed with and without CONFIG_PREEMPT_RT.
* No new warnings/errors are seen the kernel log.
* Tests done on assorted Intel and AMD client and server parts.
Changes since v7:
* Merged patches 2/3 into one. (Borislav)
* Dropped wrapper functions for ci_cpu_cacheinfo. (Borislav)
* Check for zero cache leaves in init_cache_level() for x86.
(Borislav)
* Removed an ugly line break. (Borislav)
Changes since v6:
* Merged patches 1 and 2 into one. (Borislav)
* Fixed an formatting issue in allocate_cache_info(). (Borislav)
Changes since v5:
* Reordered the arguments of set_num_cache_leaves().
* Fixed wording on the subject of patch 2.
* Added Reviewed-by tags from Andreas and Nikolay. Thanks!
* Added Tested-by tags from Andreas. Thanks!
Changes since v4:
* Combined two condition checks into one line. (Sudeep)
* Added one more Reviewed-by tag from Sudeep. Thanks!
Changes since v3:
* Fixed another NULL-pointer dereference when checking the validity of
the last-level cache info.
* Added the Reviewed-by tags from Radu and Sudeep. Thanks!
* Rebased on v6.7-rc5.
Changes since v2:
* This version uncovered a NULL-pointer dereference in recent changes to
cacheinfo[10]. This dereference is observed when the system does not
configure cacheinfo early during boot nor makes corrections later
during CPU hotplug; as is the case in x86. Patch 1 fixes this issue.
Changes since v1:
* Dave Hansen suggested to use the existing per-CPU ci_cpu_cacheinfo
variable. Now the global variable num_cache_leaves became useless.
* While here, I noticed that init_cache_level() also became useless:
x86 does not need ci_cpu_cacheinfo::num_levels.
Thanks and BR,
Ricardo
[1]. https://lore.kernel.org/lkml/20230314231658.30169-1-ricardo.neri-calderon@linux.intel.com/
[2]. https://lore.kernel.org/all/20230424001956.21434-1-ricardo.neri-calderon@linux.intel.com/
[3]. https://lore.kernel.org/lkml/20230805012421.7002-1-ricardo.neri-calderon@linux.intel.com/
[4]. https://lore.kernel.org/all/20231212222519.12834-1-ricardo.neri-calderon@linux.intel.com/
[5]. https://lore.kernel.org/all/20240827051635.9114-1-ricardo.neri-calderon@linux.intel.com/
[6]. https://lore.kernel.org/all/20240905060036.5655-1-ricardo.neri-calderon@linux.intel.com/
[7]. https://lore.kernel.org/all/20240913083155.9783-1-ricardo.neri-calderon@linux.intel.com/
[8]. https://lore.kernel.org/lkml/20230912032350.GA17008@ranerica-svr.sc.intel.com/
[9]. https://lore.kernel.org/all/20240902074140.GA4179@alberich/
[10]. https://lore.kernel.org/all/20230412185759.755408-1-rrendec@redhat.com/
Ricardo Neri (2):
cacheinfo: Allocate memory during CPU hotplug if not done from the
primary CPU
x86/cacheinfo: Delete global num_cache_leaves
arch/x86/kernel/cpu/cacheinfo.c | 41 +++++++++++++++------------------
drivers/base/cacheinfo.c | 11 +++++----
2 files changed, 25 insertions(+), 27 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread* [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Ricardo Neri @ 2024-11-28 0:22 ` Ricardo Neri 2024-11-29 16:12 ` Radu Rendec ` (4 more replies) 2024-11-28 0:22 ` [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves Ricardo Neri 2024-11-28 9:30 ` [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Borislav Petkov 2 siblings, 5 replies; 23+ messages in thread From: Ricardo Neri @ 2024-11-28 0:22 UTC (permalink / raw) To: x86 Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") adds functionality that architectures can use to optionally allocate and build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") lets secondary CPUs correct (and reallocate memory) cacheinfo data if needed. If the early build functionality is not used and cacheinfo does not need correction, memory for cacheinfo is never allocated. x86 does not use the early build functionality. Consequently, during the cacheinfo CPU hotplug callback, last_level_cache_is_valid() attempts to dereference a NULL pointer: BUG: kernel NULL pointer dereference, address: 0000000000000100 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not present page PGD 0 P4D 0 Oops: 0000 [#1] PREEPMT SMP NOPTI CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 RIP: 0010: last_level_cache_is_valid+0x95/0xe0a Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if not done earlier. Moreover, before determining the validity of the last-level cache info, ensure that it has been allocated. Simply checking for non-zero cache_leaves() is not sufficient, as some architectures (e.g., Intel processors) have non-zero cache_leaves() before allocation. Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). This function iterates over all online CPUs. However, a CPU may have come online recently, but its cacheinfo may not have been allocated yet. While here, remove an unnecessary indentation in allocate_cache_info(). Reviewed-by: Andreas Herrmann <aherrmann@suse.de> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Reviewed-by: Radu Rendec <rrendec@redhat.com> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Tested-by: Andreas Herrmann <aherrmann@suse.de> Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> --- Cc: Andreas Herrmann <aherrmann@suse.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Chen Yu <yu.c.chen@intel.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Len Brown <len.brown@intel.com> Cc: Nikolay Borisov <nik.borisov@suse.com> Cc: Radu Rendec <rrendec@redhat.com> Cc: Pierre Gondois <Pierre.Gondois@arm.com> Cc: Pu Wen <puwen@hygon.cn> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: Will Deacon <will@kernel.org> Cc: Zhang Rui <rui.zhang@intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: stable@vger.kernel.org # 6.3+ --- Change since v7: * None Changes since v6: * Merged patches 1 and 2 of v6 into one. (Borislav) * Merged the history of patches 1 and 2ino this patch. * Kept the Reviewed-by and Tested-by tags from the two merged patches. * Fixed a formatting issue in allocate_cache_info(). (Borislav) Changes since v5: * Fixed nonsensical subject (Nikolay). * Added Reviewed-by and Tested-by tags from Andreas. Thanks! * Added Reviewed-by tag from Nikolay. Thanks! Changes since v4: * Combined checks for per_cpu_cacheinfo() and cache_leaves() in a single line. (Sudeep) * Added Reviewed-by tag from Sudeep. Thanks! Changes since v3: * Added Reviewed-by tag from Radu and Sudeep. Thanks! Changes since v2: * Introduced this patch. Changes since v1: * N/A --- The motivation for commit 5944ce092b97 was to prevent a BUG splat in PREEMPT_RT kernels during memory allocation. This splat is not observed on x86 because the memory allocation for cacheinfo happens in detect_cache_attributes() from the cacheinfo CPU hotplug callback. The dereference of a NULL cacheinfo is not observed today because cache_leaves(cpu) is zero until after init_cache_level() is called (during the CPU hotplug callback). A subsequent changeset will set the number of cache leaves earlier and the NULL-pointer dereference will be observed. --- drivers/base/cacheinfo.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 7a7609298e18..a1afc478e0e8 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -58,7 +58,7 @@ bool last_level_cache_is_valid(unsigned int cpu) { struct cacheinfo *llc; - if (!cache_leaves(cpu)) + if (!cache_leaves(cpu) || !per_cpu_cacheinfo(cpu)) return false; llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); @@ -466,8 +466,7 @@ int __weak populate_cache_leaves(unsigned int cpu) static inline int allocate_cache_info(int cpu) { - per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), - sizeof(struct cacheinfo), GFP_ATOMIC); + per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), sizeof(struct cacheinfo), GFP_ATOMIC); if (!per_cpu_cacheinfo(cpu)) { cache_leaves(cpu) = 0; return -ENOMEM; @@ -539,7 +538,11 @@ static inline int init_level_allocate_ci(unsigned int cpu) */ ci_cacheinfo(cpu)->early_ci_levels = false; - if (cache_leaves(cpu) <= early_leaves) + /* + * Some architectures (e.g., x86) do not use early initialization. + * Allocate memory now in such case. + */ + if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu)) return 0; kfree(per_cpu_cacheinfo(cpu)); -- 2.34.1 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri @ 2024-11-29 16:12 ` Radu Rendec 2024-12-01 22:39 ` Ricardo Neri 2024-12-02 6:53 ` Nikolay Borisov ` (3 subsequent siblings) 4 siblings, 1 reply; 23+ messages in thread From: Radu Rendec @ 2024-11-29 16:12 UTC (permalink / raw) To: Ricardo Neri, x86 Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, 2024-11-27 at 16:22 -0800, Ricardo Neri wrote: > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > adds functionality that architectures can use to optionally allocate and > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > arch specific early level initializer") lets secondary CPUs correct (and > reallocate memory) cacheinfo data if needed. > > If the early build functionality is not used and cacheinfo does not need > correction, memory for cacheinfo is never allocated. x86 does not use the > early build functionality. Consequently, during the cacheinfo CPU hotplug > callback, last_level_cache_is_valid() attempts to dereference a NULL > pointer: > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > #PF: supervisor read access in kernel mode > #PF: error_code(0x0000) - not present page > PGD 0 P4D 0 > Oops: 0000 [#1] PREEPMT SMP NOPTI > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > not done earlier. > > Moreover, before determining the validity of the last-level cache info, > ensure that it has been allocated. Simply checking for non-zero > cache_leaves() is not sufficient, as some architectures (e.g., Intel > processors) have non-zero cache_leaves() before allocation. > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > This function iterates over all online CPUs. However, a CPU may have come > online recently, but its cacheinfo may not have been allocated yet. > > While here, remove an unnecessary indentation in allocate_cache_info(). > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > Reviewed-by: Radu Rendec <rrendec@redhat.com> > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > Tested-by: Andreas Herrmann <aherrmann@suse.de> > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> > --- > Cc: Andreas Herrmann <aherrmann@suse.com> > Cc: Catalin Marinas <catalin.marinas@arm.com> > Cc: Chen Yu <yu.c.chen@intel.com> > Cc: Huang Ying <ying.huang@intel.com> > Cc: Len Brown <len.brown@intel.com> > Cc: Nikolay Borisov <nik.borisov@suse.com> > Cc: Radu Rendec <rrendec@redhat.com> > Cc: Pierre Gondois <Pierre.Gondois@arm.com> > Cc: Pu Wen <puwen@hygon.cn> > Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> > Cc: Sudeep Holla <sudeep.holla@arm.com> > Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> > Cc: Will Deacon <will@kernel.org> > Cc: Zhang Rui <rui.zhang@intel.com> > Cc: linux-arm-kernel@lists.infradead.org > Cc: stable@vger.kernel.org # 6.3+ > --- > Change since v7: > * None > > Changes since v6: > * Merged patches 1 and 2 of v6 into one. (Borislav) > * Merged the history of patches 1 and 2ino this patch. > * Kept the Reviewed-by and Tested-by tags from the two merged patches. > * Fixed a formatting issue in allocate_cache_info(). (Borislav) > > Changes since v5: > * Fixed nonsensical subject (Nikolay). > * Added Reviewed-by and Tested-by tags from Andreas. Thanks! > * Added Reviewed-by tag from Nikolay. Thanks! > > Changes since v4: > * Combined checks for per_cpu_cacheinfo() and cache_leaves() in a single > line. (Sudeep) > * Added Reviewed-by tag from Sudeep. Thanks! > > Changes since v3: > * Added Reviewed-by tag from Radu and Sudeep. Thanks! > > Changes since v2: > * Introduced this patch. > > Changes since v1: > * N/A > > --- > The motivation for commit 5944ce092b97 was to prevent a BUG splat in > PREEMPT_RT kernels during memory allocation. This splat is not observed on > x86 because the memory allocation for cacheinfo happens in > detect_cache_attributes() from the cacheinfo CPU hotplug callback. > > The dereference of a NULL cacheinfo is not observed today because > cache_leaves(cpu) is zero until after init_cache_level() is called > (during the CPU hotplug callback). A subsequent changeset will set > the number of cache leaves earlier and the NULL-pointer dereference > will be observed. > --- > drivers/base/cacheinfo.c | 11 +++++++---- > 1 file changed, 7 insertions(+), 4 deletions(-) > > diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c > index 7a7609298e18..a1afc478e0e8 100644 > --- a/drivers/base/cacheinfo.c > +++ b/drivers/base/cacheinfo.c > @@ -58,7 +58,7 @@ bool last_level_cache_is_valid(unsigned int cpu) > { > struct cacheinfo *llc; > > - if (!cache_leaves(cpu)) > + if (!cache_leaves(cpu) || !per_cpu_cacheinfo(cpu)) > return false; > > llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); > @@ -466,8 +466,7 @@ int __weak populate_cache_leaves(unsigned int cpu) > static inline > int allocate_cache_info(int cpu) > { > - per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), > - sizeof(struct cacheinfo), GFP_ATOMIC); > + per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), sizeof(struct cacheinfo), GFP_ATOMIC); > if (!per_cpu_cacheinfo(cpu)) { > cache_leaves(cpu) = 0; > return -ENOMEM; > @@ -539,7 +538,11 @@ static inline int init_level_allocate_ci(unsigned int cpu) > */ > ci_cacheinfo(cpu)->early_ci_levels = false; > > - if (cache_leaves(cpu) <= early_leaves) > + /* > + * Some architectures (e.g., x86) do not use early initialization. > + * Allocate memory now in such case. > + */ > + if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu)) > return 0; > > kfree(per_cpu_cacheinfo(cpu)); Since Borislav explicitly said you were not supposed to keep the tags, I reviewed it again, and I'm OK to keep mine. Thanks! Reviewed-by: Radu Rendec <rrendec@redhat.com> -- Best regards, Radu ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-29 16:12 ` Radu Rendec @ 2024-12-01 22:39 ` Ricardo Neri 0 siblings, 0 replies; 23+ messages in thread From: Ricardo Neri @ 2024-12-01 22:39 UTC (permalink / raw) To: Radu Rendec Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Fri, Nov 29, 2024 at 11:12:52AM -0500, Radu Rendec wrote: > On Wed, 2024-11-27 at 16:22 -0800, Ricardo Neri wrote: > > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > > adds functionality that architectures can use to optionally allocate and > > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > > arch specific early level initializer") lets secondary CPUs correct (and > > reallocate memory) cacheinfo data if needed. > > > > If the early build functionality is not used and cacheinfo does not need > > correction, memory for cacheinfo is never allocated. x86 does not use the > > early build functionality. Consequently, during the cacheinfo CPU hotplug > > callback, last_level_cache_is_valid() attempts to dereference a NULL > > pointer: > > > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > > #PF: supervisor read access in kernel mode > > #PF: error_code(0x0000) - not present page > > PGD 0 P4D 0 > > Oops: 0000 [#1] PREEPMT SMP NOPTI > > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > > not done earlier. > > > > Moreover, before determining the validity of the last-level cache info, > > ensure that it has been allocated. Simply checking for non-zero > > cache_leaves() is not sufficient, as some architectures (e.g., Intel > > processors) have non-zero cache_leaves() before allocation. > > > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > > This function iterates over all online CPUs. However, a CPU may have come > > online recently, but its cacheinfo may not have been allocated yet. > > > > While here, remove an unnecessary indentation in allocate_cache_info(). > > > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > > Reviewed-by: Radu Rendec <rrendec@redhat.com> > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > > Tested-by: Andreas Herrmann <aherrmann@suse.de> > > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> > > --- > > Cc: Andreas Herrmann <aherrmann@suse.com> > > Cc: Catalin Marinas <catalin.marinas@arm.com> > > Cc: Chen Yu <yu.c.chen@intel.com> > > Cc: Huang Ying <ying.huang@intel.com> > > Cc: Len Brown <len.brown@intel.com> > > Cc: Nikolay Borisov <nik.borisov@suse.com> > > Cc: Radu Rendec <rrendec@redhat.com> > > Cc: Pierre Gondois <Pierre.Gondois@arm.com> > > Cc: Pu Wen <puwen@hygon.cn> > > Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> > > Cc: Sudeep Holla <sudeep.holla@arm.com> > > Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> > > Cc: Will Deacon <will@kernel.org> > > Cc: Zhang Rui <rui.zhang@intel.com> > > Cc: linux-arm-kernel@lists.infradead.org > > Cc: stable@vger.kernel.org # 6.3+ > > --- > > Change since v7: > > * None > > > > Changes since v6: > > * Merged patches 1 and 2 of v6 into one. (Borislav) > > * Merged the history of patches 1 and 2ino this patch. > > * Kept the Reviewed-by and Tested-by tags from the two merged patches. > > * Fixed a formatting issue in allocate_cache_info(). (Borislav) > > > > Changes since v5: > > * Fixed nonsensical subject (Nikolay). > > * Added Reviewed-by and Tested-by tags from Andreas. Thanks! > > * Added Reviewed-by tag from Nikolay. Thanks! > > > > Changes since v4: > > * Combined checks for per_cpu_cacheinfo() and cache_leaves() in a single > > line. (Sudeep) > > * Added Reviewed-by tag from Sudeep. Thanks! > > > > Changes since v3: > > * Added Reviewed-by tag from Radu and Sudeep. Thanks! > > > > Changes since v2: > > * Introduced this patch. > > > > Changes since v1: > > * N/A > > > > --- > > The motivation for commit 5944ce092b97 was to prevent a BUG splat in > > PREEMPT_RT kernels during memory allocation. This splat is not observed on > > x86 because the memory allocation for cacheinfo happens in > > detect_cache_attributes() from the cacheinfo CPU hotplug callback. > > > > The dereference of a NULL cacheinfo is not observed today because > > cache_leaves(cpu) is zero until after init_cache_level() is called > > (during the CPU hotplug callback). A subsequent changeset will set > > the number of cache leaves earlier and the NULL-pointer dereference > > will be observed. > > --- > > drivers/base/cacheinfo.c | 11 +++++++---- > > 1 file changed, 7 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c > > index 7a7609298e18..a1afc478e0e8 100644 > > --- a/drivers/base/cacheinfo.c > > +++ b/drivers/base/cacheinfo.c > > @@ -58,7 +58,7 @@ bool last_level_cache_is_valid(unsigned int cpu) > > { > > struct cacheinfo *llc; > > > > - if (!cache_leaves(cpu)) > > + if (!cache_leaves(cpu) || !per_cpu_cacheinfo(cpu)) > > return false; > > > > llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); > > @@ -466,8 +466,7 @@ int __weak populate_cache_leaves(unsigned int cpu) > > static inline > > int allocate_cache_info(int cpu) > > { > > - per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), > > - sizeof(struct cacheinfo), GFP_ATOMIC); > > + per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), sizeof(struct cacheinfo), GFP_ATOMIC); > > if (!per_cpu_cacheinfo(cpu)) { > > cache_leaves(cpu) = 0; > > return -ENOMEM; > > @@ -539,7 +538,11 @@ static inline int init_level_allocate_ci(unsigned int cpu) > > */ > > ci_cacheinfo(cpu)->early_ci_levels = false; > > > > - if (cache_leaves(cpu) <= early_leaves) > > + /* > > + * Some architectures (e.g., x86) do not use early initialization. > > + * Allocate memory now in such case. > > + */ > > + if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu)) > > return 0; > > > > kfree(per_cpu_cacheinfo(cpu)); > > Since Borislav explicitly said you were not supposed to keep the tags, > I reviewed it again, and I'm OK to keep mine. Thanks! > > Reviewed-by: Radu Rendec <rrendec@redhat.com> Thank you! ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri 2024-11-29 16:12 ` Radu Rendec @ 2024-12-02 6:53 ` Nikolay Borisov 2024-12-03 4:09 ` Ricardo Neri 2024-12-02 8:02 ` Andreas Herrmann ` (2 subsequent siblings) 4 siblings, 1 reply; 23+ messages in thread From: Nikolay Borisov @ 2024-12-02 6:53 UTC (permalink / raw) To: Ricardo Neri, x86 Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Huang Ying, Ricardo Neri, linux-kernel On 28.11.24 г. 2:22 ч., Ricardo Neri wrote: > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > adds functionality that architectures can use to optionally allocate and > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > arch specific early level initializer") lets secondary CPUs correct (and > reallocate memory) cacheinfo data if needed. > > If the early build functionality is not used and cacheinfo does not need > correction, memory for cacheinfo is never allocated. x86 does not use the > early build functionality. Consequently, during the cacheinfo CPU hotplug > callback, last_level_cache_is_valid() attempts to dereference a NULL > pointer: > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > #PF: supervisor read access in kernel mode > #PF: error_code(0x0000) - not present page > PGD 0 P4D 0 > Oops: 0000 [#1] PREEPMT SMP NOPTI > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > not done earlier. > > Moreover, before determining the validity of the last-level cache info, > ensure that it has been allocated. Simply checking for non-zero > cache_leaves() is not sufficient, as some architectures (e.g., Intel > processors) have non-zero cache_leaves() before allocation. > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > This function iterates over all online CPUs. However, a CPU may have come > online recently, but its cacheinfo may not have been allocated yet. > > While here, remove an unnecessary indentation in allocate_cache_info(). > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > Reviewed-by: Radu Rendec <rrendec@redhat.com> > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > Tested-by: Andreas Herrmann <aherrmann@suse.de> > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-12-02 6:53 ` Nikolay Borisov @ 2024-12-03 4:09 ` Ricardo Neri 0 siblings, 0 replies; 23+ messages in thread From: Ricardo Neri @ 2024-12-03 4:09 UTC (permalink / raw) To: Nikolay Borisov Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Huang Ying, Ricardo Neri, linux-kernel On Mon, Dec 02, 2024 at 08:53:44AM +0200, Nikolay Borisov wrote: > > > On 28.11.24 г. 2:22 ч., Ricardo Neri wrote: > > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > > adds functionality that architectures can use to optionally allocate and > > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > > arch specific early level initializer") lets secondary CPUs correct (and > > reallocate memory) cacheinfo data if needed. > > > > If the early build functionality is not used and cacheinfo does not need > > correction, memory for cacheinfo is never allocated. x86 does not use the > > early build functionality. Consequently, during the cacheinfo CPU hotplug > > callback, last_level_cache_is_valid() attempts to dereference a NULL > > pointer: > > > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > > #PF: supervisor read access in kernel mode > > #PF: error_code(0x0000) - not present page > > PGD 0 P4D 0 > > Oops: 0000 [#1] PREEPMT SMP NOPTI > > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > > not done earlier. > > > > Moreover, before determining the validity of the last-level cache info, > > ensure that it has been allocated. Simply checking for non-zero > > cache_leaves() is not sufficient, as some architectures (e.g., Intel > > processors) have non-zero cache_leaves() before allocation. > > > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > > This function iterates over all online CPUs. However, a CPU may have come > > online recently, but its cacheinfo may not have been allocated yet. > > > > While here, remove an unnecessary indentation in allocate_cache_info(). > > > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > > Reviewed-by: Radu Rendec <rrendec@redhat.com> > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > > Tested-by: Andreas Herrmann <aherrmann@suse.de> > > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> > > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Thank you! ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri 2024-11-29 16:12 ` Radu Rendec 2024-12-02 6:53 ` Nikolay Borisov @ 2024-12-02 8:02 ` Andreas Herrmann 2024-12-03 4:09 ` Ricardo Neri 2024-12-02 11:03 ` Sudeep Holla 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 4 siblings, 1 reply; 23+ messages in thread From: Andreas Herrmann @ 2024-12-02 8:02 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Nov 27, 2024 at 04:22:46PM -0800, Ricardo Neri wrote: > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > adds functionality that architectures can use to optionally allocate and > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > arch specific early level initializer") lets secondary CPUs correct (and > reallocate memory) cacheinfo data if needed. > > If the early build functionality is not used and cacheinfo does not need > correction, memory for cacheinfo is never allocated. x86 does not use the > early build functionality. Consequently, during the cacheinfo CPU hotplug > callback, last_level_cache_is_valid() attempts to dereference a NULL > pointer: > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > #PF: supervisor read access in kernel mode > #PF: error_code(0x0000) - not present page > PGD 0 P4D 0 > Oops: 0000 [#1] PREEPMT SMP NOPTI > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > not done earlier. > > Moreover, before determining the validity of the last-level cache info, > ensure that it has been allocated. Simply checking for non-zero > cache_leaves() is not sufficient, as some architectures (e.g., Intel > processors) have non-zero cache_leaves() before allocation. > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > This function iterates over all online CPUs. However, a CPU may have come > online recently, but its cacheinfo may not have been allocated yet. > > While here, remove an unnecessary indentation in allocate_cache_info(). > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > Reviewed-by: Radu Rendec <rrendec@redhat.com> > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > Tested-by: Andreas Herrmann <aherrmann@suse.de> > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> > --- Reviewed-by: Andreas Herrmann <aherrmann@suse.de> -- Regards, Andreas ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-12-02 8:02 ` Andreas Herrmann @ 2024-12-03 4:09 ` Ricardo Neri 0 siblings, 0 replies; 23+ messages in thread From: Ricardo Neri @ 2024-12-03 4:09 UTC (permalink / raw) To: Andreas Herrmann Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Mon, Dec 02, 2024 at 09:02:03AM +0100, Andreas Herrmann wrote: > On Wed, Nov 27, 2024 at 04:22:46PM -0800, Ricardo Neri wrote: > > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > > adds functionality that architectures can use to optionally allocate and > > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > > arch specific early level initializer") lets secondary CPUs correct (and > > reallocate memory) cacheinfo data if needed. > > > > If the early build functionality is not used and cacheinfo does not need > > correction, memory for cacheinfo is never allocated. x86 does not use the > > early build functionality. Consequently, during the cacheinfo CPU hotplug > > callback, last_level_cache_is_valid() attempts to dereference a NULL > > pointer: > > > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > > #PF: supervisor read access in kernel mode > > #PF: error_code(0x0000) - not present page > > PGD 0 P4D 0 > > Oops: 0000 [#1] PREEPMT SMP NOPTI > > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > > not done earlier. > > > > Moreover, before determining the validity of the last-level cache info, > > ensure that it has been allocated. Simply checking for non-zero > > cache_leaves() is not sufficient, as some architectures (e.g., Intel > > processors) have non-zero cache_leaves() before allocation. > > > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > > This function iterates over all online CPUs. However, a CPU may have come > > online recently, but its cacheinfo may not have been allocated yet. > > > > While here, remove an unnecessary indentation in allocate_cache_info(). > > > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > > Reviewed-by: Radu Rendec <rrendec@redhat.com> > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > > Tested-by: Andreas Herrmann <aherrmann@suse.de> > > Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") > > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> > > --- > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> Thank you! ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri ` (2 preceding siblings ...) 2024-12-02 8:02 ` Andreas Herrmann @ 2024-12-02 11:03 ` Sudeep Holla 2024-12-03 4:08 ` Ricardo Neri 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 4 siblings, 1 reply; 23+ messages in thread From: Sudeep Holla @ 2024-12-02 11:03 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Sudeep Holla, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Nov 27, 2024 at 04:22:46PM -0800, Ricardo Neri wrote: > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > adds functionality that architectures can use to optionally allocate and > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > arch specific early level initializer") lets secondary CPUs correct (and > reallocate memory) cacheinfo data if needed. > > If the early build functionality is not used and cacheinfo does not need > correction, memory for cacheinfo is never allocated. x86 does not use the > early build functionality. Consequently, during the cacheinfo CPU hotplug > callback, last_level_cache_is_valid() attempts to dereference a NULL > pointer: > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > #PF: supervisor read access in kernel mode > #PF: error_code(0x0000) - not present page > PGD 0 P4D 0 > Oops: 0000 [#1] PREEPMT SMP NOPTI > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > not done earlier. > > Moreover, before determining the validity of the last-level cache info, > ensure that it has been allocated. Simply checking for non-zero > cache_leaves() is not sufficient, as some architectures (e.g., Intel > processors) have non-zero cache_leaves() before allocation. > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > This function iterates over all online CPUs. However, a CPU may have come > online recently, but its cacheinfo may not have been allocated yet. > > While here, remove an unnecessary indentation in allocate_cache_info(). > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > Reviewed-by: Radu Rendec <rrendec@redhat.com> > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> In case old tags are deemed null 😄, Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> -- Regards, Sudeep ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-12-02 11:03 ` Sudeep Holla @ 2024-12-03 4:08 ` Ricardo Neri 0 siblings, 0 replies; 23+ messages in thread From: Ricardo Neri @ 2024-12-03 4:08 UTC (permalink / raw) To: Sudeep Holla Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Mon, Dec 02, 2024 at 11:03:49AM +0000, Sudeep Holla wrote: > On Wed, Nov 27, 2024 at 04:22:46PM -0800, Ricardo Neri wrote: > > Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") > > adds functionality that architectures can use to optionally allocate and > > build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add > > arch specific early level initializer") lets secondary CPUs correct (and > > reallocate memory) cacheinfo data if needed. > > > > If the early build functionality is not used and cacheinfo does not need > > correction, memory for cacheinfo is never allocated. x86 does not use the > > early build functionality. Consequently, during the cacheinfo CPU hotplug > > callback, last_level_cache_is_valid() attempts to dereference a NULL > > pointer: > > > > BUG: kernel NULL pointer dereference, address: 0000000000000100 > > #PF: supervisor read access in kernel mode > > #PF: error_code(0x0000) - not present page > > PGD 0 P4D 0 > > Oops: 0000 [#1] PREEPMT SMP NOPTI > > CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 > > RIP: 0010: last_level_cache_is_valid+0x95/0xe0a > > > > Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if > > not done earlier. > > > > Moreover, before determining the validity of the last-level cache info, > > ensure that it has been allocated. Simply checking for non-zero > > cache_leaves() is not sufficient, as some architectures (e.g., Intel > > processors) have non-zero cache_leaves() before allocation. > > > > Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). > > This function iterates over all online CPUs. However, a CPU may have come > > online recently, but its cacheinfo may not have been allocated yet. > > > > While here, remove an unnecessary indentation in allocate_cache_info(). > > > > Reviewed-by: Andreas Herrmann <aherrmann@suse.de> > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> > > Reviewed-by: Radu Rendec <rrendec@redhat.com> > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> > > In case old tags are deemed null 😄, > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Thank you! ^ permalink raw reply [flat|nested] 23+ messages in thread
* [tip: x86/urgent] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri ` (3 preceding siblings ...) 2024-12-02 11:03 ` Sudeep Holla @ 2024-12-06 12:24 ` tip-bot2 for Ricardo Neri 4 siblings, 0 replies; 23+ messages in thread From: tip-bot2 for Ricardo Neri @ 2024-12-06 12:24 UTC (permalink / raw) To: linux-tip-commits Cc: Ricardo Neri, Borislav Petkov (AMD), Radu Rendec, Nikolay Borisov, Andreas Herrmann, Sudeep Holla, stable, #, 6.3+, x86, linux-kernel The following commit has been merged into the x86/urgent branch of tip: Commit-ID: b3fce429a1e030b50c1c91351d69b8667eef627b Gitweb: https://git.kernel.org/tip/b3fce429a1e030b50c1c91351d69b8667eef627b Author: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> AuthorDate: Wed, 27 Nov 2024 16:22:46 -08:00 Committer: Borislav Petkov (AMD) <bp@alien8.de> CommitterDate: Fri, 06 Dec 2024 13:07:47 +01:00 cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Commit 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU") adds functionality that architectures can use to optionally allocate and build cacheinfo early during boot. Commit 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") lets secondary CPUs correct (and reallocate memory) cacheinfo data if needed. If the early build functionality is not used and cacheinfo does not need correction, memory for cacheinfo is never allocated. x86 does not use the early build functionality. Consequently, during the cacheinfo CPU hotplug callback, last_level_cache_is_valid() attempts to dereference a NULL pointer: BUG: kernel NULL pointer dereference, address: 0000000000000100 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not present page PGD 0 P4D 0 Oops: 0000 [#1] PREEPMT SMP NOPTI CPU: 0 PID 19 Comm: cpuhp/0 Not tainted 6.4.0-rc2 #1 RIP: 0010: last_level_cache_is_valid+0x95/0xe0a Allocate memory for cacheinfo during the cacheinfo CPU hotplug callback if not done earlier. Moreover, before determining the validity of the last-level cache info, ensure that it has been allocated. Simply checking for non-zero cache_leaves() is not sufficient, as some architectures (e.g., Intel processors) have non-zero cache_leaves() before allocation. Dereferencing NULL cacheinfo can occur in update_per_cpu_data_slice_size(). This function iterates over all online CPUs. However, a CPU may have come online recently, but its cacheinfo may not have been allocated yet. While here, remove an unnecessary indentation in allocate_cache_info(). [ bp: Massage. ] Fixes: 6539cffa9495 ("cacheinfo: Add arch specific early level initializer") Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Radu Rendec <rrendec@redhat.com> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Reviewed-by: Andreas Herrmann <aherrmann@suse.de> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Cc: stable@vger.kernel.org # 6.3+ Link: https://lore.kernel.org/r/20241128002247.26726-2-ricardo.neri-calderon@linux.intel.com --- drivers/base/cacheinfo.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 609935a..cf0d455 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -58,7 +58,7 @@ bool last_level_cache_is_valid(unsigned int cpu) { struct cacheinfo *llc; - if (!cache_leaves(cpu)) + if (!cache_leaves(cpu) || !per_cpu_cacheinfo(cpu)) return false; llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); @@ -458,11 +458,9 @@ int __weak populate_cache_leaves(unsigned int cpu) return -ENOENT; } -static inline -int allocate_cache_info(int cpu) +static inline int allocate_cache_info(int cpu) { - per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), - sizeof(struct cacheinfo), GFP_ATOMIC); + per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), sizeof(struct cacheinfo), GFP_ATOMIC); if (!per_cpu_cacheinfo(cpu)) { cache_leaves(cpu) = 0; return -ENOMEM; @@ -534,7 +532,11 @@ static inline int init_level_allocate_ci(unsigned int cpu) */ ci_cacheinfo(cpu)->early_ci_levels = false; - if (cache_leaves(cpu) <= early_leaves) + /* + * Some architectures (e.g., x86) do not use early initialization. + * Allocate memory now in such case. + */ + if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu)) return 0; kfree(per_cpu_cacheinfo(cpu)); ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-11-28 0:22 [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Ricardo Neri 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri @ 2024-11-28 0:22 ` Ricardo Neri 2024-12-04 14:32 ` Borislav Petkov 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 2024-11-28 9:30 ` [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Borislav Petkov 2 siblings, 2 replies; 23+ messages in thread From: Ricardo Neri @ 2024-11-28 0:22 UTC (permalink / raw) To: x86 Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel Linux remembers cpu_cachinfo::num_leaves per CPU, but x86 initializes all CPUs from the same global "num_cache_leaves". This is erroneous on systems such as Meteor Lake, where each CPU has a distinct num_leaves value. Delete the global "num_cache_leaves" and initialize num_leaves on each CPU. init_cache_level() no longer needs to set num_leaves. Also, it never had to set num_levels as it is unnecessary in x86. Keep checking for zero cache leaves. Such condition indicates a bug. Reviewed-by: Andreas Herrmann <aherrmann@suse.de> Reviewed-by: Len Brown <len.brown@intel.com> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Tested-by: Andreas Herrmann <aherrmann@suse.de> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> --- Cc: Andreas Herrmann <aherrmann@suse.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Chen Yu <yu.c.chen@intel.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Len Brown <len.brown@intel.com> Cc: Nikolay Borisov <nik.borisov@suse.com> Cc: Radu Rendec <rrendec@redhat.com> Cc: Pierre Gondois <Pierre.Gondois@arm.com> Cc: Pu Wen <puwen@hygon.cn> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: Will Deacon <will@kernel.org> Cc: Zhang Rui <rui.zhang@intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: stable@vger.kernel.org # 6.3+ --- After this change, all CPUs will traverse CPUID leaf 0x4 when booted for the first time. On systems with symmetric cache topologies this is useless work. Creating a list of processor models that have asymmetric cache topologies was considered. The burden of maintaining such list would outweigh the performance benefit of skipping this extra step. --- Changes since v7: * Removed an ugly linebreak. (Boris) * Folded patch 3/3 into 2/3 as both patches deal with init_cache_level(). (Boris) * Removed the [set,get]_num_cache_leaves() wrappers. Instead, use the existing get_cpu_cacheinfo(). (Boris) * Future-proof init_cache_level() for cases in which cpu_cacheinfo:: num_leaves is still zero afer cache info initialization. Changes since v6: * None Changes since v5: * Reordered the arguments of set_num_cache_leaves() for readability. (Nikolay) * Added Reviewed-by tag from Nikolay and Andreas. Thanks! * Added Tested-by tag from Andreas. Thanks! Changes since v4: * None Changes since v3: * Rebased on v6.7-rc5. Changes since v2: * None Changes since v1: * Do not make num_cache_leaves a per-CPU variable. Instead, reuse the existing per-CPU ci_cpu_cacheinfo variable. (Dave Hansen) --- arch/x86/kernel/cpu/cacheinfo.c | 41 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c index 392d09c936d6..95e38ab98a72 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -178,8 +178,6 @@ struct _cpuid4_info_regs { struct amd_northbridge *nb; }; -static unsigned short num_cache_leaves; - /* AMD doesn't have CPUID4. Emulate it here to report the same information to the user. This makes some assumptions about the machine: L2 not shared, no SMT etc. that is currently true on AMD CPUs. @@ -718,19 +716,21 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c) void init_amd_cacheinfo(struct cpuinfo_x86 *c) { + unsigned int cpu = c->cpu_index; + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { - num_cache_leaves = find_num_cache_leaves(c); + get_cpu_cacheinfo(cpu)->num_leaves = find_num_cache_leaves(c); } else if (c->extended_cpuid_level >= 0x80000006) { if (cpuid_edx(0x80000006) & 0xf000) - num_cache_leaves = 4; + get_cpu_cacheinfo(cpu)->num_leaves = 4; else - num_cache_leaves = 3; + get_cpu_cacheinfo(cpu)->num_leaves = 3; } } void init_hygon_cacheinfo(struct cpuinfo_x86 *c) { - num_cache_leaves = find_num_cache_leaves(c); + get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); } void init_intel_cacheinfo(struct cpuinfo_x86 *c) @@ -742,19 +742,18 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; if (c->cpuid_level > 3) { - static int is_initialized; - - if (is_initialized == 0) { - /* Init num_cache_leaves from boot CPU */ - num_cache_leaves = find_num_cache_leaves(c); - is_initialized++; - } + /* + * There should be at least one leaf. A non-zero value means + * that the number of leaves has been initialized. + */ + if (!get_cpu_cacheinfo(c->cpu_index)->num_leaves) + get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); /* * Whenever possible use cpuid(4), deterministic cache * parameters cpuid leaf to find the cache details */ - for (i = 0; i < num_cache_leaves; i++) { + for (i = 0; i < get_cpu_cacheinfo(c->cpu_index)->num_leaves; i++) { struct _cpuid4_info_regs this_leaf = {}; int retval; @@ -790,14 +789,14 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if ((!get_cpu_cacheinfo(c->cpu_index)->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { /* supports eax=2 call */ int j, n; unsigned int regs[4]; unsigned char *dp = (unsigned char *)regs; int only_trace = 0; - if (num_cache_leaves != 0 && c->x86 == 15) + if (get_cpu_cacheinfo(c->cpu_index)->num_leaves && c->x86 == 15) only_trace = 1; /* Number of times to iterate */ @@ -991,14 +990,10 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, int init_cache_level(unsigned int cpu) { - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - - if (!num_cache_leaves) + /* There should be at least one leaf. */ + if (!get_cpu_cacheinfo(cpu)->num_leaves) return -ENOENT; - if (!this_cpu_ci) - return -EINVAL; - this_cpu_ci->num_levels = 3; - this_cpu_ci->num_leaves = num_cache_leaves; + return 0; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-11-28 0:22 ` [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves Ricardo Neri @ 2024-12-04 14:32 ` Borislav Petkov 2024-12-04 16:39 ` Ricardo Neri 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 1 sibling, 1 reply; 23+ messages in thread From: Borislav Petkov @ 2024-12-04 14:32 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Nov 27, 2024 at 04:22:47PM -0800, Ricardo Neri wrote: > arch/x86/kernel/cpu/cacheinfo.c | 41 +++++++++++++++------------------ > 1 file changed, 18 insertions(+), 23 deletions(-) Does that work too? --- diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c index 95e38ab98a72..e6fa03ed9172 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -715,22 +715,23 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c) void init_amd_cacheinfo(struct cpuinfo_x86 *c) { - - unsigned int cpu = c->cpu_index; + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { - get_cpu_cacheinfo(cpu)->num_leaves = find_num_cache_leaves(c); + ci->num_leaves = find_num_cache_leaves(c); } else if (c->extended_cpuid_level >= 0x80000006) { if (cpuid_edx(0x80000006) & 0xf000) - get_cpu_cacheinfo(cpu)->num_leaves = 4; + ci->num_leaves = 4; else - get_cpu_cacheinfo(cpu)->num_leaves = 3; + ci->num_leaves = 3; } } void init_hygon_cacheinfo(struct cpuinfo_x86 *c) { - get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); + + ci->num_leaves = find_num_cache_leaves(c); } void init_intel_cacheinfo(struct cpuinfo_x86 *c) @@ -740,20 +741,21 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); if (c->cpuid_level > 3) { /* * There should be at least one leaf. A non-zero value means * that the number of leaves has been initialized. */ - if (!get_cpu_cacheinfo(c->cpu_index)->num_leaves) - get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); + if (!ci->num_leaves) + ci->num_leaves = find_num_cache_leaves(c); /* * Whenever possible use cpuid(4), deterministic cache * parameters cpuid leaf to find the cache details */ - for (i = 0; i < get_cpu_cacheinfo(c->cpu_index)->num_leaves; i++) { + for (i = 0; i < ci->num_leaves; i++) { struct _cpuid4_info_regs this_leaf = {}; int retval; @@ -789,14 +791,14 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((!get_cpu_cacheinfo(c->cpu_index)->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { + if ((!ci->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { /* supports eax=2 call */ int j, n; unsigned int regs[4]; unsigned char *dp = (unsigned char *)regs; int only_trace = 0; - if (get_cpu_cacheinfo(c->cpu_index)->num_leaves && c->x86 == 15) + if (ci->num_leaves && c->x86 == 15) only_trace = 1; /* Number of times to iterate */ @@ -990,8 +992,10 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, int init_cache_level(unsigned int cpu) { + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu); + /* There should be at least one leaf. */ - if (!get_cpu_cacheinfo(cpu)->num_leaves) + if (!ci->num_leaves) return -ENOENT; return 0; -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-04 14:32 ` Borislav Petkov @ 2024-12-04 16:39 ` Ricardo Neri 2024-12-04 19:32 ` Borislav Petkov 0 siblings, 1 reply; 23+ messages in thread From: Ricardo Neri @ 2024-12-04 16:39 UTC (permalink / raw) To: Borislav Petkov Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Dec 04, 2024 at 03:32:06PM +0100, Borislav Petkov wrote: > On Wed, Nov 27, 2024 at 04:22:47PM -0800, Ricardo Neri wrote: > > arch/x86/kernel/cpu/cacheinfo.c | 41 +++++++++++++++------------------ > > 1 file changed, 18 insertions(+), 23 deletions(-) > > Does that work too? > > --- > diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c > index 95e38ab98a72..e6fa03ed9172 100644 > --- a/arch/x86/kernel/cpu/cacheinfo.c > +++ b/arch/x86/kernel/cpu/cacheinfo.c > @@ -715,22 +715,23 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c) > > void init_amd_cacheinfo(struct cpuinfo_x86 *c) > { > - > - unsigned int cpu = c->cpu_index; > + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); > > if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { > - get_cpu_cacheinfo(cpu)->num_leaves = find_num_cache_leaves(c); > + ci->num_leaves = find_num_cache_leaves(c); > } else if (c->extended_cpuid_level >= 0x80000006) { > if (cpuid_edx(0x80000006) & 0xf000) > - get_cpu_cacheinfo(cpu)->num_leaves = 4; > + ci->num_leaves = 4; > else > - get_cpu_cacheinfo(cpu)->num_leaves = 3; > + ci->num_leaves = 3; > } > } > > void init_hygon_cacheinfo(struct cpuinfo_x86 *c) > { > - get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); > + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); > + > + ci->num_leaves = find_num_cache_leaves(c); > } > > void init_intel_cacheinfo(struct cpuinfo_x86 *c) > @@ -740,20 +741,21 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) > unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ > unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ > unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; > + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); > > if (c->cpuid_level > 3) { > /* > * There should be at least one leaf. A non-zero value means > * that the number of leaves has been initialized. > */ > - if (!get_cpu_cacheinfo(c->cpu_index)->num_leaves) > - get_cpu_cacheinfo(c->cpu_index)->num_leaves = find_num_cache_leaves(c); > + if (!ci->num_leaves) > + ci->num_leaves = find_num_cache_leaves(c); > > /* > * Whenever possible use cpuid(4), deterministic cache > * parameters cpuid leaf to find the cache details > */ > - for (i = 0; i < get_cpu_cacheinfo(c->cpu_index)->num_leaves; i++) { > + for (i = 0; i < ci->num_leaves; i++) { > struct _cpuid4_info_regs this_leaf = {}; > int retval; > > @@ -789,14 +791,14 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) > * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for > * trace cache > */ > - if ((!get_cpu_cacheinfo(c->cpu_index)->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { > + if ((!ci->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { > /* supports eax=2 call */ > int j, n; > unsigned int regs[4]; > unsigned char *dp = (unsigned char *)regs; > int only_trace = 0; > > - if (get_cpu_cacheinfo(c->cpu_index)->num_leaves && c->x86 == 15) > + if (ci->num_leaves && c->x86 == 15) > only_trace = 1; > > /* Number of times to iterate */ > @@ -990,8 +992,10 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, > > int init_cache_level(unsigned int cpu) > { > + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu); > + > /* There should be at least one leaf. */ > - if (!get_cpu_cacheinfo(cpu)->num_leaves) > + if (!ci->num_leaves) > return -ENOENT; > > return 0; Yes, this looks OK to me and is an improvement. I can post a v9 with these changes. I think I can keep the Reviewed-by tags as they were given to Patch 1. Thanks and BR, Ricardo ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-04 16:39 ` Ricardo Neri @ 2024-12-04 19:32 ` Borislav Petkov 2024-12-04 22:22 ` Ricardo Neri 0 siblings, 1 reply; 23+ messages in thread From: Borislav Petkov @ 2024-12-04 19:32 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Dec 04, 2024 at 08:39:11AM -0800, Ricardo Neri wrote: > Yes, this looks OK to me and is an improvement. > > I can post a v9 with these changes. No need - I have everything here. I can give you a branch to test one last time before I queue. > I think I can keep the Reviewed-by tags as they were given to Patch 1. I'll take care of that too. Just sit tight and wait for a note from me. :) Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-04 19:32 ` Borislav Petkov @ 2024-12-04 22:22 ` Ricardo Neri 2024-12-05 15:14 ` Borislav Petkov 0 siblings, 1 reply; 23+ messages in thread From: Ricardo Neri @ 2024-12-04 22:22 UTC (permalink / raw) To: Borislav Petkov Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Dec 04, 2024 at 08:32:05PM +0100, Borislav Petkov wrote: > On Wed, Dec 04, 2024 at 08:39:11AM -0800, Ricardo Neri wrote: > > Yes, this looks OK to me and is an improvement. > > > > I can post a v9 with these changes. > > No need - I have everything here. I can give you a branch to test one last > time before I queue. Sure! Thanks! I can test it on Meteor Lake and non-Meteor Lake. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-04 22:22 ` Ricardo Neri @ 2024-12-05 15:14 ` Borislav Petkov 2024-12-06 1:47 ` Ricardo Neri 0 siblings, 1 reply; 23+ messages in thread From: Borislav Petkov @ 2024-12-05 15:14 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Wed, Dec 04, 2024 at 02:22:38PM -0800, Ricardo Neri wrote: > Sure! Thanks! I can test it on Meteor Lake and non-Meteor Lake. Ok, pls run this: https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=tip-x86-urgent-wip Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-05 15:14 ` Borislav Petkov @ 2024-12-06 1:47 ` Ricardo Neri 2024-12-06 12:08 ` Borislav Petkov 0 siblings, 1 reply; 23+ messages in thread From: Ricardo Neri @ 2024-12-06 1:47 UTC (permalink / raw) To: Borislav Petkov Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Thu, Dec 05, 2024 at 04:14:45PM +0100, Borislav Petkov wrote: > On Wed, Dec 04, 2024 at 02:22:38PM -0800, Ricardo Neri wrote: > > Sure! Thanks! I can test it on Meteor Lake and non-Meteor Lake. > > Ok, pls run this: > > https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=tip-x86-urgent-wip I tested this branch on Alder Lake, Meteor Lake, Sapphire Rapids, Broadwell server, Granite Rapids, Icelake server, Sierra Forest, and Rome. /sys/devices/system/cpu/cpu*/cache is populated correctly. I ran the tests documented in https://lore.kernel.org/lkml/20230912032350.GA17008@ranerica-svr.sc.intel.com/ Thanks and BR, Ricardo ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves 2024-12-06 1:47 ` Ricardo Neri @ 2024-12-06 12:08 ` Borislav Petkov 0 siblings, 0 replies; 23+ messages in thread From: Borislav Petkov @ 2024-12-06 12:08 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Thu, Dec 05, 2024 at 05:47:29PM -0800, Ricardo Neri wrote: > I tested this branch on Alder Lake, Meteor Lake, Sapphire Rapids, > Broadwell server, Granite Rapids, Icelake server, Sierra Forest, and Rome. > /sys/devices/system/cpu/cpu*/cache is populated correctly. Thanks! -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 23+ messages in thread
* [tip: x86/urgent] x86/cacheinfo: Delete global num_cache_leaves 2024-11-28 0:22 ` [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves Ricardo Neri 2024-12-04 14:32 ` Borislav Petkov @ 2024-12-06 12:24 ` tip-bot2 for Ricardo Neri 1 sibling, 0 replies; 23+ messages in thread From: tip-bot2 for Ricardo Neri @ 2024-12-06 12:24 UTC (permalink / raw) To: linux-tip-commits Cc: Ricardo Neri, Borislav Petkov (AMD), stable, #, 6.3+, x86, linux-kernel The following commit has been merged into the x86/urgent branch of tip: Commit-ID: 9677be09e5e4fbe48aeccb06ae3063c5eba331c3 Gitweb: https://git.kernel.org/tip/9677be09e5e4fbe48aeccb06ae3063c5eba331c3 Author: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> AuthorDate: Wed, 27 Nov 2024 16:22:47 -08:00 Committer: Borislav Petkov (AMD) <bp@alien8.de> CommitterDate: Fri, 06 Dec 2024 13:13:36 +01:00 x86/cacheinfo: Delete global num_cache_leaves Linux remembers cpu_cachinfo::num_leaves per CPU, but x86 initializes all CPUs from the same global "num_cache_leaves". This is erroneous on systems such as Meteor Lake, where each CPU has a distinct num_leaves value. Delete the global "num_cache_leaves" and initialize num_leaves on each CPU. init_cache_level() no longer needs to set num_leaves. Also, it never had to set num_levels as it is unnecessary in x86. Keep checking for zero cache leaves. Such condition indicates a bug. [ bp: Cleanup. ] Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Cc: stable@vger.kernel.org # 6.3+ Link: https://lore.kernel.org/r/20241128002247.26726-3-ricardo.neri-calderon@linux.intel.com --- arch/x86/kernel/cpu/cacheinfo.c | 43 +++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c index 392d09c..e6fa03e 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -178,8 +178,6 @@ struct _cpuid4_info_regs { struct amd_northbridge *nb; }; -static unsigned short num_cache_leaves; - /* AMD doesn't have CPUID4. Emulate it here to report the same information to the user. This makes some assumptions about the machine: L2 not shared, no SMT etc. that is currently true on AMD CPUs. @@ -717,20 +715,23 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c) void init_amd_cacheinfo(struct cpuinfo_x86 *c) { + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { - num_cache_leaves = find_num_cache_leaves(c); + ci->num_leaves = find_num_cache_leaves(c); } else if (c->extended_cpuid_level >= 0x80000006) { if (cpuid_edx(0x80000006) & 0xf000) - num_cache_leaves = 4; + ci->num_leaves = 4; else - num_cache_leaves = 3; + ci->num_leaves = 3; } } void init_hygon_cacheinfo(struct cpuinfo_x86 *c) { - num_cache_leaves = find_num_cache_leaves(c); + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); + + ci->num_leaves = find_num_cache_leaves(c); } void init_intel_cacheinfo(struct cpuinfo_x86 *c) @@ -740,21 +741,21 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index); if (c->cpuid_level > 3) { - static int is_initialized; - - if (is_initialized == 0) { - /* Init num_cache_leaves from boot CPU */ - num_cache_leaves = find_num_cache_leaves(c); - is_initialized++; - } + /* + * There should be at least one leaf. A non-zero value means + * that the number of leaves has been initialized. + */ + if (!ci->num_leaves) + ci->num_leaves = find_num_cache_leaves(c); /* * Whenever possible use cpuid(4), deterministic cache * parameters cpuid leaf to find the cache details */ - for (i = 0; i < num_cache_leaves; i++) { + for (i = 0; i < ci->num_leaves; i++) { struct _cpuid4_info_regs this_leaf = {}; int retval; @@ -790,14 +791,14 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if ((!ci->num_leaves || c->x86 == 15) && c->cpuid_level > 1) { /* supports eax=2 call */ int j, n; unsigned int regs[4]; unsigned char *dp = (unsigned char *)regs; int only_trace = 0; - if (num_cache_leaves != 0 && c->x86 == 15) + if (ci->num_leaves && c->x86 == 15) only_trace = 1; /* Number of times to iterate */ @@ -991,14 +992,12 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, int init_cache_level(unsigned int cpu) { - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu); - if (!num_cache_leaves) + /* There should be at least one leaf. */ + if (!ci->num_leaves) return -ENOENT; - if (!this_cpu_ci) - return -EINVAL; - this_cpu_ci->num_levels = 3; - this_cpu_ci->num_leaves = num_cache_leaves; + return 0; } ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU 2024-11-28 0:22 [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Ricardo Neri 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri 2024-11-28 0:22 ` [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves Ricardo Neri @ 2024-11-28 9:30 ` Borislav Petkov 2024-12-01 22:41 ` Ricardo Neri 2 siblings, 1 reply; 23+ messages in thread From: Borislav Petkov @ 2024-11-28 9:30 UTC (permalink / raw) To: Ricardo Neri, x86 Cc: Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On November 28, 2024 1:22:45 AM GMT+01:00, Ricardo Neri <ricardo.neri-calderon@linux.intel.com> wrote: >Changes since v7: > * Merged patches 2/3 into one. (Borislav) > * Dropped wrapper functions for ci_cpu_cacheinfo. (Borislav) > * Check for zero cache leaves in init_cache_level() for x86. > (Borislav) > * Removed an ugly line break. (Borislav) > >Changes since v6: > * Merged patches 1 and 2 into one. (Borislav) > * Fixed an formatting issue in allocate_cache_info(). (Borislav) I don't think you should keep the tags after those changes... -- Sent from a small device: formatting sucks and brevity is inevitable. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU 2024-11-28 9:30 ` [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Borislav Petkov @ 2024-12-01 22:41 ` Ricardo Neri 2024-12-02 10:31 ` Borislav Petkov 0 siblings, 1 reply; 23+ messages in thread From: Ricardo Neri @ 2024-12-01 22:41 UTC (permalink / raw) To: Borislav Petkov Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Thu, Nov 28, 2024 at 10:30:46AM +0100, Borislav Petkov wrote: > On November 28, 2024 1:22:45 AM GMT+01:00, Ricardo Neri <ricardo.neri-calderon@linux.intel.com> wrote: > >Changes since v7: > > * Merged patches 2/3 into one. (Borislav) > > * Dropped wrapper functions for ci_cpu_cacheinfo. (Borislav) > > * Check for zero cache leaves in init_cache_level() for x86. > > (Borislav) > > * Removed an ugly line break. (Borislav) > > > >Changes since v6: > > * Merged patches 1 and 2 into one. (Borislav) > > * Fixed an formatting issue in allocate_cache_info(). (Borislav) > > I don't think you should keep the tags after those changes... OK. Should I post a v9 without the tags? Perhaps I could wait a few days in case reviewers and testers want to chime in. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU 2024-12-01 22:41 ` Ricardo Neri @ 2024-12-02 10:31 ` Borislav Petkov 0 siblings, 0 replies; 23+ messages in thread From: Borislav Petkov @ 2024-12-02 10:31 UTC (permalink / raw) To: Ricardo Neri Cc: x86, Andreas Herrmann, Catalin Marinas, Chen Yu, Len Brown, Radu Rendec, Pierre Gondois, Pu Wen, Rafael J. Wysocki, Sudeep Holla, Srinivas Pandruvada, Will Deacon, Zhang Rui, Nikolay Borisov, Huang Ying, Ricardo Neri, linux-kernel On Sun, Dec 01, 2024 at 02:41:26PM -0800, Ricardo Neri wrote: > OK. Should I post a v9 without the tags? Perhaps I could wait a few days > in case reviewers and testers want to chime in. Yap, and then I can collect them all so you don't need to repost. Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2024-12-06 12:24 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-11-28 0:22 [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Ricardo Neri 2024-11-28 0:22 ` [PATCH v8 1/2] cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU Ricardo Neri 2024-11-29 16:12 ` Radu Rendec 2024-12-01 22:39 ` Ricardo Neri 2024-12-02 6:53 ` Nikolay Borisov 2024-12-03 4:09 ` Ricardo Neri 2024-12-02 8:02 ` Andreas Herrmann 2024-12-03 4:09 ` Ricardo Neri 2024-12-02 11:03 ` Sudeep Holla 2024-12-03 4:08 ` Ricardo Neri 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 2024-11-28 0:22 ` [PATCH v8 2/2] x86/cacheinfo: Delete global num_cache_leaves Ricardo Neri 2024-12-04 14:32 ` Borislav Petkov 2024-12-04 16:39 ` Ricardo Neri 2024-12-04 19:32 ` Borislav Petkov 2024-12-04 22:22 ` Ricardo Neri 2024-12-05 15:14 ` Borislav Petkov 2024-12-06 1:47 ` Ricardo Neri 2024-12-06 12:08 ` Borislav Petkov 2024-12-06 12:24 ` [tip: x86/urgent] " tip-bot2 for Ricardo Neri 2024-11-28 9:30 ` [PATCH v8 0/2] x86/cacheinfo: Set the number of leaves per CPU Borislav Petkov 2024-12-01 22:41 ` Ricardo Neri 2024-12-02 10:31 ` Borislav Petkov
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.