From 3b6f69c8f59864557afe9ec3292e69a7980e1b36 Mon Sep 17 00:00:00 2001 From: Darek Stojaczyk Date: Sat, 20 Jul 2019 11:02:29 +0200 Subject: [PATCH] vhost: remove unnecessary membarrier on I/O completion We've recently switched from manually calling eventfd_write() to rte_vhost_vring_call(), which besides writing to the eventfd, always calls a full memory barrier in the upstream rte_vhost lib. With upstream rte_vhost we're actually calling two memory barriers on I/O completion - one in spdk code, one inside rte_vhost_vring_call(). The spdk barrier was only required for our internal rte_vhost lib, whose rte_vhost_vring_call() implementation (that we wrote) did not have such membarrier inside. So now we'll add this membarrier there, and remove the same barrier from spdk code. This doesn't change any code flow for the internal rte_vhost lib, but optimizes I/O path for the upstream version. Change-Id: I68738d7feb9159f718b0e60ac7eed1fafd4836b9 Signed-off-by: Darek Stojaczyk Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466037 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Vitaliy Mysak Reviewed-by: Changpeng Liu --- lib/vhost/rte_vhost/vhost.c | 7 +++++++ lib/vhost/vhost.c | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/vhost/rte_vhost/vhost.c b/lib/vhost/rte_vhost/vhost.c index 61cbb12094..d9c119f993 100644 --- a/lib/vhost/rte_vhost/vhost.c +++ b/lib/vhost/rte_vhost/vhost.c @@ -521,6 +521,13 @@ rte_vhost_vring_call(int vid, uint16_t vring_idx) if (!vq) return -1; + /* Ensure all our used ring changes are visible to the guest at the time + * of interrupt. + * TODO: this is currently an sfence on x86. For other architectures we + * will most likely need an smp_mb(), but smp_mb() is an overkill for x86. + */ + rte_wmb(); + if (vq->callfd != -1) { eventfd_write(vq->callfd, (eventfd_t)1); return 0; diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index b2c675f08b..15564562c1 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -463,13 +463,6 @@ spdk_vhost_vq_used_ring_enqueue(struct spdk_vhost_session *vsession, * (volatile uint16_t *) &used->idx = virtqueue->last_used_idx; spdk_vhost_log_used_vring_idx(vsession, virtqueue); - /* Ensure all our used ring changes are visible to the guest at the time - * of interrupt. - * TODO: this is currently an sfence on x86. For other architectures we - * will most likely need an smp_mb(), but smp_mb() is an overkill for x86. - */ - spdk_wmb(); - virtqueue->used_req_cnt++; }