Message ID | 20230425075655.4037980-4-Henry.Wang@arm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Device tree based NUMA support for Arm - Part#3 | expand |
On 25.04.2023 09:56, Henry Wang wrote: > --- a/xen/arch/arm/numa.c > +++ b/xen/arch/arm/numa.c > @@ -28,6 +28,12 @@ enum dt_numa_status { > > static enum dt_numa_status __ro_after_init device_tree_numa = DT_NUMA_DEFAULT; > > +static unsigned char __ro_after_init > +node_distance_map[MAX_NUMNODES][MAX_NUMNODES] = { > + [0 ... MAX_NUMNODES - 1] = { [0 ... MAX_NUMNODES - 1] = NUMA_NO_DISTANCE } > +}; > + > + Nit: A stray 2nd blank line has appeared here. > @@ -48,3 +54,52 @@ int __init arch_numa_setup(const char *opt) > { > return -EINVAL; > } > + > +void __init numa_set_distance(nodeid_t from, nodeid_t to, > + unsigned int distance) > +{ > + if ( from >= ARRAY_SIZE(node_distance_map) || > + to >= ARRAY_SIZE(node_distance_map[0]) ) > + { > + printk(KERN_WARNING > + "NUMA: invalid nodes: from=%"PRIu8" to=%"PRIu8" MAX=%"PRIu8"\n", > + from, to, MAX_NUMNODES); > + return; > + } > + > + /* NUMA defines NUMA_NO_DISTANCE as unreachable and 0-9 are undefined */ > + if ( distance >= NUMA_NO_DISTANCE || distance <= NUMA_DISTANCE_UDF_MAX || > + (from == to && distance != NUMA_LOCAL_DISTANCE) ) > + { > + printk(KERN_WARNING > + "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8" distance=%"PRIu32"\n", > + from, to, distance); > + return; > + } I appreciate the checking that node-local references are NUMA_LOCAL_DISTANCE, but if they're wrongly passed into here, shouldn't the resulting array still have NUMA_LOCAL_DISTANCE on its diagonal, at least as far as present nodes go? > + node_distance_map[from][to] = distance; > +} > + > +unsigned char __node_distance(nodeid_t from, nodeid_t to) > +{ > + if ( from == to ) > + return NUMA_LOCAL_DISTANCE; > + > + /* > + * When NUMA is off, any distance will be treated as unreachable, so > + * directly return NUMA_NO_DISTANCE from here as an optimization. > + */ > + if ( numa_disabled() ) > + return NUMA_NO_DISTANCE; > + > + /* > + * Check whether the nodes are in the matrix range. > + * When any node is out of range, except from and to nodes are the > + * same, we treat them as unreachable. I think this "except ..." part is slightly confusing, as it doesn't comment the subsequent code, but instead refers to the first check in the function. If you want to keep it, may I suggest to add something like "(see above)" before the comma? Jan
Hi Jan, > -----Original Message----- > From: Jan Beulich <jbeulich@suse.com> > Subject: Re: [PATCH v4 03/17] xen/arm: implement node distance helpers for > Arm > > On 25.04.2023 09:56, Henry Wang wrote: > > --- a/xen/arch/arm/numa.c > > +++ b/xen/arch/arm/numa.c > > @@ -28,6 +28,12 @@ enum dt_numa_status { > > > > static enum dt_numa_status __ro_after_init device_tree_numa = > DT_NUMA_DEFAULT; > > > > +static unsigned char __ro_after_init > > +node_distance_map[MAX_NUMNODES][MAX_NUMNODES] = { > > + [0 ... MAX_NUMNODES - 1] = { [0 ... MAX_NUMNODES - 1] = > NUMA_NO_DISTANCE } > > +}; > > + > > + > > Nit: A stray 2nd blank line has appeared here. Will fix this in v5. > > > + /* NUMA defines NUMA_NO_DISTANCE as unreachable and 0-9 are > undefined */ > > + if ( distance >= NUMA_NO_DISTANCE || distance <= > NUMA_DISTANCE_UDF_MAX || > > + (from == to && distance != NUMA_LOCAL_DISTANCE) ) > > + { > > + printk(KERN_WARNING > > + "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8" > distance=%"PRIu32"\n", > > + from, to, distance); > > + return; > > + } > > I appreciate the checking that node-local references are > NUMA_LOCAL_DISTANCE, > but if they're wrongly passed into here, shouldn't the resulting array still > have NUMA_LOCAL_DISTANCE on its diagonal, at least as far as present nodes > go? Apologies in advance to ask more specific details from you as I am not sure if I can correctly understand the "if they're wrongly passed into here" case. Do you mean we are always guaranteed that if from == to, the distance will always be NUMA_LOCAL_DISTANCE so the (from == to && distance != NUMA_LOCAL_DISTANCE) check is redundant and can be removed? Thanks. > > > + node_distance_map[from][to] = distance; > > +} [...] > > + /* > > + * Check whether the nodes are in the matrix range. > > + * When any node is out of range, except from and to nodes are the > > + * same, we treat them as unreachable. > > I think this "except ..." part is slightly confusing, as it doesn't comment > the subsequent code, but instead refers to the first check in the function. > If you want to keep it, may I suggest to add something like "(see above)" > before the comma? Sure, I will add "(see above)" in v5. Kind regards, Henry > > Jan
On 25.04.2023 11:31, Henry Wang wrote: >> -----Original Message----- >> From: Jan Beulich <jbeulich@suse.com> >> >> On 25.04.2023 09:56, Henry Wang wrote: >>> + /* NUMA defines NUMA_NO_DISTANCE as unreachable and 0-9 are >> undefined */ >>> + if ( distance >= NUMA_NO_DISTANCE || distance <= >> NUMA_DISTANCE_UDF_MAX || >>> + (from == to && distance != NUMA_LOCAL_DISTANCE) ) >>> + { >>> + printk(KERN_WARNING >>> + "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8" >> distance=%"PRIu32"\n", >>> + from, to, distance); >>> + return; >>> + } >> >> I appreciate the checking that node-local references are >> NUMA_LOCAL_DISTANCE, >> but if they're wrongly passed into here, shouldn't the resulting array still >> have NUMA_LOCAL_DISTANCE on its diagonal, at least as far as present nodes >> go? > > Apologies in advance to ask more specific details from you as I am not sure > if I can correctly understand the "if they're wrongly passed into here" case. Do you > mean we are always guaranteed that if from == to, the distance will always be > NUMA_LOCAL_DISTANCE so the (from == to && distance != NUMA_LOCAL_DISTANCE) > check is redundant and can be removed? Thanks. It's a little odd that you ask me: It is your code which insists on NUMA_LOCAL_DISTANCE when from == to. If you insist on your caller to pass only this one value, then I think it is only logical to also set the respective table entries to that value (rather than leaving them at NUMA_NO_DISTANCE). Jan
Hi Jan, > -----Original Message----- > From: Jan Beulich <jbeulich@suse.com> > Subject: Re: [PATCH v4 03/17] xen/arm: implement node distance helpers for > Arm > > On 25.04.2023 11:31, Henry Wang wrote: > >> -----Original Message----- > >> From: Jan Beulich <jbeulich@suse.com> > >> > >> On 25.04.2023 09:56, Henry Wang wrote: > >>> + /* NUMA defines NUMA_NO_DISTANCE as unreachable and 0-9 are > >> undefined */ > >>> + if ( distance >= NUMA_NO_DISTANCE || distance <= > >> NUMA_DISTANCE_UDF_MAX || > >>> + (from == to && distance != NUMA_LOCAL_DISTANCE) ) > >>> + { > >>> + printk(KERN_WARNING > >>> + "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8" > >> distance=%"PRIu32"\n", > >>> + from, to, distance); > >>> + return; > >>> + } > >> > >> I appreciate the checking that node-local references are > >> NUMA_LOCAL_DISTANCE, > >> but if they're wrongly passed into here, shouldn't the resulting array still > >> have NUMA_LOCAL_DISTANCE on its diagonal, at least as far as present > nodes > >> go? > > > > Apologies in advance to ask more specific details from you as I am not sure > > if I can correctly understand the "if they're wrongly passed into here" case. > Do you > > mean we are always guaranteed that if from == to, the distance will always > be > > NUMA_LOCAL_DISTANCE so the (from == to && distance != > NUMA_LOCAL_DISTANCE) > > check is redundant and can be removed? Thanks. > > It's a little odd that you ask me: It is your code which insists on > NUMA_LOCAL_DISTANCE when from == to. If you insist on your caller to pass > only this one value, then I think it is only logical to also set the > respective table entries to that value (rather than leaving them at > NUMA_NO_DISTANCE). I think I understand what do you mean now. I was only checking this specific patch so didn't make the connection with the latter patches. Kind regards, Henry > > Jan
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 4d076b278b..9073398d6e 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_LIVEPATCH) += livepatch.o obj-y += mem_access.o obj-y += mm.o obj-y += monitor.o +obj-$(CONFIG_NUMA) += numa.o obj-y += p2m.o obj-y += percpu.o obj-y += platform.o diff --git a/xen/arch/arm/include/asm/numa.h b/xen/arch/arm/include/asm/numa.h index 83f60ad05b..96c856a9f7 100644 --- a/xen/arch/arm/include/asm/numa.h +++ b/xen/arch/arm/include/asm/numa.h @@ -22,7 +22,19 @@ typedef u8 nodeid_t; */ #define NR_NODE_MEMBLKS NR_MEM_BANKS +/* + * In ACPI spec, 0-9 are the reserved values for node distance, + * 10 indicates local node distance, 20 indicates remote node + * distance. Set node distance map in device tree will follow + * the ACPI's definition. + */ +#define NUMA_DISTANCE_UDF_MAX 9 +#define NUMA_LOCAL_DISTANCE 10 +#define NUMA_REMOTE_DISTANCE 20 + extern bool numa_disabled(void); +extern void numa_set_distance(nodeid_t from, nodeid_t to, + unsigned int distance); #else diff --git a/xen/arch/arm/numa.c b/xen/arch/arm/numa.c index eb5d0632cb..e4f75f314b 100644 --- a/xen/arch/arm/numa.c +++ b/xen/arch/arm/numa.c @@ -28,6 +28,12 @@ enum dt_numa_status { static enum dt_numa_status __ro_after_init device_tree_numa = DT_NUMA_DEFAULT; +static unsigned char __ro_after_init +node_distance_map[MAX_NUMNODES][MAX_NUMNODES] = { + [0 ... MAX_NUMNODES - 1] = { [0 ... MAX_NUMNODES - 1] = NUMA_NO_DISTANCE } +}; + + void __init numa_fw_bad(void) { printk(KERN_ERR "NUMA: device tree numa info table not used.\n"); @@ -48,3 +54,52 @@ int __init arch_numa_setup(const char *opt) { return -EINVAL; } + +void __init numa_set_distance(nodeid_t from, nodeid_t to, + unsigned int distance) +{ + if ( from >= ARRAY_SIZE(node_distance_map) || + to >= ARRAY_SIZE(node_distance_map[0]) ) + { + printk(KERN_WARNING + "NUMA: invalid nodes: from=%"PRIu8" to=%"PRIu8" MAX=%"PRIu8"\n", + from, to, MAX_NUMNODES); + return; + } + + /* NUMA defines NUMA_NO_DISTANCE as unreachable and 0-9 are undefined */ + if ( distance >= NUMA_NO_DISTANCE || distance <= NUMA_DISTANCE_UDF_MAX || + (from == to && distance != NUMA_LOCAL_DISTANCE) ) + { + printk(KERN_WARNING + "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8" distance=%"PRIu32"\n", + from, to, distance); + return; + } + + node_distance_map[from][to] = distance; +} + +unsigned char __node_distance(nodeid_t from, nodeid_t to) +{ + if ( from == to ) + return NUMA_LOCAL_DISTANCE; + + /* + * When NUMA is off, any distance will be treated as unreachable, so + * directly return NUMA_NO_DISTANCE from here as an optimization. + */ + if ( numa_disabled() ) + return NUMA_NO_DISTANCE; + + /* + * Check whether the nodes are in the matrix range. + * When any node is out of range, except from and to nodes are the + * same, we treat them as unreachable. + */ + if ( from >= ARRAY_SIZE(node_distance_map) || + to >= ARRAY_SIZE(node_distance_map[0]) ) + return NUMA_NO_DISTANCE; + + return node_distance_map[from][to]; +} diff --git a/xen/arch/x86/include/asm/numa.h b/xen/arch/x86/include/asm/numa.h index 7866afa408..45456ac441 100644 --- a/xen/arch/x86/include/asm/numa.h +++ b/xen/arch/x86/include/asm/numa.h @@ -22,7 +22,6 @@ extern void init_cpu_to_node(void); #define arch_want_default_dmazone() (num_online_nodes() > 1) void srat_parse_regions(paddr_t addr); -extern u8 __node_distance(nodeid_t a, nodeid_t b); unsigned int arch_get_dma_bitsize(void); #endif diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 56749ddca5..50faf5d352 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -328,7 +328,7 @@ unsigned int numa_node_to_arch_nid(nodeid_t n) return 0; } -u8 __node_distance(nodeid_t a, nodeid_t b) +unsigned char __node_distance(nodeid_t a, nodeid_t b) { unsigned index; u8 slit_val; diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h index b86d0851fc..8356e47b61 100644 --- a/xen/include/xen/numa.h +++ b/xen/include/xen/numa.h @@ -114,6 +114,7 @@ extern bool numa_memblks_available(void); extern bool numa_update_node_memblks(nodeid_t node, unsigned int arch_nid, paddr_t start, paddr_t size, bool hotplug); extern void numa_set_processor_nodes_parsed(nodeid_t node); +extern unsigned char __node_distance(nodeid_t a, nodeid_t b); #else