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

memblock: Factor the lowest level alloc function

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

+27 -32
+27 -32
mm/memblock.c
··· 294 294 return (addr + (size - 1)) & ~(size - 1); 295 295 } 296 296 297 - static u64 __init memblock_alloc_nid_unreserved(u64 start, u64 end, 298 - u64 size, u64 align) 297 + static u64 __init memblock_alloc_region(u64 start, u64 end, 298 + u64 size, u64 align) 299 299 { 300 300 u64 base, res_base; 301 301 long j; ··· 318 318 return ~(u64)0; 319 319 } 320 320 321 + u64 __weak __init memblock_nid_range(u64 start, u64 end, int *nid) 322 + { 323 + *nid = 0; 324 + 325 + return end; 326 + } 327 + 321 328 static u64 __init memblock_alloc_nid_region(struct memblock_region *mp, 322 329 u64 size, u64 align, int nid) 323 330 { ··· 340 333 341 334 this_end = memblock_nid_range(start, end, &this_nid); 342 335 if (this_nid == nid) { 343 - u64 ret = memblock_alloc_nid_unreserved(start, this_end, 344 - size, align); 336 + u64 ret = memblock_alloc_region(start, this_end, size, align); 345 337 if (ret != ~(u64)0) 346 338 return ret; 347 339 } ··· 357 351 358 352 BUG_ON(0 == size); 359 353 354 + /* We do a bottom-up search for a region with the right 355 + * nid since that's easier considering how memblock_nid_range() 356 + * works 357 + */ 360 358 size = memblock_align_up(size, align); 361 359 362 360 for (i = 0; i < mem->cnt; i++) { ··· 393 383 394 384 u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr) 395 385 { 396 - long i, j; 386 + long i; 397 387 u64 base = 0; 398 388 u64 res_base; 399 389 ··· 406 396 if (max_addr == MEMBLOCK_ALLOC_ANYWHERE) 407 397 max_addr = MEMBLOCK_REAL_LIMIT; 408 398 399 + /* Pump up max_addr */ 400 + if (max_addr == MEMBLOCK_ALLOC_ANYWHERE) 401 + max_addr = ~(u64)0; 402 + 403 + /* We do a top-down search, this tends to limit memory 404 + * fragmentation by keeping early boot allocs near the 405 + * top of memory 406 + */ 409 407 for (i = memblock.memory.cnt - 1; i >= 0; i--) { 410 408 u64 memblockbase = memblock.memory.regions[i].base; 411 409 u64 memblocksize = memblock.memory.regions[i].size; 412 410 413 411 if (memblocksize < size) 414 412 continue; 415 - if (max_addr == MEMBLOCK_ALLOC_ANYWHERE) 416 - base = memblock_align_down(memblockbase + memblocksize - size, align); 417 - else if (memblockbase < max_addr) { 418 - base = min(memblockbase + memblocksize, max_addr); 419 - base = memblock_align_down(base - size, align); 420 - } else 421 - continue; 422 - 423 - while (base && memblockbase <= base) { 424 - j = memblock_overlaps_region(&memblock.reserved, base, size); 425 - if (j < 0) { 426 - /* this area isn't reserved, take it */ 427 - if (memblock_add_region(&memblock.reserved, base, size) < 0) 428 - return 0; 429 - return base; 430 - } 431 - res_base = memblock.reserved.regions[j].base; 432 - if (res_base < size) 433 - break; 434 - base = memblock_align_down(res_base - size, align); 435 - } 413 + base = min(memblockbase + memblocksize, max_addr); 414 + res_base = memblock_alloc_region(memblockbase, base, size, align); 415 + if (res_base != ~(u64)0) 416 + return res_base; 436 417 } 437 418 return 0; 438 419 } ··· 529 528 return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; 530 529 } 531 530 532 - u64 __weak memblock_nid_range(u64 start, u64 end, int *nid) 533 - { 534 - *nid = 0; 535 - 536 - return end; 537 - }