Commit 3671543a authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Daniel Verkamp
Browse files

vhost: changed dev_construct()/destruct() to dev_load()/unload()



Since vhost_scsi::new_device() would look mostly the same in vhost_blk,
most of it's logic has been moved into spdk_vhost_dev_construct(),
which is now renamed to spdk_vhost_dev_load().

Change-Id: Ic6db93273f916bd021c2ff68946706d055a514d6
Signed-off-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/362547


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent d7054e23
Loading
Loading
Loading
Loading
+82 −58
Original line number Diff line number Diff line
@@ -166,62 +166,6 @@ spdk_vhost_dev_find_by_vid(int vid)
	return NULL;
}

void
spdk_vhost_dev_destruct(struct spdk_vhost_dev *vdev)
{
	struct rte_vhost_vring *q;
	uint16_t i;

	for (i = 0; i < vdev->num_queues; i++) {
		q = &vdev->virtqueue[i];
		rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx);
	}

	free(vdev->mem);
}

int
spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev)
{
	int vid = vdev->vid;
	uint16_t num_queues = rte_vhost_get_vring_num(vid);
	uint16_t i;

	if (num_queues > MAX_VHOST_VRINGS) {
		SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues,
			    MAX_VHOST_VRINGS);
		return -1;
	}

	for (i = 0; i < num_queues; i++) {
		if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) {
			SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
			return -1;
		}

		/* Disable notifications. */
		if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) {
			SPDK_ERRLOG("vhost device %d: Failed to disable guest notification on queue %"PRIu16"\n", vid, i);
			return -1;
		}

	}

	vdev->num_queues = num_queues;

	if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
		return -1;
	}

	if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid);
		return -1;
	}

	return 0;
}

#define SHIFT_2MB	21
#define SIZE_2MB	(1ULL << SHIFT_2MB)
#define FLOOR_2MB(x)	(((uintptr_t)x) / SIZE_2MB) << SHIFT_2MB
@@ -283,7 +227,7 @@ spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev)
	vdev->task_cnt--;
}

void
static void
spdk_vhost_free_reactor(uint32_t lcore)
{
	g_num_ctrlrs[lcore]--;
@@ -487,7 +431,7 @@ spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev)
	return vdev->cpumask;
}

uint32_t
static uint32_t
spdk_vhost_allocate_reactor(uint64_t cpumask)
{
	uint32_t i, selected_core;
@@ -517,6 +461,86 @@ spdk_vhost_allocate_reactor(uint64_t cpumask)
	return selected_core;
}

void
spdk_vhost_dev_unload(struct spdk_vhost_dev *vdev)
{
	struct rte_vhost_vring *q;
	uint16_t i;

	for (i = 0; i < vdev->num_queues; i++) {
		q = &vdev->virtqueue[i];
		rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx);
	}

	free(vdev->mem);

	spdk_vhost_free_reactor(vdev->lcore);
	vdev->lcore = -1;
}

struct spdk_vhost_dev *
spdk_vhost_dev_load(int vid)
{
	struct spdk_vhost_dev *vdev;
	char ifname[PATH_MAX];

	uint16_t num_queues = rte_vhost_get_vring_num(vid);
	uint16_t i;

	if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) {
		SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid);
		return NULL;
	}

	vdev = spdk_vhost_dev_find(ifname);
	if (vdev == NULL) {
		SPDK_ERRLOG("Controller %s not found.\n", ifname);
		return NULL;
	}

	if (vdev->lcore != -1) {
		SPDK_ERRLOG("Controller %s already connected.\n", ifname);
		return NULL;
	}

	if (num_queues > MAX_VHOST_VRINGS) {
		SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues,
			    MAX_VHOST_VRINGS);
		return NULL;
	}

	for (i = 0; i < num_queues; i++) {
		if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) {
			SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
			return NULL;
		}

		/* Disable notifications. */
		if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) {
			SPDK_ERRLOG("vhost device %d: Failed to disable guest notification on queue %"PRIu16"\n", vid, i);
			return NULL;
		}

	}

	vdev->vid = vid;
	vdev->num_queues = num_queues;

	if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
		return NULL;
	}

	if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) {
		SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid);
		return NULL;
	}

	vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);

	return vdev;
}

void
spdk_vhost_startup(void *arg1, void *arg2)
{
+2 −6
Original line number Diff line number Diff line
@@ -66,15 +66,11 @@ struct spdk_vhost_dev_backend {
	const struct vhost_device_ops ops;
};


void spdk_vhost_dev_mem_register(struct spdk_vhost_dev *vdev);
void spdk_vhost_dev_mem_unregister(struct spdk_vhost_dev *vdev);

void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr);

uint32_t spdk_vhost_allocate_reactor(uint64_t cpumask);
void spdk_vhost_free_reactor(uint32_t lcore);

uint16_t spdk_vhost_vq_avail_ring_get(struct rte_vhost_vring *vq, uint16_t *reqs,
				      uint16_t reqs_len);
bool spdk_vhost_vq_should_notify(struct spdk_vhost_dev *vdev, struct rte_vhost_vring *vq);
@@ -89,10 +85,10 @@ struct vring_desc *spdk_vhost_vring_desc_get_next(struct vring_desc *vq_desc,
bool spdk_vhost_vring_desc_is_wr(struct vring_desc *cur_desc);

struct spdk_vhost_dev *spdk_vhost_dev_find_by_vid(int vid);
int spdk_vhost_dev_construct(struct spdk_vhost_dev *dev);
struct spdk_vhost_dev *spdk_vhost_dev_load(int vid);
int spdk_vhost_dev_register(struct spdk_vhost_dev *dev,
			    const struct spdk_vhost_dev_backend *backend);
int spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev);
void spdk_vhost_dev_destruct(struct spdk_vhost_dev *dev);
void spdk_vhost_dev_unload(struct spdk_vhost_dev *dev);

#endif /* SPDK_VHOST_INTERNAL_H */
+2 −25
Original line number Diff line number Diff line
@@ -850,33 +850,13 @@ new_device(int vid)
{
	struct spdk_vhost_dev *vdev = NULL;
	struct spdk_event *event;

	char ifname[PATH_MAX];
	sem_t added;

	if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) {
		SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid);
		return -1;
	}

	vdev = spdk_vhost_dev_find(ifname);
	vdev = spdk_vhost_dev_load(vid);
	if (vdev == NULL) {
		SPDK_ERRLOG("Controller %s not found.\n", ifname);
		return -1;
	}

	if (vdev->lcore != -1) {
		SPDK_ERRLOG("Controller %s already connected.\n", ifname);
		return -1;
	}

	vdev->vid = vid;
	if (spdk_vhost_dev_construct(vdev) != 0) {
		return -1;
	}

	vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);

	event = vhost_sem_event_alloc(vdev->lcore, add_vdev_cb, vdev, &added);
	spdk_event_call(event);
	if (vhost_sem_timedwait(&added, 1))
@@ -923,10 +903,7 @@ destroy_device(int vid)
	if (vhost_sem_timedwait(&done_sem, 1))
		rte_panic("%s: failed to unregister poller.\n", vdev->name);

	spdk_vhost_free_reactor(vdev->lcore);
	vdev->lcore = -1;

	spdk_vhost_dev_destruct(vdev);
	spdk_vhost_dev_unload(vdev);
}

SPDK_LOG_REGISTER_TRACE_FLAG("vhost", SPDK_TRACE_VHOST)