vhost: bring back interrupt suppressing hints

Try to do the same as DPDK does: volatile write on used->idx and memory
barier before reading avail->flags.

Change-Id: Ibe4629a8228a02088913593ac9b32de56a60b062
Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-on: https://review.gerrithub.io/373578
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Pawel Wodkowski 2017-08-09 19:05:06 +02:00 committed by Daniel Verkamp
parent dd3ec6e6b5
commit 551b0e9128

View File

@ -37,6 +37,7 @@
#include "spdk/likely.h" #include "spdk/likely.h"
#include "spdk/string.h" #include "spdk/string.h"
#include "spdk/util.h" #include "spdk/util.h"
#include "spdk/barrier.h"
#include "spdk/vhost.h" #include "spdk/vhost.h"
#include "vhost_internal.h" #include "vhost_internal.h"
@ -99,30 +100,31 @@ spdk_vhost_vq_used_ring_enqueue(struct spdk_vhost_dev *vdev, struct rte_vhost_vr
uint16_t id, uint16_t id,
uint32_t len) uint32_t len)
{ {
int need_event = 0;
struct vring_used *used = vq->used; struct vring_used *used = vq->used;
uint16_t size_mask = vq->size - 1; uint16_t last_idx = vq->last_used_idx & (vq->size - 1);
uint16_t last_idx = vq->last_used_idx;
SPDK_TRACELOG(SPDK_TRACE_VHOST_RING, "USED: last_idx=%"PRIu16" req id=%"PRIu16" len=%"PRIu32"\n", SPDK_TRACELOG(SPDK_TRACE_VHOST_RING, "USED: last_idx=%"PRIu16" req id=%"PRIu16" len=%"PRIu32"\n",
last_idx, id, len); vq->last_used_idx, id, len);
vq->last_used_idx++; vq->last_used_idx++;
last_idx &= size_mask;
used->ring[last_idx].id = id; used->ring[last_idx].id = id;
used->ring[last_idx].len = len; used->ring[last_idx].len = len;
rte_compiler_barrier(); spdk_wmb();
* (volatile uint16_t *) &used->idx = vq->last_used_idx;
vq->used->idx = vq->last_used_idx; if (spdk_vhost_dev_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
spdk_unlikely(vq->avail->idx == vq->last_avail_idx)) {
need_event = 1;
} else {
spdk_mb();
need_event = !(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
}
/* if (need_event) {
* We should be able to used hints form guest but simply checking
* avail->flags prove to be unreliable. Till it is figured out how
* reliable use avail->flags value interrupts are always sent to guest.
*/
eventfd_write(vq->callfd, (eventfd_t)1); eventfd_write(vq->callfd, (eventfd_t)1);
}
} }
bool bool