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