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_dev *vdev = vsession->vdev; 269 struct spdk_vhost_virtqueue *vq; 270 struct vring_desc *desc, *desc_table; 271 struct virtio_scsi_event *desc_ev; 272 uint32_t desc_table_size, req_size = 0; 273 uint16_t req; 274 int rc; 275 276 assert(scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); 277 vq = &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]; 278 279 if (vq->vring.desc == NULL || spdk_vhost_vq_avail_ring_get(vq, &req, 1) != 1) { 280 SPDK_ERRLOG("Controller %s: Failed to send virtio event (no avail ring entries?).\n", 281 vdev->name); 282 return; 283 } 284 285 rc = spdk_vhost_vq_get_desc(vsession, vq, req, &desc, &desc_table, &desc_table_size); 286 if (rc != 0 || desc->len < sizeof(*desc_ev)) { 287 SPDK_ERRLOG("Controller %s: Invalid eventq descriptor at index %"PRIu16".\n", 288 vdev->name, req); 289 goto out; 290 } 291 292 desc_ev = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*desc_ev)); 293 if (desc_ev == NULL) { 294 SPDK_ERRLOG("Controller %s: Eventq descriptor at index %"PRIu16" points to unmapped guest memory address %p.\n", 295 vdev->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 spdk_vhost_dev *vdev = vsession->vdev; 421 struct vring_desc *desc, *desc_table; 422 struct virtio_scsi_ctrl_tmf_req *ctrl_req; 423 struct virtio_scsi_ctrl_an_resp *an_resp; 424 uint32_t desc_table_size, used_len = 0; 425 int rc; 426 427 spdk_scsi_task_construct(&task->scsi, spdk_vhost_scsi_task_mgmt_cpl, spdk_vhost_scsi_task_free_cb); 428 rc = spdk_vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table, 429 &desc_table_size); 430 if (spdk_unlikely(rc != 0)) { 431 SPDK_ERRLOG("%s: Invalid controlq descriptor at index %d.\n", 432 vdev->name, task->req_idx); 433 goto out; 434 } 435 436 ctrl_req = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*ctrl_req)); 437 if (ctrl_req == NULL) { 438 SPDK_ERRLOG("%s: Invalid task management request at index %d.\n", 439 vdev->name, task->req_idx); 440 goto out; 441 } 442 443 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, 444 "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n", 445 task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx, 446 task->vq->vring.kickfd, task->vq->vring.size); 447 SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_QUEUE, "Request descriptor", (uint8_t *)ctrl_req, desc->len); 448 449 spdk_vhost_scsi_task_init_target(task, ctrl_req->lun); 450 451 spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_size); 452 if (spdk_unlikely(desc == NULL)) { 453 SPDK_ERRLOG("%s: No response descriptor for controlq request %d.\n", 454 vdev->name, task->req_idx); 455 goto out; 456 } 457 458 /* Process the TMF request */ 459 switch (ctrl_req->type) { 460 case VIRTIO_SCSI_T_TMF: 461 task->tmf_resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->tmf_resp)); 462 if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) { 463 SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n", 464 vdev->name, task->req_idx); 465 goto out; 466 } 467 468 /* Check if we are processing a valid request */ 469 if (task->scsi_dev == NULL) { 470 task->tmf_resp->response = VIRTIO_SCSI_S_BAD_TARGET; 471 break; 472 } 473 474 switch (ctrl_req->subtype) { 475 case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET: 476 /* Handle LUN reset */ 477 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "LUN reset\n"); 478 479 mgmt_task_submit(task, SPDK_SCSI_TASK_FUNC_LUN_RESET); 480 return; 481 default: 482 task->tmf_resp->response = VIRTIO_SCSI_S_ABORTED; 483 /* Unsupported command */ 484 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "Unsupported TMF command %x\n", 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 vdev->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, "Unsupported control command %x\n", ctrl_req->type); 502 break; 503 } 504 505 used_len = sizeof(struct virtio_scsi_ctrl_tmf_resp); 506 out: 507 spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx, used_len); 508 spdk_vhost_scsi_task_put(task); 509 } 510 511 /* 512 * Process task's descriptor chain and setup data related fields. 513 * Return 514 * -1 if request is invalid and must be aborted, 515 * 0 if all data are set. 516 */ 517 static int 518 task_data_setup(struct spdk_vhost_scsi_task *task, 519 struct virtio_scsi_cmd_req **req) 520 { 521 struct spdk_vhost_session *vsession = &task->svsession->vsession; 522 struct spdk_vhost_dev *vdev = vsession->vdev; 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 vdev->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 vdev->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 vdev->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 vdev->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 vdev->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("FROM DEV cmd: descriptor nr %" PRIu16" in payload chain is read only.\n", iovcnt); 594 goto invalid_task; 595 } 596 597 if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) { 598 goto invalid_task; 599 } 600 len += desc->len; 601 602 rc = spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len); 603 if (spdk_unlikely(rc != 0)) { 604 SPDK_WARNLOG("%s: invalid payload in descriptor chain starting at index %d.\n", 605 vdev->name, task->req_idx); 606 goto invalid_task; 607 } 608 } 609 610 task->used_len = sizeof(struct virtio_scsi_cmd_resp) + len; 611 } else { 612 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "TO DEV"); 613 /* 614 * TO_DEV (WRITE):[RD_req][RD_buf0]...[RD_bufN][WR_resp] 615 * No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir. 616 */ 617 618 /* Process descriptors up to response. */ 619 while (!spdk_vhost_vring_desc_is_wr(desc)) { 620 if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) { 621 goto invalid_task; 622 } 623 len += desc->len; 624 625 spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len); 626 if (spdk_unlikely(desc == NULL)) { 627 SPDK_WARNLOG("TO_DEV cmd: no response descriptor.\n"); 628 goto invalid_task; 629 } 630 } 631 632 task->resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp)); 633 if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) { 634 SPDK_WARNLOG("%s: Response descriptor at index %d points to invalid guest memory region\n", 635 vdev->name, task->req_idx); 636 goto invalid_task; 637 } 638 639 task->used_len = sizeof(struct virtio_scsi_cmd_resp); 640 } 641 642 task->scsi.iovcnt = iovcnt; 643 task->scsi.length = len; 644 task->scsi.transfer_len = len; 645 return 0; 646 647 invalid_task: 648 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "%s: Invalid task at index %"PRIu16".\n", 649 vdev->name, task->req_idx); 650 return -1; 651 } 652 653 static int 654 process_request(struct spdk_vhost_scsi_task *task) 655 { 656 struct virtio_scsi_cmd_req *req; 657 int result; 658 659 result = task_data_setup(task, &req); 660 if (result) { 661 return result; 662 } 663 664 result = spdk_vhost_scsi_task_init_target(task, req->lun); 665 if (spdk_unlikely(result != 0)) { 666 task->resp->response = VIRTIO_SCSI_S_BAD_TARGET; 667 return -1; 668 } 669 670 task->scsi.cdb = req->cdb; 671 SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_DATA, "request CDB", req->cdb, VIRTIO_SCSI_CDB_SIZE); 672 673 if (spdk_unlikely(task->scsi.lun == NULL)) { 674 spdk_scsi_task_process_null_lun(&task->scsi); 675 task->resp->response = VIRTIO_SCSI_S_OK; 676 return 1; 677 } 678 679 return 0; 680 } 681 682 static void 683 process_controlq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq) 684 { 685 struct spdk_vhost_scsi_dev *svdev = svsession->svdev; 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 svdev->vdev.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 svdev->vdev.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_dev *vdev = vsession->vdev; 721 struct spdk_vhost_scsi_task *task; 722 uint16_t reqs[32]; 723 uint16_t reqs_cnt, i; 724 int result; 725 726 reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs)); 727 assert(reqs_cnt <= 32); 728 729 for (i = 0; i < reqs_cnt; i++) { 730 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n", 731 reqs[i]); 732 733 if (spdk_unlikely(reqs[i] >= vq->vring.size)) { 734 SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n", 735 vdev->name, reqs[i], vq->vring.size); 736 spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0); 737 continue; 738 } 739 740 task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]]; 741 if (spdk_unlikely(task->used)) { 742 SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n", 743 vdev->name, reqs[i]); 744 spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0); 745 continue; 746 } 747 748 vsession->task_cnt++; 749 memset(&task->scsi, 0, sizeof(task->scsi)); 750 task->resp = NULL; 751 task->used = true; 752 task->used_len = 0; 753 result = process_request(task); 754 if (likely(result == 0)) { 755 task_submit(task); 756 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d submitted ======\n", task, 757 task->req_idx); 758 } else if (result > 0) { 759 spdk_vhost_scsi_task_cpl(&task->scsi); 760 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d finished early ======\n", task, 761 task->req_idx); 762 } else { 763 invalid_request(task); 764 SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d failed ======\n", task, 765 task->req_idx); 766 } 767 } 768 } 769 770 static int 771 vdev_mgmt_worker(void *arg) 772 { 773 struct spdk_vhost_scsi_session *svsession = arg; 774 struct spdk_vhost_session *vsession = &svsession->vsession; 775 776 process_removed_devs(svsession); 777 spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]); 778 779 process_controlq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); 780 spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); 781 782 return -1; 783 } 784 785 static int 786 vdev_worker(void *arg) 787 { 788 struct spdk_vhost_scsi_session *svsession = arg; 789 struct spdk_vhost_session *vsession = &svsession->vsession; 790 uint32_t q_idx; 791 792 for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) { 793 process_requestq(svsession, &vsession->virtqueue[q_idx]); 794 } 795 796 spdk_vhost_session_used_signal(vsession); 797 798 return -1; 799 } 800 801 static struct spdk_vhost_scsi_dev * 802 to_scsi_dev(struct spdk_vhost_dev *ctrlr) 803 { 804 if (ctrlr == NULL) { 805 return NULL; 806 } 807 808 if (ctrlr->backend != &spdk_vhost_scsi_device_backend) { 809 SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name); 810 return NULL; 811 } 812 813 return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev); 814 } 815 816 static struct spdk_vhost_scsi_session * 817 to_scsi_session(struct spdk_vhost_session *vsession) 818 { 819 if (vsession == NULL) { 820 return NULL; 821 } 822 823 if (vsession->vdev->backend != &spdk_vhost_scsi_device_backend) { 824 SPDK_ERRLOG("%s: not a vhost-scsi device.\n", vsession->vdev->name); 825 return NULL; 826 } 827 828 return (struct spdk_vhost_scsi_session *)vsession; 829 } 830 831 int 832 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask) 833 { 834 struct spdk_vhost_scsi_dev *svdev = calloc(1, sizeof(*svdev)); 835 int rc; 836 837 if (svdev == NULL) { 838 return -ENOMEM; 839 } 840 841 spdk_vhost_lock(); 842 rc = spdk_vhost_dev_register(&svdev->vdev, name, cpumask, 843 &spdk_vhost_scsi_device_backend); 844 845 if (rc) { 846 free(svdev); 847 } 848 849 spdk_vhost_unlock(); 850 return rc; 851 } 852 853 static int 854 spdk_vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev) 855 { 856 struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev); 857 int rc, i; 858 859 if (svdev == NULL) { 860 return -EINVAL; 861 } 862 863 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) { 864 if (svdev->scsi_dev_state[i].dev) { 865 if (vdev->registered) { 866 SPDK_ERRLOG("Trying to remove non-empty controller: %s.\n", vdev->name); 867 return -EBUSY; 868 } 869 870 rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL); 871 if (rc != 0) { 872 SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i); 873 return rc; 874 } 875 } 876 } 877 878 rc = spdk_vhost_dev_unregister(vdev); 879 if (rc != 0) { 880 return rc; 881 } 882 883 free(svdev); 884 return 0; 885 } 886 887 struct spdk_scsi_dev * 888 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num) 889 { 890 struct spdk_vhost_scsi_dev *svdev; 891 892 assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); 893 svdev = to_scsi_dev(vdev); 894 if (svdev == NULL || svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) { 895 return NULL; 896 } 897 898 assert(svdev->scsi_dev_state[num].dev != NULL); 899 return svdev->scsi_dev_state[num].dev; 900 } 901 902 static void 903 spdk_vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg) 904 { 905 struct spdk_vhost_scsi_dev *svdev = arg; 906 const struct spdk_scsi_dev *scsi_dev; 907 unsigned scsi_dev_num; 908 909 assert(lun != NULL); 910 assert(svdev != NULL); 911 scsi_dev = spdk_scsi_lun_get_dev(lun); 912 for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) { 913 if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) { 914 break; 915 } 916 } 917 918 if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 919 /* The entire device has been already removed. */ 920 return; 921 } 922 923 /* remove entire device */ 924 spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL); 925 } 926 927 static int 928 spdk_vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev, 929 struct spdk_vhost_session *vsession, void *ctx) 930 { 931 unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx; 932 struct spdk_vhost_scsi_session *svsession; 933 struct spdk_scsi_dev_vhost_state *vhost_sdev; 934 struct spdk_scsi_dev_session_state *session_sdev; 935 int rc; 936 937 if (vsession == NULL) { 938 struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev, 939 struct spdk_vhost_scsi_dev, vdev); 940 vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num]; 941 942 /* All sessions have added the target */ 943 assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING); 944 vhost_sdev->status = VHOST_SCSI_DEV_PRESENT; 945 return 0; 946 } 947 948 svsession = (struct spdk_vhost_scsi_session *)vsession; 949 session_sdev = &svsession->scsi_dev_state[scsi_tgt_num]; 950 if (!vsession->started || session_sdev->dev != NULL) { 951 /* Nothing to do. */ 952 return 0; 953 } 954 955 vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num]; 956 session_sdev->dev = vhost_sdev->dev; 957 session_sdev->status = VHOST_SCSI_DEV_PRESENT; 958 959 rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev); 960 if (rc != 0) { 961 SPDK_ERRLOG("Couldn't allocate io channnel for SCSI target %u in device %s\n", 962 scsi_tgt_num, vdev->name); 963 964 /* unset the SCSI target so that all I/O to it will be rejected */ 965 session_sdev->dev = NULL; 966 /* Set status to EMPTY so that we won't reply with SCSI hotremove 967 * sense codes - the device hasn't ever been added. 968 */ 969 session_sdev->status = VHOST_SCSI_DEV_EMPTY; 970 971 /* Return with no error. We'll continue allocating io_channels for 972 * other sessions on this device in hopes they succeed. The sessions 973 * that failed to allocate io_channels simply won't be able to 974 * detect the SCSI target, nor do any I/O to it. 975 */ 976 return 0; 977 } 978 979 if (spdk_vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) { 980 eventq_enqueue(svsession, scsi_tgt_num, 981 VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN); 982 } else { 983 SPDK_NOTICELOG("Device %s does not support hotplug. " 984 "Please restart the driver or perform a rescan.\n", 985 vdev->name); 986 } 987 988 return 0; 989 } 990 991 int 992 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num, 993 const char *bdev_name) 994 { 995 struct spdk_vhost_scsi_dev *svdev; 996 struct spdk_scsi_dev_vhost_state *state; 997 char target_name[SPDK_SCSI_DEV_MAX_NAME]; 998 int lun_id_list[1]; 999 const char *bdev_names_list[1]; 1000 1001 svdev = to_scsi_dev(vdev); 1002 if (svdev == NULL) { 1003 return -EINVAL; 1004 } 1005 1006 if (scsi_tgt_num < 0) { 1007 for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) { 1008 if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) { 1009 break; 1010 } 1011 } 1012 1013 if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1014 SPDK_ERRLOG("Controller %s - all targets already in use.\n", vdev->name); 1015 return -ENOSPC; 1016 } 1017 } else { 1018 if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1019 SPDK_ERRLOG("Controller %s target %d number too big (max %d)\n", vdev->name, scsi_tgt_num, 1020 SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); 1021 return -EINVAL; 1022 } 1023 } 1024 1025 if (bdev_name == NULL) { 1026 SPDK_ERRLOG("No lun name specified\n"); 1027 return -EINVAL; 1028 } 1029 1030 state = &svdev->scsi_dev_state[scsi_tgt_num]; 1031 if (state->dev != NULL) { 1032 SPDK_ERRLOG("Controller %s target %u already occupied\n", vdev->name, scsi_tgt_num); 1033 return -EEXIST; 1034 } 1035 1036 /* 1037 * At this stage only one LUN per target 1038 */ 1039 snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num); 1040 lun_id_list[0] = 0; 1041 bdev_names_list[0] = (char *)bdev_name; 1042 1043 state->status = VHOST_SCSI_DEV_ADDING; 1044 state->dev = spdk_scsi_dev_construct(target_name, bdev_names_list, lun_id_list, 1, 1045 SPDK_SPC_PROTOCOL_IDENTIFIER_SAS, 1046 spdk_vhost_scsi_lun_hotremove, svdev); 1047 1048 if (state->dev == NULL) { 1049 state->status = VHOST_SCSI_DEV_EMPTY; 1050 SPDK_ERRLOG("Couldn't create spdk SCSI target '%s' using bdev '%s' in controller: %s\n", 1051 target_name, bdev_name, vdev->name); 1052 return -EINVAL; 1053 } 1054 spdk_scsi_dev_add_port(state->dev, 0, "vhost"); 1055 1056 SPDK_INFOLOG(SPDK_LOG_VHOST, "Controller %s: defined target '%s' using bdev '%s'\n", 1057 vdev->name, target_name, bdev_name); 1058 1059 spdk_vhost_dev_foreach_session(vdev, spdk_vhost_scsi_session_add_tgt, 1060 (void *)(uintptr_t)scsi_tgt_num); 1061 return scsi_tgt_num; 1062 } 1063 1064 struct scsi_tgt_hotplug_ctx { 1065 unsigned scsi_tgt_num; 1066 bool async_fini; 1067 }; 1068 1069 static int 1070 spdk_vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev, 1071 struct spdk_vhost_session *vsession, void *_ctx) 1072 { 1073 struct scsi_tgt_hotplug_ctx *ctx = _ctx; 1074 unsigned scsi_tgt_num = ctx->scsi_tgt_num; 1075 struct spdk_vhost_scsi_session *svsession; 1076 struct spdk_scsi_dev_session_state *state; 1077 int rc = 0; 1078 1079 if (vsession == NULL) { 1080 struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev, 1081 struct spdk_vhost_scsi_dev, vdev); 1082 1083 if (!ctx->async_fini) { 1084 /* there aren't any active sessions, so remove the dev and exit */ 1085 rc = remove_scsi_tgt(svdev, scsi_tgt_num); 1086 } 1087 1088 free(ctx); 1089 return rc; 1090 } 1091 1092 svsession = (struct spdk_vhost_scsi_session *)vsession; 1093 state = &svsession->scsi_dev_state[scsi_tgt_num]; 1094 1095 if (!vsession->started || state->dev == NULL) { 1096 /* Nothing to do */ 1097 return 0; 1098 } 1099 1100 /* Mark the target for removal */ 1101 assert(state->status == VHOST_SCSI_DEV_PRESENT); 1102 state->status = VHOST_SCSI_DEV_REMOVING; 1103 1104 /* Send a hotremove Virtio event */ 1105 if (spdk_vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) { 1106 eventq_enqueue(svsession, scsi_tgt_num, 1107 VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED); 1108 } 1109 1110 /* Wait for the session's management poller to remove the target after 1111 * all its pending I/O has finished. 1112 */ 1113 ctx->async_fini = true; 1114 return 0; 1115 } 1116 1117 int 1118 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num, 1119 spdk_vhost_event_fn cb_fn, void *cb_arg) 1120 { 1121 struct spdk_vhost_scsi_dev *svdev; 1122 struct spdk_scsi_dev_vhost_state *scsi_dev_state; 1123 struct scsi_tgt_hotplug_ctx *ctx; 1124 1125 if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) { 1126 SPDK_ERRLOG("%s: invalid target number %d\n", vdev->name, scsi_tgt_num); 1127 return -EINVAL; 1128 } 1129 1130 svdev = to_scsi_dev(vdev); 1131 if (svdev == NULL) { 1132 return -ENODEV; 1133 } 1134 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("Controller %s 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: 'Target %u' has been already marked to hotremove.\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 spdk_vhost_dev_foreach_session(vdev, spdk_vhost_scsi_session_remove_tgt, ctx); 1162 return 0; 1163 } 1164 1165 int 1166 spdk_vhost_scsi_controller_construct(void) 1167 { 1168 struct spdk_conf_section *sp = spdk_conf_first_section(NULL); 1169 struct spdk_vhost_dev *vdev; 1170 int i, dev_num; 1171 unsigned ctrlr_num = 0; 1172 char *bdev_name, *tgt_num_str; 1173 char *cpumask; 1174 char *name; 1175 char *tgt = NULL; 1176 1177 while (sp != NULL) { 1178 if (!spdk_conf_section_match_prefix(sp, "VhostScsi")) { 1179 sp = spdk_conf_next_section(sp); 1180 continue; 1181 } 1182 1183 if (sscanf(spdk_conf_section_get_name(sp), "VhostScsi%u", &ctrlr_num) != 1) { 1184 SPDK_ERRLOG("Section '%s' has non-numeric suffix.\n", 1185 spdk_conf_section_get_name(sp)); 1186 return -1; 1187 } 1188 1189 name = spdk_conf_section_get_val(sp, "Name"); 1190 cpumask = spdk_conf_section_get_val(sp, "Cpumask"); 1191 1192 if (spdk_vhost_scsi_dev_construct(name, cpumask) < 0) { 1193 return -1; 1194 } 1195 1196 vdev = spdk_vhost_dev_find(name); 1197 assert(vdev); 1198 1199 for (i = 0; ; i++) { 1200 1201 tgt = spdk_conf_section_get_nval(sp, "Target", i); 1202 if (tgt == NULL) { 1203 break; 1204 } 1205 1206 tgt_num_str = spdk_conf_section_get_nmval(sp, "Target", i, 0); 1207 if (tgt_num_str == NULL) { 1208 SPDK_ERRLOG("%s: Invalid or missing target number\n", name); 1209 return -1; 1210 } 1211 1212 dev_num = (int)strtol(tgt_num_str, NULL, 10); 1213 bdev_name = spdk_conf_section_get_nmval(sp, "Target", i, 1); 1214 if (bdev_name == NULL) { 1215 SPDK_ERRLOG("%s: Invalid or missing bdev name for target %d\n", name, dev_num); 1216 return -1; 1217 } else if (spdk_conf_section_get_nmval(sp, "Target", i, 2)) { 1218 SPDK_ERRLOG("%s: Only one LUN per vhost SCSI device supported\n", name); 1219 return -1; 1220 } 1221 1222 if (spdk_vhost_scsi_dev_add_tgt(vdev, dev_num, bdev_name) < 0) { 1223 return -1; 1224 } 1225 } 1226 1227 sp = spdk_conf_next_section(sp); 1228 } 1229 1230 return 0; 1231 } 1232 1233 static void 1234 free_task_pool(struct spdk_vhost_scsi_session *svsession) 1235 { 1236 struct spdk_vhost_session *vsession = &svsession->vsession; 1237 struct spdk_vhost_virtqueue *vq; 1238 uint16_t i; 1239 1240 for (i = 0; i < vsession->max_queues; i++) { 1241 vq = &vsession->virtqueue[i]; 1242 if (vq->tasks == NULL) { 1243 continue; 1244 } 1245 1246 spdk_free(vq->tasks); 1247 vq->tasks = NULL; 1248 } 1249 } 1250 1251 static int 1252 alloc_task_pool(struct spdk_vhost_scsi_session *svsession) 1253 { 1254 struct spdk_vhost_session *vsession = &svsession->vsession; 1255 struct spdk_vhost_scsi_dev *svdev = svsession->svdev; 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("Controller %s: virtuque %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n", 1272 svdev->vdev.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("Controller %s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n", 1281 svdev->vdev.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 spdk_vhost_scsi_start_cb(struct spdk_vhost_dev *vdev, 1299 struct spdk_vhost_session *vsession, void *unused) 1300 { 1301 struct spdk_vhost_scsi_dev *svdev; 1302 struct spdk_vhost_scsi_session *svsession; 1303 struct spdk_scsi_dev_vhost_state *state; 1304 uint32_t i; 1305 int rc; 1306 1307 svsession = to_scsi_session(vsession); 1308 assert(svsession != NULL); 1309 svdev = svsession->svdev; 1310 1311 /* validate all I/O queues are in a contiguous index range */ 1312 for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) { 1313 if (vsession->virtqueue[i].vring.desc == NULL) { 1314 SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->vdev->name, i); 1315 rc = -1; 1316 goto out; 1317 } 1318 } 1319 1320 rc = alloc_task_pool(svsession); 1321 if (rc != 0) { 1322 SPDK_ERRLOG("%s: failed to alloc task pool.\n", vdev->name); 1323 goto out; 1324 } 1325 1326 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1327 state = &svdev->scsi_dev_state[i]; 1328 if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) { 1329 continue; 1330 } 1331 1332 assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY); 1333 svsession->scsi_dev_state[i].dev = state->dev; 1334 svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT; 1335 rc = spdk_scsi_dev_allocate_io_channels(state->dev); 1336 if (rc != 0) { 1337 SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n", vdev->name, i); 1338 /* unset the SCSI target so that all I/O to it will be rejected */ 1339 svsession->scsi_dev_state[i].dev = NULL; 1340 /* set EMPTY state so that we won't reply with SCSI hotremove 1341 * sense codes - the device hasn't ever been added. 1342 */ 1343 svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY; 1344 continue; 1345 } 1346 } 1347 SPDK_INFOLOG(SPDK_LOG_VHOST, "Started poller for vhost controller %s on lcore %d\n", 1348 vdev->name, spdk_env_get_current_core()); 1349 1350 svsession->requestq_poller = spdk_poller_register(vdev_worker, svsession, 0); 1351 if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc && 1352 vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) { 1353 svsession->mgmt_poller = spdk_poller_register(vdev_mgmt_worker, svsession, 1354 MGMT_POLL_PERIOD_US); 1355 } 1356 out: 1357 spdk_vhost_session_start_done(vsession, rc); 1358 return rc; 1359 } 1360 1361 static int 1362 spdk_vhost_scsi_start(struct spdk_vhost_session *vsession) 1363 { 1364 struct spdk_vhost_scsi_session *svsession; 1365 struct spdk_vhost_scsi_dev *svdev; 1366 int rc; 1367 1368 svsession = to_scsi_session(vsession); 1369 if (svsession == NULL) { 1370 SPDK_ERRLOG("Trying to start non-scsi session as a scsi one.\n"); 1371 return -1; 1372 } 1373 1374 svdev = to_scsi_dev(vsession->vdev); 1375 assert(svdev != NULL); 1376 svsession->svdev = svdev; 1377 1378 if (svdev->vdev.active_session_num == 0) { 1379 svdev->poll_group = spdk_vhost_get_poll_group(svdev->vdev.cpumask); 1380 } 1381 1382 rc = spdk_vhost_session_send_event(svdev->poll_group, vsession, spdk_vhost_scsi_start_cb, 1383 3, "start session"); 1384 if (rc != 0) { 1385 if (svdev->vdev.active_session_num == 0) { 1386 spdk_vhost_put_poll_group(svdev->poll_group); 1387 svdev->poll_group = NULL; 1388 } 1389 } 1390 1391 return rc; 1392 } 1393 1394 static int 1395 destroy_session_poller_cb(void *arg) 1396 { 1397 struct spdk_vhost_scsi_session *svsession = arg; 1398 struct spdk_vhost_session *vsession = &svsession->vsession; 1399 struct spdk_scsi_dev_session_state *state; 1400 uint32_t i; 1401 1402 if (vsession->task_cnt > 0) { 1403 return -1; 1404 } 1405 1406 if (spdk_vhost_trylock() != 0) { 1407 return -1; 1408 } 1409 1410 for (i = 0; i < vsession->max_queues; i++) { 1411 spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[i]); 1412 } 1413 1414 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1415 enum spdk_scsi_dev_vhost_status prev_status; 1416 1417 state = &svsession->scsi_dev_state[i]; 1418 /* clear the REMOVED status so that we won't send hotremove events anymore */ 1419 prev_status = state->status; 1420 state->status = VHOST_SCSI_DEV_EMPTY; 1421 if (state->dev == NULL) { 1422 continue; 1423 } 1424 1425 spdk_scsi_dev_free_io_channels(state->dev); 1426 1427 state->dev = NULL; 1428 1429 if (prev_status == VHOST_SCSI_DEV_REMOVING) { 1430 /* try to detach it globally */ 1431 spdk_vhost_dev_foreach_session(vsession->vdev, 1432 spdk_vhost_scsi_session_process_removed, 1433 (void *)(uintptr_t)i); 1434 } 1435 } 1436 1437 SPDK_INFOLOG(SPDK_LOG_VHOST, "Stopping poller for vhost controller %s\n", 1438 svsession->svdev->vdev.name); 1439 1440 free_task_pool(svsession); 1441 1442 spdk_poller_unregister(&svsession->stop_poller); 1443 spdk_vhost_session_stop_done(vsession, 0); 1444 1445 spdk_vhost_unlock(); 1446 return -1; 1447 } 1448 1449 static int 1450 spdk_vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev, 1451 struct spdk_vhost_session *vsession, void *unused) 1452 { 1453 struct spdk_vhost_scsi_session *svsession; 1454 1455 svsession = to_scsi_session(vsession); 1456 assert(svsession != NULL); 1457 1458 /* Stop receiving new I/O requests */ 1459 spdk_poller_unregister(&svsession->requestq_poller); 1460 1461 /* Stop receiving controlq requests, also stop processing the 1462 * asynchronous hotremove events. All the remaining events 1463 * will be finalized by the stop_poller below. 1464 */ 1465 spdk_poller_unregister(&svsession->mgmt_poller); 1466 1467 /* Wait for all pending I/Os to complete, then process all the 1468 * remaining hotremove events one last time. 1469 */ 1470 svsession->stop_poller = spdk_poller_register(destroy_session_poller_cb, 1471 svsession, 1000); 1472 1473 return 0; 1474 } 1475 1476 static int 1477 spdk_vhost_scsi_stop(struct spdk_vhost_session *vsession) 1478 { 1479 struct spdk_vhost_scsi_session *svsession; 1480 int rc; 1481 1482 svsession = to_scsi_session(vsession); 1483 if (svsession == NULL) { 1484 SPDK_ERRLOG("Trying to stop non-scsi session as a scsi one.\n"); 1485 return -1; 1486 } 1487 rc = spdk_vhost_session_send_event(vsession->poll_group, vsession, 1488 spdk_vhost_scsi_stop_cb, 3, "stop session"); 1489 if (rc != 0) { 1490 return rc; 1491 } 1492 1493 if (vsession->vdev->active_session_num == 0) { 1494 spdk_vhost_put_poll_group(svsession->svdev->poll_group); 1495 svsession->svdev->poll_group = NULL; 1496 } 1497 return 0; 1498 } 1499 1500 static void 1501 spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) 1502 { 1503 struct spdk_scsi_dev *sdev; 1504 struct spdk_scsi_lun *lun; 1505 uint32_t dev_idx; 1506 uint32_t lun_idx; 1507 1508 assert(vdev != NULL); 1509 spdk_json_write_named_array_begin(w, "scsi"); 1510 for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) { 1511 sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx); 1512 if (!sdev) { 1513 continue; 1514 } 1515 1516 spdk_json_write_object_begin(w); 1517 1518 spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx); 1519 1520 spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev)); 1521 1522 spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev)); 1523 1524 spdk_json_write_named_array_begin(w, "luns"); 1525 1526 for (lun_idx = 0; lun_idx < SPDK_SCSI_DEV_MAX_LUN; lun_idx++) { 1527 lun = spdk_scsi_dev_get_lun(sdev, lun_idx); 1528 if (!lun) { 1529 continue; 1530 } 1531 1532 spdk_json_write_object_begin(w); 1533 1534 spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun)); 1535 1536 spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun)); 1537 1538 spdk_json_write_object_end(w); 1539 } 1540 1541 spdk_json_write_array_end(w); 1542 spdk_json_write_object_end(w); 1543 } 1544 1545 spdk_json_write_array_end(w); 1546 } 1547 1548 static void 1549 spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) 1550 { 1551 struct spdk_scsi_dev *scsi_dev; 1552 struct spdk_scsi_lun *lun; 1553 uint32_t i; 1554 1555 if (to_scsi_dev(vdev) == NULL) { 1556 return; 1557 } 1558 1559 spdk_json_write_object_begin(w); 1560 spdk_json_write_named_string(w, "method", "construct_vhost_scsi_controller"); 1561 1562 spdk_json_write_named_object_begin(w, "params"); 1563 spdk_json_write_named_string(w, "ctrlr", vdev->name); 1564 spdk_json_write_named_string(w, "cpumask", spdk_cpuset_fmt(vdev->cpumask)); 1565 spdk_json_write_object_end(w); 1566 1567 spdk_json_write_object_end(w); 1568 1569 for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 1570 scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i); 1571 if (scsi_dev == NULL) { 1572 continue; 1573 } 1574 1575 lun = spdk_scsi_dev_get_lun(scsi_dev, 0); 1576 1577 spdk_json_write_object_begin(w); 1578 spdk_json_write_named_string(w, "method", "add_vhost_scsi_lun"); 1579 1580 spdk_json_write_named_object_begin(w, "params"); 1581 spdk_json_write_named_string(w, "ctrlr", vdev->name); 1582 spdk_json_write_named_uint32(w, "scsi_target_num", i); 1583 1584 spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun)); 1585 spdk_json_write_object_end(w); 1586 1587 spdk_json_write_object_end(w); 1588 } 1589 } 1590 1591 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi", SPDK_LOG_VHOST_SCSI) 1592 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_queue", SPDK_LOG_VHOST_SCSI_QUEUE) 1593 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_data", SPDK_LOG_VHOST_SCSI_DATA) 1594