When domain memory is allocated, domain_adjust_tot_pages(),
also reduces the outstanding claim.
Replace the checks to not over-reduce the claim beyond 0
by using min() which prevents the claim to become negative
(and also not be over-conumed for the node and globally)
Cc: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Bernhard Kaindl <bernhard.kaindl@cloud.com>
---
Changes:
- Was added as 2/7 in v2, the review by Jan Beulich is applied.
---
xen/common/page_alloc.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 1f67b88a89..e056624583 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -510,8 +510,15 @@ static unsigned long avail_heap_pages(
return free_pages;
}
+/*
+ * Update the total number of pages and outstanding claims of a domain.
+ * - When pages were freed, we do not increase outstanding claims.
+ * - On a domain's claims update, global outstanding_claims are updated as well.
+ */
unsigned long domain_adjust_tot_pages(struct domain *d, long pages)
{
+ unsigned long adjustment;
+
ASSERT(rspin_is_locked(&d->page_alloc_lock));
d->tot_pages += pages;
@@ -519,23 +526,22 @@ unsigned long domain_adjust_tot_pages(struct domain *d, long pages)
* can test d->outstanding_pages race-free because it can only change
* if d->page_alloc_lock and heap_lock are both held, see also
* domain_set_outstanding_pages below
+ *
+ * If the domain has no outstanding claims (or we freed pages instead),
+ * we don't update outstanding claims and skip the claims adjustment.
*/
if ( !d->outstanding_pages || pages <= 0 )
goto out;
spin_lock(&heap_lock);
BUG_ON(outstanding_claims < d->outstanding_pages);
- if ( d->outstanding_pages < pages )
- {
- /* `pages` exceeds the domain's outstanding count. Zero it out. */
- outstanding_claims -= d->outstanding_pages;
- d->outstanding_pages = 0;
- }
- else
- {
- outstanding_claims -= pages;
- d->outstanding_pages -= pages;
- }
+ /*
+ * Reduce claims by outstanding claims or pages (whichever is smaller):
+ * If allocated > outstanding, reduce the claims only by outstanding pages.
+ */
+ adjustment = min(d->outstanding_pages + 0UL, pages + 0UL);
+ d->outstanding_pages -= adjustment;
+ outstanding_claims -= adjustment;
spin_unlock(&heap_lock);
out:
--
2.43.0