Commit 39276ee8 authored by Jin Yu's avatar Jin Yu Committed by Changpeng Liu
Browse files

vhost: negotiate the packed ring feature



Add the packed ring support in spdk vhost.
Negotiate packed ring feature when start device.

Change-Id: Idef50a1426b6e38d789d8c6982a3ed7594e32cf5
Signed-off-by: default avatarJin Yu <jin.yu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/672


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 4d2e26d8
Loading
Loading
Loading
Loading
+46 −7
Original line number Diff line number Diff line
@@ -880,9 +880,24 @@ _stop_session(struct spdk_vhost_session *vsession)

	for (i = 0; i < vsession->max_queues; i++) {
		q = &vsession->virtqueue[i];

		/* vring.desc and vring.desc_packed are in a union struct
		 * so q->vring.desc can replace q->vring.desc_packed.
		 */
		if (q->vring.desc == NULL) {
			continue;
		}

		/* Packed virtqueues support up to 2^15 entries each
		 * so left one bit can be used as wrap counter.
		 */
		if (q->packed.packed_ring) {
			q->last_avail_idx = q->last_avail_idx |
					    ((uint16_t)q->packed.avail_phase << 15);
			q->last_used_idx = q->last_used_idx |
					   ((uint16_t)q->packed.used_phase << 15);
		}

		rte_vhost_set_vring_base(vsession->vid, i, q->last_avail_idx, q->last_used_idx);
	}

@@ -925,6 +940,7 @@ vhost_start_device_cb(int vid)
	struct spdk_vhost_session *vsession;
	int rc = -1;
	uint16_t i;
	bool packed_ring;

	pthread_mutex_lock(&g_vhost_mutex);

@@ -941,6 +957,13 @@ vhost_start_device_cb(int vid)
		goto out;
	}

	if (vhost_get_negotiated_features(vid, &vsession->negotiated_features) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
		goto out;
	}

	packed_ring = ((vsession->negotiated_features & (1ULL << VIRTIO_F_RING_PACKED)) != 0);

	vsession->max_queues = 0;
	memset(vsession->virtqueue, 0, sizeof(vsession->virtqueue));
	for (i = 0; i < SPDK_VHOST_MAX_VQUEUES; i++) {
@@ -953,6 +976,9 @@ vhost_start_device_cb(int vid)
		q->vring_idx = i;
		rte_vhost_get_vhost_ring_inflight(vid, i, &q->vring_inflight);

		/* vring.desc and vring.desc_packed are in a union struct
		 * so q->vring.desc can replace q->vring.desc_packed.
		 */
		if (q->vring.desc == NULL || q->vring.size == 0) {
			continue;
		}
@@ -962,14 +988,24 @@ vhost_start_device_cb(int vid)
			continue;
		}

		if (packed_ring) {
			/* Packed virtqueues support up to 2^15 entries each
			 * so left one bit can be used as wrap counter.
			 */
			q->packed.avail_phase = q->last_avail_idx >> 15;
			q->last_avail_idx = q->last_avail_idx & 0x7FFF;
			q->packed.used_phase = q->last_used_idx >> 15;
			q->last_used_idx = q->last_used_idx & 0x7FFF;

			/* Disable I/O submission notifications, we'll be polling. */
			q->vring.device_event->flags = VRING_PACKED_EVENT_FLAG_DISABLE;
		} else {
			/* Disable I/O submission notifications, we'll be polling. */
			q->vring.used->flags = VRING_USED_F_NO_NOTIFY;
		vsession->max_queues = i + 1;
		}

	if (vhost_get_negotiated_features(vid, &vsession->negotiated_features) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
		goto out;
		q->packed.packed_ring = packed_ring;
		vsession->max_queues = i + 1;
	}

	if (vhost_get_mem_table(vid, &vsession->mem) != 0) {
@@ -989,6 +1025,9 @@ vhost_start_device_cb(int vid)
	for (i = 0; i < vsession->max_queues; i++) {
		struct spdk_vhost_virtqueue *q = &vsession->virtqueue[i];

		/* vring.desc and vring.desc_packed are in a union struct
		 * so q->vring.desc can replace q->vring.desc_packed.
		 */
		if (q->vring.desc != NULL && q->vring.size > 0) {
			rte_vhost_vring_call(vsession->vid, q->vring_idx);
		}
+13 −1
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@
 */
#define SPDK_VHOST_COALESCING_DELAY_BASE_US 0


#define SPDK_VHOST_FEATURES ((1ULL << VHOST_F_LOG_ALL) | \
	(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
	(1ULL << VIRTIO_F_VERSION_1) | \
@@ -88,6 +87,19 @@ struct spdk_vhost_virtqueue {
	uint16_t last_avail_idx;
	uint16_t last_used_idx;

	struct {
		/* To mark a descriptor as available in packed ring
		 * Equal to avail_wrap_counter in spec.
		 */
		uint8_t avail_phase	: 1;
		/* To mark a descriptor as used in packed ring
		 * Equal to used_wrap_counter in spec.
		 */
		uint8_t used_phase	: 1;
		uint8_t padding		: 5;
		bool packed_ring	: 1;
	} packed;

	void *tasks;

	/* Request count from last stats check */