diff --git a/0030-vhost-add-vhost-interrupt-coalescing-based-on-virtio.patch b/0030-vhost-add-vhost-interrupt-coalescing-based-on-virtio.patch new file mode 100644 index 0000000000000000000000000000000000000000..803f3d310e784d761765319c2dead4964d8a9277 --- /dev/null +++ b/0030-vhost-add-vhost-interrupt-coalescing-based-on-virtio.patch @@ -0,0 +1,175 @@ +From 22a2c96738e20fce1ee870935866a5f4e5cc5fc8 Mon Sep 17 00:00:00 2001 +From: Jia Qingtong +Date: Sat, 10 May 2025 17:29:35 +0800 +Subject: [PATCH] vhost: add vhost interrupt coalescing. + +Based on virtio event idx. use vhost -E option to enable + +Signed-off-by: Jia Qingtong +--- + app/vhost/vhost.c | 4 ++++ + include/spdk/event.h | 2 +- + include/spdk/vhost.h | 8 +++++++ + lib/vhost/spdk_vhost.map | 1 + + lib/vhost/vhost.c | 44 ++++++++++++++++++++++++++++++++++++++ + lib/vhost/vhost_internal.h | 4 ++++ + 6 files changed, 62 insertions(+), 1 deletion(-) + +diff --git a/app/vhost/vhost.c b/app/vhost/vhost.c +index a100f56..095c3ed 100644 +--- a/app/vhost/vhost.c ++++ b/app/vhost/vhost.c +@@ -44,6 +44,7 @@ vhost_usage(void) + { + printf(" -f save pid to file under given path\n"); + printf(" -S directory where to create vhost sockets (default: pwd)\n"); ++ printf(" -E Enable Backend Interrupt Coalescing\n"); + } + + static void +@@ -71,6 +72,9 @@ vhost_parse_arg(int ch, char *arg) + case 'S': + spdk_vhost_set_socket_path(arg); + break; ++ case 'E': ++ spdk_vhost_set_backend_interrupt_coalescing(true); ++ break; + default: + return -EINVAL; + } +diff --git a/include/spdk/event.h b/include/spdk/event.h +index f757b33..312fa05 100644 +--- a/include/spdk/event.h ++++ b/include/spdk/event.h +@@ -249,7 +249,7 @@ int spdk_app_parse_core_mask(const char *mask, struct spdk_cpuset *cpumask); + */ + const struct spdk_cpuset *spdk_app_get_core_mask(void); + +-#define SPDK_APP_GETOPT_STRING "c:de:ghi:m:n:p:r:s:uvA:B:L:RW:" ++#define SPDK_APP_GETOPT_STRING "c:de:ghi:m:n:p:r:s:uvA:B:L:RW:E" + + enum spdk_app_parse_args_rvals { + SPDK_APP_PARSE_ARGS_HELP = 0, +diff --git a/include/spdk/vhost.h b/include/spdk/vhost.h +index 211c2d3..588acd3 100644 +--- a/include/spdk/vhost.h ++++ b/include/spdk/vhost.h +@@ -330,6 +330,14 @@ int spdk_vhost_blk_construct(const char *name, const char *cpumask, const char * + */ + int spdk_vhost_dev_remove(struct spdk_vhost_dev *vdev); + ++/** ++ * Enable spdk backend interrupt coalescing. ++ * Diff than spdk_vhost_get_coalescing, this use virtio used event idx. ++ * \param enable to enable or disable. ++ * ++ */ ++void spdk_vhost_set_backend_interrupt_coalescing(bool enable); ++ + #ifdef __cplusplus + } + #endif +diff --git a/lib/vhost/spdk_vhost.map b/lib/vhost/spdk_vhost.map +index de38e5a..2dce13b 100644 +--- a/lib/vhost/spdk_vhost.map ++++ b/lib/vhost/spdk_vhost.map +@@ -2,6 +2,7 @@ + global: + + # public functions ++ spdk_vhost_set_backend_interrupt_coalescing; + spdk_vhost_set_socket_path; + spdk_vhost_init; + spdk_vhost_fini; +diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c +index 18c17b3..b4cc522 100644 +--- a/lib/vhost/vhost.c ++++ b/lib/vhost/vhost.c +@@ -88,6 +88,8 @@ static TAILQ_HEAD(, spdk_vhost_dev) g_vhost_devices = TAILQ_HEAD_INITIALIZER( + g_vhost_devices); + static pthread_mutex_t g_vhost_mutex = PTHREAD_MUTEX_INITIALIZER; + ++static bool g_backend_interrupt_coalescing = false; ++ + void *vhost_gpa_to_vva(struct spdk_vhost_session *vsession, uint64_t addr, uint64_t len) + { + void *vva; +@@ -360,6 +362,31 @@ vhost_inflight_queue_get_desc(struct spdk_vhost_session *vsession, + return 0; + } + ++void spdk_vhost_set_backend_interrupt_coalescing(bool enable) { ++ SPDK_NOTICELOG("Set SPDK backend interrupt coalescing mode.\n"); ++ g_backend_interrupt_coalescing = enable; ++} ++ ++bool spdk_vhost_get_backend_interrupt_coalescing(void) { ++ return g_backend_interrupt_coalescing; ++} ++ ++#define spdk_vhost_used_event(vr) \ ++ (*(volatile uint16_t*)&(vr)->vring.avail->ring[(vr)->vring.size]) ++ ++/* ++ * The following is used with VIRTIO_RING_F_EVENT_IDX. ++ * Assuming a given event_idx value from the other size, if we have ++ * just incremented index from old to new_idx, should we trigger an ++ * event? ++ */ ++static inline int ++spdk_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old) ++{ ++ return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old); ++} ++ ++ + int + vhost_vq_used_signal(struct spdk_vhost_session *vsession, + struct spdk_vhost_virtqueue *virtqueue) +@@ -375,6 +402,23 @@ vhost_vq_used_signal(struct spdk_vhost_session *vsession, + "Queue %td - USED RING: sending IRQ: last used %"PRIu16"\n", + virtqueue - vsession->virtqueue, virtqueue->last_used_idx); + ++ if (spdk_vhost_get_backend_interrupt_coalescing() == true) { ++ bool used_signalled_valid = virtqueue->used_signalled_valid; ++ uint16_t old = virtqueue->used_signalled; ++ uint16_t new = virtqueue->last_used_idx; ++ ++ struct rte_vhost_vring *vring = &virtqueue->vring; ++ struct vring_avail *avail = vring->avail; ++ uint16_t guest_used_event = spdk_vhost_used_event(virtqueue); ++ uint16_t target = guest_used_event + (uint16_t)(avail->idx - guest_used_event) * 1 / 2; ++ virtqueue->used_signalled_valid = true; ++ virtqueue->used_signalled = virtqueue->last_used_idx; ++ ++ if(!spdk_need_event(target, new, old) && used_signalled_valid) { ++ return 0; ++ } ++ } ++ + if (rte_vhost_vring_call(vsession->vid, virtqueue->vring_idx) == 0) { + /* interrupt signalled */ + return 1; +diff --git a/lib/vhost/vhost_internal.h b/lib/vhost/vhost_internal.h +index dee1a28..7d08e4b 100644 +--- a/lib/vhost/vhost_internal.h ++++ b/lib/vhost/vhost_internal.h +@@ -95,6 +95,8 @@ struct spdk_vhost_virtqueue { + struct rte_vhost_ring_inflight vring_inflight; + uint16_t last_avail_idx; + uint16_t last_used_idx; ++ uint16_t used_signalled; ++ uint16_t used_signalled_valid; + + struct { + /* To mark a descriptor as available in packed ring +@@ -498,4 +500,6 @@ int vhost_get_negotiated_features(int vid, uint64_t *negotiated_features); + + int remove_vhost_controller(struct spdk_vhost_dev *vdev); + ++bool spdk_vhost_get_backend_interrupt_coalescing(void); ++ + #endif /* SPDK_VHOST_INTERNAL_H */ +-- +2.33.0 + diff --git a/spdk.spec b/spdk.spec index 3529abfd9cb0a333b99ca391e0a1ab4f872ccd34..81941eb9b47f121911f0237b09b0cb92a36fdd6b 100644 --- a/spdk.spec +++ b/spdk.spec @@ -3,7 +3,7 @@ Name: spdk Version: 21.01.1 -Release: 16 +Release: 17 Summary: Set of libraries and utilities for high performance user-mode storage License: BSD and MIT URL: http://spdk.io @@ -37,6 +37,7 @@ Patch26: 0026-lib-nvme-add-mutex-before-submit-admin-request.patch Patch27: 0027--nvme-cuse-Add-ctrlr_lock-for-cuse-register-and-unreg.patch Patch28: 0028-fixed-use-after-free-detected-by-Coverity.patch Patch29: 0029-scripts-Do-msr-existence-check-only-on-x86_64-machin.patch +Patch30: 0030-vhost-add-vhost-interrupt-coalescing-based-on-virtio.patch %define package_version %{version}-%{release} @@ -207,6 +208,9 @@ mv doc/output/html/ %{install_docdir} %changelog +* Sat May 10 2025 jiaqingtong - 21.01.1-17 +- vhost: add vhost interrupt coalescing model + * Thu Jul 11 2024 cenhuilin - 21.01.1-16 - scripts: Do msr existence check only on x86_64 machines