Commit 551b0e91 authored by Pawel Wodkowski's avatar Pawel Wodkowski Committed by Daniel Verkamp
Browse files

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: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-on: https://review.gerrithub.io/373578


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent dd3ec6e6
Loading
Loading
Loading
Loading
+16 −14
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "spdk/likely.h"
#include "spdk/string.h"
#include "spdk/util.h"
#include "spdk/barrier.h"

#include "spdk/vhost.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,
				uint32_t len)
{
	int need_event = 0;
	struct vring_used *used = vq->used;
	uint16_t size_mask = vq->size - 1;
	uint16_t last_idx = vq->last_used_idx;
	uint16_t last_idx = vq->last_used_idx & (vq->size - 1);

	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++;
	last_idx &= size_mask;

	used->ring[last_idx].id = id;
	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);
	}

	/*
	 * 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.
	 */
	if (need_event) {
		eventfd_write(vq->callfd, (eventfd_t)1);

	}
}

bool