* [PATCH v2 1/3] virtio_balloon: add tracepoints for inflate and deflate operations
2026-10-30 8:33 [PATCH v2 0/3] Add virtio_balloon operation tracepoints liuqiangneo
@ 2026-10-30 8:33 ` liuqiangneo
2026-10-30 8:38 ` sashiko-bot
2026-10-30 8:33 ` [PATCH v2 2/3] virtio_balloon: add tracepoint for host ack latency liuqiangneo
2026-10-30 8:34 ` [PATCH v2 3/3] virtio_balloon: add tracepoints for free page hinting and migration liuqiangneo
2 siblings, 1 reply; 7+ messages in thread
From: liuqiangneo @ 2026-10-30 8:33 UTC (permalink / raw)
To: Michael S . Tsirkin, David Hildenbrand
Cc: Jason Wang, Eugenio Pérez, Xuan Zhuo, linux-kernel,
virtualization, Qiang Liu
From: Qiang Liu <liuqiang@kylinos.cn>
When the guest responds unexpectedly to balloon resize requests,
the actual applied delta cannot be observed from the guest side.
Add a "virtio_balloon" trace system with three tracepoints:
config_change (target / resulting size / delta), and
inflate and deflate (requested / applied page units / resulting size).
Signed-off-by: Qiang Liu <liuqiang@kylinos.cn>
---
MAINTAINERS | 1 +
drivers/virtio/virtio_balloon.c | 13 ++++
include/trace/events/virtio_balloon.h | 87 +++++++++++++++++++++++++++
3 files changed, 101 insertions(+)
create mode 100644 include/trace/events/virtio_balloon.h
diff --git a/MAINTAINERS b/MAINTAINERS
index e4ca41cdd872..0ef6f34471de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29590,6 +29590,7 @@ M: David Hildenbrand <david@kernel.org>
L: virtualization@lists.linux.dev
S: Maintained
F: drivers/virtio/virtio_balloon.c
+F: include/trace/events/virtio_balloon.h
F: include/uapi/linux/virtio_balloon.h
VIRTIO BLOCK AND SCSI DRIVERS
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index ab3e3d887e00..2d0b16383661 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -19,6 +19,8 @@
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/page_reporting.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/virtio_balloon.h>
/*
* Balloon device works in 4K page units. So each page is pointed to by
@@ -285,6 +287,8 @@ static unsigned int fill_balloon(struct virtio_balloon *vb, size_t num)
/* Did we get any? */
if (vb->num_pfns != 0)
tell_host(vb, vb->inflate_vq);
+
+ trace_virtio_balloon_inflate(num, num_allocated_pages, vb->num_pages);
mutex_unlock(&vb->balloon_lock);
return num_allocated_pages;
@@ -333,6 +337,8 @@ static unsigned int leak_balloon(struct virtio_balloon *vb, size_t num)
if (vb->num_pfns != 0)
tell_host(vb, vb->deflate_vq);
release_pages_balloon(vb, &pages);
+
+ trace_virtio_balloon_deflate(num, num_freed_pages, vb->num_pages);
mutex_unlock(&vb->balloon_lock);
return num_freed_pages;
}
@@ -567,11 +573,18 @@ static void update_balloon_size_func(struct work_struct *work)
diff = towards_target(vb);
if (diff) {
+ unsigned long target = vb->num_pages + diff;
+ unsigned long before = vb->num_pages;
+
if (diff > 0)
diff -= fill_balloon(vb, diff);
else
diff += leak_balloon(vb, -diff);
update_balloon_size(vb);
+
+ trace_virtio_balloon_config_change(target, vb->num_pages,
+ (long)vb->num_pages -
+ (long)before);
}
if (diff)
diff --git a/include/trace/events/virtio_balloon.h b/include/trace/events/virtio_balloon.h
new file mode 100644
index 000000000000..f733fc360d8b
--- /dev/null
+++ b/include/trace/events/virtio_balloon.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM virtio_balloon
+
+#if !defined(_TRACE_VIRTIO_BALLOON_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_VIRTIO_BALLOON_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * All page counts reported by these events are in balloon page units, i.e.
+ * the 4K units the virtio balloon device operates on. Divide by
+ * VIRTIO_BALLOON_PAGES_PER_PAGE to obtain the number of guest pages.
+ */
+
+TRACE_EVENT(virtio_balloon_config_change,
+
+ TP_PROTO(unsigned long target, unsigned long num_pages, long delta),
+
+ TP_ARGS(target, num_pages, delta),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, target)
+ __field(unsigned long, num_pages)
+ __field(long, delta)
+ ),
+
+ TP_fast_assign(
+ __entry->target = target;
+ __entry->num_pages = num_pages;
+ __entry->delta = delta;
+ ),
+
+ TP_printk("target=%lu num_pages=%lu delta=%ld",
+ __entry->target, __entry->num_pages, __entry->delta)
+);
+
+TRACE_EVENT(virtio_balloon_inflate,
+
+ TP_PROTO(unsigned long requested, unsigned long inflated,
+ unsigned long num_pages),
+
+ TP_ARGS(requested, inflated, num_pages),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, requested)
+ __field(unsigned long, inflated)
+ __field(unsigned long, num_pages)
+ ),
+
+ TP_fast_assign(
+ __entry->requested = requested;
+ __entry->inflated = inflated;
+ __entry->num_pages = num_pages;
+ ),
+
+ TP_printk("requested=%lu inflated=%lu num_pages=%lu",
+ __entry->requested, __entry->inflated, __entry->num_pages)
+);
+
+TRACE_EVENT(virtio_balloon_deflate,
+
+ TP_PROTO(unsigned long requested, unsigned long deflated,
+ unsigned long num_pages),
+
+ TP_ARGS(requested, deflated, num_pages),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, requested)
+ __field(unsigned long, deflated)
+ __field(unsigned long, num_pages)
+ ),
+
+ TP_fast_assign(
+ __entry->requested = requested;
+ __entry->deflated = deflated;
+ __entry->num_pages = num_pages;
+ ),
+
+ TP_printk("requested=%lu deflated=%lu num_pages=%lu",
+ __entry->requested, __entry->deflated, __entry->num_pages)
+);
+
+#endif /* _TRACE_VIRTIO_BALLOON_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.43.0
No virus found
Checked by Hillstone Network AntiVirus
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/3] virtio_balloon: add tracepoint for host ack latency
2026-10-30 8:33 [PATCH v2 0/3] Add virtio_balloon operation tracepoints liuqiangneo
2026-10-30 8:33 ` [PATCH v2 1/3] virtio_balloon: add tracepoints for inflate and deflate operations liuqiangneo
@ 2026-10-30 8:33 ` liuqiangneo
2026-10-30 8:37 ` sashiko-bot
2026-10-30 8:34 ` [PATCH v2 3/3] virtio_balloon: add tracepoints for free page hinting and migration liuqiangneo
2 siblings, 1 reply; 7+ messages in thread
From: liuqiangneo @ 2026-10-30 8:33 UTC (permalink / raw)
To: Michael S . Tsirkin, David Hildenbrand
Cc: Jason Wang, Eugenio Pérez, Xuan Zhuo, linux-kernel,
virtualization, Qiang Liu
From: Qiang Liu <liuqiang@kylinos.cn>
Balloon inflate/deflate block in tell_host() for host buffer consumption.
Host-side stalls are easily mistaken for guest allocation issues.
Add virtio_balloon_host_ack to record tell_host() wait time,
virtqueue and PFN count, to split balloon latency between guest and host.
Signed-off-by: Qiang Liu <liuqiang@kylinos.cn>
---
drivers/virtio/virtio_balloon.c | 19 +++++++++++++++++--
include/trace/events/virtio_balloon.h | 22 ++++++++++++++++++++++
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 2d0b16383661..c4fdc6815b41 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -19,6 +19,7 @@
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/page_reporting.h>
+#include <linux/ktime.h>
#define CREATE_TRACE_POINTS
#include <trace/events/virtio_balloon.h>
@@ -197,8 +198,22 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
return;
virtqueue_kick(vq);
- /* When host has read buffer, this completes via balloon_ack */
- wait_event(vb->acked, virtqueue_get_buf(vq, &len));
+ /*
+ * When host has read buffer, this completes via balloon_ack.
+ *
+ * The latency is only measured when the tracepoint is enabled, so a
+ * disabled tracepoint adds no clock reads on this (hot) path.
+ */
+ if (trace_virtio_balloon_host_ack_enabled()) {
+ ktime_t start = ktime_get();
+
+ wait_event(vb->acked, virtqueue_get_buf(vq, &len));
+ trace_virtio_balloon_host_ack(vb->num_pfns,
+ vq->name,
+ ktime_to_ns(ktime_sub(ktime_get(), start)));
+ } else {
+ wait_event(vb->acked, virtqueue_get_buf(vq, &len));
+ }
}
static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
diff --git a/include/trace/events/virtio_balloon.h b/include/trace/events/virtio_balloon.h
index f733fc360d8b..559deb997e88 100644
--- a/include/trace/events/virtio_balloon.h
+++ b/include/trace/events/virtio_balloon.h
@@ -81,6 +81,28 @@ TRACE_EVENT(virtio_balloon_deflate,
__entry->requested, __entry->deflated, __entry->num_pages)
);
+TRACE_EVENT(virtio_balloon_host_ack,
+
+ TP_PROTO(unsigned int num_pfns, const char *vq_name, s64 latency_ns),
+
+ TP_ARGS(num_pfns, vq_name, latency_ns),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, num_pfns)
+ __string(vq_name, vq_name)
+ __field(s64, latency_ns)
+ ),
+
+ TP_fast_assign(
+ __entry->num_pfns = num_pfns;
+ __assign_str(vq_name);
+ __entry->latency_ns = latency_ns;
+ ),
+
+ TP_printk("vq=%s num_pfns=%u latency=%lldns",
+ __get_str(vq_name), __entry->num_pfns, __entry->latency_ns)
+);
+
#endif /* _TRACE_VIRTIO_BALLOON_H */
/* This part must be outside protection */
--
2.43.0
No virus found
Checked by Hillstone Network AntiVirus
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 3/3] virtio_balloon: add tracepoints for free page hinting and migration
2026-10-30 8:33 [PATCH v2 0/3] Add virtio_balloon operation tracepoints liuqiangneo
2026-10-30 8:33 ` [PATCH v2 1/3] virtio_balloon: add tracepoints for inflate and deflate operations liuqiangneo
2026-10-30 8:33 ` [PATCH v2 2/3] virtio_balloon: add tracepoint for host ack latency liuqiangneo
@ 2026-10-30 8:34 ` liuqiangneo
2026-10-30 8:38 ` sashiko-bot
2 siblings, 1 reply; 7+ messages in thread
From: liuqiangneo @ 2026-10-30 8:34 UTC (permalink / raw)
To: Michael S . Tsirkin, David Hildenbrand
Cc: Jason Wang, Eugenio Pérez, Xuan Zhuo, linux-kernel,
virtualization, Qiang Liu
From: Qiang Liu <liuqiang@kylinos.cn>
Free page hint requests cannot be traced, and migration only
provides summary stats. Lock contention causing migration abort
cannot be distinguished, making these two flows hard to debug.
Add tracepoints to record host hint commands, leftover hint blocks
and balloon_lock -EAGAIN migration failures.
Signed-off-by: Qiang Liu <liuqiang@kylinos.cn>
---
drivers/virtio/virtio_balloon.c | 11 +++++-
include/trace/events/virtio_balloon.h | 48 +++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index c4fdc6815b41..26c9c118ad96 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -817,6 +817,10 @@ static void virtio_balloon_report_free_page(struct virtio_balloon *vb)
err = send_cmd_id_stop(vb);
if (unlikely(err))
dev_err(dev, "Failed to send a stop id, err = %d\n", err);
+
+ trace_virtio_balloon_free_page_hint(
+ virtio32_to_cpu(vb->vdev, vb->cmd_id_active),
+ READ_ONCE(vb->num_free_page_blocks));
}
static void report_free_page_func(struct work_struct *work)
@@ -869,8 +873,11 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
* recursion in the case it ends up triggering memory compaction
* while it is attempting to inflate the ballon.
*/
- if (!mutex_trylock(&vb->balloon_lock))
+ if (!mutex_trylock(&vb->balloon_lock)) {
+ trace_virtio_balloon_migrate(page_to_pfn(page),
+ page_to_pfn(newpage), -EAGAIN);
return -EAGAIN;
+ }
/* balloon's page migration 1st step -- inflate "newpage" */
vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
@@ -883,6 +890,8 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
tell_host(vb, vb->deflate_vq);
mutex_unlock(&vb->balloon_lock);
+
+ trace_virtio_balloon_migrate(page_to_pfn(page), page_to_pfn(newpage), 0);
return 0;
}
#endif /* CONFIG_BALLOON_MIGRATION */
diff --git a/include/trace/events/virtio_balloon.h b/include/trace/events/virtio_balloon.h
index 559deb997e88..38e74a53bcd5 100644
--- a/include/trace/events/virtio_balloon.h
+++ b/include/trace/events/virtio_balloon.h
@@ -103,6 +103,54 @@ TRACE_EVENT(virtio_balloon_host_ack,
__get_str(vq_name), __entry->num_pfns, __entry->latency_ns)
);
+TRACE_EVENT(virtio_balloon_free_page_hint,
+
+ /*
+ * unreclaimed_blocks: hint blocks given to the host but not yet
+ * reclaimed via CMD_ID_DONE; accumulated across reporting rounds.
+ */
+ TP_PROTO(u32 cmd_id, unsigned long unreclaimed_blocks),
+
+ TP_ARGS(cmd_id, unreclaimed_blocks),
+
+ TP_STRUCT__entry(
+ __field(u32, cmd_id)
+ __field(unsigned long, unreclaimed_blocks)
+ ),
+
+ TP_fast_assign(
+ __entry->cmd_id = cmd_id;
+ __entry->unreclaimed_blocks = unreclaimed_blocks;
+ ),
+
+ TP_printk("cmd_id=%u unreclaimed_blocks=%lu",
+ __entry->cmd_id, __entry->unreclaimed_blocks)
+);
+
+#ifdef CONFIG_BALLOON_MIGRATION
+TRACE_EVENT(virtio_balloon_migrate,
+
+ TP_PROTO(unsigned long old_pfn, unsigned long new_pfn, long ret),
+
+ TP_ARGS(old_pfn, new_pfn, ret),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, old_pfn)
+ __field(unsigned long, new_pfn)
+ __field(long, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->old_pfn = old_pfn;
+ __entry->new_pfn = new_pfn;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("old_pfn=0x%lx new_pfn=0x%lx ret=%ld",
+ __entry->old_pfn, __entry->new_pfn, __entry->ret)
+);
+#endif /* CONFIG_BALLOON_MIGRATION */
+
#endif /* _TRACE_VIRTIO_BALLOON_H */
/* This part must be outside protection */
--
2.43.0
No virus found
Checked by Hillstone Network AntiVirus
^ permalink raw reply related [flat|nested] 7+ messages in thread