|
33 | 33 | #include "gc/z/zLock.inline.hpp" |
34 | 34 | #include "gc/z/zMappedCache.hpp" |
35 | 35 | #include "gc/z/zMemory.inline.hpp" |
36 | | -#include "gc/z/zNUMA.hpp" |
| 36 | +#include "gc/z/zNUMA.inline.hpp" |
37 | 37 | #include "gc/z/zPage.inline.hpp" |
38 | 38 | #include "gc/z/zPageAge.hpp" |
39 | 39 | #include "gc/z/zPageAllocator.inline.hpp" |
@@ -361,18 +361,9 @@ ZPageAllocator::ZPageAllocator(size_t min_capacity, |
361 | 361 | return; |
362 | 362 | } |
363 | 363 |
|
364 | | - const int numa_nodes = ZNUMA::count(); |
365 | | - const size_t capacity_per_state = align_up(max_capacity / numa_nodes, ZGranuleSize); |
366 | | - size_t capacity_left = max_capacity; |
367 | | - |
368 | | - for (int numa_id = 0; numa_id < numa_nodes; numa_id++) { |
369 | | - const size_t capacity = MIN2(capacity_per_state, capacity_left); |
370 | | - capacity_left -= capacity; |
371 | | - |
372 | | - ZCacheState& state = _states.get(numa_id); |
373 | | - state.initialize(capacity); |
374 | | - _physical.install_capacity(numa_id, zoffset(capacity_per_state * numa_id), capacity); |
375 | | - } |
| 364 | + ZNUMA::divide_resource(max_capacity, [&](uint32_t numa_id, size_t capacity) { |
| 365 | + _states.get(numa_id).initialize(capacity); |
| 366 | + }); |
376 | 367 |
|
377 | 368 | log_info_p(gc, init)("Min Capacity: %zuM", min_capacity / M); |
378 | 369 | log_info_p(gc, init)("Initial Capacity: %zuM", initial_capacity / M); |
@@ -438,48 +429,51 @@ class ZPreTouchTask : public ZTask { |
438 | 429 | } |
439 | 430 | }; |
440 | 431 |
|
441 | | -bool ZPageAllocator::prime_cache(ZWorkers* workers, size_t size) { |
442 | | - const int numa_nodes = ZNUMA::count(); |
443 | | - const size_t size_per_state = align_up(size / numa_nodes, ZGranuleSize); |
444 | | - size_t size_left = size; |
445 | | - |
446 | | - for (int numa_id = 0; numa_id < numa_nodes; numa_id++) { |
447 | | - const size_t to_prime = MIN2(size_left, size_per_state); |
448 | | - size_left -= to_prime; |
449 | | - |
450 | | - if (to_prime == 0) { |
451 | | - // Nothing more to prime, exit |
452 | | - return true; |
453 | | - } |
| 432 | +bool ZPageAllocator::prime_state_cache(ZWorkers* workers, int numa_id, size_t to_prime) { |
| 433 | + if (to_prime == 0) { |
| 434 | + return true; |
| 435 | + } |
454 | 436 |
|
455 | | - ZCacheState& state = _states.get(numa_id); |
456 | | - ZMemoryRange vmem = _virtual.alloc(to_prime, numa_id, true /* force_low_address */); |
| 437 | + ZMemoryRange vmem = _virtual.alloc(to_prime, numa_id, true /* force_low_address */); |
| 438 | + ZCacheState& state = _states.get(numa_id); |
457 | 439 |
|
458 | | - // Increase capacity, allocate and commit physical memory |
459 | | - state.increase_capacity(to_prime); |
460 | | - _physical.alloc(_physical_mappings.get_addr(vmem.start()), to_prime, numa_id); |
461 | | - if (!commit_physical(&vmem, numa_id)) { |
462 | | - // This is a failure state. We do not cleanup the maybe partially committed memory. |
463 | | - return false; |
464 | | - } |
| 440 | + // Increase capacity, allocate and commit physical memory |
| 441 | + state.increase_capacity(to_prime); |
| 442 | + _physical.alloc(_physical_mappings.get_addr(vmem.start()), to_prime, numa_id); |
| 443 | + if (!commit_physical(&vmem, numa_id)) { |
| 444 | + // This is a failure state. We do not cleanup the maybe partially committed memory. |
| 445 | + return false; |
| 446 | + } |
465 | 447 |
|
466 | | - map_virtual_to_physical(vmem, numa_id); |
| 448 | + map_virtual_to_physical(vmem, numa_id); |
467 | 449 |
|
| 450 | + if (ZNUMA::is_enabled()) { |
468 | 451 | // Memory should have ended up on the desired NUMA id, if that's not the case, print error. |
469 | 452 | int actual = ZNUMA::memory_id(untype(ZOffset::address(vmem.start()))); |
470 | 453 | if (actual != numa_id) { |
471 | 454 | log_debug(gc, heap)("NUMA Mismatch (priming): desired %d, actual %d", numa_id, actual); |
472 | 455 | } |
| 456 | + } |
473 | 457 |
|
474 | | - if (AlwaysPreTouch) { |
475 | | - // Pre-touch memory |
476 | | - ZPreTouchTask task(vmem.start(), vmem.end()); |
477 | | - workers->run_all(&task); |
478 | | - } |
| 458 | + if (AlwaysPreTouch) { |
| 459 | + // Pre-touch memory |
| 460 | + ZPreTouchTask task(vmem.start(), vmem.end()); |
| 461 | + workers->run_all(&task); |
| 462 | + } |
479 | 463 |
|
480 | | - // We don't have to take a lock here as no other threads will access the |
481 | | - // mapped cache until we're finished. |
482 | | - state._cache.insert_mapping(vmem); |
| 464 | + // We don't have to take a lock here as no other threads will access the |
| 465 | + // mapped cache until we're finished. |
| 466 | + state._cache.insert_mapping(vmem); |
| 467 | + |
| 468 | + return true; |
| 469 | +} |
| 470 | + |
| 471 | +bool ZPageAllocator::prime_cache(ZWorkers* workers, size_t size) { |
| 472 | + for (uint32_t numa_id = 0; numa_id < ZNUMA::count(); numa_id++) { |
| 473 | + const size_t to_prime = ZNUMA::calculate_share(numa_id, size); |
| 474 | + if (!prime_state_cache(workers, numa_id, to_prime)) { |
| 475 | + return false; |
| 476 | + } |
483 | 477 | } |
484 | 478 |
|
485 | 479 | return true; |
|
0 commit comments