[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] x86/NUMA: correct memnode_shift calculation for single node system
Jan Beulich <jbeulich@xxxxxxxx> writes: > SRAT may describe even a single node system (including such with > multiple nodes, but only one having any memory) using multiple ranges. > Hence simply counting the number of ranges (note that function > parameters are mis-named) is not an indication of the number of nodes in > use. Since we only care about knowing whether we're on a single node > system, accounting for this is easy: Increment the local variable only > when adjacent ranges are for different nodes. That way the count may > still end up larger than the number of nodes in use, but it won't be > larger than 1 when only a single node has any memory. > > To compensate populate_memnodemap() now needs to be prepared to find > the correct node ID already in place for a range. (This could of course > also happen when there's more than one node with memory, while at least > one node has multiple adjacent ranges, provided extract_lsb_from_nodes() > would also know to recognize this case.) > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > On my Skylake system this changes memnodemapsize from 17 to 1 (and the > shift from 20 to 63). > > --- a/xen/arch/x86/numa.c > +++ b/xen/arch/x86/numa.c > @@ -78,7 +78,8 @@ static int __init populate_memnodemap(co > if ( (epdx >> shift) >= memnodemapsize ) > return 0; > do { > - if ( memnodemap[spdx >> shift] != NUMA_NO_NODE ) > + if ( memnodemap[spdx >> shift] != NUMA_NO_NODE && > + (!nodeids || memnodemap[spdx >> shift] != nodeids[i]) ) > return -1; > > if ( !nodeids ) > @@ -114,7 +115,7 @@ static int __init allocate_cachealigned_ > * maximum possible shift. > */ > static int __init extract_lsb_from_nodes(const struct node *nodes, > - int numnodes) > + int numnodes, const nodeid_t > *nodeids) > { > int i, nodes_used = 0; > unsigned long spdx, epdx; > @@ -127,7 +128,7 @@ static int __init extract_lsb_from_nodes > if ( spdx >= epdx ) > continue; > bitfield |= spdx; > - nodes_used++; > + nodes_used += i == 0 || !nodeids || nodeids[i - 1] != > nodeids[i]; Is that boolean short cutting worth it instead of a more easily readable: if (i == 0 || !nodeids || nodeids[i - 1] != nodeids[i]) nodes_used++; ? > if ( epdx > memtop ) > memtop = epdx; > } > @@ -144,7 +145,7 @@ int __init compute_hash_shift(struct nod > { > int shift; > > - shift = extract_lsb_from_nodes(nodes, numnodes); > + shift = extract_lsb_from_nodes(nodes, numnodes, nodeids); > if ( memnodemapsize <= ARRAY_SIZE(_memnodemap) ) > memnodemap = _memnodemap; > else if ( allocate_cachealigned_memnodemap() ) -- Alex Bennée
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |