Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, NUMA: Trim numa meminfo with max_pfn in a separate loop

During testing 32bit numa unifying code from tj, found one system with
more than 64g fails to use numa. It turns out we do not trim numa
meminfo correctly against max_pfn in case start address of a node is
higher than 64GiB. Bug fix made it to tip tree.

This patch moves the checking and trimming to a separate loop. So we
don't need to compare low/high in following merge loops. It makes the
code more readable.

Also it makes the node merge printouts less strange. On a 512GiB numa
system with 32bit,

before:
> NUMA: Node 0 [0,a0000) + [100000,80000000) -> [0,80000000)
> NUMA: Node 0 [0,80000000) + [100000000,1080000000) -> [0,1000000000)

after:
> NUMA: Node 0 [0,a0000) + [100000,80000000) -> [0,80000000)
> NUMA: Node 0 [0,80000000) + [100000000,1000000000) -> [0,1000000000)

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
[Updated patch description and comment slightly.]
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Yinghai Lu and committed by
Tejun Heo
e5a10c1b a56bca80

+10 -5
+10 -5
arch/x86/mm/numa.c
··· 270 270 const u64 high = PFN_PHYS(max_pfn); 271 271 int i, j, k; 272 272 273 + /* first, trim all entries */ 273 274 for (i = 0; i < mi->nr_blks; i++) { 274 275 struct numa_memblk *bi = &mi->blk[i]; 275 276 ··· 279 278 bi->end = min(bi->end, high); 280 279 281 280 /* and there's no empty block */ 282 - if (bi->start >= bi->end) { 281 + if (bi->start >= bi->end) 283 282 numa_remove_memblk_from(i--, mi); 284 - continue; 285 - } 283 + } 284 + 285 + /* merge neighboring / overlapping entries */ 286 + for (i = 0; i < mi->nr_blks; i++) { 287 + struct numa_memblk *bi = &mi->blk[i]; 286 288 287 289 for (j = i + 1; j < mi->nr_blks; j++) { 288 290 struct numa_memblk *bj = &mi->blk[j]; ··· 315 311 */ 316 312 if (bi->nid != bj->nid) 317 313 continue; 318 - start = max(min(bi->start, bj->start), low); 319 - end = min(max(bi->end, bj->end), high); 314 + start = min(bi->start, bj->start); 315 + end = max(bi->end, bj->end); 320 316 for (k = 0; k < mi->nr_blks; k++) { 321 317 struct numa_memblk *bk = &mi->blk[k]; 322 318 ··· 336 332 } 337 333 } 338 334 335 + /* clear unused ones */ 339 336 for (i = mi->nr_blks; i < ARRAY_SIZE(mi->blk); i++) { 340 337 mi->blk[i].start = mi->blk[i].end = 0; 341 338 mi->blk[i].nid = NUMA_NO_NODE;