3.6. Redeeming Claims
After a successful allocation, redeem_claims_for_allocation() redeems claims up to the size of the allocation in the same critical region that updates the free-page counters.
The function performs the following steps to redeem the matching claims for this allocation, ensuring the domain’s total memory allocation as domain_tot_pages(domain) plus its outstanding claims as domain.global_claims + domain.node_claims remain within the domain’s limits, defined by domain.max_pages:
3.6.1. Steps to redeem claims for an allocation
- Step 1:
Redeem claims from domain.claims[alloc_node] on the allocation node, up to the size of that claim.
- Step 2:
If the allocation exceeds domain.claims[alloc_node], redeem the remaining pages from the global fallback claim domain.global_claims (if one exists).
- Step 3:
If the allocation exceeds the combination of those claims, redeem the remaining pages from other per-node claims so that the domain’s total allocation plus claims remain within the domain’s domain.max_pages limit.
3.6.2. Enforcing the domain.max_pages limit
domain_tot_pages(domain) + domain.global_claims + domain.node_claims must not exceed the domain.max_pages limit, otherwise the domain would exceed its memory entitlement.
- At claim installation time
This check is done by domain_set_node_claims() and domain_set_outstanding_pages().
- At memory allocation time
If (unexpectedly) a domain builder ends up allocating memory from different nodes than it claimed from, the domain’s total allocation plus claims could exceed the domain’s domain.max_pages limit, unless the page allocator redeems claims from other nodes to ensure the sum of the domain’s claims and populated pages remains within the domain.max_pages limit.
redeem_claims_for_allocation() cannot reliably check domain.max_pages race-free because domain.max_pages is not protected by the heap_lock taken by the page allocator during allocation.
To check the domain’s limits, it would have to take the domain.page_alloc_lock to inspect the domain’s limits and its current allocation. However, taking that lock while holding the heap_lock would invert the locking order and could lead to deadlocks.
Therefore, redeem_claims_for_allocation() redeems the remaining allocation from other-node claims in Step 3.