From fccd35b732541e20c64e620545af3ebffcbd1e91 Mon Sep 17 00:00:00 2001 From: stl Date: Thu, 20 Aug 2026 17:15:15 +0800 Subject: [PATCH 1/3] fix(loongarch64):Fix Virtio using too much CPU --- driver/hvisor_main.c | 7 +++++++ include/hvisor.h | 1 + tools/virtio/virtio.c | 4 ---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/driver/hvisor_main.c b/driver/hvisor_main.c index 11fca95e..49546e16 100644 --- a/driver/hvisor_main.c +++ b/driver/hvisor_main.c @@ -471,6 +471,13 @@ static irqreturn_t virtio_irq_handler(int irq, void *dev_id) { pr_err("eventfd_signal: counter overflow or no increment\n"); #endif +#ifdef LOONGARCH64 + /* Re-arm the level-like wakeup line after recording the eventfd kick. */ + if (hvisor_call(HVISOR_HC_CLEAR_INJECT_IRQ, 0, + HVISOR_VIRTIO_WAKEUP_HWI)) + pr_err_ratelimited("failed to acknowledge virtio wakeup HWI\n"); +#endif + return IRQ_HANDLED; } diff --git a/include/hvisor.h b/include/hvisor.h index df448b93..00b695eb 100644 --- a/include/hvisor.h +++ b/include/hvisor.h @@ -212,6 +212,7 @@ struct hvisor_scmi_power_args { #define HVISOR_DEASSERT_IRQ _IOW(1, 11, struct hvisor_irq_line_args) #define HVISOR_HC_CLEAR_INJECT_IRQ 11 // hvcall code in hvisor +#define HVISOR_VIRTIO_WAKEUP_HWI 4 // LoongArch CPUINTC HWI2 #endif /* LOONGARCH64 */ #ifdef LOONGARCH64 diff --git a/tools/virtio/virtio.c b/tools/virtio/virtio.c index 2d3cc4e0..ef071745 100644 --- a/tools/virtio/virtio.c +++ b/tools/virtio/virtio.c @@ -1398,7 +1398,6 @@ void handle_virtio_requests(void) { int signal_count = 0, proc_count = 0; struct epoll_event events[16]; while (true) { -#ifndef LOONGARCH64 log_debug("signal_count is %d, proc_count is %d", signal_count, proc_count); @@ -1428,14 +1427,11 @@ void handle_virtio_requests(void) { if (read(efd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) { continue; } -#endif // Process all pending requests until the ring is empty proc_count += consume_pending_requests(); -#ifndef LOONGARCH64 } } -#endif } } From 375443c28bcfad94ef39d83420c4c5a9ffd14382 Mon Sep 17 00:00:00 2001 From: stl Date: Fri, 21 Aug 2026 10:08:11 +0800 Subject: [PATCH 2/3] fix(loongarch64): handle pending VirtIO requests before epoll wait --- tools/virtio/virtio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/virtio/virtio.c b/tools/virtio/virtio.c index ef071745..02f30c98 100644 --- a/tools/virtio/virtio.c +++ b/tools/virtio/virtio.c @@ -1391,12 +1391,22 @@ void handle_virtio_requests(void) { return; } - // Initial state: Mark backend as ready to receive notifications - __atomic_store_n(&virtio_bridge->need_wakeup, 1, memory_order_relaxed); - log_info("virtio request handler loop started."); int signal_count = 0, proc_count = 0; struct epoll_event events[16]; + +#ifdef LOONGARCH64 + /* + * Drain requests that may have arrived before the event loop became ready. + * consume_pending_requests() also performs the sleep handshake: it sets + * need_wakeup, issues a full barrier, and rechecks the ring before returning. + */ + proc_count += consume_pending_requests(); +#else + // Preserve the existing initialization behavior on other architectures. + __atomic_store_n(&virtio_bridge->need_wakeup, 1, memory_order_relaxed); +#endif + while (true) { log_debug("signal_count is %d, proc_count is %d", signal_count, proc_count); From cdb9487fe4a30af85f2726036e976beb94eaec23 Mon Sep 17 00:00:00 2001 From: stl Date: Fri, 21 Aug 2026 11:10:35 +0800 Subject: [PATCH 3/3] style: fix clang-format violations --- driver/hvisor_main.c | 3 +-- include/hvisor.h | 2 +- tools/virtio/virtio.c | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/driver/hvisor_main.c b/driver/hvisor_main.c index 49546e16..76345253 100644 --- a/driver/hvisor_main.c +++ b/driver/hvisor_main.c @@ -473,8 +473,7 @@ static irqreturn_t virtio_irq_handler(int irq, void *dev_id) { #ifdef LOONGARCH64 /* Re-arm the level-like wakeup line after recording the eventfd kick. */ - if (hvisor_call(HVISOR_HC_CLEAR_INJECT_IRQ, 0, - HVISOR_VIRTIO_WAKEUP_HWI)) + if (hvisor_call(HVISOR_HC_CLEAR_INJECT_IRQ, 0, HVISOR_VIRTIO_WAKEUP_HWI)) pr_err_ratelimited("failed to acknowledge virtio wakeup HWI\n"); #endif diff --git a/include/hvisor.h b/include/hvisor.h index 00b695eb..68b77c48 100644 --- a/include/hvisor.h +++ b/include/hvisor.h @@ -212,7 +212,7 @@ struct hvisor_scmi_power_args { #define HVISOR_DEASSERT_IRQ _IOW(1, 11, struct hvisor_irq_line_args) #define HVISOR_HC_CLEAR_INJECT_IRQ 11 // hvcall code in hvisor -#define HVISOR_VIRTIO_WAKEUP_HWI 4 // LoongArch CPUINTC HWI2 +#define HVISOR_VIRTIO_WAKEUP_HWI 4 // LoongArch CPUINTC HWI2 #endif /* LOONGARCH64 */ #ifdef LOONGARCH64 diff --git a/tools/virtio/virtio.c b/tools/virtio/virtio.c index 02f30c98..244f783e 100644 --- a/tools/virtio/virtio.c +++ b/tools/virtio/virtio.c @@ -1399,7 +1399,8 @@ void handle_virtio_requests(void) { /* * Drain requests that may have arrived before the event loop became ready. * consume_pending_requests() also performs the sleep handshake: it sets - * need_wakeup, issues a full barrier, and rechecks the ring before returning. + * need_wakeup, issues a full barrier, and rechecks the ring before + * returning. */ proc_count += consume_pending_requests(); #else