sched/topology: Enable topology_span_sane check only for debug builds
Subsystems (2)
PATCH v3 1/1 sched/topology: Enable topology_span_sane check only for debug builds
From: Saurabh Sengar <[email protected]>
On a x86 system under test with 1780 CPUs, topology_span_sane() takes around 8 seconds cumulatively for all the iterations. It is an expensive operation which does the sanity of non-NUMA topology masks.
CPU topology is not something which changes very frequently hence make this check optional for the systems where the topology is trusted and need faster bootup.
Restrict this to sched_verbose kernel cmdline option so that this penalty can be avoided for the systems who want to avoid it.
---
Changes since v2:
https://lore.kernel.org/all/[email protected]/
- Use sched_debug() instead of using sched_debug_verbose variable directly (addressing Prateek's comment)
Changes since v1:
https://lore.kernel.org/all/[email protected]/
- Use kernel cmdline param instead of compile time flag.
Adding a link to the other patch which is under review.
https://lore.kernel.org/lkml/[email protected]/
Above patch tries to optimize the topology sanity check, whereas this patch makes it optional. We believe both patches can coexist, as even with optimization, there will still be some performance overhead for this check.
--- kernel/sched/topology.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/sched/topology.c +7 -0
@@ -2359,6 +2359,13 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl, {int i = cpu +1 ; +/* Skip the topology sanity check for non-debug, as it is a time-consuming operatin */ +if (!sched_debug ()) { +pr_info_once ("%s: Skipping topology span sanity check. Use `sched_verbose` boot parameter to enable it.\n" , + __func__); +return true; + } +/* NUMA levels are allowed to overlap */ if (tl->flags &SDTL_OVERLAP )return true;
base-commit: 00f3246adeeacbda0bd0b303604e46eb59c32e6e
Signature · 1 line
2.43.0
Hello Naman,
Quoted 43 lines · Naman Jain
From: Saurabh Sengar <[email protected]>
On a x86 system under test with 1780 CPUs,
topology_span_sane()takes around 8 seconds cumulatively for all the iterations. It is an expensive operation which does the sanity of non-NUMA topology masks.CPU topology is not something which changes very frequently hence make this check optional for the systems where the topology is trusted and need faster bootup.
Restrict this to
sched_verbosekernel cmdline option so that this penalty can be avoided for the systems who want to avoid it.Fixes ccf74128d66c ("sched/topology: Assert non-NUMA topology masks don't (partially) overlap")Signed-off-by Saurabh Sengar <[email protected]>Co-developed-by Naman Jain <[email protected]>Signed-off-by Naman Jain <[email protected]>---
Changes since v2:
https://lore.kernel.org/all/[email protected]/
- Usesched_debug()instead of usingsched_debug_verbosevariable directly (addressing Prateek's comment)Changes since v1:
https://lore.kernel.org/all/[email protected]/
- Use kernel cmdline param instead of compile time flag.Adding a link to the other patch which is under review.
https://lore.kernel.org/lkml/[email protected]/
Above patch tries to optimize the topology sanity check, whereas this patch makes it optional. We believe both patches can coexist, as even with optimization, there will still be some performance overhead for this check. > ---kernel/sched/topology.c | 7 +++++++ 1 file changed, 7 insertions(+)kernel/sched/topology.c +0
-0
kernel/sched/topology.c static bool topology_span_sane(struct sched_domain_topology_level *tl, · line 2362
Quoted 4 lines
kernel/sched/topology.c +1
-0@@ -2359,6 +2359,13 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl, {int i = cpu +1 ; +/* Skip the topology sanity check for non-debug, as it is a time-consuming operatin */
s/operatin/operation/
kernel/sched/topology.c static bool topology_span_sane(struct sched_domain_topology_level *tl, · line 2364
Quoted 2 lines
kernel/sched/topology.c +2
-0+if (!sched_debug ()) { + pr_info_once("%s: Skipping topology span sanity check. Use `sched_verbose` boot parameter to enable it.\n",
This could be broken down as follows:
pr_info_once("%s: Skipping topology span sanity check."
" Use sched_verbose boot parameter to enable it.\n", __func__);
Running:
grep -r -A 5 "pr_info(.*[^;,]$" kernel/
gives similar usage across kernel/*. Apart from those nits, feel free to add:
if the future version does not change much.
Signature · 2 lines
Thanks and Regards, Prateek
Quoted 9 lines
kernel/sched/topology.c +4
-0+ __func__); +return true; + } +/* NUMA levels are allowed to overlap */ if (tl->flags &SDTL_OVERLAP )return true;base-commit:
00f3246adeeacbda0bd0b303604e46eb59c32e6e
Quoted 6 lines · K Prateek Nayak
Hello Naman,
Quoted 3 lines · Naman Jain
From: Saurabh Sengar <[email protected]>
On a x86 system under test with 1780 CPUs,
topology_span_sane()takes
<.>
Quoted 19 lines
Quoted 4 lines
{
int i = cpu + 1;
+ /* Skip the topology sanity check for non-debug, as it is a time- consuming operatin */s/operatin/operation/
Quoted 3 lines
+ if (!sched_debug()) {
+ pr_info_once("%s: Skipping topology span sanity check. Usesched_verboseboot parameter to enable it.\n",This could be broken down as follows:
pr_info_once("%s: Skipping topology span sanity check." " Use
sched_verboseboot parameter to enable it.\n",__func__);Running:
Quoted 9 lines
grep -r -A 5 "pr_info(.*[^;,]$"
kernel/gives similar usage across
kernel/*. Apart from those nits, feel free to add:if the future version does not change much.
Hello Prateek,
Thanks for reviewing and testing this. I'll make changes based on your feedback in next version.
Regards,
Naman
Quoted 41 lines · Naman Jain
Quoted 6 lines · K Prateek Nayak
Hello Naman,
Quoted 3 lines · Naman Jain
From: Saurabh Sengar <[email protected]>
On a x86 system under test with 1780 CPUs,
topology_span_sane()takes<.>
Quoted 19 lines
Quoted 4 lines
{
int i = cpu + 1;
+ /* Skip the topology sanity check for non-debug, as it is a time- consuming operatin */s/operatin/operation/
Quoted 3 lines
+ if (!sched_debug()) {
+ pr_info_once("%s: Skipping topology span sanity check. Usesched_verboseboot parameter to enable it.\n",This could be broken down as follows:
pr_info_once("%s: Skipping topology span sanity check." " Use
sched_verboseboot parameter to enable it.\n",__func__);Running:
Quoted 9 lines
grep -r -A 5 "pr_info(.*[^;,]$"
kernel/gives similar usage across
kernel/*. Apart from those nits, feel free to add:if the future version does not change much.
Quoted 7 lines
Hello Prateek,
Thanks for reviewing and testing this. I'll make changes based on your feedback in next version.Regards,
Naman
Hi Prateek,
After breaking down the print msg based on your suggestion, checkpatch gives a warning. There are no warnings reported with current version of change. Even the fix suggested by checkpatch is aligned to what we have right now. So I'll keep it like this, not push further changes as of now and wait for the maintainers to pick the patch.
WARNING: quoted string split across lines
#57: FILE: kernel/sched/topology.c:2365:
+ pr_info_once("%s: Skipping topology span sanity check."
+ " Use sched_verbose boot parameter to
enable it.\n",
total: 0 errors, 1 warnings, 14 lines checked
Regards,
Naman
K Prateek Nayak
reviewerHello all,
Quoted 8 lines · Naman Jain
[..snip..]
Adding a link to the other patch which is under review.
https://lore.kernel.org/lkml/[email protected]/
Above patch tries to optimize the topology sanity check, whereas this patch makes it optional. We believe both patches can coexist, as even with optimization, there will still be some performance overhead for this check.
I would like to discuss this parallelly here. Going back to the original problem highlighted in [1], the topology_span_sane() came to be as a result of how drivers/base/arch_topology.c computed the cpu_coregroup_mask().
[1] https://lore.kernel.org/all/[email protected]/
Originally described problematic topology is as follows:
**************************
NUMA: 0-2, 3-7
core_siblings: 0-3, 4-7
**************************with the problematic bit in the handling being:
const struct cpumask *cpu_coregroup_mask(int cpu)
{
const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu));
...
if (last_level_cache_is_valid(cpu)) {
/* If the llc_sibling is subset of node return llc_sibling */
if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))
core_mask = &cpu_topology[cpu].llc_sibling;
/* else the core_mask remains cpumask_of_node() */
}
...
return core_mask;
}For CPU3, the llc_sibling 0-3 is not a subset of node mask 3-7, and the fallback is to use 3-7. For CPUs 4-7, the llc_sibling 4-7 is a subset of the node mask 3-7 and the coremask is returned a 4-7.
In case of x86 (and perhaps other arch too) the arch/x86 bits ensure that this inconsistency never happens for !NUMA domains using the topology IDs. If a set of IDs match between two CPUs, the CPUs are set in each other's per-CPU topology mask (see link_mask() usage and match_*() functions in arch/x86/kernel/smpboot.c)
If the set of IDs match with one CPU, it should match with all other CPUs set in the cpumask for a given topology level. If it doesn't match with one, it will not match with any other CPUs in the cpumask either. The cpumasks of two CPUs can either be equal or disjoint at any given level. Steve's optimization reverses this to check if the the cpumask of set of CPUs match.
Have there been any reports on an x86 system / VM where topology_span_sane() was tripped? Looking at the implementation it does not seem possible (at least to my eyes) with one exception of AMD Fam 0x15 processors which set "cu_id" and match_smt() will look at cu_id if the core_id doesn't match between 2 CPUs. It may so happen that core IDs may match with one set of CPUs and cu_id may match with another set of CPUs if the information from CPUID is faulty.
What I'm getting to is that the arch specific topology parsing code can set a "SDTL_ARCH_VERIFIED" flag indicating that the arch specific bits have verified that the cpumasks are either equal or disjoint and since sched_debug() is "false" by default, topology_span_sane() can bail out if:
if (!sched_debug() && (tl->flags & SDTL_ARCH_VERIFIED)) return;
In case arch specific parsing was wrong, "sched_verbose" can always be used to double check the topology and for the arch that require this sanity check, Steve's optimized version of topology_span_sane() can be run to be sure of the sanity.
All this justification is in case folks want to keep topology_span_sane() around but if no one cares, Naman and Saurabh's approach works as intended.
Signature · 2 lines
Thanks and Regards, Prateek
Quoted 25 lines
--- kernel/sched/topology.c | 7 +++++++ 1 file changed, 7 insertions(+)kernel/sched/topology.c +7
-0@@ -2359,6 +2359,13 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl, {int i = cpu +1 ; +/* Skip the topology sanity check for non-debug, as it is a time-consuming operatin */ +if (!sched_debug ()) { +pr_info_once ("%s: Skipping topology span sanity check. Use `sched_verbose` boot parameter to enable it.\n" , + __func__); +return true; + } +/* NUMA levels are allowed to overlap */ if (tl->flags &SDTL_OVERLAP )return true;base-commit:
00f3246adeeacbda0bd0b303604e46eb59c32e6e
Peter Zijlstra
maintainerQuoted 2 lines · K Prateek Nayak
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped?
At the very least Intel SNC 'feature' tripped it at some point. They figured it made sense to have the LLC span two nodes.
But I think there were some really dodgy VMs too.
But yeah, its not been often. But basically dodgy BIOS/VM data can mess up things badly enough for it to trip.
K Prateek Nayak
reviewerHello Peter,
Thank you for the background!
Quoted 5 lines · Peter Zijlstra
Quoted 2 lines · K Prateek Nayak
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped?
Quoted 7 lines
At the very least Intel SNC 'feature' tripped it at some point. They figured it made sense to have the LLC span two nodes.
But I think there were some really dodgy VMs too.
But yeah, its not been often. But basically dodgy BIOS/VM data can mess up things badly enough for it to trip.
Has it ever happened without tripping the topology_sane() check first on the x86 side?
Signature · 2 lines
Thanks and Regards, Prateek
Peter Zijlstra
maintainerQuoted 13 lines · K Prateek Nayak
Hello Peter,
Thank you for the background!
Quoted 8 lines · Peter Zijlstra
Quoted 2 lines · K Prateek Nayak
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped?At the very least Intel SNC 'feature' tripped it at some point. They figured it made sense to have the LLC span two nodes.
Quoted 7 lines
Quoted 4 lines
But I think there were some really dodgy VMs too.
But yeah, its not been often. But basically dodgy BIOS/VM data can mess up things badly enough for it to trip.
Has it ever happened without tripping the
topology_sane()check first on the x86 side?
That I can't remember, sorry :/
K Prateek Nayak
reviewerHello Peter,
Quoted 5 lines · Peter Zijlstra
Quoted 4 lines · K Prateek Nayak
Hello Peter,
Thank you for the background!
Quoted 8 lines
Quoted 8 lines · Peter Zijlstra
Quoted 7 lines · K Prateek Nayak
Quoted 3 lines
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped?At the very least Intel SNC 'feature' tripped it at some point. They figured it made sense to have the LLC span two nodes.
I'm 99% sure that this might have been the topology_sane() check on the x86 side and not the topology_span_sane() check in kernel/sched/topology.c
I believe one of the original changes that did the plumbing for SNC was commit 2c88d45edbb8 ("x86, sched: Treat Intel SNC topology as default, COD as exception") from Alison where they mentions that they saw the following splat when running with SNC:
sched: CPU #3's llc-sibling CPU #0 is not on the same node! [node: 1 != 0]. Ignoring dependency.
This comes from the topology_sane() check in arch/x86/boot/smpboot.c and match_llc() on x86 side was modified to work around that.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
But I think there were some really dodgy VMs too.
For VMs too, it is easy to trip topology_sane() check on x86 side. With QEMU, I can run:
qemu-system-x86_64 -enable-kvm -cpu host \
-smp cpus=32,sockets=2,cores=8,threads=2 \
...
-numa node,cpus=0-7,cpus=16-23,memdev=m0,nodeid=0 \
-numa node,cpus=8-15,cpus=24-31,memdev=m1,nodeid=1 \
...and I get:
sched: CPU #8's llc-sibling CPU #0 is not on the same node! [node: 1 != 0]. Ignoring dependency.
This is because consecutive CPUs (0-1,2-3,...) are SMT siblings and CPUs 0-15 are on the same socket as a result of how QEMU presents MADT to the guest but then I go ahead and mess things up by saying CPUs 0-7,16-23 are on one NUMA node, and the rest are on the other.
I still haven't managed to trip topology_span_sane() tho.
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
But yeah, its not been often. But basically dodgy BIOS/VM data can mess up things badly enough for it to trip.
Has it ever happened without tripping the
topology_sane()check first on the x86 side?
What topology_span_sane() does is, it iterates over all the CPUs at a given topology level and makes sure that the cpumask for a CPU at that domain is same as the cpumask of every other CPU set on that mask for that topology level.
If two CPUs are set on a mask, they should have the same mask. If CPUs are not set on each other's mask, the masks should be disjoint.
On x86, the way set_cpu_sibling_map() works, CPUs are set on each other's shared masks iff match_*() returns true:
o For SMT, this means:
- If X86_FEATURE_TOPOEXT is set:
- pkg_id must match.
- die_id must match.
- amd_node_id must match.
- llc_id must match.
- Either core_id or cu_id must match. (*)
- NUMA nodes must match.
- If !X86_FEATURE_TOPOEXT:
- pkg_id must match.
- die_id must match.
- core_id must match.
- NUMA nodes must match.
o For CLUSTER this means:
- If l2c_id is not populated (== BAD_APICID)
- Same conditions as SMT.
- If l2c_id is populated (!= BAD_APICID)
- l2c_id must match.
- NUMA nodes must match.
o For MC it means:
- llc_id must be populated (!= BAD_APICID) and must match.
- If INTEL_SNC: pkg_id must match.
- If !INTEL_SNC: NUMA nodes must match.
o For PKG domain:
- Inserted only if !x86_has_numa_in_package.
- CPUs should be in same NUMA node.
All in all, other that the one (*) decision point, everything else has to strictly match for CPUs to be set in each other's CPU mask. And if they match with one CPU, they should match will all other CPUs in mask and it they mismatch with one, they should mismatch with all leading to link_mask() never being called.
This is why I think that the topology_span_sane() check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.
So circling back to my original question around "SDTL_ARCH_VERIFIED", would folks be okay to an early bailout from topology_span_sane() on:
if (!sched_debug() && (tl->flags & SDTL_ARCH_VERIFIED))
return;and more importantly, do folks care enough about topology_span_sane() to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?
(Sorry for the long answer explaining my thought process.)
Quoted 2 lines
That I can't remember, sorry :/
Signature · 2 lines
Thanks and Regards, Prateek
Quoted 123 lines · K Prateek Nayak
Hello Peter,
Quoted 5 lines · Peter Zijlstra
Quoted 4 lines · K Prateek Nayak
Hello Peter,
Thank you for the background!
Quoted 8 lines
Quoted 8 lines · Peter Zijlstra
Quoted 7 lines · K Prateek Nayak
Quoted 3 lines
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped?At the very least Intel SNC 'feature' tripped it at some point. They figured it made sense to have the LLC span two nodes.
I'm 99% sure that this might have been the
topology_sane()check on the x86 side and not thetopology_span_sane()check inkernel/sched/topology.cI believe one of the original changes that did the plumbing for SNC was commit
2c88d45edbb8("x86, sched: Treat Intel SNC topology as default, COD as exception") from Alison where they mentions that they saw the following splat when running with SNC:sched: CPU #3's llc-sibling CPU #0 is not on the same node! [node:
1 != 0]. Ignoring dependency.This comes from the
topology_sane()check inarch/x86/boot/smpboot.candmatch_llc()on x86 side was modified to work around that.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
But I think there were some really dodgy VMs too.
For VMs too, it is easy to trip
topology_sane()check on x86 side. With QEMU, I can run:qemu-system-x86_64 -enable-kvm -cpu host \
-smp cpus=32,sockets=2,cores=8,threads=2 \
...
-numa node,cpus=0-7,cpus=16-23,memdev=m0,nodeid=0 \
-numa node,cpus=8-15,cpus=24-31,memdev=m1,nodeid=1 \
...and I get:
sched: CPU #8's llc-sibling CPU #0 is not on the same node! [node:
1 != 0]. Ignoring dependency.This is because consecutive CPUs (0-1,2-3,...) are SMT siblings and CPUs 0-15 are on the same socket as a result of how QEMU presents MADT to the guest but then I go ahead and mess things up by saying CPUs 0-7,16-23 are on one NUMA node, and the rest are on the other.
I still haven't managed to trip
topology_span_sane()tho.Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
But yeah, its not been often. But basically dodgy BIOS/VM data can mess up things badly enough for it to trip.
Has it ever happened without tripping the
topology_sane()check first on the x86 side?What
topology_span_sane()does is, it iterates over all the CPUs at a given topology level and makes sure that the cpumask for a CPU at that domain is same as the cpumask of every other CPU set on that mask for that topology level.If two CPUs are set on a mask, they should have the same mask. If CPUs are not set on each other's mask, the masks should be disjoint.
On x86, the way
set_cpu_sibling_map()works, CPUs are set on each other's shared masks iff match_*() returns true:o For SMT, this means:
- If
X86_FEATURE_TOPOEXTis set:
-pkg_idmust match.
-die_idmust match.
-amd_node_idmust match.
-llc_idmust match.
- Eithercore_idorcu_idmust match. (*)
- NUMA nodes must match.- If !X86_FEATURE_TOPOEXT:
-pkg_idmust match.
-die_idmust match.
-core_idmust match.
- NUMA nodes must match.o For CLUSTER this means:
- If
l2c_idis not populated (==BAD_APICID)
- Same conditions as SMT.- If
l2c_idis populated (!=BAD_APICID)
-l2c_idmust match.
- NUMA nodes must match.o For MC it means:
-
llc_idmust be populated (!=BAD_APICID) and must match.
- IfINTEL_SNC:pkg_idmust match.
- If !INTEL_SNC: NUMA nodes must match.o For PKG domain:
- Inserted only if !x86_has_numa_in_package.
- CPUs should be in same NUMA node.All in all, other that the one (*) decision point, everything else has to strictly match for CPUs to be set in each other's CPU mask. And if they match with one CPU, they should match will all other CPUs in mask and it they mismatch with one, they should mismatch with all leading to
link_mask()never being called.This is why I think that the
topology_span_sane()check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:
Quoted 9 lines
if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?(Sorry for the long answer explaining my thought process.)
Thanks for sharing your valuable insights.
I am sorry, I could not find SDTL_ARCH_VERIFIED in linux-next tip. Am I missing something?
Regards,
Naman
K Prateek Nayak
reviewerHello Naman,
Quoted 16 lines · Naman Jain
[..snip..]
Quoted 15 lines
This is why I think that the
topology_span_sane()check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?
Quoted 7 lines
Quoted 2 lines
(Sorry for the long answer explaining my thought process.)
Thanks for sharing your valuable insights.
I am sorry, I could not findSDTL_ARCH_VERIFIEDin linux-next tip. Am I missing something?
It does not exits yet. I was proposing on defining this new flag "SDTL_ARCH_VERIFIED" which a particular arch can set if the topology parsing code has taken care of making sure that the cpumasks cannot overlap. The original motivation for topology_span_sane() discussed in
[1] came from an ARM processor where the functions that returns the cpumask is not based on ID checks and can possibly allow overlapping masks.
With the exception of AMD Fam 0x15 processors which populates cu_id (and that too it is theoretical case), I believe all x86 processors can set this new flag "SDTL_ARCH_VERIFIED" and can safely skip the topology_span_sane() since it checks for a condition that cannot possibly be false as result of how these masks are built on x86.
[1] https://lore.kernel.org/lkml/[email protected]/
Quoted 5 lines
Regards,
Naman
Signature · 2 lines
Thanks and Regards, Prateek
Quoted 35 lines · K Prateek Nayak
Hello Naman,
Quoted 16 lines · Naman Jain
[..snip..]
Quoted 15 lines
This is why I think that the
topology_span_sane()check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?Quoted 7 lines
Quoted 2 lines
(Sorry for the long answer explaining my thought process.)
Thanks for sharing your valuable insights.
I am sorry, I could not findSDTL_ARCH_VERIFIEDin linux-next tip. Am I missing something?It does not exits yet. I was proposing on defining this new flag "
SDTL_ARCH_VERIFIED" which a particular arch can set if the topology parsing code has taken care of making sure that the cpumasks cannot overlap. The original motivation fortopology_span_sane()discussed in
[1] came from an ARM processor where the functions that returns the cpumask is not based on ID checks and can possibly allow overlapping masks.
Quoted 7 lines
With the exception of AMD Fam
0x15processors which populatescu_id(and that too it is theoretical case), I believe all x86 processors can set this new flag "SDTL_ARCH_VERIFIED" and can safely skip thetopology_span_sane()since it checks for a condition that cannot possibly be false as result of how these masks are built on x86.
I think the check for sched_debug() should suffice here, without making it more complicated. This way, we give the control to the user to have it or not. I'll wait for a few more days to get any additional feedback and post v4 with your initial review comments addressed.
Regards,
Naman
Valentin Schneider
reviewerQuoted 44 lines · K Prateek Nayak
What
topology_span_sane()does is, it iterates over all the CPUs at a given topology level and makes sure that the cpumask for a CPU at that domain is same as the cpumask of every other CPU set on that mask for that topology level.If two CPUs are set on a mask, they should have the same mask. If CPUs are not set on each other's mask, the masks should be disjoint.
On x86, the way
set_cpu_sibling_map()works, CPUs are set on each other's shared masks iff match_*() returns true:o For SMT, this means:
- If
X86_FEATURE_TOPOEXTis set:
-pkg_idmust match.
-die_idmust match.
-amd_node_idmust match.
-llc_idmust match.
- Eithercore_idorcu_idmust match. (*)
- NUMA nodes must match.- If !X86_FEATURE_TOPOEXT:
-pkg_idmust match.
-die_idmust match.
-core_idmust match.
- NUMA nodes must match.o For CLUSTER this means:
- If
l2c_idis not populated (==BAD_APICID)
- Same conditions as SMT.- If
l2c_idis populated (!=BAD_APICID)
-l2c_idmust match.
- NUMA nodes must match.o For MC it means:
-
llc_idmust be populated (!=BAD_APICID) and must match.
- IfINTEL_SNC:pkg_idmust match.
- If !INTEL_SNC: NUMA nodes must match.o For PKG domain:
Quoted 9 lines
- Inserted only if !x86_has_numa_in_package.
- CPUs should be in same NUMA node.All in all, other that the one (*) decision point, everything else has to strictly match for CPUs to be set in each other's CPU mask. And if they match with one CPU, they should match will all other CPUs in mask and it they mismatch with one, they should mismatch with all leading to
link_mask()never being called.
Nice summary, thanks for that - I'm not that familiar with the x86 topology faff.
Quoted 7 lines
This is why I think that the
topology_span_sane()check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:
Quoted 7 lines
if (!sched_debug() && (tl->flags & SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?
If/when possible I prefer to have sanity checks run unconditionally, as long as they don't noticeably impact runtime. Unfortunately this does show up in the boot time, though Steve had a promising improvement for that.
Anyway, if someone gets one of those hangs on a
do { } while (group != sd->groups)
they'll quickly turn on sched_verbose (or be told to) and the sanity check will holler at them, so I'm not entirely against it.
Quoted 8 lines
(Sorry for the long answer explaining my thought process.)
Quoted 2 lines
That I can't remember, sorry :/
--
Thanks and Regards,
Prateek
Quoted 4 lines · Valentin Schneider
If/when possible I prefer to have sanity checks run unconditionally, as long as they don't noticeably impact runtime. Unfortunately this does show up in the boot time, though Steve had a promising improvement for that.
Just to let you know, I had other tasks interrupt me, but I'm back to looking at this and you should see a new version from me within the next few days.
Thanks,
--> Steve
Signature · 1 line
Steve Wahl, Hewlett Packard Enterprise
Quoted 78 lines · Valentin Schneider
Quoted 44 lines · K Prateek Nayak
What
topology_span_sane()does is, it iterates over all the CPUs at a given topology level and makes sure that the cpumask for a CPU at that domain is same as the cpumask of every other CPU set on that mask for that topology level.If two CPUs are set on a mask, they should have the same mask. If CPUs are not set on each other's mask, the masks should be disjoint.
On x86, the way
set_cpu_sibling_map()works, CPUs are set on each other's shared masks iff match_*() returns true:o For SMT, this means:
- If
X86_FEATURE_TOPOEXTis set:
-pkg_idmust match.
-die_idmust match.
-amd_node_idmust match.
-llc_idmust match.
- Eithercore_idorcu_idmust match. (*)
- NUMA nodes must match.- If !X86_FEATURE_TOPOEXT:
-pkg_idmust match.
-die_idmust match.
-core_idmust match.
- NUMA nodes must match.o For CLUSTER this means:
- If
l2c_idis not populated (==BAD_APICID)
- Same conditions as SMT.- If
l2c_idis populated (!=BAD_APICID)
-l2c_idmust match.
- NUMA nodes must match.o For MC it means:
-
llc_idmust be populated (!=BAD_APICID) and must match.
- IfINTEL_SNC:pkg_idmust match.
- If !INTEL_SNC: NUMA nodes must match.o For PKG domain:
Quoted 9 lines
- Inserted only if !x86_has_numa_in_package.
- CPUs should be in same NUMA node.All in all, other that the one (*) decision point, everything else has to strictly match for CPUs to be set in each other's CPU mask. And if they match with one CPU, they should match will all other CPUs in mask and it they mismatch with one, they should mismatch with all leading to
link_mask()never being called.Nice summary, thanks for that - I'm not that familiar with the x86 topology faff.
Quoted 7 lines
This is why I think that the
topology_span_sane()check is redundant when the x86 bits have already ensured masks cannot overlap in all cases except for potentially in the (*) case.So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:Quoted 7 lines
if (!sched_debug() && (tl->flags & SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?If/when possible I prefer to have sanity checks run unconditionally, as long as they don't noticeably impact runtime. Unfortunately this does show up in the boot time, though Steve had a promising improvement for that.
Quoted 6 lines
Anyway, if someone gets one of those hangs on a
do { } while (group != sd->groups)they'll quickly turn on
sched_verbose(or be told to) and the sanity check will holler at them, so I'm not entirely against it.
Thanks for the feedback :)
Regards,
Naman
K Prateek Nayak
reviewerHello Valentin,
Quoted 16 lines · Valentin Schneider
[..snip..]
Quoted 10 lines
So circling back to my original question around "
SDTL_ARCH_VERIFIED", would folks be okay to an early bailout fromtopology_span_sane()on:if (!sched_debug() && (tl->flags & SDTL_ARCH_VERIFIED)) return;and more importantly, do folks care enough about
topology_span_sane()to have it run on other architectures and not just have it guarded behind just "sched_debug()" which starts off as false by default?If/when possible I prefer to have sanity checks run unconditionally, as long as they don't noticeably impact runtime. Unfortunately this does show up in the boot time, though Steve had a promising improvement for that.
Quoted 6 lines
Anyway, if someone gets one of those hangs on a
do { } while (group != sd->groups)they'll quickly turn on
sched_verbose(or be told to) and the sanity check will holler at them, so I'm not entirely against it.
If you're game, I'm too!
I just put it out there in case folks had any strong feelings against this on other arch but that doesn't seem to be the case and we all love a simple solution :)
Quoted 10 lines
Quoted 9 lines
(Sorry for the long answer explaining my thought process.)
Quoted 2 lines
That I can't remember, sorry :/
--
Thanks and Regards,
Prateek
Signature · 2 lines
Thanks and Regards, Prateek
Quoted 75 lines · K Prateek Nayak
Hello all,
Quoted 8 lines · Naman Jain
[..snip..]
Adding a link to the other patch which is under review.
https://lore.kernel.org/lkml/[email protected]/
Above patch tries to optimize the topology sanity check, whereas this patch makes it optional. We believe both patches can coexist, as even with optimization, there will still be some performance overhead for this check.I would like to discuss this parallelly here. Going back to the original problem highlighted in [1], the
topology_span_sane()came to be as a result of howdrivers/base/arch_topology.ccomputed thecpu_coregroup_mask().[1] https://lore.kernel.org/all/1577088979-8545-1-git-send-email- [email protected]/
Originally described problematic topology is as follows:
**************************
NUMA: 0-2, 3-7
core_siblings: 0-3, 4-7
**************************with the problematic bit in the handling being:
const struct cpumask *cpu_coregroup_mask(int cpu) {
constcpumask_t*core_mask=
cpumask_of_node(cpu_to_node(cpu));...
if (
last_level_cache_is_valid(cpu)) {
/* If thellc_siblingis subset of node returnllc_sibling*/
if (cpumask_subset(&cpu_topology[cpu].llc_sibling,core_mask))
core_mask= &cpu_topology[cpu].llc_sibling;/* else the
core_maskremainscpumask_of_node()*/ }...
return
core_mask;
}For CPU3, the
llc_sibling0-3 is not a subset of node mask 3-7, and the fallback is to use 3-7. For CPUs 4-7, thellc_sibling4-7 is a subset of the node mask 3-7 and the coremask is returned a 4-7.In case of x86 (and perhaps other arch too) the
arch/x86bits ensure that this inconsistency never happens for !NUMA domains using the topology IDs. If a set of IDs match between two CPUs, the CPUs are set in each other's per-CPU topology mask (seelink_mask()usage and match_*() functions inarch/x86/kernel/smpboot.c)If the set of IDs match with one CPU, it should match with all other CPUs set in the cpumask for a given topology level. If it doesn't match with one, it will not match with any other CPUs in the cpumask either. The cpumasks of two CPUs can either be equal or disjoint at any given level. Steve's optimization reverses this to check if the the cpumask of set of CPUs match.
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped? Looking at the implementation it does not seem possible (at least to my eyes) with one exception of AMD Fam0x15processors which set "cu_id" andmatch_smt()will look atcu_idif thecore_iddoesn't match between 2 CPUs. It may so happen that core IDs may match with one set of CPUs andcu_idmay match with another set of CPUs if the information from CPUID is faulty.
Quoted 9 lines
What I'm getting to is that the arch specific topology parsing code can set a "
SDTL_ARCH_VERIFIED" flag indicating that the arch specific bits have verified that the cpumasks are either equal or disjoint and sincesched_debug()is "false" by default,topology_span_sane()can bail out if:if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;
it would simpler to use sched_debug(). no?
Since it can be enabled at runtime by "echo Y > verbose", if one one needs to enable even after boot. Wouldn't that suffice to run topology_span_sane by doing a hotplug?
Quoted 9 lines
In case arch specific parsing was wrong, "
sched_verbose" can always be used to double check the topology and for the arch that require this sanity check, Steve's optimized version oftopology_span_sane()can be run to be sure of the sanity.All this justification is in case folks want to keep
topology_span_sane()around but if no one cares, Naman and Saurabh's approach works as intended.
Quoted 81 lines · Shrikanth Hegde
Quoted 78 lines · K Prateek Nayak
Hello all,
Quoted 8 lines · Naman Jain
[..snip..]
Adding a link to the other patch which is under review.
https://lore.kernel.org/lkml/[email protected]/
Above patch tries to optimize the topology sanity check, whereas this patch makes it optional. We believe both patches can coexist, as even with optimization, there will still be some performance overhead for this check.I would like to discuss this parallelly here. Going back to the original problem highlighted in [1], the
topology_span_sane()came to be as a result of howdrivers/base/arch_topology.ccomputed thecpu_coregroup_mask().[1] https://lore.kernel.org/all/1577088979-8545-1-git-send-email- [email protected]/
Originally described problematic topology is as follows:
**************************
NUMA: 0-2, 3-7
core_siblings: 0-3, 4-7
**************************with the problematic bit in the handling being:
const struct cpumask *cpu_coregroup_mask(int cpu)
{
constcpumask_t*core_mask= cpumask_of_node(cpu_to_node(cpu));...
if (
last_level_cache_is_valid(cpu)) {
/* If thellc_siblingis subset of node returnllc_sibling*/ if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))core_mask= &cpu_topology[cpu].llc_sibling;/* else the
core_maskremainscpumask_of_node()*/ }...
return
core_mask;
}For CPU3, the
llc_sibling0-3 is not a subset of node mask 3-7, and the fallback is to use 3-7. For CPUs 4-7, thellc_sibling4-7 is a subset of the node mask 3-7 and the coremask is returned a 4-7.In case of x86 (and perhaps other arch too) the
arch/x86bits ensure that this inconsistency never happens for !NUMA domains using the topology IDs. If a set of IDs match between two CPUs, the CPUs are set in each other's per-CPU topology mask (seelink_mask()usage and match_*() functions inarch/x86/kernel/smpboot.c)If the set of IDs match with one CPU, it should match with all other CPUs set in the cpumask for a given topology level. If it doesn't match with one, it will not match with any other CPUs in the cpumask either. The cpumasks of two CPUs can either be equal or disjoint at any given level. Steve's optimization reverses this to check if the the cpumask of set of CPUs match.
Have there been any reports on an x86 system / VM where
topology_span_sane()was tripped? Looking at the implementation it does not seem possible (at least to my eyes) with one exception of AMD Fam0x15processors which set "cu_id" andmatch_smt()will look atcu_idif thecore_iddoesn't match between 2 CPUs. It may so happen that core IDs may match with one set of CPUs andcu_idmay match with another set of CPUs if the information from CPUID is faulty.What I'm getting to is that the arch specific topology parsing code can set a "
SDTL_ARCH_VERIFIED" flag indicating that the arch specific bits have verified that the cpumasks are either equal or disjoint and sincesched_debug()is "false" by default,topology_span_sane()can bail out if:
Quoted 8 lines
Quoted 3 lines
if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;it would simpler to use
sched_debug(). no?Since it can be enabled at runtime by "echo Y > verbose", if one one needs to enable even after boot. Wouldn't that suffice to run
topology_span_saneby doing a hotplug?
I agree with your point. We are keeping it the same. Thanks.
Regards,
Naman
Quoted 9 lines
Quoted 9 lines
In case arch specific parsing was wrong, "
sched_verbose" can always be used to double check the topology and for the arch that require this sanity check, Steve's optimized version oftopology_span_sane()can be run to be sure of the sanity.All this justification is in case folks want to keep
topology_span_sane()around but if no one cares, Naman and Saurabh's approach works as intended.
K Prateek Nayak
reviewerHello Shrikanth,
Quoted 9 lines · Shrikanth Hegde
[..snip..]
Quoted 7 lines
What I'm getting to is that the arch specific topology parsing code can set a "
SDTL_ARCH_VERIFIED" flag indicating that the arch specific bits have verified that the cpumasks are either equal or disjoint and sincesched_debug()is "false" by default,topology_span_sane()can bail out if:
Quoted 7 lines
Quoted 3 lines
if (!sched_debug() && (
tl->flags&SDTL_ARCH_VERIFIED)) return;it would simpler to use
sched_debug(). no?Since it can be enabled at runtime by "echo Y > verbose", if one one needs to enable even after boot. Wouldn't that suffice to run
topology_span_saneby doing a hotplug?
Ack! It was a suggestion in case folks felt apprehensive about guarding the check behind sched_debug() ...
Quoted 9 lines
Quoted 9 lines
In case arch specific parsing was wrong, "
sched_verbose" can always be used to double check the topology and for the arch that require this sanity check, Steve's optimized version oftopology_span_sane()can be run to be sure of the sanity.All this justification is in case folks want to keep
topology_span_sane()around but if no one cares, Naman and Saurabh's approach works as intended.
... which is why I ended that long explanation with this :)
Valentin seems to be on board with the current approach from Naman and Saurabh and it works as intended.
Quoted 2 lines
Quoted 1 line
Signature · 2 lines
Thanks and Regards, Prateek