[PATCH 3/3] virtio_balloon: add tracepoints for free page hinting and migration
From: liuqiangneo
Date: Thu Oct 29 2026 - 23:00:55 EST
From: Qiang Liu <liuqiang@xxxxxxxxxx>
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@xxxxxxxxxx>
---
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..faf78c639f3c 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -803,6 +803,7 @@ static void virtio_balloon_report_free_page(struct virtio_balloon *vb)
{
int err;
struct device *dev = &vb->vdev->dev;
+ unsigned int cmd_id = virtio_balloon_cmd_id_received(vb);
/* Start by sending the received cmd id to host with an outbuf. */
err = send_cmd_id_start(vb);
@@ -817,6 +818,9 @@ 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(cmd_id,
+ 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..c29f833fa188 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,
+
+ /*
+ * outstanding_blocks is the number of hint blocks still owned by the
+ * balloon (handed to the host but not yet reclaimed via a DONE/STOP
+ * command) at the end of the reporting round. A high value means the
+ * host did not fully drain the round.
+ */
+ TP_PROTO(u32 cmd_id, unsigned long outstanding_blocks),
+
+ TP_ARGS(cmd_id, outstanding_blocks),
+
+ TP_STRUCT__entry(
+ __field(u32, cmd_id)
+ __field(unsigned long, outstanding_blocks)
+ ),
+
+ TP_fast_assign(
+ __entry->cmd_id = cmd_id;
+ __entry->outstanding_blocks = outstanding_blocks;
+ ),
+
+ TP_printk("cmd_id=%u outstanding_blocks=%lu",
+ __entry->cmd_id, __entry->outstanding_blocks)
+);
+
+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 /* _TRACE_VIRTIO_BALLOON_H */
/* This part must be outside protection */
--
2.43.0
No virus found
Checked by Hillstone Network AntiVirus