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.