From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 905B11FF09C for ; Mon, 21 Sep 2026 11:18:20 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 92BA921501; Mon, 21 Sep 2026 11:18:16 +0200 (CEST) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Mon, 21 Sep 2026 11:18:09 +0200 Message-Id: To: "Michael Ryom" , Subject: Re: [PATCH ha-manager 2/7] env: dynamic service stats: use host-side memory footprint of guests From: "Dominik Rusovac" X-Mailer: aerc 0.20.0 References: <20260920162220.574802-1-Michael@RyomHerold.dk> <20260920162220.574802-3-Michael@RyomHerold.dk> In-Reply-To: <20260920162220.574802-3-Michael@RyomHerold.dk> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1789982289661 X-SPAM-LEVEL: Spam detection results: 0 DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 6VNTFFJD4TMMODVNX76YXTOKQSPO7S4K X-Message-ID-Hash: 6VNTFFJD4TMMODVNX76YXTOKQSPO7S4K X-MailFrom: d.rusovac@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: thank you for sending this patch!=20 one nit inline, otherwise lgtm NOTE: as mentioned in the cover letter, this overlaps with https://lore.proxmox.com/all/20260828123239.1110595-2-d.rusovac@proxmox.com= / Reviewed-by: Dominik Rusovac On Sun Sep 20, 2026 at 6:22 PM CEST, Michael Ryom wrote: > The dynamic service stats used the 'mem' RRD column of the guests, which > is the guest-reported memory usage (total_mem - free_mem) whenever the > balloon driver is active, and can be considerably lower than the actual > host-side footprint of the guest process (QEMU overhead, page cache > still mapped, etc.). The node stats, on the other hand, always contain > the full host view. > > The scheduler simulates a migration by subtracting exactly the > service's stats from the source node and adding them to the target > node. With the guest-reported value, the predicted post-migration state > is systematically off by the difference between guest-reported and > host-side usage (over 1 GiB for a mid-size VM). This bias is of the > same order of magnitude as the trigger condition of the automatic load > balancer on a two-node cluster with a single dominant resource, and > contributes to a resource being moved back and forth. > > Use the 'memhost' column (host-side cgroup usage, without KSM) instead > and fall back to 'mem' if it is unset: containers do not broadcast > 'memhost', because their 'mem' already is the host-side cgroup value. > > Signed-off-by: Michael Ryom > --- > src/PVE/HA/Env/PVE2.pm | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/src/PVE/HA/Env/PVE2.pm b/src/PVE/HA/Env/PVE2.pm > index 782d19d..8c2b03d 100644 > --- a/src/PVE/HA/Env/PVE2.pm > +++ b/src/PVE/HA/Env/PVE2.pm > @@ -46,6 +46,7 @@ use constant { > RRD_VM_INDEX_CPU =3D> 6, > RRD_VM_INDEX_MAXMEM =3D> 7, > RRD_VM_INDEX_MEM =3D> 8, > + RRD_VM_INDEX_MEMHOST =3D> 15, > }; > =20 > # rrd entry indices for PVE nodes > @@ -598,11 +599,22 @@ sub get_dynamic_service_stats { > # NOTE the guests' broadcasted vmstatus() caps maxcpu at the nod= e's maxcpu > my $maxcpu =3D ($rrdentry->[RRD_VM_INDEX_MAXCPU] || 0.0) + 0.0; > =20 > + # prefer the host-side memory footprint over 'mem', which is the > + # guest-reported usage (total_mem - free_mem) when the balloon d= river > + # is active and can be considerably lower than what running the = guest > + # actually consumes on the node; the node stats contain the full= host > + # view, so mixing in the guest view makes the scheduler's predic= tion > + # of the post-migration state systematically off > + # > + # 'memhost' is only broadcasted for VMs, for CTs 'mem' already i= s the > + # host-side (cgroup) usage > + my $mem =3D int($rrdentry->[RRD_VM_INDEX_MEMHOST] || $rrdentry->= [RRD_VM_INDEX_MEM] || 0); nit: while this kind of declaration shouldn't cause problems, since it can be assumed that=20 $rrdentry->[RRD_VM_INDEX_MEMHOST] >=3D $rrdentry->[RRD_VM_INDEX_MEM],=20 technically, we aim to fall back to 'mem' only if 'memhost' is undef and not if 'memhost' is 0. [snip]