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