Commit f82a1757 authored by Darek Stojaczyk's avatar Darek Stojaczyk Committed by Jim Harris
Browse files

vhost: separate sessions from devices



Session struct will be now allocated inside the
`new_connection` rte_vhost callback. There can be
still only one connection per device, but this
change brings us one step towards supporting more.

Besides the obvious pointer changes, we'll now also
use the session pointer to check if the connection
actually exists. We used to set device vid to -1
when there was no connection but we no longer have
to do that.

Change-Id: I4d062c0b5f093fef132a6a2c9cc29458cbaad414
Signed-off-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/437776


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 40864641
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -516,8 +516,8 @@ spdk_vhost_session_find_by_vid(int vid)
	struct spdk_vhost_dev *vdev;

	TAILQ_FOREACH(vdev, &g_spdk_vhost_devices, tailq) {
		if (vdev->session.vid == vid) {
			return &vdev->session;
		if (vdev->session && vdev->session->vid == vid) {
			return vdev->session;
		}
	}

@@ -750,7 +750,6 @@ spdk_vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const cha
	vdev->name = strdup(name);
	vdev->path = strdup(path);
	vdev->id = ctrlr_num++;
	vdev->session.vid = -1;
	vdev->lcore = -1;
	vdev->cpumask = cpumask;
	vdev->registered = true;
@@ -775,7 +774,7 @@ out:
int
spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev)
{
	if (vdev->session.vid != -1) {
	if (vdev->session) {
		SPDK_ERRLOG("Controller %s has still valid connection.\n", vdev->name);
		return -EBUSY;
	}
@@ -1267,16 +1266,23 @@ new_connection(int vid)
		return -1;
	}

	/* since pollers are not running it safe not to use spdk_event here */
	vsession = &vdev->session;
	if (vsession->vid != -1) {
		SPDK_ERRLOG("Session with vid %d already exists.\n", vid);
	if (vdev->session != NULL) {
		SPDK_ERRLOG("Device %s is already connected.\n", vdev->name);
		pthread_mutex_unlock(&g_spdk_vhost_mutex);
		return -1;
	}

	vsession = spdk_dma_zmalloc(sizeof(struct spdk_vhost_session),
				    SPDK_CACHE_LINE_SIZE, NULL);
	if (vsession == NULL) {
		SPDK_ERRLOG("spdk_dma_zmalloc failed\n");
		pthread_mutex_unlock(&g_spdk_vhost_mutex);
		return -1;
	}

	vsession->vdev = vdev;
	vsession->vid = vid;
	vdev->session = vsession;
	pthread_mutex_unlock(&g_spdk_vhost_mutex);
	return 0;
}
@@ -1294,8 +1300,8 @@ destroy_connection(int vid)
		return;
	}

	/* since pollers are not running it safe not to use spdk_event here */
	vsession->vid = -1;
	vsession->vdev->session = NULL;
	spdk_dma_free(vsession);
	pthread_mutex_unlock(&g_spdk_vhost_mutex);
}

+14 −14
Original line number Diff line number Diff line
@@ -85,8 +85,8 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev
static void
blk_task_finish(struct spdk_vhost_blk_task *task)
{
	assert(task->bvdev->vdev.session.task_cnt > 0);
	task->bvdev->vdev.session.task_cnt--;
	assert(task->bvdev->vdev.session->task_cnt > 0);
	task->bvdev->vdev.session->task_cnt--;
	task->used = false;
}

@@ -97,7 +97,7 @@ invalid_blk_request(struct spdk_vhost_blk_task *task, uint8_t status)
		*task->status = status;
	}

	spdk_vhost_vq_used_ring_enqueue(&task->bvdev->vdev.session, task->vq, task->req_idx,
	spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
					task->used_len);
	blk_task_finish(task);
	SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK_DATA, "Invalid request (status=%" PRIu8")\n", status);
@@ -119,7 +119,7 @@ blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uin
	uint32_t desc_table_size, len = 0;
	int rc;

	rc = spdk_vhost_vq_get_desc(&vdev->session, vq, req_idx, &desc, &desc_table, &desc_table_size);
	rc = spdk_vhost_vq_get_desc(vdev->session, vq, req_idx, &desc, &desc_table, &desc_table_size);
	if (rc != 0) {
		SPDK_ERRLOG("%s: Invalid descriptor at index %"PRIu16".\n", vdev->name, req_idx);
		return -1;
@@ -136,7 +136,7 @@ blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uin
			return -1;
		}

		if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(&vdev->session, iovs, &cnt, desc))) {
		if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vdev->session, iovs, &cnt, desc))) {
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Invalid descriptor %" PRIu16" (req_idx = %"PRIu16").\n",
				      req_idx, cnt);
			return -1;
@@ -174,7 +174,7 @@ static void
blk_request_finish(bool success, struct spdk_vhost_blk_task *task)
{
	*task->status = success ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR;
	spdk_vhost_vq_used_ring_enqueue(&task->bvdev->vdev.session, task->vq, task->req_idx,
	spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
					task->used_len);
	SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Finished task (%p) req_idx=%d\n status: %s\n", task,
		      task->req_idx, success ? "OK" : "FAIL");
@@ -377,7 +377,7 @@ static void
process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_blk_task *task;
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	int rc;
	uint16_t reqs[32];
	uint16_t reqs_cnt, i;
@@ -427,7 +427,7 @@ static int
vdev_worker(void *arg)
{
	struct spdk_vhost_blk_dev *bvdev = arg;
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	uint16_t q_idx;

	for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
@@ -442,7 +442,7 @@ vdev_worker(void *arg)
static void
no_bdev_process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
	uint32_t length;
	uint16_t iovcnt, req_idx;
@@ -464,7 +464,7 @@ static int
no_bdev_vdev_worker(void *arg)
{
	struct spdk_vhost_blk_dev *bvdev = arg;
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	uint16_t q_idx;

	for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
@@ -534,7 +534,7 @@ bdev_remove_cb(void *remove_ctx)
static void
free_task_pool(struct spdk_vhost_blk_dev *bvdev)
{
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct spdk_vhost_virtqueue *vq;
	uint16_t i;

@@ -552,7 +552,7 @@ free_task_pool(struct spdk_vhost_blk_dev *bvdev)
static int
alloc_task_pool(struct spdk_vhost_blk_dev *bvdev)
{
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct spdk_vhost_virtqueue *vq;
	struct spdk_vhost_blk_task *task;
	uint32_t task_cnt;
@@ -602,7 +602,7 @@ static int
spdk_vhost_blk_start(struct spdk_vhost_dev *vdev, void *event_ctx)
{
	struct spdk_vhost_blk_dev *bvdev;
	struct spdk_vhost_session *vsession = &vdev->session;
	struct spdk_vhost_session *vsession = vdev->session;
	int i, rc = 0;

	bvdev = to_blk_dev(vdev);
@@ -650,7 +650,7 @@ static int
destroy_device_poller_cb(void *arg)
{
	struct spdk_vhost_blk_dev *bvdev = arg;
	struct spdk_vhost_session *vsession = &bvdev->vdev.session;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	int i;

	if (vsession->task_cnt > 0) {
+18 −16
Original line number Diff line number Diff line
@@ -133,6 +133,23 @@ struct spdk_vhost_dev_backend {
	int (*remove_device)(struct spdk_vhost_dev *vdev);
};

struct spdk_vhost_session {
	struct spdk_vhost_dev *vdev;

	/* rte_vhost connection ID. */
	int vid;

	struct rte_vhost_memory *mem;

	int task_cnt;

	uint16_t max_queues;

	uint64_t negotiated_features;

	struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];
};

struct spdk_vhost_dev {
	char *name;
	char *path;
@@ -164,22 +181,7 @@ struct spdk_vhost_dev {
	uint64_t stats_check_interval;

	/* Active connection to the device */
	struct spdk_vhost_session {
		struct spdk_vhost_dev *vdev;

		/* rte_vhost connection ID. */
		int vid;

		struct rte_vhost_memory *mem;

		int task_cnt;

		uint16_t max_queues;

		uint64_t negotiated_features;

		struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];
	} session;
	struct spdk_vhost_session *session;

	TAILQ_ENTRY(spdk_vhost_dev) tailq;
};
+7 −7
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ static int
spdk_nvme_map_prps(struct spdk_vhost_nvme_dev *nvme, struct spdk_nvme_cmd *cmd,
		   struct spdk_vhost_nvme_task *task, uint32_t len)
{
	struct spdk_vhost_session *vsession = &nvme->vdev.session;
	struct spdk_vhost_session *vsession = nvme->vdev.session;
	uint64_t prp1, prp2;
	void *vva;
	uint32_t i;
@@ -699,7 +699,7 @@ static int
vhost_nvme_doorbell_buffer_config(struct spdk_vhost_nvme_dev *nvme,
				  struct spdk_nvme_cmd *cmd, struct spdk_nvme_cpl *cpl)
{
	struct spdk_vhost_session *vsession = &nvme->vdev.session;
	struct spdk_vhost_session *vsession = nvme->vdev.session;
	uint64_t dbs_dma_addr, eis_dma_addr;

	dbs_dma_addr = cmd->dptr.prp.prp1;
@@ -765,7 +765,7 @@ vhost_nvme_create_io_sq(struct spdk_vhost_nvme_dev *nvme,
	sq->size = qsize + 1;
	sq->sq_head = sq->sq_tail = 0;
	requested_len = sizeof(struct spdk_nvme_cmd) * sq->size;
	sq->sq_cmd = spdk_vhost_gpa_to_vva(&nvme->vdev.session, dma_addr, requested_len);
	sq->sq_cmd = spdk_vhost_gpa_to_vva(nvme->vdev.session, dma_addr, requested_len);
	if (!sq->sq_cmd) {
		return -1;
	}
@@ -848,7 +848,7 @@ vhost_nvme_create_io_cq(struct spdk_vhost_nvme_dev *nvme,
	cq->guest_signaled_cq_head = 0;
	cq->need_signaled_cnt = 0;
	requested_len = sizeof(struct spdk_nvme_cpl) * cq->size;
	cq->cq_cqe = spdk_vhost_gpa_to_vva(&nvme->vdev.session, dma_addr, requested_len);
	cq->cq_cqe = spdk_vhost_gpa_to_vva(nvme->vdev.session, dma_addr, requested_len);
	if (!cq->cq_cqe) {
		return -1;
	}
@@ -893,7 +893,7 @@ spdk_vhost_nvme_get_by_name(int vid)
	struct spdk_vhost_nvme_dev *nvme;

	TAILQ_FOREACH(nvme, &g_nvme_ctrlrs, tailq) {
		if (nvme->vdev.session.vid == vid) {
		if (nvme->vdev.session != NULL && nvme->vdev.session->vid == vid) {
			return nvme;
		}
	}
@@ -1084,7 +1084,7 @@ spdk_vhost_nvme_start_device(struct spdk_vhost_dev *vdev, void *event_ctx)
		return -1;
	}

	SPDK_NOTICELOG("Start Device %u, Path %s, lcore %d\n", vdev->session.vid,
	SPDK_NOTICELOG("Start Device %u, Path %s, lcore %d\n", vdev->session->vid,
		       vdev->path, vdev->lcore);

	for (i = 0; i < nvme->num_ns; i++) {
@@ -1171,7 +1171,7 @@ spdk_vhost_nvme_stop_device(struct spdk_vhost_dev *vdev, void *event_ctx)
	}

	free_task_pool(nvme);
	SPDK_NOTICELOG("Stopping Device %u, Path %s\n", vdev->session.vid, vdev->path);
	SPDK_NOTICELOG("Stopping Device %u, Path %s\n", vdev->session->vid, vdev->path);

	nvme->destroy_ctx.event_ctx = event_ctx;
	spdk_poller_unregister(&nvme->requestq_poller);
+17 −17
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ static void
spdk_vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
{
	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
	struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
	struct spdk_vhost_session *vsession = task->svdev->vdev.session;

	assert(vsession->task_cnt > 0);
	vsession->task_cnt--;
@@ -170,7 +170,7 @@ static void
eventq_enqueue(struct spdk_vhost_scsi_dev *svdev, unsigned scsi_dev_num, uint32_t event,
	       uint32_t reason)
{
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	struct spdk_vhost_virtqueue *vq;
	struct vring_desc *desc, *desc_table;
	struct virtio_scsi_event *desc_ev;
@@ -223,7 +223,7 @@ out:
static void
submit_completion(struct spdk_vhost_scsi_task *task)
{
	struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
	struct spdk_vhost_session *vsession = task->svdev->vdev.session;

	spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
					task->used_len);
@@ -280,7 +280,7 @@ mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func fun
static void
invalid_request(struct spdk_vhost_scsi_task *task)
{
	struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
	struct spdk_vhost_session *vsession = task->svdev->vdev.session;

	spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
					task->used_len);
@@ -321,7 +321,7 @@ static void
process_ctrl_request(struct spdk_vhost_scsi_task *task)
{
	struct spdk_vhost_dev *vdev = &task->svdev->vdev;
	struct spdk_vhost_session *vsession = &vdev->session;
	struct spdk_vhost_session *vsession = vdev->session;
	struct vring_desc *desc, *desc_table;
	struct virtio_scsi_ctrl_tmf_req *ctrl_req;
	struct virtio_scsi_ctrl_an_resp *an_resp;
@@ -423,7 +423,7 @@ task_data_setup(struct spdk_vhost_scsi_task *task,
		struct virtio_scsi_cmd_req **req)
{
	struct spdk_vhost_dev *vdev = &task->svdev->vdev;
	struct spdk_vhost_session *vsession = &vdev->session;
	struct spdk_vhost_session *vsession = vdev->session;
	struct vring_desc *desc, *desc_table;
	struct iovec *iovs = task->iovs;
	uint16_t iovcnt = 0;
@@ -586,7 +586,7 @@ process_request(struct spdk_vhost_scsi_task *task)
static void
process_controlq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	struct spdk_vhost_scsi_task *task;
	uint16_t reqs[32];
	uint16_t reqs_cnt, i;
@@ -619,7 +619,7 @@ process_controlq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue
static void
process_requestq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	struct spdk_vhost_scsi_task *task;
	uint16_t reqs[32];
	uint16_t reqs_cnt, i;
@@ -673,7 +673,7 @@ static int
vdev_mgmt_worker(void *arg)
{
	struct spdk_vhost_scsi_dev *svdev = arg;
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;

	process_removed_devs(svdev);
	spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
@@ -688,7 +688,7 @@ static int
vdev_worker(void *arg)
{
	struct spdk_vhost_scsi_dev *svdev = arg;
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	uint32_t q_idx;

	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
@@ -793,7 +793,7 @@ spdk_vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
	assert(lun != NULL);
	assert(svdev != NULL);
	if (svdev->vdev.lcore != -1 &&
	    !spdk_vhost_dev_has_feature(&svdev->vdev.session, VIRTIO_SCSI_F_HOTPLUG)) {
	    !spdk_vhost_dev_has_feature(svdev->vdev.session, VIRTIO_SCSI_F_HOTPLUG)) {
		SPDK_WARNLOG("%s: hotremove is not enabled for this controller.\n", svdev->vdev.name);
		return;
	}
@@ -873,7 +873,7 @@ spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,

	spdk_scsi_dev_allocate_io_channels(svdev->scsi_dev[scsi_tgt_num]);

	if (spdk_vhost_dev_has_feature(&vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
	if (spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
		eventq_enqueue(svdev, scsi_tgt_num, VIRTIO_SCSI_T_TRANSPORT_RESET,
			       VIRTIO_SCSI_EVT_RESET_RESCAN);
	} else {
@@ -922,7 +922,7 @@ spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_nu
		return rc;
	}

	if (!spdk_vhost_dev_has_feature(&vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
	if (!spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
		SPDK_WARNLOG("%s: 'Target %u' is in use and hot-detach is not enabled for this controller.\n",
			     svdev->vdev.name, scsi_tgt_num);
		return -ENOTSUP;
@@ -1015,7 +1015,7 @@ spdk_vhost_scsi_controller_construct(void)
static void
free_task_pool(struct spdk_vhost_scsi_dev *svdev)
{
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	struct spdk_vhost_virtqueue *vq;
	uint16_t i;

@@ -1033,7 +1033,7 @@ free_task_pool(struct spdk_vhost_scsi_dev *svdev)
static int
alloc_task_pool(struct spdk_vhost_scsi_dev *svdev)
{
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	struct spdk_vhost_virtqueue *vq;
	struct spdk_vhost_scsi_task *task;
	uint32_t task_cnt;
@@ -1082,7 +1082,7 @@ static int
spdk_vhost_scsi_start(struct spdk_vhost_dev *vdev, void *event_ctx)
{
	struct spdk_vhost_scsi_dev *svdev;
	struct spdk_vhost_session *vsession = &vdev->session;
	struct spdk_vhost_session *vsession = vdev->session;
	uint32_t i;
	int rc;

@@ -1132,7 +1132,7 @@ static int
destroy_device_poller_cb(void *arg)
{
	struct spdk_vhost_scsi_dev *svdev = arg;
	struct spdk_vhost_session *vsession = &svdev->vdev.session;
	struct spdk_vhost_session *vsession = svdev->vdev.session;
	uint32_t i;

	if (vsession->task_cnt > 0) {
Loading