check the node id consistently across different arches
v2 cover check the node id consistently across different arches
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
When enabling KASAN and bios has not implemented the proximity domain of the hns3 device, there is a global-out-of-bounds error below:
[ 42.970381] ================================================================== [ 42.977595] BUG: KASAN: global-out-of-bounds in __bitmap_weight+0x48/0xb0 [ 42.984370] Read of size 8 at addr ffff20008cdf8790 by task kworker/0:1/13 [ 42.991230] [ 42.992712] CPU: 0 PID: 13 Comm: kworker/0:1 Tainted: G O 5.2.0-rc4-g8bde06a-dirty #3 [ 43.001830] Hardware name: Huawei TaiShan 2280 V2/BC82AMDA, BIOS TA BIOS 2280-A CS V2.B050.01 08/08/2019 [ 43.011298] Workqueue: events work_for_cpu_fn [ 43.015643] Call trace: [ 43.018078] dump_backtrace+0x0/0x1e8 [ 43.021727] show_stack+0x14/0x20 [ 43.025031] dump_stack+0xc4/0xfc [ 43.028335] print_address_description+0x178/0x270 [ 43.033113] __kasan_report+0x164/0x1b8 [ 43.036936] kasan_report+0xc/0x18 [ 43.040325] __asan_load8+0x84/0xa8 [ 43.043801] __bitmap_weight+0x48/0xb0 [ 43.047552] hclge_init_ae_dev+0x988/0x1e78 [hclge] [ 43.052418] hnae3_register_ae_dev+0xcc/0x278 [hnae3] [ 43.057467] hns3_probe+0xe0/0x120 [hns3] [ 43.061464] local_pci_probe+0x74/0xf0 [ 43.065200] work_for_cpu_fn+0x2c/0x48 [ 43.068937] process_one_work+0x3c0/0x878 [ 43.072934] worker_thread+0x400/0x670 [ 43.076670] kthread+0x1b0/0x1b8 [ 43.079885] ret_from_fork+0x10/0x18 [ 43.083446] [ 43.084925] The buggy address belongs to the variable: [ 43.090052] numa_distance+0x30/0x40 [ 43.093613] [ 43.095091] Memory state around the buggy address: [ 43.099870] ffff20008cdf8680: fa fa fa fa 04 fa fa fa fa fa fa fa 00 00 fa fa [ 43.107078] ffff20008cdf8700: fa fa fa fa 04 fa fa fa fa fa fa fa 00 fa fa fa [ 43.114286] >ffff20008cdf8780: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa [ 43.121494] ^ [ 43.125230] ffff20008cdf8800: 01 fa fa fa fa fa fa fa 04 fa fa fa fa fa fa fa [ 43.132439] ffff20008cdf8880: fa fa fa fa fa fa fa fa 00 00 fa fa fa fa fa fa [ 43.139646] ==================================================================
As suggested [2] by Michal Hocko:
"if the specification really allows to provide NUMA_NO_NODE (-1) then the code really has to be prepared for that. And ideally all arches should deal with that."
This patchset checks the node id with the below case consistently across different arches in order to be compliant with spec and backward compatible as much as possible:
1. if node_id < 0, return cpu_online_mask
2. if node_id >= nr_node_ids, return cpu_none_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
Note:
1. Only arm64 has been compile tested and tested on real board.
2. x86 has been compile tested with defconfig.
3. Other arch has not been compile tested or tested on real board.
Changelog:
V2: Change commit log as suggested by Michal Hocko, and make the change to
other arches as well.
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
[2] https://patchwork.kernel.org/patch/11122823/
Yunsheng Lin (9):
arm64: numa: check the node id consistently for arm64
x86: numa: check the node id consistently for x86
alpha: numa: check the node id consistently for alpha
powerpc: numa: check the node id consistently for powerpc
s390: numa: check the node id consistently for s390
sh: numa: check the node id consistently for sh
sparc64: numa: check the node id consistently for sparc64
mips: numa: check the node id consistently for mips ip27
mips: numa: check the node id consistently for mips loongson64
arch/alpha/include/asm/topology.h | 7 +++++-- arch/arm64/include/asm/numa.h | 6 ++++++ arch/arm64/mm/numa.c | 2 +- arch/mips/include/asm/mach-ip27/topology.h | 15 ++++++++++++--- arch/mips/include/asm/mach-loongson64/topology.h | 12 +++++++++++- arch/powerpc/include/asm/topology.h | 13 ++++++++++--- arch/s390/include/asm/topology.h | 6 ++++++ arch/sh/include/asm/topology.h | 14 +++++++++++++- arch/sparc/include/asm/topology_64.h | 16 +++++++++++++--- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/mm/numa.c | 2 +- 11 files changed, 84 insertions(+), 15 deletions(-)
Signature · 1 line
2.8.1
PATCH v2 1/9 arm64: numa: check the node id consistently for arm64
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
When enabling KASAN and bios has not implemented the proximity domain of the hns3 device, there is a global-out-of-bounds error below:
[ 42.970381] ================================================================== [ 42.977595] BUG: KASAN: global-out-of-bounds in __bitmap_weight+0x48/0xb0 [ 42.984370] Read of size 8 at addr ffff20008cdf8790 by task kworker/0:1/13 [ 42.991230] [ 42.992712] CPU: 0 PID: 13 Comm: kworker/0:1 Tainted: G O 5.2.0-rc4-g8bde06a-dirty #3 [ 43.001830] Hardware name: Huawei TaiShan 2280 V2/BC82AMDA, BIOS TA BIOS 2280-A CS V2.B050.01 08/08/2019 [ 43.011298] Workqueue: events work_for_cpu_fn [ 43.015643] Call trace: [ 43.018078] dump_backtrace+0x0/0x1e8 [ 43.021727] show_stack+0x14/0x20 [ 43.025031] dump_stack+0xc4/0xfc [ 43.028335] print_address_description+0x178/0x270 [ 43.033113] __kasan_report+0x164/0x1b8 [ 43.036936] kasan_report+0xc/0x18 [ 43.040325] __asan_load8+0x84/0xa8 [ 43.043801] __bitmap_weight+0x48/0xb0 [ 43.047552] hclge_init_ae_dev+0x988/0x1e78 [hclge] [ 43.052418] hnae3_register_ae_dev+0xcc/0x278 [hnae3] [ 43.057467] hns3_probe+0xe0/0x120 [hns3] [ 43.061464] local_pci_probe+0x74/0xf0 [ 43.065200] work_for_cpu_fn+0x2c/0x48 [ 43.068937] process_one_work+0x3c0/0x878 [ 43.072934] worker_thread+0x400/0x670 [ 43.076670] kthread+0x1b0/0x1b8 [ 43.079885] ret_from_fork+0x10/0x18 [ 43.083446] [ 43.084925] The buggy address belongs to the variable: [ 43.090052] numa_distance+0x30/0x40 [ 43.093613] [ 43.095091] Memory state around the buggy address: [ 43.099870] ffff20008cdf8680: fa fa fa fa 04 fa fa fa fa fa fa fa 00 00 fa fa [ 43.107078] ffff20008cdf8700: fa fa fa fa 04 fa fa fa fa fa fa fa 00 fa fa fa [ 43.114286] >ffff20008cdf8780: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa [ 43.121494] ^ [ 43.125230] ffff20008cdf8800: 01 fa fa fa fa fa fa fa 04 fa fa fa fa fa fa fa [ 43.132439] ffff20008cdf8880: fa fa fa fa fa fa fa fa 00 00 fa fa fa fa fa fa [ 43.139646] ==================================================================
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
--- arch/arm64/include/asm/numa.h | 6 ++++++ arch/arm64/mm/numa.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
arch/arm64/include/asm/numa.h +6 -0
@@ -25,6 +25,12 @@ const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; +return node_to_cpumask_map[node]; }#endif
arch/arm64/mm/numa.c +1 -1
@@ -49,7 +49,7 @@ const struct cpumask *cpumask_of_node(int node)if (WARN_ON (node >= nr_node_ids))return cpu_none_mask; -if (WARN_ON (node_to_cpumask_map[node] ==NULL )) +if (WARN_ON (node <0 || !node_to_cpumask_map[node]))return cpu_online_mask;return node_to_cpumask_map[node];
Signature · 1 line
2.8.1
PATCH v2 2/9 x86: numa: check the node id consistently for x86
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/mm/numa.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
arch/x86/include/asm/topology.h +6 -0
@@ -69,6 +69,12 @@ extern const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; +return node_to_cpumask_map[node]; }#endif
arch/x86/mm/numa.c +1 -1
@@ -868,7 +868,7 @@ const struct cpumask *cpumask_of_node(int node)dump_stack ();return cpu_none_mask; } -if (node_to_cpumask_map[node] ==NULL ) { +if (node <0 || !node_to_cpumask_map[node]) {printk (KERN_WARNING "cpumask_of_node(%d): no node_to_cpumask_map!\n" , node);
Signature · 1 line
2.8.1
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 7 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
That's just words.. what does it actually mean?
Quoted 21 lines
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. ifnode_id>=nr_node_ids, returncpu_none_mask
2. ifnode_id< 0, returncpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, returncpu_online_mask[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
Signed-off-by Yunsheng Lin <[email protected]>--- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/mm/numa.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)arch/x86/include/asm/topology.h +0
-0@@ -69,6 +69,12 @@ extern const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node)
arch/x86/include/asm/topology.h extern const struct cpumask *cpumask_of_node(int node); · line 80
Quoted 10 lines
arch/x86/include/asm/topology.h +6
-0{ +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; +return node_to_cpumask_map[node]; }#endif
I _reallly_ hate this. Users are expected to use valid numa ids. Now we're adding all this checking to all users. Why do we want to do that?
Using '(unsigned)node >= nr_nods_ids' is an error.
Quoted 16 lines
arch/x86/mm/numa.c +1
-1@@ -868,7 +868,7 @@ const struct cpumask *cpumask_of_node(int node)dump_stack ();return cpu_none_mask; } -if (node_to_cpumask_map[node] ==NULL ) { +if (node <0 || !node_to_cpumask_map[node]) {printk (KERN_WARNING "cpumask_of_node(%d): no node_to_cpumask_map!\n" , node);Signature · 1 line
2.8.1
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 10 lines · Peter Zijlstra
Quoted 7 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).That's just words.. what does it actually mean?
It means the dev_to_node(dev) may return -1 if the bios does not implement the proximity domain feature, user may use that value to call cpumask_of_node and cpumask_of_node does not protect itself from node id being -1, which causes out of bound access.
Quoted 27 lines
Quoted 27 lines
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. ifnode_id>=nr_node_ids, returncpu_none_mask
2. ifnode_id< 0, returncpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, returncpu_online_mask[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
Signed-off-by Yunsheng Lin <[email protected]>--- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/mm/numa.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)arch/x86/include/asm/topology.h +4
-0@@ -69,6 +69,12 @@ extern const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node])
Quoted 8 lines
arch/x86/include/asm/topology.h extern const struct cpumask *cpumask_of_node(int node); · line 80
Quoted 5 lines
arch/x86/include/asm/topology.h +2
-0+return cpu_online_mask; + return node_to_cpumask_map[node]; }#endif I _reallly_ hate this. Users are expected to use valid numa ids. Now we're adding all this checking to all users. Why do we want to do that?
As above, the dev_to_node(dev) may return -1.
Quoted 2 lines
Using '(unsigned)node >=
nr_nods_ids' is an error.
'node >= nr_node_ids' can be dropped if all user is expected to not call cpumask_of_node with node id greater or equal to nr_nods_ids.
From what I can see, the problem can be fixed in three place:
1. Make user dev_to_node return a valid node id even when proximity domain is not set by bios(or node id set by buggy bios is not valid), which may need info from the numa system to make sure it will return a valid node.
2. User that call cpumask_of_node should ensure the node id is valid before calling cpumask_of_node, and user also need some info to make ensure node id is valid.
3. Make sure cpumask_of_node deal with invalid node id as this patchset.
Which one do you prefer to make sure node id is valid, or do you have any better idea?
Any detail advice and suggestion will be very helpful, thanks.
Quoted 20 lines
Quoted 17 lines
arch/x86/mm/numa.c +1
-1@@ -868,7 +868,7 @@ const struct cpumask *cpumask_of_node(int node)dump_stack ();return cpu_none_mask; } -if (node_to_cpumask_map[node] ==NULL ) { +if (node <0 || !node_to_cpumask_map[node]) {printk (KERN_WARNING "cpumask_of_node(%d): no node_to_cpumask_map!\n" , node);Signature · 1 line
2.8.1.
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 36 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 7 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).That's just words.. what does it actually mean?
It means the
dev_to_node(dev)may return -1 if the bios does not implement the proximity domain feature, user may use that value to callcpumask_of_nodeandcpumask_of_nodedoes not protect itself from node id being -1, which causes out of bound access.Quoted 8 lines
Quoted 8 lines
arch/x86/include/asm/topology.h +4
-0@@ -69,6 +69,12 @@ extern const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node])Quoted 8 lines
arch/x86/include/asm/topology.h extern const struct cpumask *cpumask_of_node(int node); · line 80
Quoted 5 lines
arch/x86/include/asm/topology.h +2
-0+return cpu_online_mask; + return node_to_cpumask_map[node]; }#endif I _reallly_ hate this. Users are expected to use valid numa ids. Now we're adding all this checking to all users. Why do we want to do that?
Quoted 7 lines
As above, the
dev_to_node(dev)may return -1.Quoted 2 lines
Using '(unsigned)node >=
nr_nods_ids' is an error.'node >=
nr_node_ids' can be dropped if all user is expected to not callcpumask_of_nodewith node id greater or equal tonr_nods_ids.
you copied my typo :-)
Quoted 10 lines
From what I can see, the problem can be fixed in three place:
1. Make userdev_to_nodereturn a valid node id even when proximity domain is not set by bios(or node id set by buggy bios is not valid), which may need info from the numa system to make sure it will return a valid node.2. User that call
cpumask_of_nodeshould ensure the node id is valid before callingcpumask_of_node, and user also need some info to make ensure node id is valid.
Quoted 6 lines
3. Make sure
cpumask_of_nodedeal with invalid node id as this patchset.Which one do you prefer to make sure node id is valid, or do you have any better idea?
Any detail advice and suggestion will be very helpful, thanks.
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
2) is already true today, cpumask_of_node() requires a valid node_id.
3) is just wrong and increases overhead for everyone.
Something about loongson_llsc_mb
Hi, Peter,
I found that this patch has been merged but I haven't received the e-mail for some unknown reasons.
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=1c6c1ca318585f1096d4d04bc722297c85e9fb8a
Firstly, your comments are correct, so the barrier.h part is perfect.
Secondly, most of the rest is useless, because smp_mb__before_llsc, loongson_llsc_mb and other memory barriers are the same thing on Loongson-3. We don't need to add loongson_llsc_mb if there is already a smp_mb__before_llsc.
Thirdly, maybe the only exception is syscall.c, but mips_atomic_set is not used on Loongson-3. And if in some cases we use it, I think the user-to-kernel context switch has the same effect of a memory barrier.
Lastly, I think the real exception is test_and_set_bit_lock, it need a loongson_llsc_mb.
Huacai
A message that is not in the archive (sent off-list or not yet received): [email protected]
Peter Zijlstra
maintainerRe: Something about loongson_llsc_mb
*why* are you replying to some random unrelated thread?
Also, please use a sane MUA and wrap your lines <80 chars.
Quoted 8 lines · On Wed, Sep 04, 2019 at 10:03:31AM +0800, [email protected] wrote:
Quoted 8 lines
Hi, Peter,
I found that this patch has been merged but I haven't received the e-mail for some unknown reasons.
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=1c6c1ca318585f1096d4d04bc722297c85e9fb8aFirstly, your comments are correct, so the
barrier.hpart is perfect.Secondly, most of the rest is useless, because
smp_mb__before_llsc,loongson_llsc_mband other memory barriers are the same thing on Loongson-3. We don't need to addloongson_llsc_mbif there is already asmp_mb__before_llsc.
There wasn't. Take for example set_bit(), that didn't have smp_mb__before_llsc on.
Also; MIPS should probably convert to asm-generic/bitops/atomic.h.
Quoted 1 line
Quoted 1 line
Thirdly, maybe the only exception is
syscall.c, butmips_atomic_setis not used on Loongson-3. And if in some cases we use it, I think the user-to-kernel context switch has the same effect of a memory barrier.
And how is some random person trying to make sense of MIPS to know that?
You all created a badly documented inconsitent trainwreck. You're 'lucky' the MIPS maintainers accepted that mess in the first place.
Anyway, yes there are too many barrers now in some cases, in a previous version I had:
https://lkml.kernel.org/r/[email protected]
But because I dropped changes to local.h that might not be true anymore; it needs careful consideration. Please audit carefully and if you find all smp_mb__before_llsc() usage is now superfluous for this 'funny' chip of yours, then re-submit the above patch.
Quoted 7 lines
+. per-cpu like
local_t*should only* be written by local cpu, and may be read by remote cpu sometimes+. if and only if local cpu can write per-cpu, then Loongson3's llsc bug would not be triggerd.
same as
this_cpu_cmpxchg_doubleIf so, then no need to add sync before and after
cmpxchg_local
Correct, we already dropped the change for other local.h stuff.
Peter Zijlstra
maintainerRe: Something about loongson_llsc_mb
Quoted 30 lines · Peter Zijlstra
*why* are you replying to some random unrelated thread?
Also, please use a sane MUA and wrap your lines <80 chars.
Quoted 8 lines · On Wed, Sep 04, 2019 at 10:03:31AM +0800, [email protected] wrote:
Quoted 8 lines
Hi, Peter,
I found that this patch has been merged but I haven't received the e-mail for some unknown reasons.
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=1c6c1ca318585f1096d4d04bc722297c85e9fb8aFirstly, your comments are correct, so the
barrier.hpart is perfect.Secondly, most of the rest is useless, because
smp_mb__before_llsc,loongson_llsc_mband other memory barriers are the same thing on Loongson-3. We don't need to addloongson_llsc_mbif there is already asmp_mb__before_llsc.There wasn't. Take for example
set_bit(), that didn't havesmp_mb__before_llscon.Also; MIPS should probably convert to
asm-generic/bitops/atomic.h.Quoted 1 line
Quoted 1 line
Thirdly, maybe the only exception is
syscall.c, butmips_atomic_setis not used on Loongson-3. And if in some cases we use it, I think the user-to-kernel context switch has the same effect of a memory barrier.And how is some random person trying to make sense of MIPS to know that?
You all created a badly documented inconsitent trainwreck. You're 'lucky' the MIPS maintainers accepted that mess in the first place.
Anyway, yes there are too many barrers now in some cases, in a previous version I had:
Quoted 6 lines
https://lkml.kernel.org/r/[email protected]
But because I dropped changes to
local.hthat might not be true anymore; it needs careful consideration. Please audit carefully and if you find allsmp_mb__before_llsc()usage is now superfluous for this 'funny' chip of yours, then re-submit the above patch.
I think we're good, smp_mb__{before,after}_atomic() already doesn't work with local_t.
Re: Something about loongson_llsc_mb
In reply to Peter ZijlstraQuoted 2 lines · Peter Zijlstra
*why* are you replying to some random unrelated thread?
Chen ask me if whether your patch has more sync than needed, but I'm not sure whether sync before and after *cmpxchg_local* is.
Quoted 2 lines
Also, please use a sane MUA and wrap your lines <80 chars.
Sorry, I finally got thunderbird in plain text mode with < 80 chars. It wont happen again.
Quoted 35 lines · On Wed, Sep 04, 2019 at 10:03:31AM +0800, [email protected] wrote:
Quoted 8 lines
Quoted 8 lines
Hi, Peter,
I found that this patch has been merged but I haven't received the e-mail for some unknown reasons.
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=1c6c1ca318585f1096d4d04bc722297c85e9fb8aFirstly, your comments are correct, so the
barrier.hpart is perfect.Secondly, most of the rest is useless, because
smp_mb__before_llsc,loongson_llsc_mband other memory barriers are the same thing on Loongson-3. We don't need to addloongson_llsc_mbif there is already asmp_mb__before_llsc.There wasn't. Take for example
set_bit(), that didn't havesmp_mb__before_llscon.Also; MIPS should probably convert to
asm-generic/bitops/atomic.h.Quoted 1 line
Quoted 1 line
Thirdly, maybe the only exception is
syscall.c, butmips_atomic_setis not used on Loongson-3. And if in some cases we use it, I think the user-to-kernel context switch has the same effect of a memory barrier.And how is some random person trying to make sense of MIPS to know that?
You all created a badly documented inconsitent trainwreck. You're 'lucky' the MIPS maintainers accepted that mess in the first place.
Anyway, yes there are too many barrers now in some cases, in a previous version I had:
https://lkml.kernel.org/r/[email protected]But because I dropped changes to
local.hthat might not be true anymore; it needs careful consideration. Please audit carefully and if you find allsmp_mb__before_llsc()usage is now superfluous for this 'funny' chip of yours, then re-submit the above patch.Quoted 2 lines
+. per-cpu like
local_t*should only* be written by local cpu, and may be read by remote cpu sometimes
Quoted 8 lines
Quoted 5 lines
+. if and only if local cpu can write per-cpu, then Loongson3's llsc bug would not be triggerd.
same as
this_cpu_cmpxchg_doubleIf so, then no need to add sync before and after
cmpxchg_localCorrect, we already dropped the change for other
local.hstuff.
What about cmpxchg_local? Your patch add sync before and after ll/sc in __cmpxchg, so *cmpxchg_local* has sync around it. But cmpxchg_local operate on per-cpu, which *shall not* trigger loongson's LLSC bug, since only *this* cpu write, other cpus read.
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
In reply to Peter ZijlstraQuoted 40 lines · Peter Zijlstra
Quoted 39 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 7 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).That's just words.. what does it actually mean?
It means the
dev_to_node(dev)may return -1 if the bios does not implement the proximity domain feature, user may use that value to callcpumask_of_nodeandcpumask_of_nodedoes not protect itself from node id being -1, which causes out of bound access.Quoted 8 lines
Quoted 8 lines
arch/x86/include/asm/topology.h +4
-0@@ -69,6 +69,12 @@ extern const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node])Quoted 8 lines
arch/x86/include/asm/topology.h extern const struct cpumask *cpumask_of_node(int node); · line 80
Quoted 5 lines
arch/x86/include/asm/topology.h +2
-0+return cpu_online_mask; + return node_to_cpumask_map[node]; }#endif I _reallly_ hate this. Users are expected to use valid numa ids. Now we're adding all this checking to all users. Why do we want to do that?
As above, the
dev_to_node(dev)may return -1.Quoted 1 line
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Using '(unsigned)node >=
nr_nods_ids' is an error.'node >=
nr_node_ids' can be dropped if all user is expected to not callcpumask_of_nodewith node id greater or equal tonr_nods_ids.you copied my typo :-)
I did note the typo, corrected the first one, but missed the second one :)
Quoted 13 lines
Quoted 13 lines
From what I can see, the problem can be fixed in three place:
1. Make userdev_to_nodereturn a valid node id even when proximity domain is not set by bios(or node id set by buggy bios is not valid), which may need info from the numa system to make sure it will return a valid node.2. User that call
cpumask_of_nodeshould ensure the node id is valid before callingcpumask_of_node, and user also need some info to make ensure node id is valid.3. Make sure
cpumask_of_nodedeal with invalid node id as this patchset.
Quoted 8 lines
Quoted 4 lines
Which one do you prefer to make sure node id is valid, or do you have any better idea?
Any detail advice and suggestion will be very helpful, thanks.
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means dev_to_node() will return either NUMA_NO_NODE or a valid node id?
Quoted 2 lines
2) is already true today,
cpumask_of_node()requires a validnode_id.
Ok, most of the user does check node_id before calling cpumask_of_node(), but does a little different type of checking:
1) some does " < 0" check;
2) some does "== NUMA_NO_NODE" check;
3) some does ">= MAX_NUMNODES" check;
4) some does "< 0 || >= MAX_NUMNODES || !node_online(node)" check.
Quoted 2 lines
3) is just wrong and increases overhead for everyone.
Ok, cpumask_of_node() is also used in some critical path such as scheduling, which may not need those checking, the overhead is unnecessary.
But for non-critical path such as setup or configuration path, it better to have consistent checking, and also simplify the user code that calls cpumask_of_node().
Do you think it is worth the trouble to add a new function such as cpumask_of_node_check(maybe some other name) to do consistent checking?
Or caller just simply check if dev_to_node()'s return value is NUMA_NO_NODE before calling cpumask_of_node()?
Quoted 8 lines
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel.
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?
NUMA_NO_NODE := -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.
Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
Quoted 9 lines
Quoted 1 line
2) is already true today,
cpumask_of_node()requires a validnode_id.Ok, most of the user does check
node_idbefore callingcpumask_of_node(), but does a little different type of checking:1) some does " < 0" check;
2) some does "==NUMA_NO_NODE" check;
3) some does ">=MAX_NUMNODES" check;
4) some does "< 0 || >=MAX_NUMNODES|| !node_online(node)" check.
The one true way is:
'(unsigned)node_id >= nr_node_ids'
Quoted 10 lines
Quoted 1 line
3) is just wrong and increases overhead for everyone.
Ok,
cpumask_of_node()is also used in some critical path such as scheduling, which may not need those checking, the overhead is unnecessary.But for non-critical path such as setup or configuration path, it better to have consistent checking, and also simplify the user code that calls
cpumask_of_node().
Quoted 6 lines
Do you think it is worth the trouble to add a new function such as
cpumask_of_node_check(maybe some other name)to do consistent checking?Or caller just simply check if dev_to_node()'s return value is
NUMA_NO_NODEbefore callingcpumask_of_node()?
It is not a matter of convenience. The function is called cpumask_of_node(), when node < 0 || node >= nr_node_ids, it is not a valid node, therefore the function shouldn't return anything except an error.
Also note that the CONFIG_DEBUG_PER_CPU_MAPS version of cpumask_of_node() already does this (although it wants the below fix).
---
arch/x86/mm/numa.c +1 -1
@@ -861,7 +861,7 @@ void numa_remove_cpu(int cpu)*/ const struct cpumask *cpumask_of_node (int node) { -if (node >= nr_node_ids) { +if ((unsigned )node >= nr_node_ids) {printk (KERN_WARNING "cpumask_of_node(%d): node > nr_node_ids(%u)\n" , node, nr_node_ids);
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 7 lines · Peter Zijlstra
Quoted 6 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
Quoted 8 lines
Quoted 2 lines
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
It seems dev_to_node() does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such as cpumask_of_node().
Quoted 6 lines
Quoted 6 lines
Quoted 2 lines
2) is already true today,
cpumask_of_node()requires a validnode_id.Ok, most of the user does check
node_idbefore callingcpumask_of_node(), but does a little different type of checking:
Quoted 8 lines
Quoted 4 lines
1) some does " < 0" check;
2) some does "==NUMA_NO_NODE" check;
3) some does ">=MAX_NUMNODES" check;
4) some does "< 0 || >=MAX_NUMNODES|| !node_online(node)" check.The one true way is:
'(unsigned)node_id >= nr_node_ids'
I missed the magic of the "unsigned" in your previous reply.
Quoted 15 lines
Quoted 15 lines
Quoted 2 lines
3) is just wrong and increases overhead for everyone.
Ok,
cpumask_of_node()is also used in some critical path such as scheduling, which may not need those checking, the overhead is unnecessary.But for non-critical path such as setup or configuration path, it better to have consistent checking, and also simplify the user code that calls
cpumask_of_node().Do you think it is worth the trouble to add a new function such as
cpumask_of_node_check(maybe some other name)to do consistent checking?
Quoted 7 lines
Quoted 2 lines
Or caller just simply check if dev_to_node()'s return value is
NUMA_NO_NODEbefore callingcpumask_of_node()?It is not a matter of convenience. The function is called
cpumask_of_node(), when node < 0 || node >=nr_node_ids, it is not a valid node, therefore the function shouldn't return anything except an error.
what do you mean by error? What I can think is three type of errors:
1) return NULL, this way it seems cpumask_of_node() also leave the job to the function that calls it.
2) cpu_none_mask, I am not sure what this means, maybe it means there is no cpu on the same node with the device?
3) give a warning, stack dump, or even a BUG_ON?
I would prefer the second one, and implement the third one when the CONFIG_DEBUG_PER_CPU_MAPS is selected.
Any suggestion?
Quoted 3 lines
Also note that the
CONFIG_DEBUG_PER_CPU_MAPSversion ofcpumask_of_node()already does this (although it wants the below fix).
Thanks for the note and example.
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?
Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See device_add(), it looks to the device's parent and on NO_NODE, puts it there.
Lacking any hints, just stick it to node0 and print a FW_BUG or something.
Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().
Well, dev_to_node() doesn't do anything; nor should it. It are the callers of set_dev_node() that should be taking care.
Also note how device_add() sets the device node to the parent device's node on NUMA_NO_NODE. Arguably we should change it to complain when it finds NUMA_NO_NODE and !parent.
--- drivers/base/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/base/core.c +10 -2
@@ -2120,8 +2120,16 @@ int device_add(struct device *dev) dev->kobj.parent = kobj;/* use parent numa_node */ -if (parent && (dev_to_node (dev) ==NUMA_NO_NODE )) -set_dev_node (dev,dev_to_node (parent)); +if (dev_to_node (dev) ==NUMA_NO_NODE ) { +if (parent) +set_dev_node (dev,dev_to_node (parent)); +#ifdef CONFIG_NUMA + else { +pr_err ("device: '%s': has no assigned NUMA node\n" ,dev_name (dev)); +set_dev_node (dev,0 ); + } +#endif + }/* first, register with generic layer. */ /* we require the name to be set before, and pass NULL */
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 50 lines · Peter Zijlstra
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See
device_add(), it looks to the device's parent and onNO_NODE, puts it there.Lacking any hints, just stick it to node0 and print a
FW_BUGor something.Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().Well,
dev_to_node()doesn't do anything; nor should it. It are the callers ofset_dev_node()that should be taking care.Also note how
device_add()sets the device node to the parent device's node onNUMA_NO_NODE. Arguably we should change it to complain when it findsNUMA_NO_NODEand !parent.--- drivers/base/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)drivers/base/core.c +0
-1@@ -2120,8 +2120,16 @@ int device_add(struct device *dev) dev->kobj.parent = kobj;/* use parent numa_node */ -if (parent && (dev_to_node (dev) ==NUMA_NO_NODE ))
drivers/base/core.c int device_add(struct device *dev) · line 2131
Quoted 10 lines
drivers/base/core.c +9
-1-set_dev_node (dev,dev_to_node (parent)); +if (dev_to_node (dev) ==NUMA_NO_NODE ) { +if (parent) +set_dev_node (dev,dev_to_node (parent)); +#ifdef CONFIG_NUMA + else { +pr_err ("device: '%s': has no assigned NUMA node\n" ,dev_name (dev)); +set_dev_node (dev,0 ); + } +#endif
BTW., is firmware required to always provide a NUMA node on NUMA systems?
I.e. do we really want this warning on non-NUMA systems that don't assign NUMA nodes?
Also, even on NUMA systems, is firmware required to provide a NUMA node - i.e. is it in principle invalid to offer no NUMA binding?
Thanks,
Ingo
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 25 lines · Ingo Molnar
Quoted 9 lines · Peter Zijlstra
drivers/base/core.c +0
-1@@ -2120,8 +2120,16 @@ int device_add(struct device *dev) dev->kobj.parent = kobj;/* use parent numa_node */ -if (parent && (dev_to_node (dev) ==NUMA_NO_NODE ))drivers/base/core.c int device_add(struct device *dev) · line 2131
Quoted 10 lines
drivers/base/core.c +9
-1-set_dev_node (dev,dev_to_node (parent)); +if (dev_to_node (dev) ==NUMA_NO_NODE ) { +if (parent) +set_dev_node (dev,dev_to_node (parent)); +#ifdef CONFIG_NUMA + else { +pr_err ("device: '%s': has no assigned NUMA node\n" ,dev_name (dev)); +set_dev_node (dev,0 ); + } +#endif BTW., is firmware required to always provide a NUMA node on NUMA systems?
Quoted 2 lines
I.e. do we really want this warning on non-NUMA systems that don't assign NUMA nodes?
Good point; we might have to exclude nr_node_ids==1 systems from warning.
Quoted 2 lines
Also, even on NUMA systems, is firmware required to provide a NUMA node - i.e. is it in principle invalid to offer no NUMA binding?
I think so; a device needs to be _somewhere_, right? Typically though; devices are on a PCI bus, and the PCI bridge itself will have a NUMA binding and then the above parent rule will make everything just work.
But I don't see how you can be outside of the NUMA topology.
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
In reply to Peter ZijlstraQuoted 30 lines · Peter Zijlstra
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See
device_add(), it looks to the device's parent and onNO_NODE, puts it there.Lacking any hints, just stick it to node0 and print a
FW_BUGor something.Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().
Quoted 6 lines
Well,
dev_to_node()doesn't do anything; nor should it. It are the callers ofset_dev_node()that should be taking care.Also note how
device_add()sets the device node to the parent device's node onNUMA_NO_NODE. Arguably we should change it to complain when it findsNUMA_NO_NODEand !parent.
Is it possible that the node id set by device_add() become invalid if the node is offlined, then dev_to_node() may return a invalid node id.
From the comment in select_fallback_rq(), it seems that a node can be offlined, not sure if node offline process has taken cared of that?
/*
* If the node that the CPU is on has been offlined, cpu_to_node()
* will return -1. There is no CPU on the node, and we should
* select the CPU on the other node.
*/
With the above assumption that a device is always on a valid node, the node id returned from dev_to_node() can be safely passed to cpumask_of_node() without any checking?
Quoted 31 lines
--- drivers/base/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)drivers/base/core.c +10
-2@@ -2120,8 +2120,16 @@ int device_add(struct device *dev) dev->kobj.parent = kobj;/* use parent numa_node */ -if (parent && (dev_to_node (dev) ==NUMA_NO_NODE )) -set_dev_node (dev,dev_to_node (parent)); +if (dev_to_node (dev) ==NUMA_NO_NODE ) { +if (parent) +set_dev_node (dev,dev_to_node (parent)); +#ifdef CONFIG_NUMA + else { +pr_err ("device: '%s': has no assigned NUMA node\n" ,dev_name (dev)); +set_dev_node (dev,0 ); + } +#endif + }/* first, register with generic layer. */ /* we require the name to be set before, and pass NULL */ .
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 34 lines · Yunsheng Lin
Quoted 33 lines · Peter Zijlstra
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See
device_add(), it looks to the device's parent and onNO_NODE, puts it there.Lacking any hints, just stick it to node0 and print a
FW_BUGor something.Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().Well,
dev_to_node()doesn't do anything; nor should it. It are the callers ofset_dev_node()that should be taking care.
Quoted 7 lines
Quoted 3 lines
Also note how
device_add()sets the device node to the parent device's node onNUMA_NO_NODE. Arguably we should change it to complain when it findsNUMA_NO_NODEand !parent.Is it possible that the node id set by
device_add()become invalid if the node is offlined, thendev_to_node()may return a invalid node id.
In that case I would expect the device to go away too. Once the memory controller goes away, the PCI bus connected to it cannot continue to function.
Quoted 8 lines
From the comment in
select_fallback_rq(), it seems that a node can be offlined, not sure if node offline process has taken cared of that?/*
* If the node that the CPU is on has been offlined,cpu_to_node()
* will return -1. There is no CPU on the node, and we should
* select the CPU on the other node.
*/
Ugh, so I disagree with that notion. cpu_to_node() mapping should be fixed, you simply cannot change it after boot, too much stuff relies on it.
Setting cpu_to_node to -1 on node offline is just wrong. But alas, it seems this is already so.
Quoted 3 lines
With the above assumption that a device is always on a valid node, the node id returned from
dev_to_node()can be safely passed tocpumask_of_node()without any checking?
Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 39 lines · Peter Zijlstra
Quoted 38 lines · Yunsheng Lin
Quoted 36 lines · Peter Zijlstra
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See
device_add(), it looks to the device's parent and onNO_NODE, puts it there.Lacking any hints, just stick it to node0 and print a
FW_BUGor something.Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().Well,
dev_to_node()doesn't do anything; nor should it. It are the callers ofset_dev_node()that should be taking care.Also note how
device_add()sets the device node to the parent device's node onNUMA_NO_NODE. Arguably we should change it to complain when it findsNUMA_NO_NODEand !parent.
Quoted 7 lines
Quoted 3 lines
Is it possible that the node id set by
device_add()become invalid if the node is offlined, thendev_to_node()may return a invalid node id.In that case I would expect the device to go away too. Once the memory controller goes away, the PCI bus connected to it cannot continue to function.
Ok. To summarize the discussion in order to for me to understand it correctly:
1) Make sure device_add() set to default node0 to a device if ACPI/BIOS does not set the node id and it has not no parent device.
2) Use '(unsigned)node_id >= nr_node_ids' to fix the CONFIG_DEBUG_PER_CPU_MAPS version of cpumask_of_node() for x86 and arm64, x86 just has a fix from you now, a patch for arm64 is also needed.
3) Maybe fix some other the sign bug for node id checking through the kernel using the '(unsigned)node_id >= nr_node_ids'.
Please see if I understand it correctly or miss something. Maybe I can begin by sending a patch about item one to see if everyone is ok with the idea?
Quoted 16 lines
Quoted 9 lines
From the comment in
select_fallback_rq(), it seems that a node can be offlined, not sure if node offline process has taken cared of that?/*
* If the node that the CPU is on has been offlined,cpu_to_node()
* will return -1. There is no CPU on the node, and we should
* select the CPU on the other node.
*/Ugh, so I disagree with that notion.
cpu_to_node()mapping should be fixed, you simply cannot change it after boot, too much stuff relies on it.Setting
cpu_to_nodeto -1 on node offline is just wrong. But alas, it seems this is already so.
RE: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
In reply to Peter ZijlstraQuoted 42 lines
From: Linuxarm [mailto:[email protected]] On Behalf Of Peter Zijlstra
Sent: Tuesday, September 3, 2019 8:11 AMQuoted 38 lines · Yunsheng Lin
Quoted 36 lines · Peter Zijlstra
Quoted 11 lines · Yunsheng Lin
Quoted 10 lines · Peter Zijlstra
Quoted 8 lines · Yunsheng Lin
Quoted 3 lines · Peter Zijlstra
1) because even it is not set, the device really does belong to a node. It is impossible a device will have magic uniform access to memory when CPUs cannot.
So it means
dev_to_node()will return eitherNUMA_NO_NODEor a valid node id?Quoted 7 lines
Quoted 5 lines
NUMA_NO_NODE:= -1, which is not a valid node number. It is also, like> I said, not a valid device location on a NUMA system.Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
See
device_add(), it looks to the device's parent and onNO_NODE, puts it there.Lacking any hints, just stick it to node0 and print a
FW_BUGor something.Quoted 3 lines
It seems
dev_to_node()does not do anything about that and leave the job to the caller or whatever function that get called with its return value, such ascpumask_of_node().Well,
dev_to_node()doesn't do anything; nor should it. It are the callers ofset_dev_node()that should be taking care.Also note how
device_add()sets the device node to the parent device's node onNUMA_NO_NODE. Arguably we should change it to complain when it findsNUMA_NO_NODEand !parent.
Quoted 7 lines
Quoted 3 lines
Is it possible that the node id set by
device_add()become invalid if the node is offlined, thendev_to_node()may return a invalid node id.In that case I would expect the device to go away too. Once the memory controller goes away, the PCI bus connected to it cannot continue to function.
I am not sure if this is *exactly* true on our system as NUMA nodes are part of the SoCs and devices could still be used even if all the memory and CPUs part of the node are turned off. Although, it is highly unlikely anybody would do that(maybe could be debated for the Power Management case?)
Best Regards
Salil
Peter Zijlstra
maintainerRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
Quoted 7 lines · Salil Mehta
Quoted 7 lines
From: Linuxarm [mailto:[email protected]] On Behalf Of Peter Zijlstra
Quoted 3 lines · Yunsheng Lin
Is it possible that the node id set by
device_add()become invalid if the node is offlined, thendev_to_node()may return a invalid node id.
Quoted 8 lines
Quoted 3 lines
In that case I would expect the device to go away too. Once the memory controller goes away, the PCI bus connected to it cannot continue to function.
I am not sure if this is *exactly* true on our system as NUMA nodes are part of the SoCs and devices could still be used even if all the memory and CPUs part of the node are turned off. Although, it is highly unlikely anybody would do that(maybe could be debated for the Power Management case?)
Cute; anyway, we never change nr_node_ids (after boot), so once a node is deemed valid it always is.
The worst that can happen in the above case, is that cpumask_of_node() returns an empty mask, which, if all CPUs (of said node) are offline, is an accurate representation.
Ingo Molnar
Acked-byRe: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
In reply to Peter ZijlstraQuoted 9 lines · Peter Zijlstra
Also note that the
CONFIG_DEBUG_PER_CPU_MAPSversion ofcpumask_of_node()already does this (although it wants the below fix).---
arch/x86/mm/numa.c +0
-0
arch/x86/mm/numa.c void numa_remove_cpu(int cpu) · line 867
Quoted 8 lines
arch/x86/mm/numa.c +1
-1@@ -861,7 +861,7 @@ void numa_remove_cpu(int cpu)*/ const struct cpumask *cpumask_of_node (int node) { -if (node >= nr_node_ids) { +if ((unsigned )node >= nr_node_ids) {printk (KERN_WARNING "cpumask_of_node(%d): node > nr_node_ids(%u)\n" , node, nr_node_ids);
Nitpicking: please also fix the kernel message to say ">=".
With that:
Note that:
- arch/arm64/mm/numa.c copied the same sign bug (or unrobustness if we don't want to call it a bug).
- Kudos to the mm/memcontrol.c and kernel/bpf/syscall.c teams for not copying that bug. Booo for none of them fixing the buggy pattern elsewhere in the kernel ;-)
Thanks,
Ingo
Peter Zijlstra
maintainerPATCH 1/1 x86/mm: Fix cpumask_of_node() error condition
Quoted 1 line · Ingo Molnar
Nitpicking: please also fix the kernel message to say ">=".
Full patch below.
---
Subject: x86/mm: Fix cpumask_of_node() error condition
When CONFIG_DEBUG_PER_CPU_MAPS we validate that the @node argument of cpumask_of_node() is a valid node_id. It however forgets to check for negative numbers. Fix this by explicitly casting to unsigned.
(unsigned)node >= nr_node_ids
verifies: 0 <= node < nr_node_ids
Also ammend the error message to match the condition.
--- arch/x86/mm/numa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/mm/numa.c +2 -2
@@ -861,9 +861,9 @@ void numa_remove_cpu(int cpu)*/ const struct cpumask *cpumask_of_node (int node) { -if (node >= nr_node_ids) { +if ((unsigned )node >= nr_node_ids) {printk (KERN_WARNING -"cpumask_of_node(%d): node > nr_node_ids(%u)\n" , +"cpumask_of_node(%d): (unsigned)node >= nr_node_ids(%u)\n" , node, nr_node_ids);dump_stack ();return cpu_none_mask;
PATCH v2 3/9 alpha: numa: check the node id consistently for alpha
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
---
note node_to_cpumask_map[node] is already a pointer, so the cpumask_clear should be called with node_to_cpumask_map[node] instead of &node_to_cpumask_map[node]? And cpumask_of_node() function need to be inlined when defined in a header file? If the above are problems, maybe another patch to fix or clean it up.
--- arch/alpha/include/asm/topology.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/alpha/include/asm/topology.h +5 -2
@@ -30,8 +30,11 @@ static const struct cpumask *cpumask_of_node(int node) {int cpu; -if (node ==NUMA_NO_NODE ) -return cpu_all_mask; +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask;cpumask_clear (&node_to_cpumask_map[node]);
Signature · 1 line
2.8.1
PATCH v2 4/9 powerpc: numa: check the node id consistently for powerpc
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/powerpc/include/asm/topology.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/topology.h +10 -3
@@ -17,9 +17,16 @@ struct device_node;#include <asm/mmzone.h> -#define cpumask_of_node (node) ((node) == -1 ? \ - cpu_all_mask : \ - node_to_cpumask_map[node]) +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; + +return node_to_cpumask_map[node]; +}struct pci_bus ;#ifdef CONFIG_PCI
Signature · 1 line
2.8.1
PATCH v2 5/9 s390: numa: check the node id consistently for s390
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
This patch checks node id with the below case before returning node_to_cpumask_map[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
---
Note node_to_cpumask_map[node] is already a pointer, so returning &node_to_cpumask_map[node] does not seem to be correct, if this is problem, maybe clean it up in another patch.
--- arch/s390/include/asm/topology.h | 6 ++++++ 1 file changed, 6 insertions(+)
arch/s390/include/asm/topology.h +6 -0
@@ -78,6 +78,12 @@ static inline int cpu_to_node(int cpu)#define cpumask_of_node cpumask_of_nodestatic inline const struct cpumask *cpumask_of_node (int node) { +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; +return &node_to_cpumask_map[node]; }
Signature · 1 line
2.8.1
kbuild test robot
build botRe: [PATCH v2 5/9] s390: numa: check the node id consistently for s390
Thank you for the patch! Yet something to improve:
Hi Yunsheng,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[cannot apply to v5.3-rc6 next-20190830]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Yunsheng-Lin/check-the-node-id-consistently-across-different-arches/20190901-143722
config: s390-allmodconfig (attached as .config)
compiler: s390-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=s390
If you fix the issue, kindly add following tag
All errors (new ones prefixed by >>):
In file included from include/linux/topology.h:35:0,
from include/linux/gfp.h:9,
from include/linux/mm.h:10,
from include/linux/kvm_host.h:14,
from arch/s390/kernel/asm-offsets.c:11:
arch/s390/include/asm/topology.h: In function 'cpumask_of_node':
>> arch/s390/include/asm/topology.h:84:18: error: wrong type argument to unary exclamation mark
if (node < 0 || !node_to_cpumask_map[node])
^ make[2]: *** [arch/s390/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [sub-make] Error 2
43 real 4 user 3 sys 16.91% cpu make prepare
vim +84 arch/s390/include/asm/topology.h
76
77 /* Returns a pointer to the cpumask of CPUs on node 'node'. */
78 #define cpumask_of_node cpumask_of_node
79 static inline const struct cpumask *cpumask_of_node(int node)
80 {
81 if (node >= nr_node_ids)
82 return cpu_none_mask;
83
> 84 if (node < 0 || !node_to_cpumask_map[node])
85 return cpu_online_mask;
86
87 return &node_to_cpumask_map[node];
88 }
89 ---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
PATCH v2 6/9 sh: numa: check the node id consistently for sh
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
It seems sh does not have real numa support or uncompleted numa support, this patch still checks node id with the below case to ensure future support is consistent:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if node_to_cpumask_map[node_id] is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/sh/include/asm/topology.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
arch/sh/include/asm/topology.h +13 -1
@@ -6,7 +6,19 @@#define cpu_to_node (cpu) ((void)(cpu),0) -#define cpumask_of_node (node) ((void)node, cpu_online_mask) +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >= nr_node_ids) +return cpu_none_mask; + +if (node <0 || !node_to_cpumask_map[node]) +return cpu_online_mask; + +/* Should return actual mask based on node_to_cpumask_map +* if sh arch supports real numa node. +*/ +return cpu_online_mask; +}#define pcibus_to_node (bus) ((void)(bus), -1)#define cpumask_of_pcibus (bus) (pcibus_to_node(bus) == -1 ? \
Signature · 1 line
2.8.1
PATCH v2 7/9 sparc64: numa: check the node id consistently for sparc64
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
This patch checks node id with the below case before returning &numa_cpumask_lookup_table[node]:
1. if node_id >= nr_node_ids, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. Since numa_cpumask_lookup_table is not a pointer, a comment is added to indicate that
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/sparc/include/asm/topology_64.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
arch/sparc/include/asm/topology_64.h +13 -3
@@ -11,9 +11,19 @@ static inline int cpu_to_node(int cpu)return numa_cpu_lookup_table[cpu]; } -#define cpumask_of_node (node) ((node) == -1 ? \ - cpu_all_mask : \ - &numa_cpumask_lookup_table[node]) +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >=MAX_NUMNODES ) +return cpu_none_mask; + +/* numa_cpumask_lookup_table[node] is not a pointer, so +* no need to check for NULL here. +*/ +if (node <0 ) +return cpu_online_mask; + +return &numa_cpumask_lookup_table[node]; +}struct pci_bus ;#ifdef CONFIG_PCI
Signature · 1 line
2.8.1
David Miller
maintainerRe: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64
From: Yunsheng Lin <[email protected]>
Date: Sat, 31 Aug 2019 13:58:21 +0800
Quoted 2 lines
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
What in the world does the ACPI spec have to do with sparc64 NUMA node ID checking?
Re: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64
Quoted 8 lines · David Miller
From: Yunsheng Lin <[email protected]>
Date: Sat, 31 Aug 2019 13:58:21 +0800Quoted 2 lines
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
What in the world does the ACPI spec have to do with sparc64 NUMA node ID checking?
I am not sure I understand your question fully here.
Here is my issue when the bios does not implement the proximity domain of a device because the feature is optional according to the ACPI spec, the dev_to_node(dev) return -1, which causes out of bound access when using the value to get the device's cpu mask by calling cpumask_of_node.
Did you mean sparc64 system does not has ACPI, the device's node id will not specified by ACPI, so the ACPI is unrelated here?
Or did you mean the commit log is not clear enough to justify the change?
Or did you mean this problem should be fixed in somewhere else?
Any detail advice and suggestion will be very helpful, thanks.
Quoted 3 lines
.
David Miller
maintainerRe: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64
From: Yunsheng Lin <[email protected]>
Date: Sat, 31 Aug 2019 16:57:04 +0800
Quoted 2 lines
Did you mean sparc64 system does not has ACPI, the device's node id will not specified by ACPI, so the ACPI is unrelated here?
Yes, sparc64 never has and never will have ACPI.
This is also true for several other platforms where you have made this change.
The assumption of your entire patch set is that the semantics of the NUMA node ID are somehow completely defined by ACPI semantics. Which is not true.
Re: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64
Quoted 6 lines · David Miller
From: Yunsheng Lin <[email protected]>
Date: Sat, 31 Aug 2019 16:57:04 +0800Quoted 2 lines
Did you mean sparc64 system does not has ACPI, the device's node id will not specified by ACPI, so the ACPI is unrelated here?
Quoted 8 lines
Yes, sparc64 never has and never will have ACPI.
This is also true for several other platforms where you have made this change.
The assumption of your entire patch set is that the semantics of the NUMA node ID are somehow completely defined by ACPI semantics. Which is not true.
Thanks for pointing out.
The NUMA node id in sparc64 system is defined by DT semantics?
Quoted 3 lines
.
David Miller
maintainerRe: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64
From: Yunsheng Lin <[email protected]>
Date: Mon, 2 Sep 2019 14:08:31 +0800
Quoted 1 line
The NUMA node id in sparc64 system is defined by DT semantics?
Sometimes, and in other cases other methods are used to determine the NUMA node id.
PATCH v2 8/9 mips: numa: check the node id consistently for mips ip27
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
Since mips ip27 uses hub_data instead of node_to_cpumask_map, this patch checks node id with the below case before returning &hub_data(node)->h_cpus:
1. if node_id >= MAX_COMPACT_NODES, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if hub_data(node) is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/mips/include/asm/mach-ip27/topology.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
arch/mips/include/asm/mach-ip27/topology.h +12 -3
@@ -15,9 +15,18 @@ struct cpuinfo_ip27 {extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS ];#define cpu_to_node (cpu) (sn_cpu_info[(cpu)].p_nodeid) -#define cpumask_of_node (node) ((node) == -1 ? \ - cpu_all_mask : \ - &hub_data(node)->h_cpus) + +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >=MAX_COMPACT_NODES ) +return cpu_none_mask; + +if (node <0 || !hub_data (node)) +return cpu_online_mask; + +return &hub_data (node)->h_cpus; +} +struct pci_bus ;extern int pcibus_to_node (struct pci_bus *);
Signature · 1 line
2.8.1
Re: [PATCH v2 8/9] mips: numa: check the node id consistently for mips ip27
Hi Yunsheng,
Quoted 8 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
Quoted 8 lines
Since mips ip27 uses
hub_datainstead ofnode_to_cpumask_map, this patch checks node id with the below case before returning &hub_data(node)->h_cpus:
1. ifnode_id>=MAX_COMPACT_NODES, returncpu_none_mask
2. ifnode_id< 0, returncpu_online_mask
3. ifhub_data(node)is NULL, returncpu_online_mask[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
Similar to David's comment on the sparc patch, these systems don't use ACPI so I don't see from your commit message why this change would be relevant.
This same comment applies to patch 9 too.
Thanks,
Paul
Quoted 35 lines
Signed-off-by Yunsheng Lin <[email protected]>--- arch/mips/include/asm/mach-ip27/topology.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)arch/mips/include/asm/mach-ip27/topology.h +12
-3@@ -15,9 +15,18 @@ struct cpuinfo_ip27 {extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS ];#define cpu_to_node (cpu) (sn_cpu_info[(cpu)].p_nodeid) -#define cpumask_of_node (node) ((node) == -1 ? \ - cpu_all_mask : \ - &hub_data(node)->h_cpus) + +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >=MAX_COMPACT_NODES ) +return cpu_none_mask; + +if (node <0 || !hub_data (node)) +return cpu_online_mask; + +return &hub_data (node)->h_cpus; +} +struct pci_bus ;extern int pcibus_to_node (struct pci_bus *);Signature · 1 line
2.8.1
Re: [PATCH v2 8/9] mips: numa: check the node id consistently for mips ip27
Quoted 18 lines · Paul Burton
Hi Yunsheng,
Quoted 15 lines · Yunsheng Lin
According to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine.
_PXMevaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).Since mips ip27 uses
hub_datainstead ofnode_to_cpumask_map, this patch checks node id with the below case before returning &hub_data(node)->h_cpus:
1. ifnode_id>=MAX_COMPACT_NODES, returncpu_none_mask
2. ifnode_id< 0, returncpu_online_mask
3. ifhub_data(node)is NULL, returncpu_online_mask
Quoted 7 lines
Similar to David's comment on the sparc patch, these systems don't use ACPI so I don't see from your commit message why this change would be relevant.
This same comment applies to patch 9 too.
Thanks for pointing out.
MIPS's NUMA node id is also defined by DT?
Quoted 42 lines
Thanks,
PaulQuoted 35 lines
Signed-off-by Yunsheng Lin <[email protected]>--- arch/mips/include/asm/mach-ip27/topology.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)arch/mips/include/asm/mach-ip27/topology.h +12
-3@@ -15,9 +15,18 @@ struct cpuinfo_ip27 {extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS ];#define cpu_to_node (cpu) (sn_cpu_info[(cpu)].p_nodeid) -#define cpumask_of_node (node) ((node) == -1 ? \ - cpu_all_mask : \ - &hub_data(node)->h_cpus) + +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >=MAX_COMPACT_NODES ) +return cpu_none_mask; + +if (node <0 || !hub_data (node)) +return cpu_online_mask; + +return &hub_data (node)->h_cpus; +} +struct pci_bus ;extern int pcibus_to_node (struct pci_bus *);Signature · 1 line
2.8.1.
PATCH v2 9/9 mips: numa: check the node id consistently for mips loongson64
In reply to Yunsheng LinAccording to Section 6.2.14 from ACPI spec 6.3 [1], the setting of proximity domain is optional, as below:
This optional object is used to describe proximity domain associations within a machine. _PXM evaluates to an integer that identifies a device as belonging to a Proximity Domain defined in the System Resource Affinity Table (SRAT).
Since mips loongson64 uses __node_data instead of node_to_cpumask_map, this patch checks node id with the below case before returning &__node_data[node]->cpumask:
1. if node_id >= MAX_NUMNODES, return cpu_none_mask
2. if node_id < 0, return cpu_online_mask
3. if hub_data(node) is NULL, return cpu_online_mask
[1] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
--- arch/mips/include/asm/mach-loongson64/topology.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
arch/mips/include/asm/mach-loongson64/topology.h +11 -1
@@ -5,7 +5,17 @@#ifdef CONFIG_NUMA #define cpu_to_node (cpu) (cpu_logical_map(cpu) >> 2) -#define cpumask_of_node (node) (&__node_data[(node)]->cpumask) + +static inline const struct cpumask *cpumask_of_node (int node) +{ +if (node >=MAX_NUMNODES ) +return cpu_none_mask; + +if (node <0 || !__node_data[node]) +return cpu_online_mask; + +return &__node_data[node]->cpumask; +}struct pci_bus ;extern int pcibus_to_node (struct pci_bus *);
Signature · 1 line
2.8.1