Commit e5a10c1bd12a5d71bbb6406c1b0dbbc9d8958397
Committed by
Tejun Heo
1 parent
a56bca80db
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 10 additions and 5 deletions Side-by-side Diff
arch/x86/mm/numa.c
... | ... | @@ -270,6 +270,7 @@ |
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 | |
276 | 277 | |
277 | 278 | |
... | ... | @@ -278,11 +279,14 @@ |
278 | 279 | bi->end = min(bi->end, high); |
279 | 280 | |
280 | 281 | /* and there's no empty block */ |
281 | - if (bi->start >= bi->end) { | |
282 | + if (bi->start >= bi->end) | |
282 | 283 | numa_remove_memblk_from(i--, mi); |
283 | - continue; | |
284 | - } | |
284 | + } | |
285 | 285 | |
286 | + /* merge neighboring / overlapping entries */ | |
287 | + for (i = 0; i < mi->nr_blks; i++) { | |
288 | + struct numa_memblk *bi = &mi->blk[i]; | |
289 | + | |
286 | 290 | for (j = i + 1; j < mi->nr_blks; j++) { |
287 | 291 | struct numa_memblk *bj = &mi->blk[j]; |
288 | 292 | u64 start, end; |
... | ... | @@ -311,8 +315,8 @@ |
311 | 315 | */ |
312 | 316 | if (bi->nid != bj->nid) |
313 | 317 | continue; |
314 | - start = max(min(bi->start, bj->start), low); | |
315 | - end = min(max(bi->end, bj->end), high); | |
318 | + start = min(bi->start, bj->start); | |
319 | + end = max(bi->end, bj->end); | |
316 | 320 | for (k = 0; k < mi->nr_blks; k++) { |
317 | 321 | struct numa_memblk *bk = &mi->blk[k]; |
318 | 322 | |
... | ... | @@ -332,6 +336,7 @@ |
332 | 336 | } |
333 | 337 | } |
334 | 338 | |
339 | + /* clear unused ones */ | |
335 | 340 | for (i = mi->nr_blks; i < ARRAY_SIZE(mi->blk); i++) { |
336 | 341 | mi->blk[i].start = mi->blk[i].end = 0; |
337 | 342 | mi->blk[i].nid = NUMA_NO_NODE; |