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 vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]); 811 812 process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); 813 vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); 814 815 return SPDK_POLLER_BUSY; 816 } 817 818 static int 819 vdev_worker(void *arg) 820 { 821 struct spdk_vhost_scsi_session *svsession = arg; 822 struct spdk_vhost_session *vsession = &svsession->vsession; 823 uint32_t q_idx; 824 825 for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) { 826 process_vq(svsession, &vsession->virtqueue[q_idx]); 827 } 828 829 vhost_session_used_signal(vsession); 830 831 return SPDK_POLLER_BUSY; 832 } 833 834 static struct spdk_vhost_scsi_dev * 835 to_scsi_dev(struct spdk_vhost_dev *ctrlr) 836 { 837 if (ctrlr == NULL) { 838 return NULL; 839 } 840 841 if (ctrlr->backend != &spdk_vhost_scsi_device_backend) { 842 SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name); 843 return NULL; 844 } 845 846 return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev); 847 } 848 849 static struct spdk_vhost_scsi_session * 850 to_scsi_session(struct spdk_vhost_session *vsession) 851 { 852 assert(vsession->vdev->backend == &spdk_vhost_scsi_device_backend); 853 return (struct spdk_vhost_scsi_session *)vsession; 854 } 855 856 int 857 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask) 858 { 859 struct spdk_vhost_scsi_dev *svdev = calloc(1, sizeof(*svdev)); 860 int rc; 861 862 if (svdev == NULL) { 863 return -ENOMEM; 864 } 865 866 svdev->vdev.virtio_features = SPDK_VHOST_SCSI_FEATURES; 867 svdev->vdev.disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES; 868 svdev->vdev.protocol_features = SPDK_VHOST_SCSI_PROTOCOL_FEATURES; 869 870 spdk_vhost_lock(); 871 rc = vhost_dev_register(&svdev->vdev, name, cpumask, 872 &spdk_vhost_scsi_device_backend); 873 874 if (rc) { 875 free(svdev); 876 spdk_vhost_unlock(); 877 return rc; 878 } 879 880 svdev->registered = true; 881 882 spdk_vhost_unlock(); 883 return rc; 884 } 885 886 static int 887 vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev) 888 { 889 struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev); 890 int rc, i; 891 892 assert(svdev != NULL); 893 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) { 894 if (svdev->scsi_dev_state[i].dev) { 895 if (vdev->registered) { 896 SPDK_ERRLOG("%s: SCSI target %d is still present.\n", vdev->name, i); 897 return -EBUSY; 898 } 899 900 rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL); 901 if (rc != 0) { 902 SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i); 903 return rc; 904 } 905 } 906 } 907 908 rc = vhost_dev_unregister(vdev); 909 if (rc != 0) { 910 return rc; 911 } 912 svdev->registered = false; 913 914 if (svdev->ref == 0) { 915 free(svdev); 916 } 917 918 return 0; 919 } 920 921 struct spdk_scsi_dev * 922 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num) 923 { 924 struct spdk_vhost_scsi_dev *svdev; 925 926 assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); 927 svdev = to_scsi_dev(vdev); 928 assert(svdev != NULL); 929 if (svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) { 930 return NULL; 931 } 932 933 assert(svdev->scsi_dev_state[num].dev != NULL); 934 return svdev->scsi_dev_state[num].dev; 935 } 936 937 static unsigned 938 get_scsi_dev_num(const struct spdk_vhost_scsi_dev *svdev, 939 const struct spdk_scsi_lun *lun) 940 { 941 const struct spdk_scsi_dev *scsi_dev; 942 unsigned scsi_dev_num; 943 944 assert(lun != NULL); 945 assert(svdev != NULL); 946 scsi_dev = spdk_scsi_lun_get_dev(lun); 947 for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) { 948 if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) { 949 break; 950 } 951 } 952 953 return scsi_dev_num; 954 } 955 956 static void 957 vhost_scsi_lun_resize(const struct spdk_scsi_lun *lun, void *arg) 958 { 959 struct spdk_vhost_scsi_dev *svdev = arg; 960 unsigned scsi_dev_num; 961 962 scsi_dev_num = get_scsi_dev_num(svdev, lun); 963 if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 964 /* The entire device has been already removed. */ 965 return; 966 } 967 968 vhost_scsi_dev_param_changed(&svdev->vdev, scsi_dev_num); 969 } 970 971 static void 972 vhost_scsi_lun_hotremove(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 /* remove entire device */ 984 spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL); 985 } 986 987 static void 988 vhost_scsi_dev_add_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx) 989 { 990 unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx; 991 struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev, 992 struct spdk_vhost_scsi_dev, vdev); 993 struct spdk_scsi_dev_vhost_state *vhost_sdev; 994 995 vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num]; 996 997 /* All sessions have added the target */ 998 assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING); 999 vhost_sdev->status = VHOST_SCSI_DEV_PRESENT; 1000 svdev->ref++; 1001 } 1002 1003 static int 1004 vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev, 1005 struct spdk_vhost_session *vsession, void *ctx) 1006 { 1007 unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx; 1008 struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession; 1009 struct spdk_scsi_dev_session_state *session_sdev = &svsession->scsi_dev_state[scsi_tgt_num]; 1010 struct spdk_scsi_dev_vhost_state *vhost_sdev; 1011 int rc; 1012 1013 if (!vsession->started || session_sdev->dev != NULL) { 1014 /* Nothing to do. */ 1015 return 0; 1016 } 1017 1018 vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num]; 1019 session_sdev->dev = vhost_sdev->dev; 1020 session_sdev->status = VHOST_SCSI_DEV_PRESENT; 1021 1022 rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev); 1023 if (rc != 0) { 1024 SPDK_ERRLOG("%s: Couldn't allocate io channnel for SCSI target %u.\n", 1025 vsession->name, scsi_tgt_num); 1026 1027 /* unset the SCSI target so that all I/O to it will be rejected */ 1028 session_sdev->dev = NULL; 1029 /* Set status to EMPTY so that we won't reply with SCSI hotremove 1030 * sense codes - the device hasn't ever been added. 1031 */ 1032 session_sdev->status = VHOST_SCSI_DEV_EMPTY; 1033 1034 /* Return with no error. We'll continue allocating io_channels for 1035 * other sessions on this device in hopes they succeed. The sessions 1036 * that failed to allocate io_channels simply won't be able to 1037 * detect the SCSI target, nor do any I/O to it. 1038 */ 1039 return 0; 1040 } 1041 1042 if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) { 1043 eventq_enqueue(svsession, scsi_tgt_num, 1044 VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN); 1045 } else { 1046 SPDK_NOTICELOG("%s: driver does not support hotplug. " 1047 "Please restart it or perform a rescan.\n", 1048 vsession->name); 1049 } 1050 1051 return 0; 1052 } 1053 1054 int 1055 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num, 1056 const char *bdev_name) 1057 { 1058 struct spdk_vhost_scsi_dev *svdev; 1059 struct spdk_scsi_dev_vhost_state *state; 1060 char target_name[SPDK_SCSI_DEV_MAX_NAME]; 1061 int lun_id_list[1]; 1062 const char *bdev_names_list[1]; 1063 1064 svdev = to_scsi_dev(vdev); 1065 if (!svdev) { 1066 SPDK_ERRLOG("Before adding a SCSI target, there should be a SCSI device."); 1067 return -EINVAL; 1068 } 1069 1070 if (scsi_tgt_num < 0) { 1071 for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) { 1072 if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) { 1073 break; 1074 } 1075 } 1076 1077 if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1078 SPDK_ERRLOG("%s: all SCSI target slots are already in use.\n", vdev->name); 1079 return -ENOSPC; 1080 } 1081 } else { 1082 if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1083 SPDK_ERRLOG("%s: SCSI target number is too big (got %d, max %d)\n", 1084 vdev->name, scsi_tgt_num, SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); 1085 return -EINVAL; 1086 } 1087 } 1088 1089 if (bdev_name == NULL) { 1090 SPDK_ERRLOG("No lun name specified\n"); 1091 return -EINVAL; 1092 } 1093 1094 state = &svdev->scsi_dev_state[scsi_tgt_num]; 1095 if (state->dev != NULL) { 1096 SPDK_ERRLOG("%s: SCSI target %u already occupied\n", vdev->name, scsi_tgt_num); 1097 return -EEXIST; 1098 } 1099 1100 /* 1101 * At this stage only one LUN per target 1102 */ 1103 snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num); 1104 lun_id_list[0] = 0; 1105 bdev_names_list[0] = (char *)bdev_name; 1106 1107 state->status = VHOST_SCSI_DEV_ADDING; 1108 state->dev = spdk_scsi_dev_construct_ext(target_name, bdev_names_list, lun_id_list, 1, 1109 SPDK_SPC_PROTOCOL_IDENTIFIER_SAS, 1110 vhost_scsi_lun_resize, svdev, 1111 vhost_scsi_lun_hotremove, svdev); 1112 1113 if (state->dev == NULL) { 1114 state->status = VHOST_SCSI_DEV_EMPTY; 1115 SPDK_ERRLOG("%s: couldn't create SCSI target %u using bdev '%s'\n", 1116 vdev->name, scsi_tgt_num, bdev_name); 1117 return -EINVAL; 1118 } 1119 spdk_scsi_dev_add_port(state->dev, 0, "vhost"); 1120 1121 SPDK_INFOLOG(vhost, "%s: added SCSI target %u using bdev '%s'\n", 1122 vdev->name, scsi_tgt_num, bdev_name); 1123 1124 vhost_dev_foreach_session(vdev, vhost_scsi_session_add_tgt, 1125 vhost_scsi_dev_add_tgt_cpl_cb, 1126 (void *)(uintptr_t)scsi_tgt_num); 1127 return scsi_tgt_num; 1128 } 1129 1130 struct scsi_tgt_hotplug_ctx { 1131 unsigned scsi_tgt_num; 1132 bool async_fini; 1133 }; 1134 1135 static void 1136 vhost_scsi_dev_remove_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *_ctx) 1137 { 1138 struct scsi_tgt_hotplug_ctx *ctx = _ctx; 1139 struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev, 1140 struct spdk_vhost_scsi_dev, vdev); 1141 1142 if (!ctx->async_fini) { 1143 /* there aren't any active sessions, so remove the dev and exit */ 1144 remove_scsi_tgt(svdev, ctx->scsi_tgt_num); 1145 } 1146 1147 free(ctx); 1148 } 1149 1150 static int 1151 vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev, 1152 struct spdk_vhost_session *vsession, void *_ctx) 1153 { 1154 struct scsi_tgt_hotplug_ctx *ctx = _ctx; 1155 unsigned scsi_tgt_num = ctx->scsi_tgt_num; 1156 struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession; 1157 struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num]; 1158 1159 if (!vsession->started || state->dev == NULL) { 1160 /* Nothing to do */ 1161 return 0; 1162 } 1163 1164 /* Mark the target for removal */ 1165 assert(state->status == VHOST_SCSI_DEV_PRESENT); 1166 state->status = VHOST_SCSI_DEV_REMOVING; 1167 1168 /* Send a hotremove virtio event */ 1169 if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) { 1170 eventq_enqueue(svsession, scsi_tgt_num, 1171 VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED); 1172 } 1173 1174 /* Wait for the session's management poller to remove the target after 1175 * all its pending I/O has finished. 1176 */ 1177 ctx->async_fini = true; 1178 return 0; 1179 } 1180 1181 int 1182 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num, 1183 spdk_vhost_event_fn cb_fn, void *cb_arg) 1184 { 1185 struct spdk_vhost_scsi_dev *svdev; 1186 struct spdk_scsi_dev_vhost_state *scsi_dev_state; 1187 struct scsi_tgt_hotplug_ctx *ctx; 1188 1189 if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1190 SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num); 1191 return -EINVAL; 1192 } 1193 1194 svdev = to_scsi_dev(vdev); 1195 if (!svdev) { 1196 SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target."); 1197 return -EINVAL; 1198 } 1199 1200 scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num]; 1201 1202 if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) { 1203 return -EBUSY; 1204 } 1205 1206 if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) { 1207 SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num); 1208 return -ENODEV; 1209 } 1210 1211 assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY); 1212 ctx = calloc(1, sizeof(*ctx)); 1213 if (ctx == NULL) { 1214 SPDK_ERRLOG("calloc failed\n"); 1215 return -ENOMEM; 1216 } 1217 1218 ctx->scsi_tgt_num = scsi_tgt_num; 1219 ctx->async_fini = false; 1220 1221 scsi_dev_state->remove_cb = cb_fn; 1222 scsi_dev_state->remove_ctx = cb_arg; 1223 scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING; 1224 1225 vhost_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt, 1226 vhost_scsi_dev_remove_tgt_cpl_cb, ctx); 1227 return 0; 1228 } 1229 1230 static int 1231 vhost_scsi_session_param_changed(struct spdk_vhost_dev *vdev, 1232 struct spdk_vhost_session *vsession, void *ctx) 1233 { 1234 unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx; 1235 struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession; 1236 struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num]; 1237 1238 if (!vsession->started || state->dev == NULL) { 1239 /* Nothing to do */ 1240 return 0; 1241 } 1242 1243 /* Send a parameter change virtio event */ 1244 if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_CHANGE)) { 1245 /* 1246 * virtio 1.0 spec says: 1247 * By sending this event, the device signals a change in the configuration 1248 * parameters of a logical unit, for example the capacity or cache mode. 1249 * event is set to VIRTIO_SCSI_T_PARAM_CHANGE. lun addresses a logical unit 1250 * in the SCSI host. The same event SHOULD also be reported as a unit 1251 * attention condition. reason contains the additional sense code and 1252 * additional sense code qualifier, respectively in bits 0…7 and 8…15. 1253 * Note: For example, a change in * capacity will be reported as asc 1254 * 0x2a, ascq 0x09 (CAPACITY DATA HAS CHANGED). 1255 */ 1256 eventq_enqueue(svsession, scsi_tgt_num, VIRTIO_SCSI_T_PARAM_CHANGE, 0x2a | (0x09 << 8)); 1257 } 1258 1259 return 0; 1260 } 1261 1262 static int 1263 vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num) 1264 { 1265 struct spdk_vhost_scsi_dev *svdev; 1266 struct spdk_scsi_dev_vhost_state *scsi_dev_state; 1267 1268 if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1269 SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num); 1270 return -EINVAL; 1271 } 1272 1273 svdev = to_scsi_dev(vdev); 1274 if (!svdev) { 1275 SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target."); 1276 return -EINVAL; 1277 } 1278 1279 scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num]; 1280 1281 if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) { 1282 return -EBUSY; 1283 } 1284 1285 if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) { 1286 SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num); 1287 return -ENODEV; 1288 } 1289 1290 assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY); 1291 1292 vhost_dev_foreach_session(vdev, vhost_scsi_session_param_changed, 1293 NULL, (void *)(uintptr_t)scsi_tgt_num); 1294 return 0; 1295 } 1296 1297 static void 1298 free_task_pool(struct spdk_vhost_scsi_session *svsession) 1299 { 1300 struct spdk_vhost_session *vsession = &svsession->vsession; 1301 struct spdk_vhost_virtqueue *vq; 1302 uint16_t i; 1303 1304 for (i = 0; i < vsession->max_queues; i++) { 1305 vq = &vsession->virtqueue[i]; 1306 if (vq->tasks == NULL) { 1307 continue; 1308 } 1309 1310 spdk_free(vq->tasks); 1311 vq->tasks = NULL; 1312 } 1313 } 1314 1315 static int 1316 alloc_task_pool(struct spdk_vhost_scsi_session *svsession) 1317 { 1318 struct spdk_vhost_session *vsession = &svsession->vsession; 1319 struct spdk_vhost_virtqueue *vq; 1320 struct spdk_vhost_scsi_task *task; 1321 uint32_t task_cnt; 1322 uint16_t i; 1323 uint32_t j; 1324 1325 for (i = 0; i < vsession->max_queues; i++) { 1326 vq = &vsession->virtqueue[i]; 1327 if (vq->vring.desc == NULL) { 1328 continue; 1329 } 1330 1331 task_cnt = vq->vring.size; 1332 if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) { 1333 /* sanity check */ 1334 SPDK_ERRLOG("%s: virtuque %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n", 1335 vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE); 1336 free_task_pool(svsession); 1337 return -1; 1338 } 1339 vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt, 1340 SPDK_CACHE_LINE_SIZE, NULL, 1341 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); 1342 if (vq->tasks == NULL) { 1343 SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n", 1344 vsession->name, task_cnt, i); 1345 free_task_pool(svsession); 1346 return -1; 1347 } 1348 1349 for (j = 0; j < task_cnt; j++) { 1350 task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j]; 1351 task->svsession = svsession; 1352 task->vq = vq; 1353 task->req_idx = j; 1354 } 1355 } 1356 1357 return 0; 1358 } 1359 1360 static int 1361 vhost_scsi_start_cb(struct spdk_vhost_dev *vdev, 1362 struct spdk_vhost_session *vsession, void *unused) 1363 { 1364 struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession); 1365 struct spdk_vhost_scsi_dev *svdev = svsession->svdev; 1366 struct spdk_scsi_dev_vhost_state *state; 1367 uint32_t i; 1368 int rc; 1369 1370 /* validate all I/O queues are in a contiguous index range */ 1371 for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) { 1372 if (vsession->virtqueue[i].vring.desc == NULL) { 1373 SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->name, i); 1374 rc = -1; 1375 goto out; 1376 } 1377 } 1378 1379 rc = alloc_task_pool(svsession); 1380 if (rc != 0) { 1381 SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name); 1382 goto out; 1383 } 1384 1385 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1386 state = &svdev->scsi_dev_state[i]; 1387 if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) { 1388 continue; 1389 } 1390 1391 assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY); 1392 svsession->scsi_dev_state[i].dev = state->dev; 1393 svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT; 1394 rc = spdk_scsi_dev_allocate_io_channels(state->dev); 1395 if (rc != 0) { 1396 SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n", 1397 vsession->name, i); 1398 /* unset the SCSI target so that all I/O to it will be rejected */ 1399 svsession->scsi_dev_state[i].dev = NULL; 1400 /* set EMPTY state so that we won't reply with SCSI hotremove 1401 * sense codes - the device hasn't ever been added. 1402 */ 1403 svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY; 1404 continue; 1405 } 1406 } 1407 SPDK_INFOLOG(vhost, "%s: started poller on lcore %d\n", 1408 vsession->name, spdk_env_get_current_core()); 1409 1410 svsession->requestq_poller = SPDK_POLLER_REGISTER(vdev_worker, svsession, 0); 1411 if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc && 1412 vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) { 1413 svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession, 1414 MGMT_POLL_PERIOD_US); 1415 } 1416 out: 1417 vhost_session_start_done(vsession, rc); 1418 return rc; 1419 } 1420 1421 static int 1422 vhost_scsi_start(struct spdk_vhost_session *vsession) 1423 { 1424 struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession); 1425 struct spdk_vhost_scsi_dev *svdev; 1426 1427 svdev = to_scsi_dev(vsession->vdev); 1428 assert(svdev != NULL); 1429 svsession->svdev = svdev; 1430 1431 return vhost_session_send_event(vsession, vhost_scsi_start_cb, 1432 3, "start session"); 1433 } 1434 1435 static int 1436 destroy_session_poller_cb(void *arg) 1437 { 1438 struct spdk_vhost_scsi_session *svsession = arg; 1439 struct spdk_vhost_session *vsession = &svsession->vsession; 1440 struct spdk_scsi_dev_session_state *state; 1441 uint32_t i; 1442 1443 if (vsession->task_cnt > 0) { 1444 return SPDK_POLLER_BUSY; 1445 } 1446 1447 if (spdk_vhost_trylock() != 0) { 1448 return SPDK_POLLER_BUSY; 1449 } 1450 1451 for (i = 0; i < vsession->max_queues; i++) { 1452 vhost_vq_used_signal(vsession, &vsession->virtqueue[i]); 1453 } 1454 1455 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1456 enum spdk_scsi_dev_vhost_status prev_status; 1457 1458 state = &svsession->scsi_dev_state[i]; 1459 /* clear the REMOVED status so that we won't send hotremove events anymore */ 1460 prev_status = state->status; 1461 state->status = VHOST_SCSI_DEV_EMPTY; 1462 if (state->dev == NULL) { 1463 continue; 1464 } 1465 1466 spdk_scsi_dev_free_io_channels(state->dev); 1467 1468 state->dev = NULL; 1469 1470 if (prev_status == VHOST_SCSI_DEV_REMOVING) { 1471 /* try to detach it globally */ 1472 vhost_dev_foreach_session(vsession->vdev, 1473 vhost_scsi_session_process_removed, 1474 vhost_scsi_dev_process_removed_cpl_cb, 1475 (void *)(uintptr_t)i); 1476 } 1477 } 1478 1479 SPDK_INFOLOG(vhost, "%s: stopping poller on lcore %d\n", 1480 vsession->name, spdk_env_get_current_core()); 1481 1482 free_task_pool(svsession); 1483 1484 spdk_poller_unregister(&svsession->stop_poller); 1485 vhost_session_stop_done(vsession, 0); 1486 1487 spdk_vhost_unlock(); 1488 return SPDK_POLLER_BUSY; 1489 } 1490 1491 static int 1492 vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev, 1493 struct spdk_vhost_session *vsession, void *unused) 1494 { 1495 struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession); 1496 1497 /* Stop receiving new I/O requests */ 1498 spdk_poller_unregister(&svsession->requestq_poller); 1499 1500 /* Stop receiving controlq requests, also stop processing the 1501 * asynchronous hotremove events. All the remaining events 1502 * will be finalized by the stop_poller below. 1503 */ 1504 spdk_poller_unregister(&svsession->mgmt_poller); 1505 1506 /* Wait for all pending I/Os to complete, then process all the 1507 * remaining hotremove events one last time. 1508 */ 1509 svsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb, 1510 svsession, 1000); 1511 1512 return 0; 1513 } 1514 1515 static int 1516 vhost_scsi_stop(struct spdk_vhost_session *vsession) 1517 { 1518 return vhost_session_send_event(vsession, vhost_scsi_stop_cb, 1519 3, "stop session"); 1520 } 1521 1522 static void 1523 vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) 1524 { 1525 struct spdk_scsi_dev *sdev; 1526 struct spdk_scsi_lun *lun; 1527 uint32_t dev_idx; 1528 uint32_t lun_idx; 1529 1530 assert(vdev != NULL); 1531 spdk_json_write_named_array_begin(w, "scsi"); 1532 for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) { 1533 sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx); 1534 if (!sdev) { 1535 continue; 1536 } 1537 1538 spdk_json_write_object_begin(w); 1539 1540 spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx); 1541 1542 spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev)); 1543 1544 spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev)); 1545 1546 spdk_json_write_named_array_begin(w, "luns"); 1547 1548 for (lun_idx = 0; lun_idx < SPDK_SCSI_DEV_MAX_LUN; lun_idx++) { 1549 lun = spdk_scsi_dev_get_lun(sdev, lun_idx); 1550 if (!lun) { 1551 continue; 1552 } 1553 1554 spdk_json_write_object_begin(w); 1555 1556 spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun)); 1557 1558 spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun)); 1559 1560 spdk_json_write_object_end(w); 1561 } 1562 1563 spdk_json_write_array_end(w); 1564 spdk_json_write_object_end(w); 1565 } 1566 1567 spdk_json_write_array_end(w); 1568 } 1569 1570 static void 1571 vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) 1572 { 1573 struct spdk_scsi_dev *scsi_dev; 1574 struct spdk_scsi_lun *lun; 1575 uint32_t i; 1576 1577 spdk_json_write_object_begin(w); 1578 spdk_json_write_named_string(w, "method", "vhost_create_scsi_controller"); 1579 1580 spdk_json_write_named_object_begin(w, "params"); 1581 spdk_json_write_named_string(w, "ctrlr", vdev->name); 1582 spdk_json_write_named_string(w, "cpumask", 1583 spdk_cpuset_fmt(spdk_thread_get_cpumask(vdev->thread))); 1584 spdk_json_write_object_end(w); 1585 1586 spdk_json_write_object_end(w); 1587 1588 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1589 scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i); 1590 if (scsi_dev == NULL) { 1591 continue; 1592 } 1593 1594 lun = spdk_scsi_dev_get_lun(scsi_dev, 0); 1595 assert(lun != NULL); 1596 1597 spdk_json_write_object_begin(w); 1598 spdk_json_write_named_string(w, "method", "vhost_scsi_controller_add_target"); 1599 1600 spdk_json_write_named_object_begin(w, "params"); 1601 spdk_json_write_named_string(w, "ctrlr", vdev->name); 1602 spdk_json_write_named_uint32(w, "scsi_target_num", i); 1603 1604 spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun)); 1605 spdk_json_write_object_end(w); 1606 1607 spdk_json_write_object_end(w); 1608 } 1609 } 1610 1611 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi) 1612 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_queue) 1613 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_data) 1614