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