Skip to content

Commit 91a9be5

Browse files
kalyazinclaude
andcommitted
feat: add virtio_balloon wait-on-ACK patch for 6.1.158
Pull in commit b90e190a95c2 ("virtio_balloon: Support wait on ACK for hinting") by Jack Thomson <jackabt@amazon.com>. Adds a new virtio feature flag VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK that makes the driver wait for device ACK before adding hinted ranges to the free_page_list, enabling MADV_DONTNEED-based RSS reduction. Trades ~30% hinting duration overhead for the synchronisation guarantee. Applied only to 6.1.158 (the only fc-kernels version we currently want this on). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Nikita Kalyazin <nikita.kalyazin@e2b.dev>
1 parent da5afb2 commit 91a9be5

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
From b90e190a95c256d6ef0d7ed5ad42649decfdb6e0 Mon Sep 17 00:00:00 2001
2+
From: Jack Thomson <jackabt@amazon.com>
3+
Date: Mon, 19 Jan 2026 15:42:36 +0000
4+
Subject: [PATCH] virtio_balloon: Support wait on ACK for hinting
5+
6+
This RFC patch adds a new virtio feature for the virtio-balloon driver
7+
during free page hinting, which will wait on device ack before
8+
committing the range to the free_page_list. The reason for the change is
9+
it allows the device to modify this range without it being reclaimed
10+
from the free_page_list before the ack is sent. As expected, testing
11+
shows this adds overhead to the hinting run duration, increasing it by
12+
~30% with our Firecracker setup. Currently free page hinting is used
13+
mainly for live migration, but this would open it up for a new use-case.
14+
15+
We would like to leverage this with MADV_DONTNEED to reduce RSS of a
16+
guest. We'd like to use hinting because of the flexibility of control it
17+
brings compared to reporting, allowing memory to be reclaimed in
18+
deterministic periods. The traditional balloon device was tested to be
19+
much slower when compared to hinting for these workloads. Currently,
20+
without this synchronization, hinted pages may be reclaimed from the
21+
free list before the device finishes processing them, making hinting
22+
unsuitable for this use-case.
23+
24+
Signed-off-by: Jack Thomson <jackabt@amazon.com>
25+
---
26+
drivers/virtio/virtio_balloon.c | 19 ++++++++++++++++---
27+
include/uapi/linux/virtio_balloon.h | 1 +
28+
2 files changed, 17 insertions(+), 3 deletions(-)
29+
30+
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
31+
index fba0d8c5dcdf..d9fffefa4a05 100644
32+
--- a/drivers/virtio/virtio_balloon.c
33+
+++ b/drivers/virtio/virtio_balloon.c
34+
@@ -575,7 +575,8 @@ static int init_vqs(struct virtio_balloon *vb)
35+
36+
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
37+
names[VIRTIO_BALLOON_VQ_FREE_PAGE] = "free_page_vq";
38+
- callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
39+
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK))
40+
+ callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = balloon_ack;
41+
}
42+
43+
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) {
44+
@@ -648,8 +649,11 @@ static int send_cmd_id_start(struct virtio_balloon *vb)
45+
virtio_balloon_cmd_id_received(vb));
46+
sg_init_one(&sg, &vb->cmd_id_active, sizeof(vb->cmd_id_active));
47+
err = virtqueue_add_outbuf(vq, &sg, 1, &vb->cmd_id_active, GFP_KERNEL);
48+
- if (!err)
49+
+ if (!err) {
50+
virtqueue_kick(vq);
51+
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK))
52+
+ wait_event(vb->acked, virtqueue_get_buf(vq, &unused));
53+
+ }
54+
return err;
55+
}
56+
57+
@@ -665,8 +669,11 @@ static int send_cmd_id_stop(struct virtio_balloon *vb)
58+
59+
sg_init_one(&sg, &vb->cmd_id_stop, sizeof(vb->cmd_id_stop));
60+
err = virtqueue_add_outbuf(vq, &sg, 1, &vb->cmd_id_stop, GFP_KERNEL);
61+
- if (!err)
62+
+ if (!err) {
63+
virtqueue_kick(vq);
64+
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK))
65+
+ wait_event(vb->acked, virtqueue_get_buf(vq, &unused));
66+
+ }
67+
return err;
68+
}
69+
70+
@@ -702,6 +709,8 @@ static int get_free_page_and_send(struct virtio_balloon *vb)
71+
return err;
72+
}
73+
virtqueue_kick(vq);
74+
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK))
75+
+ wait_event(vb->acked, virtqueue_get_buf(vq, &unused));
76+
spin_lock_irq(&vb->free_page_list_lock);
77+
balloon_page_push(&vb->free_page_list, page);
78+
vb->num_free_page_blocks++;
79+
@@ -1152,6 +1161,9 @@ static int virtballoon_validate(struct virtio_device *vdev)
80+
else if (!virtio_has_feature(vdev, VIRTIO_BALLOON_F_PAGE_POISON))
81+
__virtio_clear_bit(vdev, VIRTIO_BALLOON_F_REPORTING);
82+
83+
+ if (!virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
84+
+ __virtio_clear_bit(vdev, VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK);
85+
+
86+
__virtio_clear_bit(vdev, VIRTIO_F_ACCESS_PLATFORM);
87+
return 0;
88+
}
89+
@@ -1163,6 +1175,7 @@ static unsigned int features[] = {
90+
VIRTIO_BALLOON_F_FREE_PAGE_HINT,
91+
VIRTIO_BALLOON_F_PAGE_POISON,
92+
VIRTIO_BALLOON_F_REPORTING,
93+
+ VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK,
94+
};
95+
96+
static struct virtio_driver virtio_balloon_driver = {
97+
diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h
98+
index ddaa45e723c4..1705d9191f7e 100644
99+
--- a/include/uapi/linux/virtio_balloon.h
100+
+++ b/include/uapi/linux/virtio_balloon.h
101+
@@ -37,6 +37,7 @@
102+
#define VIRTIO_BALLOON_F_FREE_PAGE_HINT 3 /* VQ to report free pages */
103+
#define VIRTIO_BALLOON_F_PAGE_POISON 4 /* Guest is using page poisoning */
104+
#define VIRTIO_BALLOON_F_REPORTING 5 /* Page reporting virtqueue */
105+
+#define VIRTIO_BALLOON_F_HINT_WAIT_ON_ACK 6 /* Page hinting waits on device ack */
106+
107+
/* Size of a PFN in the balloon interface. */
108+
#define VIRTIO_BALLOON_PFN_SHIFT 12
109+
--
110+
2.51.0
111+

0 commit comments

Comments
 (0)