xref: /spdk/lib/vhost/vhost_scsi.c (revision ba8f1a9e5d59b6dfa9fd07c1300891b4e03722d9)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include <linux/virtio_scsi.h>
37 
38 #include "spdk/env.h"
39 #include "spdk/thread.h"
40 #include "spdk/scsi.h"
41 #include "spdk/scsi_spec.h"
42 #include "spdk/util.h"
43 #include "spdk/likely.h"
44 
45 #include "spdk/vhost.h"
46 #include "vhost_internal.h"
47 
48 /* Features supported by SPDK VHOST lib. */
49 #define SPDK_VHOST_SCSI_FEATURES	(SPDK_VHOST_FEATURES | \
50 					(1ULL << VIRTIO_SCSI_F_INOUT) | \
51 					(1ULL << VIRTIO_SCSI_F_HOTPLUG) | \
52 					(1ULL << VIRTIO_SCSI_F_CHANGE ) | \
53 					(1ULL << VIRTIO_SCSI_F_T10_PI ))
54 
55 /* Features that are specified in VIRTIO SCSI but currently not supported:
56  * - Live migration not supported yet
57  * - T10 PI
58  */
59 #define SPDK_VHOST_SCSI_DISABLED_FEATURES	(SPDK_VHOST_DISABLED_FEATURES | \
60 						(1ULL << VIRTIO_SCSI_F_T10_PI ))
61 
62 /* Vhost-user-scsi support protocol features */
63 #define SPDK_VHOST_SCSI_PROTOCOL_FEATURES	(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)
64 
65 #define MGMT_POLL_PERIOD_US (1000 * 5)
66 
67 #define VIRTIO_SCSI_CONTROLQ   0
68 #define VIRTIO_SCSI_EVENTQ   1
69 #define VIRTIO_SCSI_REQUESTQ   2
70 
71 enum spdk_scsi_dev_vhost_status {
72 	/* Target ID is empty. */
73 	VHOST_SCSI_DEV_EMPTY,
74 
75 	/* Target is still being added. */
76 	VHOST_SCSI_DEV_ADDING,
77 
78 	/* Target ID occupied. */
79 	VHOST_SCSI_DEV_PRESENT,
80 
81 	/* Target ID is occupied but removal is in progress. */
82 	VHOST_SCSI_DEV_REMOVING,
83 
84 	/* In session - device (SCSI target) seen but removed. */
85 	VHOST_SCSI_DEV_REMOVED,
86 };
87 
88 /** Context for a SCSI target in a vhost device */
89 struct spdk_scsi_dev_vhost_state {
90 	struct spdk_scsi_dev *dev;
91 	enum spdk_scsi_dev_vhost_status status;
92 	spdk_vhost_event_fn remove_cb;
93 	void *remove_ctx;
94 };
95 
96 struct spdk_vhost_scsi_dev {
97 	int ref;
98 	bool registered;
99 	struct spdk_vhost_dev vdev;
100 	struct spdk_scsi_dev_vhost_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
101 };
102 
103 /** Context for a SCSI target in a vhost session */
104 struct spdk_scsi_dev_session_state {
105 	struct spdk_scsi_dev *dev;
106 	enum spdk_scsi_dev_vhost_status status;
107 };
108 
109 struct spdk_vhost_scsi_session {
110 	struct spdk_vhost_session vsession;
111 
112 	struct spdk_vhost_scsi_dev *svdev;
113 	/** Local copy of the device state */
114 	struct spdk_scsi_dev_session_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
115 	struct spdk_poller *requestq_poller;
116 	struct spdk_poller *mgmt_poller;
117 	struct spdk_poller *stop_poller;
118 };
119 
120 struct spdk_vhost_scsi_task {
121 	struct spdk_scsi_task	scsi;
122 	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
123 
124 	union {
125 		struct virtio_scsi_cmd_resp *resp;
126 		struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
127 	};
128 
129 	struct spdk_vhost_scsi_session *svsession;
130 	struct spdk_scsi_dev *scsi_dev;
131 
132 	/** Number of bytes that were written. */
133 	uint32_t used_len;
134 
135 	int req_idx;
136 
137 	/* If set, the task is currently used for I/O processing. */
138 	bool used;
139 
140 	struct spdk_vhost_virtqueue *vq;
141 };
142 
143 static int vhost_scsi_start(struct spdk_vhost_session *vsession);
144 static int vhost_scsi_stop(struct spdk_vhost_session *vsession);
145 static void vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev,
146 				      struct spdk_json_write_ctx *w);
147 static void vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
148 		struct spdk_json_write_ctx *w);
149 static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
150 static int vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev,
151 					unsigned scsi_tgt_num);
152 
153 static const struct spdk_vhost_user_dev_backend spdk_vhost_scsi_user_device_backend = {
154 	.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
155 	.start_session =  vhost_scsi_start,
156 	.stop_session = vhost_scsi_stop,
157 };
158 
159 static const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
160 	.dump_info_json = vhost_scsi_dump_info_json,
161 	.write_config_json = vhost_scsi_write_config_json,
162 	.remove_device = vhost_scsi_dev_remove,
163 };
164 
165 static inline void
166 scsi_task_init(struct spdk_vhost_scsi_task *task)
167 {
168 	memset(&task->scsi, 0, sizeof(task->scsi));
169 	/* Tmf_resp pointer and resp pointer are in a union.
170 	 * Here means task->tmf_resp = task->resp = NULL.
171 	 */
172 	task->resp = NULL;
173 	task->used = true;
174 	task->used_len = 0;
175 }
176 
177 static void
178 vhost_scsi_task_put(struct spdk_vhost_scsi_task *task)
179 {
180 	spdk_scsi_task_put(&task->scsi);
181 }
182 
183 static void
184 vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
185 {
186 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
187 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
188 
189 	assert(vsession->task_cnt > 0);
190 	vsession->task_cnt--;
191 	task->used = false;
192 }
193 
194 static void
195 remove_scsi_tgt(struct spdk_vhost_scsi_dev *svdev,
196 		unsigned scsi_tgt_num)
197 {
198 	struct spdk_scsi_dev_vhost_state *state;
199 	struct spdk_scsi_dev *dev;
200 
201 	state = &svdev->scsi_dev_state[scsi_tgt_num];
202 	dev = state->dev;
203 	state->dev = NULL;
204 	assert(state->status == VHOST_SCSI_DEV_REMOVING);
205 	state->status = VHOST_SCSI_DEV_EMPTY;
206 	spdk_scsi_dev_destruct(dev, NULL, NULL);
207 	if (state->remove_cb) {
208 		state->remove_cb(&svdev->vdev, state->remove_ctx);
209 		state->remove_cb = NULL;
210 	}
211 	SPDK_INFOLOG(vhost, "removed target 'Target %u'\n", scsi_tgt_num);
212 
213 	if (--svdev->ref == 0 && svdev->registered == false) {
214 		free(svdev);
215 	}
216 }
217 
218 static void
219 vhost_scsi_dev_process_removed_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
220 {
221 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
222 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
223 					    struct spdk_vhost_scsi_dev, vdev);
224 
225 	/* all sessions have already detached the device */
226 	if (svdev->scsi_dev_state[scsi_tgt_num].status != VHOST_SCSI_DEV_REMOVING) {
227 		/* device was already removed in the meantime */
228 		return;
229 	}
230 
231 	remove_scsi_tgt(svdev, scsi_tgt_num);
232 }
233 
234 static int
235 vhost_scsi_session_process_removed(struct spdk_vhost_dev *vdev,
236 				   struct spdk_vhost_session *vsession, void *ctx)
237 {
238 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
239 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
240 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
241 
242 	if (state->dev != NULL) {
243 		/* there's still a session that references this device,
244 		 * so abort our foreach chain here. We'll be called
245 		 * again from this session's management poller after it
246 		 * is removed in there
247 		 */
248 		return -1;
249 	}
250 
251 	return 0;
252 }
253 
254 static void
255 process_removed_devs(struct spdk_vhost_scsi_session *svsession)
256 {
257 	struct spdk_scsi_dev *dev;
258 	struct spdk_scsi_dev_session_state *state;
259 	int i;
260 
261 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
262 		state = &svsession->scsi_dev_state[i];
263 		dev = state->dev;
264 
265 		if (dev && state->status == VHOST_SCSI_DEV_REMOVING &&
266 		    !spdk_scsi_dev_has_pending_tasks(dev, NULL)) {
267 			/* detach the device from this session */
268 			spdk_scsi_dev_free_io_channels(dev);
269 			state->dev = NULL;
270 			state->status = VHOST_SCSI_DEV_REMOVED;
271 			/* try to detach it globally */
272 			spdk_vhost_lock();
273 			vhost_user_dev_foreach_session(&svsession->svdev->vdev,
274 						       vhost_scsi_session_process_removed,
275 						       vhost_scsi_dev_process_removed_cpl_cb,
276 						       (void *)(uintptr_t)i);
277 			spdk_vhost_unlock();
278 		}
279 	}
280 }
281 
282 static void
283 eventq_enqueue(struct spdk_vhost_scsi_session *svsession, unsigned scsi_dev_num,
284 	       uint32_t event, uint32_t reason)
285 {
286 	struct spdk_vhost_session *vsession = &svsession->vsession;
287 	struct spdk_vhost_virtqueue *vq;
288 	struct vring_desc *desc, *desc_table;
289 	struct virtio_scsi_event *desc_ev;
290 	uint32_t desc_table_size, req_size = 0;
291 	uint16_t req;
292 	int rc;
293 
294 	assert(scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
295 	vq = &vsession->virtqueue[VIRTIO_SCSI_EVENTQ];
296 
297 	if (vq->vring.desc == NULL || vhost_vq_avail_ring_get(vq, &req, 1) != 1) {
298 		SPDK_ERRLOG("%s: failed to send virtio event (no avail ring entries?).\n",
299 			    vsession->name);
300 		return;
301 	}
302 
303 	rc = vhost_vq_get_desc(vsession, vq, req, &desc, &desc_table, &desc_table_size);
304 	if (rc != 0 || desc->len < sizeof(*desc_ev)) {
305 		SPDK_ERRLOG("%s: invalid eventq descriptor at index %"PRIu16".\n",
306 			    vsession->name, req);
307 		goto out;
308 	}
309 
310 	desc_ev = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*desc_ev));
311 	if (desc_ev == NULL) {
312 		SPDK_ERRLOG("%s: eventq descriptor at index %"PRIu16" points "
313 			    "to unmapped guest memory address %p.\n",
314 			    vsession->name, req, (void *)(uintptr_t)desc->addr);
315 		goto out;
316 	}
317 
318 	desc_ev->event = event;
319 	desc_ev->lun[0] = 1;
320 	desc_ev->lun[1] = scsi_dev_num;
321 	/* virtio LUN id 0 can refer either to the entire device
322 	 * or actual LUN 0 (the only supported by vhost for now)
323 	 */
324 	desc_ev->lun[2] = 0 >> 8;
325 	desc_ev->lun[3] = 0 & 0xFF;
326 	/* virtio doesn't specify any strict format for LUN id (bytes 2 and 3)
327 	 * current implementation relies on linux kernel sources
328 	 */
329 	memset(&desc_ev->lun[4], 0, 4);
330 	desc_ev->reason = reason;
331 	req_size = sizeof(*desc_ev);
332 
333 out:
334 	vhost_vq_used_ring_enqueue(vsession, vq, req, req_size);
335 }
336 
337 static void
338 submit_completion(struct spdk_vhost_scsi_task *task)
339 {
340 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
341 
342 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
343 				   task->used_len);
344 	SPDK_DEBUGLOG(vhost_scsi, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
345 
346 	vhost_scsi_task_put(task);
347 }
348 
349 static void
350 vhost_scsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task)
351 {
352 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
353 
354 	submit_completion(task);
355 }
356 
357 static void
358 vhost_scsi_task_cpl(struct spdk_scsi_task *scsi_task)
359 {
360 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
361 
362 	/* The SCSI task has completed.  Do final processing and then post
363 	   notification to the virtqueue's "used" ring.
364 	 */
365 	task->resp->status = task->scsi.status;
366 
367 	if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
368 		memcpy(task->resp->sense, task->scsi.sense_data, task->scsi.sense_data_len);
369 		task->resp->sense_len = task->scsi.sense_data_len;
370 		SPDK_DEBUGLOG(vhost_scsi, "Task (%p) req_idx=%d failed - status=%u\n", task, task->req_idx,
371 			      task->scsi.status);
372 	}
373 	assert(task->scsi.transfer_len == task->scsi.length);
374 	task->resp->resid = task->scsi.length - task->scsi.data_transferred;
375 
376 	submit_completion(task);
377 }
378 
379 static void
380 task_submit(struct spdk_vhost_scsi_task *task)
381 {
382 	task->resp->response = VIRTIO_SCSI_S_OK;
383 	spdk_scsi_dev_queue_task(task->scsi_dev, &task->scsi);
384 }
385 
386 static void
387 mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func func)
388 {
389 	task->tmf_resp->response = VIRTIO_SCSI_S_OK;
390 	task->scsi.function = func;
391 	spdk_scsi_dev_queue_mgmt_task(task->scsi_dev, &task->scsi);
392 }
393 
394 static void
395 invalid_request(struct spdk_vhost_scsi_task *task)
396 {
397 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
398 
399 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
400 				   task->used_len);
401 	vhost_scsi_task_put(task);
402 
403 	SPDK_DEBUGLOG(vhost_scsi, "Invalid request (status=%" PRIu8")\n",
404 		      task->resp ? task->resp->response : -1);
405 }
406 
407 static int
408 vhost_scsi_task_init_target(struct spdk_vhost_scsi_task *task, const __u8 *lun)
409 {
410 	struct spdk_vhost_scsi_session *svsession = task->svsession;
411 	struct spdk_scsi_dev_session_state *state;
412 	uint16_t lun_id = (((uint16_t)lun[2] << 8) | lun[3]) & 0x3FFF;
413 
414 	SPDK_LOGDUMP(vhost_scsi_queue, "LUN", lun, 8);
415 
416 	/* First byte must be 1 and second is target */
417 	if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
418 		return -1;
419 	}
420 
421 	state = &svsession->scsi_dev_state[lun[1]];
422 	task->scsi_dev = state->dev;
423 	if (state->dev == NULL || state->status != VHOST_SCSI_DEV_PRESENT) {
424 		/* If dev has been hotdetached, return 0 to allow sending
425 		 * additional hotremove event via sense codes.
426 		 */
427 		return state->status != VHOST_SCSI_DEV_EMPTY ? 0 : -1;
428 	}
429 
430 	task->scsi.target_port = spdk_scsi_dev_find_port_by_id(task->scsi_dev, 0);
431 	task->scsi.lun = spdk_scsi_dev_get_lun(state->dev, lun_id);
432 	return 0;
433 }
434 
435 static void
436 process_ctrl_request(struct spdk_vhost_scsi_task *task)
437 {
438 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
439 	struct vring_desc *desc, *desc_table;
440 	struct virtio_scsi_ctrl_tmf_req *ctrl_req;
441 	struct virtio_scsi_ctrl_an_resp *an_resp;
442 	uint32_t desc_table_size, used_len = 0;
443 	int rc;
444 
445 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_mgmt_cpl, vhost_scsi_task_free_cb);
446 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table,
447 			       &desc_table_size);
448 	if (spdk_unlikely(rc != 0)) {
449 		SPDK_ERRLOG("%s: invalid controlq descriptor at index %d.\n",
450 			    vsession->name, task->req_idx);
451 		goto out;
452 	}
453 
454 	ctrl_req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*ctrl_req));
455 	if (ctrl_req == NULL) {
456 		SPDK_ERRLOG("%s: invalid task management request at index %d.\n",
457 			    vsession->name, task->req_idx);
458 		goto out;
459 	}
460 
461 	SPDK_DEBUGLOG(vhost_scsi_queue,
462 		      "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n",
463 		      task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx,
464 		      task->vq->vring.kickfd, task->vq->vring.size);
465 	SPDK_LOGDUMP(vhost_scsi_queue, "Request descriptor", (uint8_t *)ctrl_req, desc->len);
466 
467 	vhost_scsi_task_init_target(task, ctrl_req->lun);
468 
469 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_size);
470 	if (spdk_unlikely(desc == NULL)) {
471 		SPDK_ERRLOG("%s: no response descriptor for controlq request %d.\n",
472 			    vsession->name, task->req_idx);
473 		goto out;
474 	}
475 
476 	/* Process the TMF request */
477 	switch (ctrl_req->type) {
478 	case VIRTIO_SCSI_T_TMF:
479 		task->tmf_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->tmf_resp));
480 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) {
481 			SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n",
482 				    vsession->name, task->req_idx);
483 			goto out;
484 		}
485 
486 		/* Check if we are processing a valid request */
487 		if (task->scsi_dev == NULL) {
488 			task->tmf_resp->response = VIRTIO_SCSI_S_BAD_TARGET;
489 			break;
490 		}
491 
492 		switch (ctrl_req->subtype) {
493 		case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
494 			/* Handle LUN reset */
495 			SPDK_DEBUGLOG(vhost_scsi_queue, "%s: LUN reset\n", vsession->name);
496 
497 			mgmt_task_submit(task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
498 			return;
499 		default:
500 			task->tmf_resp->response = VIRTIO_SCSI_S_ABORTED;
501 			/* Unsupported command */
502 			SPDK_DEBUGLOG(vhost_scsi_queue, "%s: unsupported TMF command %x\n",
503 				      vsession->name, ctrl_req->subtype);
504 			break;
505 		}
506 		break;
507 	case VIRTIO_SCSI_T_AN_QUERY:
508 	case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
509 		an_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*an_resp));
510 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_an_resp) || an_resp == NULL)) {
511 			SPDK_WARNLOG("%s: asynchronous response descriptor points to invalid guest memory region\n",
512 				     vsession->name);
513 			goto out;
514 		}
515 
516 		an_resp->response = VIRTIO_SCSI_S_ABORTED;
517 		break;
518 	}
519 	default:
520 		SPDK_DEBUGLOG(vhost_scsi_queue, "%s: Unsupported control command %x\n",
521 			      vsession->name, ctrl_req->type);
522 		break;
523 	}
524 
525 	used_len = sizeof(struct virtio_scsi_ctrl_tmf_resp);
526 out:
527 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx, used_len);
528 	vhost_scsi_task_put(task);
529 }
530 
531 /*
532  * Process task's descriptor chain and setup data related fields.
533  * Return
534  *   -1 if request is invalid and must be aborted,
535  *    0 if all data are set.
536  */
537 static int
538 task_data_setup(struct spdk_vhost_scsi_task *task,
539 		struct virtio_scsi_cmd_req **req)
540 {
541 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
542 	struct vring_desc *desc, *desc_table;
543 	struct iovec *iovs = task->iovs;
544 	uint16_t iovcnt = 0;
545 	uint32_t desc_table_len, len = 0;
546 	int rc;
547 
548 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_cpl, vhost_scsi_task_free_cb);
549 
550 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table, &desc_table_len);
551 	/* First descriptor must be readable */
552 	if (spdk_unlikely(rc != 0  || vhost_vring_desc_is_wr(desc) ||
553 			  desc->len < sizeof(struct virtio_scsi_cmd_req))) {
554 		SPDK_WARNLOG("%s: invalid first request descriptor at index %"PRIu16".\n",
555 			     vsession->name, task->req_idx);
556 		goto invalid_task;
557 	}
558 
559 	*req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(**req));
560 	if (spdk_unlikely(*req == NULL)) {
561 		SPDK_WARNLOG("%s: request descriptor at index %d points to invalid guest memory region\n",
562 			     vsession->name, task->req_idx);
563 		goto invalid_task;
564 	}
565 
566 	/* Each request must have at least 2 descriptors (e.g. request and response) */
567 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
568 	if (desc == NULL) {
569 		SPDK_WARNLOG("%s: descriptor chain at index %d contains neither payload nor response buffer.\n",
570 			     vsession->name, task->req_idx);
571 		goto invalid_task;
572 	}
573 	task->scsi.dxfer_dir = vhost_vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV :
574 			       SPDK_SCSI_DIR_TO_DEV;
575 	task->scsi.iovs = iovs;
576 
577 	if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
578 		/*
579 		 * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN]
580 		 */
581 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
582 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
583 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
584 				     vsession->name, task->req_idx);
585 			goto invalid_task;
586 		}
587 		rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
588 		if (spdk_unlikely(rc != 0)) {
589 			SPDK_WARNLOG("%s: invalid descriptor chain at request index %d (descriptor id overflow?).\n",
590 				     vsession->name, task->req_idx);
591 			goto invalid_task;
592 		}
593 
594 		if (desc == NULL) {
595 			/*
596 			 * TEST UNIT READY command and some others might not contain any payload and this is not an error.
597 			 */
598 			SPDK_DEBUGLOG(vhost_scsi_data,
599 				      "No payload descriptors for FROM DEV command req_idx=%"PRIu16".\n", task->req_idx);
600 			SPDK_LOGDUMP(vhost_scsi_data, "CDB=", (*req)->cdb, VIRTIO_SCSI_CDB_SIZE);
601 			task->used_len = sizeof(struct virtio_scsi_cmd_resp);
602 			task->scsi.iovcnt = 1;
603 			task->scsi.iovs[0].iov_len = 0;
604 			task->scsi.length = 0;
605 			task->scsi.transfer_len = 0;
606 			return 0;
607 		}
608 
609 		/* All remaining descriptors are data. */
610 		while (desc) {
611 			if (spdk_unlikely(!vhost_vring_desc_is_wr(desc))) {
612 				SPDK_WARNLOG("%s: FROM DEV cmd: descriptor nr %" PRIu16" in payload chain is read only.\n",
613 					     vsession->name, iovcnt);
614 				goto invalid_task;
615 			}
616 
617 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
618 				goto invalid_task;
619 			}
620 			len += desc->len;
621 
622 			rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
623 			if (spdk_unlikely(rc != 0)) {
624 				SPDK_WARNLOG("%s: invalid payload in descriptor chain starting at index %d.\n",
625 					     vsession->name, task->req_idx);
626 				goto invalid_task;
627 			}
628 		}
629 
630 		task->used_len = sizeof(struct virtio_scsi_cmd_resp) + len;
631 	} else {
632 		SPDK_DEBUGLOG(vhost_scsi_data, "TO DEV");
633 		/*
634 		 * TO_DEV (WRITE):[RD_req][RD_buf0]...[RD_bufN][WR_resp]
635 		 * No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir.
636 		 */
637 
638 		/* Process descriptors up to response. */
639 		while (!vhost_vring_desc_is_wr(desc)) {
640 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
641 				goto invalid_task;
642 			}
643 			len += desc->len;
644 
645 			vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
646 			if (spdk_unlikely(desc == NULL)) {
647 				SPDK_WARNLOG("%s: TO_DEV cmd: no response descriptor.\n", vsession->name);
648 				goto invalid_task;
649 			}
650 		}
651 
652 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
653 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
654 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
655 				     vsession->name, task->req_idx);
656 			goto invalid_task;
657 		}
658 
659 		task->used_len = sizeof(struct virtio_scsi_cmd_resp);
660 	}
661 
662 	task->scsi.iovcnt = iovcnt;
663 	task->scsi.length = len;
664 	task->scsi.transfer_len = len;
665 	return 0;
666 
667 invalid_task:
668 	SPDK_DEBUGLOG(vhost_scsi_data, "%s: Invalid task at index %"PRIu16".\n",
669 		      vsession->name, task->req_idx);
670 	return -1;
671 }
672 
673 static int
674 process_request(struct spdk_vhost_scsi_task *task)
675 {
676 	struct virtio_scsi_cmd_req *req;
677 	int result;
678 
679 	result = task_data_setup(task, &req);
680 	if (result) {
681 		return result;
682 	}
683 
684 	result = vhost_scsi_task_init_target(task, req->lun);
685 	if (spdk_unlikely(result != 0)) {
686 		task->resp->response = VIRTIO_SCSI_S_BAD_TARGET;
687 		return -1;
688 	}
689 
690 	task->scsi.cdb = req->cdb;
691 	SPDK_LOGDUMP(vhost_scsi_data, "request CDB", req->cdb, VIRTIO_SCSI_CDB_SIZE);
692 
693 	if (spdk_unlikely(task->scsi.lun == NULL)) {
694 		spdk_scsi_task_process_null_lun(&task->scsi);
695 		task->resp->response = VIRTIO_SCSI_S_OK;
696 		return 1;
697 	}
698 
699 	return 0;
700 }
701 
702 static void
703 process_scsi_task(struct spdk_vhost_session *vsession,
704 		  struct spdk_vhost_virtqueue *vq,
705 		  uint16_t req_idx)
706 {
707 	struct spdk_vhost_scsi_task *task;
708 	int result;
709 
710 	task = &((struct spdk_vhost_scsi_task *)vq->tasks)[req_idx];
711 	if (spdk_unlikely(task->used)) {
712 		SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
713 			    vsession->name, req_idx);
714 		vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
715 		return;
716 	}
717 
718 	vsession->task_cnt++;
719 	scsi_task_init(task);
720 
721 	if (spdk_unlikely(vq->vring_idx == VIRTIO_SCSI_CONTROLQ)) {
722 		process_ctrl_request(task);
723 	} else {
724 		result = process_request(task);
725 		if (likely(result == 0)) {
726 			task_submit(task);
727 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d submitted ======\n", task,
728 				      task->req_idx);
729 		} else if (result > 0) {
730 			vhost_scsi_task_cpl(&task->scsi);
731 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d finished early ======\n", task,
732 				      task->req_idx);
733 		} else {
734 			invalid_request(task);
735 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d failed ======\n", task,
736 				      task->req_idx);
737 		}
738 	}
739 }
740 
741 static void
742 submit_inflight_desc(struct spdk_vhost_scsi_session *svsession,
743 		     struct spdk_vhost_virtqueue *vq)
744 {
745 	struct spdk_vhost_session *vsession;
746 	spdk_vhost_resubmit_info *resubmit;
747 	spdk_vhost_resubmit_desc *resubmit_list;
748 	uint16_t req_idx;
749 	int i;
750 
751 	resubmit = vq->vring_inflight.resubmit_inflight;
752 	if (spdk_likely(resubmit == NULL || resubmit->resubmit_list == NULL ||
753 			resubmit->resubmit_num == 0)) {
754 		return;
755 	}
756 
757 	resubmit_list = resubmit->resubmit_list;
758 	vsession = &svsession->vsession;
759 
760 	for (i = resubmit->resubmit_num - 1; i >= 0; --i) {
761 		req_idx = resubmit_list[resubmit->resubmit_num].index;
762 		SPDK_DEBUGLOG(vhost_scsi, "====== Start processing resubmit request idx %"PRIu16"======\n",
763 			      req_idx);
764 
765 		if (spdk_unlikely(req_idx >= vq->vring.size)) {
766 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
767 				    vsession->name, req_idx, vq->vring.size);
768 			vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
769 			continue;
770 		}
771 
772 		process_scsi_task(vsession, vq, req_idx);
773 	}
774 
775 	resubmit->resubmit_num = 0;
776 }
777 
778 static void
779 process_vq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
780 {
781 	struct spdk_vhost_session *vsession = &svsession->vsession;
782 	uint16_t reqs[32];
783 	uint16_t reqs_cnt, i;
784 
785 	submit_inflight_desc(svsession, vq);
786 
787 	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
788 	assert(reqs_cnt <= 32);
789 
790 	for (i = 0; i < reqs_cnt; i++) {
791 		SPDK_DEBUGLOG(vhost_scsi, "====== Starting processing request idx %"PRIu16"======\n",
792 			      reqs[i]);
793 
794 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
795 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
796 				    vsession->name, reqs[i], vq->vring.size);
797 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
798 			continue;
799 		}
800 
801 		rte_vhost_set_inflight_desc_split(vsession->vid, vq->vring_idx, reqs[i]);
802 
803 		process_scsi_task(vsession, vq, reqs[i]);
804 	}
805 }
806 
807 static int
808 vdev_mgmt_worker(void *arg)
809 {
810 	struct spdk_vhost_scsi_session *svsession = arg;
811 	struct spdk_vhost_session *vsession = &svsession->vsession;
812 
813 	process_removed_devs(svsession);
814 
815 	if (vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) {
816 		vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
817 	}
818 
819 	if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc) {
820 		process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
821 		vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
822 	}
823 
824 	return SPDK_POLLER_BUSY;
825 }
826 
827 static int
828 vdev_worker(void *arg)
829 {
830 	struct spdk_vhost_scsi_session *svsession = arg;
831 	struct spdk_vhost_session *vsession = &svsession->vsession;
832 	uint32_t q_idx;
833 
834 	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
835 		process_vq(svsession, &vsession->virtqueue[q_idx]);
836 	}
837 
838 	vhost_session_used_signal(vsession);
839 
840 	return SPDK_POLLER_BUSY;
841 }
842 
843 static struct spdk_vhost_scsi_dev *
844 to_scsi_dev(struct spdk_vhost_dev *ctrlr)
845 {
846 	if (ctrlr == NULL) {
847 		return NULL;
848 	}
849 
850 	if (ctrlr->backend != &spdk_vhost_scsi_device_backend) {
851 		SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name);
852 		return NULL;
853 	}
854 
855 	return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev);
856 }
857 
858 static struct spdk_vhost_scsi_session *
859 to_scsi_session(struct spdk_vhost_session *vsession)
860 {
861 	assert(vsession->vdev->backend == &spdk_vhost_scsi_device_backend);
862 	return (struct spdk_vhost_scsi_session *)vsession;
863 }
864 
865 int
866 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask)
867 {
868 	struct spdk_vhost_scsi_dev *svdev = calloc(1, sizeof(*svdev));
869 	int rc;
870 
871 	if (svdev == NULL) {
872 		return -ENOMEM;
873 	}
874 
875 	svdev->vdev.virtio_features = SPDK_VHOST_SCSI_FEATURES;
876 	svdev->vdev.disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES;
877 	svdev->vdev.protocol_features = SPDK_VHOST_SCSI_PROTOCOL_FEATURES;
878 
879 	spdk_vhost_lock();
880 	rc = vhost_dev_register(&svdev->vdev, name, cpumask,
881 				&spdk_vhost_scsi_device_backend,
882 				&spdk_vhost_scsi_user_device_backend);
883 
884 	if (rc) {
885 		free(svdev);
886 		spdk_vhost_unlock();
887 		return rc;
888 	}
889 
890 	svdev->registered = true;
891 
892 	spdk_vhost_unlock();
893 	return rc;
894 }
895 
896 static int
897 vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
898 {
899 	struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev);
900 	struct spdk_vhost_user_dev *user_dev = vdev->ctxt;
901 	int rc, i;
902 
903 	if (user_dev->pending_async_op_num) {
904 		return -EBUSY;
905 	}
906 
907 	assert(svdev != NULL);
908 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
909 		if (svdev->scsi_dev_state[i].dev) {
910 			if (vdev->registered) {
911 				SPDK_ERRLOG("%s: SCSI target %d is still present.\n", vdev->name, i);
912 				return -EBUSY;
913 			}
914 
915 			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);
916 			if (rc != 0) {
917 				SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i);
918 				return rc;
919 			}
920 		}
921 	}
922 
923 	rc = vhost_dev_unregister(vdev);
924 	if (rc != 0) {
925 		return rc;
926 	}
927 	svdev->registered = false;
928 
929 	if (svdev->ref == 0) {
930 		free(svdev);
931 	}
932 
933 	return 0;
934 }
935 
936 struct spdk_scsi_dev *
937 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num)
938 {
939 	struct spdk_vhost_scsi_dev *svdev;
940 
941 	assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
942 	svdev = to_scsi_dev(vdev);
943 	assert(svdev != NULL);
944 	if (svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) {
945 		return NULL;
946 	}
947 
948 	assert(svdev->scsi_dev_state[num].dev != NULL);
949 	return svdev->scsi_dev_state[num].dev;
950 }
951 
952 static unsigned
953 get_scsi_dev_num(const struct spdk_vhost_scsi_dev *svdev,
954 		 const struct spdk_scsi_lun *lun)
955 {
956 	const struct spdk_scsi_dev *scsi_dev;
957 	unsigned scsi_dev_num;
958 
959 	assert(lun != NULL);
960 	assert(svdev != NULL);
961 	scsi_dev = spdk_scsi_lun_get_dev(lun);
962 	for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) {
963 		if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) {
964 			break;
965 		}
966 	}
967 
968 	return scsi_dev_num;
969 }
970 
971 static void
972 vhost_scsi_lun_resize(const struct spdk_scsi_lun *lun, void *arg)
973 {
974 	struct spdk_vhost_scsi_dev *svdev = arg;
975 	unsigned scsi_dev_num;
976 
977 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
978 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
979 		/* The entire device has been already removed. */
980 		return;
981 	}
982 
983 	vhost_scsi_dev_param_changed(&svdev->vdev, scsi_dev_num);
984 }
985 
986 static void
987 vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
988 {
989 	struct spdk_vhost_scsi_dev *svdev = arg;
990 	unsigned scsi_dev_num;
991 
992 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
993 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
994 		/* The entire device has been already removed. */
995 		return;
996 	}
997 
998 	/* remove entire device */
999 	spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL);
1000 }
1001 
1002 static void
1003 vhost_scsi_dev_add_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
1004 {
1005 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1006 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1007 					    struct spdk_vhost_scsi_dev, vdev);
1008 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1009 
1010 	vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num];
1011 
1012 	/* All sessions have added the target */
1013 	assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING);
1014 	vhost_sdev->status = VHOST_SCSI_DEV_PRESENT;
1015 	svdev->ref++;
1016 }
1017 
1018 static int
1019 vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev,
1020 			   struct spdk_vhost_session *vsession, void *ctx)
1021 {
1022 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1023 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1024 	struct spdk_scsi_dev_session_state *session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];
1025 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1026 	int rc;
1027 
1028 	if (!vsession->started || session_sdev->dev != NULL) {
1029 		/* Nothing to do. */
1030 		return 0;
1031 	}
1032 
1033 	vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num];
1034 	session_sdev->dev = vhost_sdev->dev;
1035 	session_sdev->status = VHOST_SCSI_DEV_PRESENT;
1036 
1037 	rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev);
1038 	if (rc != 0) {
1039 		SPDK_ERRLOG("%s: Couldn't allocate io channel for SCSI target %u.\n",
1040 			    vsession->name, scsi_tgt_num);
1041 
1042 		/* unset the SCSI target so that all I/O to it will be rejected */
1043 		session_sdev->dev = NULL;
1044 		/* Set status to EMPTY so that we won't reply with SCSI hotremove
1045 		 * sense codes - the device hasn't ever been added.
1046 		 */
1047 		session_sdev->status = VHOST_SCSI_DEV_EMPTY;
1048 
1049 		/* Return with no error. We'll continue allocating io_channels for
1050 		 * other sessions on this device in hopes they succeed. The sessions
1051 		 * that failed to allocate io_channels simply won't be able to
1052 		 * detect the SCSI target, nor do any I/O to it.
1053 		 */
1054 		return 0;
1055 	}
1056 
1057 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1058 		eventq_enqueue(svsession, scsi_tgt_num,
1059 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN);
1060 	} else {
1061 		SPDK_NOTICELOG("%s: driver does not support hotplug. "
1062 			       "Please restart it or perform a rescan.\n",
1063 			       vsession->name);
1064 	}
1065 
1066 	return 0;
1067 }
1068 
1069 int
1070 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num,
1071 			    const char *bdev_name)
1072 {
1073 	struct spdk_vhost_scsi_dev *svdev;
1074 	struct spdk_scsi_dev_vhost_state *state;
1075 	char target_name[SPDK_SCSI_DEV_MAX_NAME];
1076 	int lun_id_list[1];
1077 	const char *bdev_names_list[1];
1078 
1079 	svdev = to_scsi_dev(vdev);
1080 	if (!svdev) {
1081 		SPDK_ERRLOG("Before adding a SCSI target, there should be a SCSI device.");
1082 		return -EINVAL;
1083 	}
1084 
1085 	if (scsi_tgt_num < 0) {
1086 		for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) {
1087 			if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) {
1088 				break;
1089 			}
1090 		}
1091 
1092 		if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1093 			SPDK_ERRLOG("%s: all SCSI target slots are already in use.\n", vdev->name);
1094 			return -ENOSPC;
1095 		}
1096 	} else {
1097 		if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1098 			SPDK_ERRLOG("%s: SCSI target number is too big (got %d, max %d), started from 0.\n",
1099 				    vdev->name, scsi_tgt_num, SPDK_VHOST_SCSI_CTRLR_MAX_DEVS - 1);
1100 			return -EINVAL;
1101 		}
1102 	}
1103 
1104 	if (bdev_name == NULL) {
1105 		SPDK_ERRLOG("No lun name specified\n");
1106 		return -EINVAL;
1107 	}
1108 
1109 	state = &svdev->scsi_dev_state[scsi_tgt_num];
1110 	if (state->dev != NULL) {
1111 		SPDK_ERRLOG("%s: SCSI target %u already occupied\n", vdev->name, scsi_tgt_num);
1112 		return -EEXIST;
1113 	}
1114 
1115 	/*
1116 	 * At this stage only one LUN per target
1117 	 */
1118 	snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num);
1119 	lun_id_list[0] = 0;
1120 	bdev_names_list[0] = (char *)bdev_name;
1121 
1122 	state->status = VHOST_SCSI_DEV_ADDING;
1123 	state->dev = spdk_scsi_dev_construct_ext(target_name, bdev_names_list, lun_id_list, 1,
1124 			SPDK_SPC_PROTOCOL_IDENTIFIER_SAS,
1125 			vhost_scsi_lun_resize, svdev,
1126 			vhost_scsi_lun_hotremove, svdev);
1127 
1128 	if (state->dev == NULL) {
1129 		state->status = VHOST_SCSI_DEV_EMPTY;
1130 		SPDK_ERRLOG("%s: couldn't create SCSI target %u using bdev '%s'\n",
1131 			    vdev->name, scsi_tgt_num, bdev_name);
1132 		return -EINVAL;
1133 	}
1134 	spdk_scsi_dev_add_port(state->dev, 0, "vhost");
1135 
1136 	SPDK_INFOLOG(vhost, "%s: added SCSI target %u using bdev '%s'\n",
1137 		     vdev->name, scsi_tgt_num, bdev_name);
1138 
1139 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
1140 				       vhost_scsi_dev_add_tgt_cpl_cb,
1141 				       (void *)(uintptr_t)scsi_tgt_num);
1142 	return scsi_tgt_num;
1143 }
1144 
1145 struct scsi_tgt_hotplug_ctx {
1146 	unsigned scsi_tgt_num;
1147 	bool async_fini;
1148 };
1149 
1150 static void
1151 vhost_scsi_dev_remove_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *_ctx)
1152 {
1153 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1154 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1155 					    struct spdk_vhost_scsi_dev, vdev);
1156 
1157 	if (!ctx->async_fini) {
1158 		/* there aren't any active sessions, so remove the dev and exit */
1159 		remove_scsi_tgt(svdev, ctx->scsi_tgt_num);
1160 	}
1161 
1162 	free(ctx);
1163 }
1164 
1165 static int
1166 vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev,
1167 			      struct spdk_vhost_session *vsession, void *_ctx)
1168 {
1169 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1170 	unsigned scsi_tgt_num = ctx->scsi_tgt_num;
1171 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1172 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1173 
1174 	if (!vsession->started || state->dev == NULL) {
1175 		/* Nothing to do */
1176 		return 0;
1177 	}
1178 
1179 	/* Mark the target for removal */
1180 	assert(state->status == VHOST_SCSI_DEV_PRESENT);
1181 	state->status = VHOST_SCSI_DEV_REMOVING;
1182 
1183 	/* Send a hotremove virtio event */
1184 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1185 		eventq_enqueue(svsession, scsi_tgt_num,
1186 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED);
1187 	}
1188 
1189 	/* Wait for the session's management poller to remove the target after
1190 	 * all its pending I/O has finished.
1191 	 */
1192 	ctx->async_fini = true;
1193 	return 0;
1194 }
1195 
1196 int
1197 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
1198 			       spdk_vhost_event_fn cb_fn, void *cb_arg)
1199 {
1200 	struct spdk_vhost_scsi_dev *svdev;
1201 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1202 	struct scsi_tgt_hotplug_ctx *ctx;
1203 
1204 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1205 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1206 		return -EINVAL;
1207 	}
1208 
1209 	svdev = to_scsi_dev(vdev);
1210 	if (!svdev) {
1211 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1212 		return -EINVAL;
1213 	}
1214 
1215 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1216 
1217 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1218 		return -EBUSY;
1219 	}
1220 
1221 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1222 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1223 		return -ENODEV;
1224 	}
1225 
1226 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1227 	ctx = calloc(1, sizeof(*ctx));
1228 	if (ctx == NULL) {
1229 		SPDK_ERRLOG("calloc failed\n");
1230 		return -ENOMEM;
1231 	}
1232 
1233 	ctx->scsi_tgt_num = scsi_tgt_num;
1234 	ctx->async_fini = false;
1235 
1236 	scsi_dev_state->remove_cb = cb_fn;
1237 	scsi_dev_state->remove_ctx = cb_arg;
1238 	scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING;
1239 
1240 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
1241 				       vhost_scsi_dev_remove_tgt_cpl_cb, ctx);
1242 	return 0;
1243 }
1244 
1245 static int
1246 vhost_scsi_session_param_changed(struct spdk_vhost_dev *vdev,
1247 				 struct spdk_vhost_session *vsession, void *ctx)
1248 {
1249 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1250 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1251 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1252 
1253 	if (!vsession->started || state->dev == NULL) {
1254 		/* Nothing to do */
1255 		return 0;
1256 	}
1257 
1258 	/* Send a parameter change virtio event */
1259 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_CHANGE)) {
1260 		/*
1261 		 * virtio 1.0 spec says:
1262 		 * By sending this event, the device signals a change in the configuration
1263 		 * parameters of a logical unit, for example the capacity or cache mode.
1264 		 * event is set to VIRTIO_SCSI_T_PARAM_CHANGE. lun addresses a logical unit
1265 		 * in the SCSI host. The same event SHOULD also be reported as a unit
1266 		 * attention condition. reason contains the additional sense code and
1267 		 * additional sense code qualifier, respectively in bits 0…7 and 8…15.
1268 		 * Note: For example, a change in * capacity will be reported as asc
1269 		 * 0x2a, ascq 0x09 (CAPACITY DATA HAS CHANGED).
1270 		 */
1271 		eventq_enqueue(svsession, scsi_tgt_num, VIRTIO_SCSI_T_PARAM_CHANGE, 0x2a | (0x09 << 8));
1272 	}
1273 
1274 	return 0;
1275 }
1276 
1277 static int
1278 vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num)
1279 {
1280 	struct spdk_vhost_scsi_dev *svdev;
1281 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1282 
1283 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1284 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1285 		return -EINVAL;
1286 	}
1287 
1288 	svdev = to_scsi_dev(vdev);
1289 	if (!svdev) {
1290 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1291 		return -EINVAL;
1292 	}
1293 
1294 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1295 
1296 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1297 		return -EBUSY;
1298 	}
1299 
1300 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1301 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1302 		return -ENODEV;
1303 	}
1304 
1305 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1306 
1307 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_param_changed,
1308 				       NULL, (void *)(uintptr_t)scsi_tgt_num);
1309 	return 0;
1310 }
1311 
1312 static void
1313 free_task_pool(struct spdk_vhost_scsi_session *svsession)
1314 {
1315 	struct spdk_vhost_session *vsession = &svsession->vsession;
1316 	struct spdk_vhost_virtqueue *vq;
1317 	uint16_t i;
1318 
1319 	for (i = 0; i < vsession->max_queues; i++) {
1320 		vq = &vsession->virtqueue[i];
1321 		if (vq->tasks == NULL) {
1322 			continue;
1323 		}
1324 
1325 		spdk_free(vq->tasks);
1326 		vq->tasks = NULL;
1327 	}
1328 }
1329 
1330 static int
1331 alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
1332 {
1333 	struct spdk_vhost_session *vsession = &svsession->vsession;
1334 	struct spdk_vhost_virtqueue *vq;
1335 	struct spdk_vhost_scsi_task *task;
1336 	uint32_t task_cnt;
1337 	uint16_t i;
1338 	uint32_t j;
1339 
1340 	for (i = 0; i < vsession->max_queues; i++) {
1341 		vq = &vsession->virtqueue[i];
1342 		if (vq->vring.desc == NULL) {
1343 			continue;
1344 		}
1345 
1346 		task_cnt = vq->vring.size;
1347 		if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
1348 			/* sanity check */
1349 			SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
1350 				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
1351 			free_task_pool(svsession);
1352 			return -1;
1353 		}
1354 		vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
1355 					 SPDK_CACHE_LINE_SIZE, NULL,
1356 					 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
1357 		if (vq->tasks == NULL) {
1358 			SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
1359 				    vsession->name, task_cnt, i);
1360 			free_task_pool(svsession);
1361 			return -1;
1362 		}
1363 
1364 		for (j = 0; j < task_cnt; j++) {
1365 			task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
1366 			task->svsession = svsession;
1367 			task->vq = vq;
1368 			task->req_idx = j;
1369 		}
1370 	}
1371 
1372 	return 0;
1373 }
1374 
1375 static int
1376 vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
1377 		    struct spdk_vhost_session *vsession, void *unused)
1378 {
1379 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1380 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1381 	struct spdk_scsi_dev_vhost_state *state;
1382 	uint32_t i;
1383 	int rc;
1384 
1385 	/* validate all I/O queues are in a contiguous index range */
1386 	for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) {
1387 		if (vsession->virtqueue[i].vring.desc == NULL) {
1388 			SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->name, i);
1389 			rc = -1;
1390 			goto out;
1391 		}
1392 	}
1393 
1394 	rc = alloc_task_pool(svsession);
1395 	if (rc != 0) {
1396 		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
1397 		goto out;
1398 	}
1399 
1400 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1401 		state = &svdev->scsi_dev_state[i];
1402 		if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {
1403 			continue;
1404 		}
1405 
1406 		assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY);
1407 		svsession->scsi_dev_state[i].dev = state->dev;
1408 		svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT;
1409 		rc = spdk_scsi_dev_allocate_io_channels(state->dev);
1410 		if (rc != 0) {
1411 			SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n",
1412 				    vsession->name, i);
1413 			/* unset the SCSI target so that all I/O to it will be rejected */
1414 			svsession->scsi_dev_state[i].dev = NULL;
1415 			/* set EMPTY state so that we won't reply with SCSI hotremove
1416 			 * sense codes - the device hasn't ever been added.
1417 			 */
1418 			svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY;
1419 			continue;
1420 		}
1421 	}
1422 	SPDK_INFOLOG(vhost, "%s: started poller on lcore %d\n",
1423 		     vsession->name, spdk_env_get_current_core());
1424 
1425 	svsession->requestq_poller = SPDK_POLLER_REGISTER(vdev_worker, svsession, 0);
1426 	svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession,
1427 				 MGMT_POLL_PERIOD_US);
1428 out:
1429 	vhost_user_session_start_done(vsession, rc);
1430 	return rc;
1431 }
1432 
1433 static int
1434 vhost_scsi_start(struct spdk_vhost_session *vsession)
1435 {
1436 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1437 	struct spdk_vhost_scsi_dev *svdev;
1438 
1439 	svdev = to_scsi_dev(vsession->vdev);
1440 	assert(svdev != NULL);
1441 	svsession->svdev = svdev;
1442 
1443 	return vhost_user_session_send_event(vsession, vhost_scsi_start_cb,
1444 					     3, "start session");
1445 }
1446 
1447 static int
1448 destroy_session_poller_cb(void *arg)
1449 {
1450 	struct spdk_vhost_scsi_session *svsession = arg;
1451 	struct spdk_vhost_session *vsession = &svsession->vsession;
1452 	struct spdk_scsi_dev_session_state *state;
1453 	uint32_t i;
1454 
1455 	if (vsession->task_cnt > 0 || spdk_vhost_trylock() != 0) {
1456 		assert(vsession->stop_retry_count > 0);
1457 		vsession->stop_retry_count--;
1458 		if (vsession->stop_retry_count == 0) {
1459 			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
1460 				    vsession->task_cnt);
1461 			spdk_poller_unregister(&svsession->stop_poller);
1462 			vhost_user_session_stop_done(vsession, -ETIMEDOUT);
1463 		}
1464 
1465 		return SPDK_POLLER_BUSY;
1466 	}
1467 
1468 	for (i = 0; i < vsession->max_queues; i++) {
1469 		vhost_vq_used_signal(vsession, &vsession->virtqueue[i]);
1470 	}
1471 
1472 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1473 		enum spdk_scsi_dev_vhost_status prev_status;
1474 
1475 		state = &svsession->scsi_dev_state[i];
1476 		/* clear the REMOVED status so that we won't send hotremove events anymore */
1477 		prev_status = state->status;
1478 		state->status = VHOST_SCSI_DEV_EMPTY;
1479 		if (state->dev == NULL) {
1480 			continue;
1481 		}
1482 
1483 		spdk_scsi_dev_free_io_channels(state->dev);
1484 
1485 		state->dev = NULL;
1486 
1487 		if (prev_status == VHOST_SCSI_DEV_REMOVING) {
1488 			/* try to detach it globally */
1489 			vhost_user_dev_foreach_session(vsession->vdev,
1490 						       vhost_scsi_session_process_removed,
1491 						       vhost_scsi_dev_process_removed_cpl_cb,
1492 						       (void *)(uintptr_t)i);
1493 		}
1494 	}
1495 
1496 	SPDK_INFOLOG(vhost, "%s: stopping poller on lcore %d\n",
1497 		     vsession->name, spdk_env_get_current_core());
1498 
1499 	free_task_pool(svsession);
1500 
1501 	spdk_poller_unregister(&svsession->stop_poller);
1502 	vhost_user_session_stop_done(vsession, 0);
1503 
1504 	spdk_vhost_unlock();
1505 	return SPDK_POLLER_BUSY;
1506 }
1507 
1508 static int
1509 vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
1510 		   struct spdk_vhost_session *vsession, void *unused)
1511 {
1512 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1513 
1514 	/* Stop receiving new I/O requests */
1515 	spdk_poller_unregister(&svsession->requestq_poller);
1516 
1517 	/* Stop receiving controlq requests, also stop processing the
1518 	 * asynchronous hotremove events. All the remaining events
1519 	 * will be finalized by the stop_poller below.
1520 	 */
1521 	spdk_poller_unregister(&svsession->mgmt_poller);
1522 
1523 	/* vhost_user_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
1524 	svsession->vsession.stop_retry_count = 4000;
1525 
1526 	/* Wait for all pending I/Os to complete, then process all the
1527 	 * remaining hotremove events one last time.
1528 	 */
1529 	svsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb,
1530 				 svsession, 1000);
1531 
1532 	return 0;
1533 }
1534 
1535 static int
1536 vhost_scsi_stop(struct spdk_vhost_session *vsession)
1537 {
1538 	return vhost_user_session_send_event(vsession, vhost_scsi_stop_cb,
1539 					     3, "stop session");
1540 }
1541 
1542 static void
1543 vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1544 {
1545 	struct spdk_scsi_dev *sdev;
1546 	struct spdk_scsi_lun *lun;
1547 	uint32_t dev_idx;
1548 
1549 	assert(vdev != NULL);
1550 	spdk_json_write_named_array_begin(w, "scsi");
1551 	for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) {
1552 		sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx);
1553 		if (!sdev) {
1554 			continue;
1555 		}
1556 
1557 		spdk_json_write_object_begin(w);
1558 
1559 		spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx);
1560 
1561 		spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev));
1562 
1563 		spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev));
1564 
1565 		spdk_json_write_named_array_begin(w, "luns");
1566 
1567 		for (lun = spdk_scsi_dev_get_first_lun(sdev); lun != NULL;
1568 		     lun = spdk_scsi_dev_get_next_lun(lun)) {
1569 			spdk_json_write_object_begin(w);
1570 
1571 			spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun));
1572 
1573 			spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1574 
1575 			spdk_json_write_object_end(w);
1576 		}
1577 
1578 		spdk_json_write_array_end(w);
1579 		spdk_json_write_object_end(w);
1580 	}
1581 
1582 	spdk_json_write_array_end(w);
1583 }
1584 
1585 static void
1586 vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1587 {
1588 	struct spdk_scsi_dev *scsi_dev;
1589 	struct spdk_scsi_lun *lun;
1590 	uint32_t i;
1591 
1592 	spdk_json_write_object_begin(w);
1593 	spdk_json_write_named_string(w, "method", "vhost_create_scsi_controller");
1594 
1595 	spdk_json_write_named_object_begin(w, "params");
1596 	spdk_json_write_named_string(w, "ctrlr", vdev->name);
1597 	spdk_json_write_named_string(w, "cpumask",
1598 				     spdk_cpuset_fmt(spdk_thread_get_cpumask(vdev->thread)));
1599 	spdk_json_write_object_end(w);
1600 
1601 	spdk_json_write_object_end(w);
1602 
1603 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1604 		scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i);
1605 		if (scsi_dev == NULL) {
1606 			continue;
1607 		}
1608 
1609 		lun = spdk_scsi_dev_get_lun(scsi_dev, 0);
1610 		assert(lun != NULL);
1611 
1612 		spdk_json_write_object_begin(w);
1613 		spdk_json_write_named_string(w, "method", "vhost_scsi_controller_add_target");
1614 
1615 		spdk_json_write_named_object_begin(w, "params");
1616 		spdk_json_write_named_string(w, "ctrlr", vdev->name);
1617 		spdk_json_write_named_uint32(w, "scsi_target_num", i);
1618 
1619 		spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1620 		spdk_json_write_object_end(w);
1621 
1622 		spdk_json_write_object_end(w);
1623 	}
1624 }
1625 
1626 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi)
1627 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_queue)
1628 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_data)
1629