1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation 3 */ 4 5 #include <stdint.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <fcntl.h> 9 #include <string.h> 10 #include <errno.h> 11 #include <sys/mman.h> 12 #include <unistd.h> 13 #include <sys/eventfd.h> 14 #include <sys/types.h> 15 #include <sys/stat.h> 16 17 #include <rte_alarm.h> 18 #include <rte_string_fns.h> 19 #include <rte_eal_memconfig.h> 20 #include <rte_malloc.h> 21 #include <rte_io.h> 22 23 #include "vhost.h" 24 #include "virtio_user_dev.h" 25 #include "../virtio_ethdev.h" 26 27 #define VIRTIO_USER_MEM_EVENT_CLB_NAME "virtio_user_mem_event_clb" 28 29 const char * const virtio_user_backend_strings[] = { 30 [VIRTIO_USER_BACKEND_UNKNOWN] = "VIRTIO_USER_BACKEND_UNKNOWN", 31 [VIRTIO_USER_BACKEND_VHOST_USER] = "VHOST_USER", 32 [VIRTIO_USER_BACKEND_VHOST_KERNEL] = "VHOST_NET", 33 [VIRTIO_USER_BACKEND_VHOST_VDPA] = "VHOST_VDPA", 34 }; 35 36 static int 37 virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel) 38 { 39 /* Of all per virtqueue MSGs, make sure VHOST_SET_VRING_CALL come 40 * firstly because vhost depends on this msg to allocate virtqueue 41 * pair. 42 */ 43 struct vhost_vring_file file; 44 int ret; 45 46 file.index = queue_sel; 47 file.fd = dev->callfds[queue_sel]; 48 ret = dev->ops->set_vring_call(dev, &file); 49 if (ret < 0) { 50 PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u", dev->path, queue_sel); 51 return -1; 52 } 53 54 return 0; 55 } 56 57 static int 58 virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) 59 { 60 int ret; 61 struct vhost_vring_file file; 62 struct vhost_vring_state state; 63 struct vring *vring = &dev->vrings.split[queue_sel]; 64 struct vring_packed *pq_vring = &dev->vrings.packed[queue_sel]; 65 struct vhost_vring_addr addr = { 66 .index = queue_sel, 67 .log_guest_addr = 0, 68 .flags = 0, /* disable log */ 69 }; 70 71 if (queue_sel == dev->max_queue_pairs * 2) { 72 if (!dev->scvq) { 73 PMD_INIT_LOG(ERR, "(%s) Shadow control queue expected but missing", 74 dev->path); 75 goto err; 76 } 77 78 /* Use shadow control queue information */ 79 vring = &dev->scvq->vq_split.ring; 80 pq_vring = &dev->scvq->vq_packed.ring; 81 } 82 83 if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) { 84 addr.desc_user_addr = 85 (uint64_t)(uintptr_t)pq_vring->desc; 86 addr.avail_user_addr = 87 (uint64_t)(uintptr_t)pq_vring->driver; 88 addr.used_user_addr = 89 (uint64_t)(uintptr_t)pq_vring->device; 90 } else { 91 addr.desc_user_addr = (uint64_t)(uintptr_t)vring->desc; 92 addr.avail_user_addr = (uint64_t)(uintptr_t)vring->avail; 93 addr.used_user_addr = (uint64_t)(uintptr_t)vring->used; 94 } 95 96 state.index = queue_sel; 97 state.num = vring->num; 98 ret = dev->ops->set_vring_num(dev, &state); 99 if (ret < 0) 100 goto err; 101 102 state.index = queue_sel; 103 state.num = 0; /* no reservation */ 104 if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) 105 state.num |= (1 << 15); 106 ret = dev->ops->set_vring_base(dev, &state); 107 if (ret < 0) 108 goto err; 109 110 ret = dev->ops->set_vring_addr(dev, &addr); 111 if (ret < 0) 112 goto err; 113 114 /* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes 115 * lastly because vhost depends on this msg to judge if 116 * virtio is ready. 117 */ 118 file.index = queue_sel; 119 file.fd = dev->kickfds[queue_sel]; 120 ret = dev->ops->set_vring_kick(dev, &file); 121 if (ret < 0) 122 goto err; 123 124 return 0; 125 err: 126 PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u", dev->path, queue_sel); 127 128 return -1; 129 } 130 131 static int 132 virtio_user_foreach_queue(struct virtio_user_dev *dev, 133 int (*fn)(struct virtio_user_dev *, uint32_t)) 134 { 135 uint32_t i, nr_vq; 136 137 nr_vq = dev->max_queue_pairs * 2; 138 if (dev->hw_cvq) 139 nr_vq++; 140 141 for (i = 0; i < nr_vq; i++) 142 if (fn(dev, i) < 0) 143 return -1; 144 145 return 0; 146 } 147 148 int 149 virtio_user_dev_set_features(struct virtio_user_dev *dev) 150 { 151 uint64_t features; 152 int ret = -1; 153 154 pthread_mutex_lock(&dev->mutex); 155 156 /* Step 0: tell vhost to create queues */ 157 if (virtio_user_foreach_queue(dev, virtio_user_create_queue) < 0) 158 goto error; 159 160 features = dev->features; 161 162 /* Strip VIRTIO_NET_F_MAC, as MAC address is handled in vdev init */ 163 features &= ~(1ull << VIRTIO_NET_F_MAC); 164 /* Strip VIRTIO_NET_F_CTRL_VQ if the devices does not really support control VQ */ 165 if (!dev->hw_cvq) 166 features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ); 167 features &= ~(1ull << VIRTIO_NET_F_STATUS); 168 ret = dev->ops->set_features(dev, features); 169 if (ret < 0) 170 goto error; 171 PMD_DRV_LOG(INFO, "(%s) set features: 0x%" PRIx64, dev->path, features); 172 error: 173 pthread_mutex_unlock(&dev->mutex); 174 175 return ret; 176 } 177 178 int 179 virtio_user_start_device(struct virtio_user_dev *dev) 180 { 181 int ret; 182 183 /* 184 * XXX workaround! 185 * 186 * We need to make sure that the locks will be 187 * taken in the correct order to avoid deadlocks. 188 * 189 * Before releasing this lock, this thread should 190 * not trigger any memory hotplug events. 191 * 192 * This is a temporary workaround, and should be 193 * replaced when we get proper supports from the 194 * memory subsystem in the future. 195 */ 196 rte_mcfg_mem_read_lock(); 197 pthread_mutex_lock(&dev->mutex); 198 199 /* Step 2: share memory regions */ 200 ret = dev->ops->set_memory_table(dev); 201 if (ret < 0) 202 goto error; 203 204 /* Step 3: kick queues */ 205 ret = virtio_user_foreach_queue(dev, virtio_user_kick_queue); 206 if (ret < 0) 207 goto error; 208 209 /* Step 4: enable queues 210 * we enable the 1st queue pair by default. 211 */ 212 ret = dev->ops->enable_qp(dev, 0, 1); 213 if (ret < 0) 214 goto error; 215 216 if (dev->scvq) { 217 ret = dev->ops->cvq_enable(dev, 1); 218 if (ret < 0) 219 goto error; 220 } 221 222 dev->started = true; 223 224 pthread_mutex_unlock(&dev->mutex); 225 rte_mcfg_mem_read_unlock(); 226 227 return 0; 228 error: 229 pthread_mutex_unlock(&dev->mutex); 230 rte_mcfg_mem_read_unlock(); 231 232 PMD_INIT_LOG(ERR, "(%s) Failed to start device", dev->path); 233 234 /* TODO: free resource here or caller to check */ 235 return -1; 236 } 237 238 int virtio_user_stop_device(struct virtio_user_dev *dev) 239 { 240 struct vhost_vring_state state; 241 uint32_t i; 242 int ret; 243 244 pthread_mutex_lock(&dev->mutex); 245 if (!dev->started) 246 goto out; 247 248 for (i = 0; i < dev->max_queue_pairs; ++i) { 249 ret = dev->ops->enable_qp(dev, i, 0); 250 if (ret < 0) 251 goto err; 252 } 253 254 if (dev->scvq) { 255 ret = dev->ops->cvq_enable(dev, 0); 256 if (ret < 0) 257 goto err; 258 } 259 260 /* Stop the backend. */ 261 for (i = 0; i < dev->max_queue_pairs * 2; ++i) { 262 state.index = i; 263 ret = dev->ops->get_vring_base(dev, &state); 264 if (ret < 0) { 265 PMD_DRV_LOG(ERR, "(%s) get_vring_base failed, index=%u", dev->path, i); 266 goto err; 267 } 268 } 269 270 dev->started = false; 271 272 out: 273 pthread_mutex_unlock(&dev->mutex); 274 275 return 0; 276 err: 277 pthread_mutex_unlock(&dev->mutex); 278 279 PMD_INIT_LOG(ERR, "(%s) Failed to stop device", dev->path); 280 281 return -1; 282 } 283 284 static int 285 virtio_user_dev_init_max_queue_pairs(struct virtio_user_dev *dev, uint32_t user_max_qp) 286 { 287 int ret; 288 289 if (!(dev->device_features & (1ULL << VIRTIO_NET_F_MQ))) { 290 dev->max_queue_pairs = 1; 291 return 0; 292 } 293 294 if (!dev->ops->get_config) { 295 dev->max_queue_pairs = user_max_qp; 296 return 0; 297 } 298 299 ret = dev->ops->get_config(dev, (uint8_t *)&dev->max_queue_pairs, 300 offsetof(struct virtio_net_config, max_virtqueue_pairs), 301 sizeof(uint16_t)); 302 if (ret) { 303 /* 304 * We need to know the max queue pair from the device so that 305 * the control queue gets the right index. 306 */ 307 dev->max_queue_pairs = 1; 308 PMD_DRV_LOG(ERR, "(%s) Failed to get max queue pairs from device", dev->path); 309 310 return ret; 311 } 312 313 return 0; 314 } 315 316 int 317 virtio_user_dev_get_rss_config(struct virtio_user_dev *dev, void *dst, size_t offset, int length) 318 { 319 int ret = 0; 320 321 if (!(dev->device_features & (1ULL << VIRTIO_NET_F_RSS))) 322 return -ENOTSUP; 323 324 if (!dev->ops->get_config) 325 return -ENOTSUP; 326 327 ret = dev->ops->get_config(dev, dst, offset, length); 328 if (ret) 329 PMD_DRV_LOG(ERR, "(%s) Failed to get rss config in device", dev->path); 330 331 return ret; 332 } 333 334 int 335 virtio_user_dev_set_mac(struct virtio_user_dev *dev) 336 { 337 int ret = 0; 338 339 if (!(dev->device_features & (1ULL << VIRTIO_NET_F_MAC))) 340 return -ENOTSUP; 341 342 if (!dev->ops->set_config) 343 return -ENOTSUP; 344 345 ret = dev->ops->set_config(dev, dev->mac_addr, 346 offsetof(struct virtio_net_config, mac), 347 RTE_ETHER_ADDR_LEN); 348 if (ret) 349 PMD_DRV_LOG(ERR, "(%s) Failed to set MAC address in device", dev->path); 350 351 return ret; 352 } 353 354 int 355 virtio_user_dev_get_mac(struct virtio_user_dev *dev) 356 { 357 int ret = 0; 358 359 if (!(dev->device_features & (1ULL << VIRTIO_NET_F_MAC))) 360 return -ENOTSUP; 361 362 if (!dev->ops->get_config) 363 return -ENOTSUP; 364 365 ret = dev->ops->get_config(dev, dev->mac_addr, 366 offsetof(struct virtio_net_config, mac), 367 RTE_ETHER_ADDR_LEN); 368 if (ret) 369 PMD_DRV_LOG(ERR, "(%s) Failed to get MAC address from device", dev->path); 370 371 return ret; 372 } 373 374 static void 375 virtio_user_dev_init_mac(struct virtio_user_dev *dev, const char *mac) 376 { 377 struct rte_ether_addr cmdline_mac; 378 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 379 int ret; 380 381 if (mac && rte_ether_unformat_addr(mac, &cmdline_mac) == 0) { 382 /* 383 * MAC address was passed from command-line, try to store 384 * it in the device if it supports it. Otherwise try to use 385 * the device one. 386 */ 387 memcpy(dev->mac_addr, &cmdline_mac, RTE_ETHER_ADDR_LEN); 388 dev->mac_specified = 1; 389 390 /* Setting MAC may fail, continue to get the device one in this case */ 391 virtio_user_dev_set_mac(dev); 392 ret = virtio_user_dev_get_mac(dev); 393 if (ret == -ENOTSUP) 394 goto out; 395 396 if (memcmp(&cmdline_mac, dev->mac_addr, RTE_ETHER_ADDR_LEN)) 397 PMD_DRV_LOG(INFO, "(%s) Device MAC update failed", dev->path); 398 } else { 399 ret = virtio_user_dev_get_mac(dev); 400 if (ret) { 401 PMD_DRV_LOG(ERR, "(%s) No valid MAC in devargs or device, use random", 402 dev->path); 403 return; 404 } 405 406 dev->mac_specified = 1; 407 } 408 out: 409 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, 410 (struct rte_ether_addr *)dev->mac_addr); 411 PMD_DRV_LOG(INFO, "(%s) MAC %s specified", dev->path, buf); 412 } 413 414 static int 415 virtio_user_dev_init_notify(struct virtio_user_dev *dev) 416 { 417 uint32_t i, j, nr_vq; 418 int callfd; 419 int kickfd; 420 421 nr_vq = dev->max_queue_pairs * 2; 422 if (dev->hw_cvq) 423 nr_vq++; 424 425 for (i = 0; i < nr_vq; i++) { 426 /* May use invalid flag, but some backend uses kickfd and 427 * callfd as criteria to judge if dev is alive. so finally we 428 * use real event_fd. 429 */ 430 callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); 431 if (callfd < 0) { 432 PMD_DRV_LOG(ERR, "(%s) callfd error, %s", dev->path, strerror(errno)); 433 goto err; 434 } 435 kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); 436 if (kickfd < 0) { 437 close(callfd); 438 PMD_DRV_LOG(ERR, "(%s) kickfd error, %s", dev->path, strerror(errno)); 439 goto err; 440 } 441 dev->callfds[i] = callfd; 442 dev->kickfds[i] = kickfd; 443 } 444 445 if (dev->device_features & (1ULL << VIRTIO_F_NOTIFICATION_DATA)) 446 if (dev->ops->map_notification_area && 447 dev->ops->map_notification_area(dev)) 448 goto err; 449 450 return 0; 451 err: 452 for (j = 0; j < i; j++) { 453 if (dev->kickfds[j] >= 0) { 454 close(dev->kickfds[j]); 455 dev->kickfds[j] = -1; 456 } 457 if (dev->callfds[j] >= 0) { 458 close(dev->callfds[j]); 459 dev->callfds[j] = -1; 460 } 461 } 462 463 return -1; 464 } 465 466 static void 467 virtio_user_dev_uninit_notify(struct virtio_user_dev *dev) 468 { 469 uint32_t i; 470 471 for (i = 0; i < dev->max_queue_pairs * 2; ++i) { 472 if (dev->kickfds[i] >= 0) { 473 close(dev->kickfds[i]); 474 dev->kickfds[i] = -1; 475 } 476 if (dev->callfds[i] >= 0) { 477 close(dev->callfds[i]); 478 dev->callfds[i] = -1; 479 } 480 } 481 if (dev->ops->unmap_notification_area && dev->notify_area) 482 dev->ops->unmap_notification_area(dev); 483 } 484 485 static int 486 virtio_user_fill_intr_handle(struct virtio_user_dev *dev) 487 { 488 uint32_t i; 489 struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; 490 491 if (eth_dev->intr_handle == NULL) { 492 eth_dev->intr_handle = 493 rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); 494 if (eth_dev->intr_handle == NULL) { 495 PMD_DRV_LOG(ERR, "(%s) failed to allocate intr_handle", dev->path); 496 return -1; 497 } 498 } 499 500 for (i = 0; i < dev->max_queue_pairs; ++i) { 501 if (rte_intr_efds_index_set(eth_dev->intr_handle, i, 502 dev->callfds[2 * i + VTNET_SQ_RQ_QUEUE_IDX])) 503 return -rte_errno; 504 } 505 506 if (rte_intr_nb_efd_set(eth_dev->intr_handle, dev->max_queue_pairs)) 507 return -rte_errno; 508 509 if (rte_intr_max_intr_set(eth_dev->intr_handle, 510 dev->max_queue_pairs + 1)) 511 return -rte_errno; 512 513 if (rte_intr_type_set(eth_dev->intr_handle, RTE_INTR_HANDLE_VDEV)) 514 return -rte_errno; 515 516 /* For virtio vdev, no need to read counter for clean */ 517 if (rte_intr_efd_counter_size_set(eth_dev->intr_handle, 0)) 518 return -rte_errno; 519 520 if (rte_intr_fd_set(eth_dev->intr_handle, dev->ops->get_intr_fd(dev))) 521 return -rte_errno; 522 523 return 0; 524 } 525 526 static void 527 virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused, 528 const void *addr, 529 size_t len __rte_unused, 530 void *arg) 531 { 532 struct virtio_user_dev *dev = arg; 533 struct rte_memseg_list *msl; 534 uint16_t i; 535 int ret = 0; 536 537 /* ignore externally allocated memory */ 538 msl = rte_mem_virt2memseg_list(addr); 539 if (msl->external) 540 return; 541 542 pthread_mutex_lock(&dev->mutex); 543 544 if (dev->started == false) 545 goto exit; 546 547 /* Step 1: pause the active queues */ 548 for (i = 0; i < dev->queue_pairs; i++) { 549 ret = dev->ops->enable_qp(dev, i, 0); 550 if (ret < 0) 551 goto exit; 552 } 553 554 /* Step 2: update memory regions */ 555 ret = dev->ops->set_memory_table(dev); 556 if (ret < 0) 557 goto exit; 558 559 /* Step 3: resume the active queues */ 560 for (i = 0; i < dev->queue_pairs; i++) { 561 ret = dev->ops->enable_qp(dev, i, 1); 562 if (ret < 0) 563 goto exit; 564 } 565 566 exit: 567 pthread_mutex_unlock(&dev->mutex); 568 569 if (ret < 0) 570 PMD_DRV_LOG(ERR, "(%s) Failed to update memory table", dev->path); 571 } 572 573 static int 574 virtio_user_dev_setup(struct virtio_user_dev *dev) 575 { 576 if (dev->is_server) { 577 if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER) { 578 PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!"); 579 return -1; 580 } 581 } 582 583 switch (dev->backend_type) { 584 case VIRTIO_USER_BACKEND_VHOST_USER: 585 dev->ops = &virtio_ops_user; 586 break; 587 case VIRTIO_USER_BACKEND_VHOST_KERNEL: 588 dev->ops = &virtio_ops_kernel; 589 break; 590 case VIRTIO_USER_BACKEND_VHOST_VDPA: 591 dev->ops = &virtio_ops_vdpa; 592 break; 593 default: 594 PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path); 595 return -1; 596 } 597 598 if (dev->ops->setup(dev) < 0) { 599 PMD_INIT_LOG(ERR, "(%s) Failed to setup backend", dev->path); 600 return -1; 601 } 602 603 return 0; 604 } 605 606 static int 607 virtio_user_alloc_vrings(struct virtio_user_dev *dev) 608 { 609 int i, size, nr_vrings; 610 bool packed_ring = !!(dev->device_features & (1ull << VIRTIO_F_RING_PACKED)); 611 612 nr_vrings = dev->max_queue_pairs * 2; 613 if (dev->device_features & (1ull << VIRTIO_NET_F_MQ)) 614 nr_vrings++; 615 616 dev->callfds = rte_zmalloc("virtio_user_dev", nr_vrings * sizeof(*dev->callfds), 0); 617 if (!dev->callfds) { 618 PMD_INIT_LOG(ERR, "(%s) Failed to alloc callfds", dev->path); 619 return -1; 620 } 621 622 dev->kickfds = rte_zmalloc("virtio_user_dev", nr_vrings * sizeof(*dev->kickfds), 0); 623 if (!dev->kickfds) { 624 PMD_INIT_LOG(ERR, "(%s) Failed to alloc kickfds", dev->path); 625 goto free_callfds; 626 } 627 628 for (i = 0; i < nr_vrings; i++) { 629 dev->callfds[i] = -1; 630 dev->kickfds[i] = -1; 631 } 632 633 if (packed_ring) 634 size = sizeof(*dev->vrings.packed); 635 else 636 size = sizeof(*dev->vrings.split); 637 dev->vrings.ptr = rte_zmalloc("virtio_user_dev", nr_vrings * size, 0); 638 if (!dev->vrings.ptr) { 639 PMD_INIT_LOG(ERR, "(%s) Failed to alloc vrings metadata", dev->path); 640 goto free_kickfds; 641 } 642 643 if (packed_ring) { 644 dev->packed_queues = rte_zmalloc("virtio_user_dev", 645 nr_vrings * sizeof(*dev->packed_queues), 0); 646 if (!dev->packed_queues) { 647 PMD_INIT_LOG(ERR, "(%s) Failed to alloc packed queues metadata", 648 dev->path); 649 goto free_vrings; 650 } 651 } 652 653 dev->qp_enabled = rte_zmalloc("virtio_user_dev", 654 dev->max_queue_pairs * sizeof(*dev->qp_enabled), 0); 655 if (!dev->qp_enabled) { 656 PMD_INIT_LOG(ERR, "(%s) Failed to alloc QP enable states", dev->path); 657 goto free_packed_queues; 658 } 659 660 return 0; 661 662 free_packed_queues: 663 rte_free(dev->packed_queues); 664 dev->packed_queues = NULL; 665 free_vrings: 666 rte_free(dev->vrings.ptr); 667 dev->vrings.ptr = NULL; 668 free_kickfds: 669 rte_free(dev->kickfds); 670 dev->kickfds = NULL; 671 free_callfds: 672 rte_free(dev->callfds); 673 dev->callfds = NULL; 674 675 return -1; 676 } 677 678 static void 679 virtio_user_free_vrings(struct virtio_user_dev *dev) 680 { 681 rte_free(dev->qp_enabled); 682 dev->qp_enabled = NULL; 683 rte_free(dev->packed_queues); 684 dev->packed_queues = NULL; 685 rte_free(dev->vrings.ptr); 686 dev->vrings.ptr = NULL; 687 rte_free(dev->kickfds); 688 dev->kickfds = NULL; 689 rte_free(dev->callfds); 690 dev->callfds = NULL; 691 } 692 693 /* Use below macro to filter features from vhost backend */ 694 #define VIRTIO_USER_SUPPORTED_FEATURES \ 695 (1ULL << VIRTIO_NET_F_MAC | \ 696 1ULL << VIRTIO_NET_F_STATUS | \ 697 1ULL << VIRTIO_NET_F_MQ | \ 698 1ULL << VIRTIO_NET_F_CTRL_MAC_ADDR | \ 699 1ULL << VIRTIO_NET_F_CTRL_VQ | \ 700 1ULL << VIRTIO_NET_F_CTRL_RX | \ 701 1ULL << VIRTIO_NET_F_CTRL_VLAN | \ 702 1ULL << VIRTIO_NET_F_CSUM | \ 703 1ULL << VIRTIO_NET_F_HOST_TSO4 | \ 704 1ULL << VIRTIO_NET_F_HOST_TSO6 | \ 705 1ULL << VIRTIO_NET_F_MRG_RXBUF | \ 706 1ULL << VIRTIO_RING_F_INDIRECT_DESC | \ 707 1ULL << VIRTIO_NET_F_GUEST_CSUM | \ 708 1ULL << VIRTIO_NET_F_GUEST_TSO4 | \ 709 1ULL << VIRTIO_NET_F_GUEST_TSO6 | \ 710 1ULL << VIRTIO_F_IN_ORDER | \ 711 1ULL << VIRTIO_F_VERSION_1 | \ 712 1ULL << VIRTIO_F_RING_PACKED | \ 713 1ULL << VIRTIO_F_NOTIFICATION_DATA | \ 714 1ULL << VIRTIO_F_ORDER_PLATFORM | \ 715 1ULL << VIRTIO_NET_F_RSS) 716 717 int 718 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, uint16_t queues, 719 int cq, int queue_size, const char *mac, char **ifname, 720 int server, int mrg_rxbuf, int in_order, int packed_vq, 721 enum virtio_user_backend_type backend_type) 722 { 723 uint64_t backend_features; 724 725 pthread_mutex_init(&dev->mutex, NULL); 726 strlcpy(dev->path, path, PATH_MAX); 727 728 dev->started = 0; 729 dev->queue_pairs = 1; /* mq disabled by default */ 730 dev->max_queue_pairs = queues; /* initialize to user requested value for kernel backend */ 731 dev->queue_size = queue_size; 732 dev->is_server = server; 733 dev->mac_specified = 0; 734 dev->frontend_features = 0; 735 dev->unsupported_features = 0; 736 dev->backend_type = backend_type; 737 dev->ifname = *ifname; 738 739 if (virtio_user_dev_setup(dev) < 0) { 740 PMD_INIT_LOG(ERR, "(%s) backend set up fails", dev->path); 741 return -1; 742 } 743 744 if (dev->ops->set_owner(dev) < 0) { 745 PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path); 746 goto destroy; 747 } 748 749 if (dev->ops->get_backend_features(&backend_features) < 0) { 750 PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path); 751 goto destroy; 752 } 753 754 dev->unsupported_features = ~(VIRTIO_USER_SUPPORTED_FEATURES | backend_features); 755 756 if (dev->ops->get_features(dev, &dev->device_features) < 0) { 757 PMD_INIT_LOG(ERR, "(%s) Failed to get device features", dev->path); 758 goto destroy; 759 } 760 761 virtio_user_dev_init_mac(dev, mac); 762 763 if (virtio_user_dev_init_max_queue_pairs(dev, queues)) 764 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ); 765 766 if (dev->max_queue_pairs > 1 || dev->hw_cvq) 767 cq = 1; 768 769 if (!mrg_rxbuf) 770 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF); 771 772 if (!in_order) 773 dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER); 774 775 if (!packed_vq) 776 dev->unsupported_features |= (1ull << VIRTIO_F_RING_PACKED); 777 778 if (dev->mac_specified) 779 dev->frontend_features |= (1ull << VIRTIO_NET_F_MAC); 780 else 781 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MAC); 782 783 if (cq) { 784 /* Except for vDPA, the device does not really need to know 785 * anything about CQ, so if necessary, we just claim to support 786 * control queue. 787 */ 788 dev->frontend_features |= (1ull << VIRTIO_NET_F_CTRL_VQ); 789 } else { 790 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VQ); 791 /* Also disable features that depend on VIRTIO_NET_F_CTRL_VQ */ 792 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_RX); 793 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VLAN); 794 dev->unsupported_features |= 795 (1ull << VIRTIO_NET_F_GUEST_ANNOUNCE); 796 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ); 797 dev->unsupported_features |= 798 (1ull << VIRTIO_NET_F_CTRL_MAC_ADDR); 799 } 800 801 /* The backend will not report this feature, we add it explicitly */ 802 if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) 803 dev->frontend_features |= (1ull << VIRTIO_NET_F_STATUS); 804 805 dev->frontend_features &= ~dev->unsupported_features; 806 dev->device_features &= ~dev->unsupported_features; 807 808 if (virtio_user_alloc_vrings(dev) < 0) { 809 PMD_INIT_LOG(ERR, "(%s) Failed to allocate vring metadata", dev->path); 810 goto destroy; 811 } 812 813 if (virtio_user_dev_init_notify(dev) < 0) { 814 PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers", dev->path); 815 goto free_vrings; 816 } 817 818 if (virtio_user_fill_intr_handle(dev) < 0) { 819 PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler", dev->path); 820 goto notify_uninit; 821 } 822 823 if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME, 824 virtio_user_mem_event_cb, dev)) { 825 if (rte_errno != ENOTSUP) { 826 PMD_INIT_LOG(ERR, "(%s) Failed to register mem event callback", 827 dev->path); 828 goto notify_uninit; 829 } 830 } 831 832 *ifname = NULL; 833 return 0; 834 835 notify_uninit: 836 virtio_user_dev_uninit_notify(dev); 837 free_vrings: 838 virtio_user_free_vrings(dev); 839 destroy: 840 dev->ops->destroy(dev); 841 842 return -1; 843 } 844 845 void 846 virtio_user_dev_uninit(struct virtio_user_dev *dev) 847 { 848 struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; 849 850 rte_intr_instance_free(eth_dev->intr_handle); 851 eth_dev->intr_handle = NULL; 852 853 virtio_user_stop_device(dev); 854 855 rte_mem_event_callback_unregister(VIRTIO_USER_MEM_EVENT_CLB_NAME, dev); 856 857 virtio_user_dev_uninit_notify(dev); 858 859 virtio_user_free_vrings(dev); 860 861 free(dev->ifname); 862 863 if (dev->is_server) 864 unlink(dev->path); 865 866 dev->ops->destroy(dev); 867 } 868 869 static uint8_t 870 virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs) 871 { 872 uint16_t i; 873 uint8_t ret = 0; 874 875 if (q_pairs > dev->max_queue_pairs) { 876 PMD_INIT_LOG(ERR, "(%s) multi-q config %u, but only %u supported", 877 dev->path, q_pairs, dev->max_queue_pairs); 878 return -1; 879 } 880 881 for (i = 0; i < q_pairs; ++i) 882 ret |= dev->ops->enable_qp(dev, i, 1); 883 for (i = q_pairs; i < dev->max_queue_pairs; ++i) 884 ret |= dev->ops->enable_qp(dev, i, 0); 885 886 dev->queue_pairs = q_pairs; 887 888 return ret; 889 } 890 891 #define CVQ_MAX_DATA_DESCS 32 892 893 static uint32_t 894 virtio_user_handle_ctrl_msg_split(struct virtio_user_dev *dev, struct vring *vring, 895 uint16_t idx_hdr) 896 { 897 struct virtio_net_ctrl_hdr *hdr; 898 virtio_net_ctrl_ack status = ~0; 899 uint16_t i, idx_data, idx_status; 900 uint32_t n_descs = 0; 901 int dlen[CVQ_MAX_DATA_DESCS], nb_dlen = 0; 902 903 /* locate desc for header, data, and status */ 904 idx_data = vring->desc[idx_hdr].next; 905 n_descs++; 906 907 i = idx_data; 908 while (vring->desc[i].flags == VRING_DESC_F_NEXT) { 909 dlen[nb_dlen++] = vring->desc[i].len; 910 i = vring->desc[i].next; 911 n_descs++; 912 } 913 914 /* locate desc for status */ 915 idx_status = i; 916 n_descs++; 917 918 hdr = (void *)(uintptr_t)vring->desc[idx_hdr].addr; 919 if (hdr->class == VIRTIO_NET_CTRL_MQ && 920 hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) { 921 uint16_t queues; 922 923 queues = *(uint16_t *)(uintptr_t)vring->desc[idx_data].addr; 924 status = virtio_user_handle_mq(dev, queues); 925 } else if (hdr->class == VIRTIO_NET_CTRL_MQ && hdr->cmd == VIRTIO_NET_CTRL_MQ_RSS_CONFIG) { 926 struct virtio_net_ctrl_rss *rss; 927 928 rss = (struct virtio_net_ctrl_rss *)(uintptr_t)vring->desc[idx_data].addr; 929 status = virtio_user_handle_mq(dev, rss->max_tx_vq); 930 } else if (hdr->class == VIRTIO_NET_CTRL_RX || 931 hdr->class == VIRTIO_NET_CTRL_MAC || 932 hdr->class == VIRTIO_NET_CTRL_VLAN) { 933 status = 0; 934 } 935 936 if (!status && dev->scvq) 937 status = virtio_send_command(&dev->scvq->cq, 938 (struct virtio_pmd_ctrl *)hdr, dlen, nb_dlen); 939 940 /* Update status */ 941 *(virtio_net_ctrl_ack *)(uintptr_t)vring->desc[idx_status].addr = status; 942 943 return n_descs; 944 } 945 946 static inline int 947 desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter) 948 { 949 uint16_t flags = rte_atomic_load_explicit(&desc->flags, rte_memory_order_acquire); 950 951 return wrap_counter == !!(flags & VRING_PACKED_DESC_F_AVAIL) && 952 wrap_counter != !!(flags & VRING_PACKED_DESC_F_USED); 953 } 954 955 static uint32_t 956 virtio_user_handle_ctrl_msg_packed(struct virtio_user_dev *dev, 957 struct vring_packed *vring, 958 uint16_t idx_hdr) 959 { 960 struct virtio_net_ctrl_hdr *hdr; 961 virtio_net_ctrl_ack status = ~0; 962 uint16_t idx_data, idx_status; 963 /* initialize to one, header is first */ 964 uint32_t n_descs = 1; 965 int dlen[CVQ_MAX_DATA_DESCS], nb_dlen = 0; 966 967 /* locate desc for header, data, and status */ 968 idx_data = idx_hdr + 1; 969 if (idx_data >= dev->queue_size) 970 idx_data -= dev->queue_size; 971 972 n_descs++; 973 974 idx_status = idx_data; 975 while (vring->desc[idx_status].flags & VRING_DESC_F_NEXT) { 976 dlen[nb_dlen++] = vring->desc[idx_status].len; 977 idx_status++; 978 if (idx_status >= dev->queue_size) 979 idx_status -= dev->queue_size; 980 n_descs++; 981 } 982 983 hdr = (void *)(uintptr_t)vring->desc[idx_hdr].addr; 984 if (hdr->class == VIRTIO_NET_CTRL_MQ && 985 hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) { 986 uint16_t queues; 987 988 queues = *(uint16_t *)(uintptr_t) 989 vring->desc[idx_data].addr; 990 status = virtio_user_handle_mq(dev, queues); 991 } else if (hdr->class == VIRTIO_NET_CTRL_MQ && hdr->cmd == VIRTIO_NET_CTRL_MQ_RSS_CONFIG) { 992 struct virtio_net_ctrl_rss *rss; 993 994 rss = (struct virtio_net_ctrl_rss *)(uintptr_t)vring->desc[idx_data].addr; 995 status = virtio_user_handle_mq(dev, rss->max_tx_vq); 996 } else if (hdr->class == VIRTIO_NET_CTRL_RX || 997 hdr->class == VIRTIO_NET_CTRL_MAC || 998 hdr->class == VIRTIO_NET_CTRL_VLAN) { 999 status = 0; 1000 } 1001 1002 if (!status && dev->scvq) 1003 status = virtio_send_command(&dev->scvq->cq, 1004 (struct virtio_pmd_ctrl *)hdr, dlen, nb_dlen); 1005 1006 /* Update status */ 1007 *(virtio_net_ctrl_ack *)(uintptr_t) 1008 vring->desc[idx_status].addr = status; 1009 1010 /* Update used descriptor */ 1011 vring->desc[idx_hdr].id = vring->desc[idx_status].id; 1012 vring->desc[idx_hdr].len = sizeof(status); 1013 1014 return n_descs; 1015 } 1016 1017 static void 1018 virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx) 1019 { 1020 struct virtio_user_queue *vq = &dev->packed_queues[queue_idx]; 1021 struct vring_packed *vring = &dev->vrings.packed[queue_idx]; 1022 uint16_t n_descs, flags; 1023 1024 /* Perform a load-acquire barrier in desc_is_avail to 1025 * enforce the ordering between desc flags and desc 1026 * content. 1027 */ 1028 while (desc_is_avail(&vring->desc[vq->used_idx], 1029 vq->used_wrap_counter)) { 1030 1031 n_descs = virtio_user_handle_ctrl_msg_packed(dev, vring, 1032 vq->used_idx); 1033 1034 flags = VRING_DESC_F_WRITE; 1035 if (vq->used_wrap_counter) 1036 flags |= VRING_PACKED_DESC_F_AVAIL_USED; 1037 1038 rte_atomic_store_explicit(&vring->desc[vq->used_idx].flags, flags, 1039 rte_memory_order_release); 1040 1041 vq->used_idx += n_descs; 1042 if (vq->used_idx >= dev->queue_size) { 1043 vq->used_idx -= dev->queue_size; 1044 vq->used_wrap_counter ^= 1; 1045 } 1046 } 1047 } 1048 1049 static void 1050 virtio_user_handle_cq_split(struct virtio_user_dev *dev, uint16_t queue_idx) 1051 { 1052 uint16_t avail_idx, desc_idx; 1053 struct vring_used_elem *uep; 1054 uint32_t n_descs; 1055 struct vring *vring = &dev->vrings.split[queue_idx]; 1056 1057 /* Consume avail ring, using used ring idx as first one */ 1058 while (rte_atomic_load_explicit(&vring->used->idx, rte_memory_order_relaxed) 1059 != vring->avail->idx) { 1060 avail_idx = rte_atomic_load_explicit(&vring->used->idx, rte_memory_order_relaxed) 1061 & (vring->num - 1); 1062 desc_idx = vring->avail->ring[avail_idx]; 1063 1064 n_descs = virtio_user_handle_ctrl_msg_split(dev, vring, desc_idx); 1065 1066 /* Update used ring */ 1067 uep = &vring->used->ring[avail_idx]; 1068 uep->id = desc_idx; 1069 uep->len = n_descs; 1070 1071 rte_atomic_fetch_add_explicit(&vring->used->idx, 1, rte_memory_order_relaxed); 1072 } 1073 } 1074 1075 void 1076 virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx) 1077 { 1078 if (virtio_with_packed_queue(&dev->hw)) 1079 virtio_user_handle_cq_packed(dev, queue_idx); 1080 else 1081 virtio_user_handle_cq_split(dev, queue_idx); 1082 } 1083 1084 static void 1085 virtio_user_control_queue_notify(struct virtqueue *vq, void *cookie) 1086 { 1087 struct virtio_user_dev *dev = cookie; 1088 uint64_t notify_data = 1; 1089 1090 if (!dev->notify_area) { 1091 if (write(dev->kickfds[vq->vq_queue_index], ¬ify_data, sizeof(notify_data)) < 0) 1092 PMD_DRV_LOG(ERR, "failed to kick backend: %s", 1093 strerror(errno)); 1094 return; 1095 } else if (!virtio_with_feature(&dev->hw, VIRTIO_F_NOTIFICATION_DATA)) { 1096 rte_write16(vq->vq_queue_index, vq->notify_addr); 1097 return; 1098 } 1099 1100 if (virtio_with_packed_queue(&dev->hw)) { 1101 /* Bit[0:15]: vq queue index 1102 * Bit[16:30]: avail index 1103 * Bit[31]: avail wrap counter 1104 */ 1105 notify_data = ((uint32_t)(!!(vq->vq_packed.cached_flags & 1106 VRING_PACKED_DESC_F_AVAIL)) << 31) | 1107 ((uint32_t)vq->vq_avail_idx << 16) | 1108 vq->vq_queue_index; 1109 } else { 1110 /* Bit[0:15]: vq queue index 1111 * Bit[16:31]: avail index 1112 */ 1113 notify_data = ((uint32_t)vq->vq_avail_idx << 16) | 1114 vq->vq_queue_index; 1115 } 1116 rte_write32(notify_data, vq->notify_addr); 1117 } 1118 1119 int 1120 virtio_user_dev_create_shadow_cvq(struct virtio_user_dev *dev, struct virtqueue *vq) 1121 { 1122 char name[VIRTQUEUE_MAX_NAME_SZ]; 1123 struct virtqueue *scvq; 1124 1125 snprintf(name, sizeof(name), "port%d_shadow_cvq", vq->hw->port_id); 1126 scvq = virtqueue_alloc(&dev->hw, vq->vq_queue_index, vq->vq_nentries, 1127 VTNET_CQ, SOCKET_ID_ANY, name); 1128 if (!scvq) { 1129 PMD_INIT_LOG(ERR, "(%s) Failed to alloc shadow control vq\n", dev->path); 1130 return -ENOMEM; 1131 } 1132 1133 scvq->cq.notify_queue = &virtio_user_control_queue_notify; 1134 scvq->cq.notify_cookie = dev; 1135 scvq->notify_addr = vq->notify_addr; 1136 dev->scvq = scvq; 1137 1138 return 0; 1139 } 1140 1141 void 1142 virtio_user_dev_destroy_shadow_cvq(struct virtio_user_dev *dev) 1143 { 1144 if (!dev->scvq) 1145 return; 1146 1147 virtqueue_free(dev->scvq); 1148 dev->scvq = NULL; 1149 } 1150 1151 int 1152 virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status) 1153 { 1154 int ret; 1155 1156 pthread_mutex_lock(&dev->mutex); 1157 dev->status = status; 1158 ret = dev->ops->set_status(dev, status); 1159 if (ret && ret != -ENOTSUP) 1160 PMD_INIT_LOG(ERR, "(%s) Failed to set backend status", dev->path); 1161 1162 pthread_mutex_unlock(&dev->mutex); 1163 return ret; 1164 } 1165 1166 int 1167 virtio_user_dev_update_status(struct virtio_user_dev *dev) 1168 { 1169 int ret; 1170 uint8_t status; 1171 1172 pthread_mutex_lock(&dev->mutex); 1173 1174 ret = dev->ops->get_status(dev, &status); 1175 if (!ret) { 1176 dev->status = status; 1177 PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n" 1178 "\t-RESET: %u\n" 1179 "\t-ACKNOWLEDGE: %u\n" 1180 "\t-DRIVER: %u\n" 1181 "\t-DRIVER_OK: %u\n" 1182 "\t-FEATURES_OK: %u\n" 1183 "\t-DEVICE_NEED_RESET: %u\n" 1184 "\t-FAILED: %u", 1185 dev->status, 1186 (dev->status == VIRTIO_CONFIG_STATUS_RESET), 1187 !!(dev->status & VIRTIO_CONFIG_STATUS_ACK), 1188 !!(dev->status & VIRTIO_CONFIG_STATUS_DRIVER), 1189 !!(dev->status & VIRTIO_CONFIG_STATUS_DRIVER_OK), 1190 !!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK), 1191 !!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET), 1192 !!(dev->status & VIRTIO_CONFIG_STATUS_FAILED)); 1193 } else if (ret != -ENOTSUP) { 1194 PMD_INIT_LOG(ERR, "(%s) Failed to get backend status", dev->path); 1195 } 1196 1197 pthread_mutex_unlock(&dev->mutex); 1198 return ret; 1199 } 1200 1201 int 1202 virtio_user_dev_update_link_state(struct virtio_user_dev *dev) 1203 { 1204 if (dev->ops->update_link_state) 1205 return dev->ops->update_link_state(dev); 1206 1207 return 0; 1208 } 1209 1210 static void 1211 virtio_user_dev_reset_queues_packed(struct rte_eth_dev *eth_dev) 1212 { 1213 struct virtio_user_dev *dev = eth_dev->data->dev_private; 1214 struct virtio_hw *hw = &dev->hw; 1215 struct virtnet_rx *rxvq; 1216 struct virtnet_tx *txvq; 1217 uint16_t i; 1218 1219 /* Add lock to avoid queue contention. */ 1220 rte_spinlock_lock(&hw->state_lock); 1221 hw->started = 0; 1222 1223 /* 1224 * Waiting for datapath to complete before resetting queues. 1225 * 1 ms should be enough for the ongoing Tx/Rx function to finish. 1226 */ 1227 rte_delay_ms(1); 1228 1229 /* Vring reset for each Tx queue and Rx queue. */ 1230 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { 1231 rxvq = eth_dev->data->rx_queues[i]; 1232 virtqueue_rxvq_reset_packed(virtnet_rxq_to_vq(rxvq)); 1233 virtio_dev_rx_queue_setup_finish(eth_dev, i); 1234 } 1235 1236 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { 1237 txvq = eth_dev->data->tx_queues[i]; 1238 virtqueue_txvq_reset_packed(virtnet_txq_to_vq(txvq)); 1239 } 1240 1241 hw->started = 1; 1242 rte_spinlock_unlock(&hw->state_lock); 1243 } 1244 1245 void 1246 virtio_user_dev_delayed_disconnect_handler(void *param) 1247 { 1248 struct virtio_user_dev *dev = param; 1249 struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; 1250 1251 if (rte_intr_disable(eth_dev->intr_handle) < 0) { 1252 PMD_DRV_LOG(ERR, "interrupt disable failed"); 1253 return; 1254 } 1255 PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d", 1256 rte_intr_fd_get(eth_dev->intr_handle)); 1257 if (rte_intr_callback_unregister(eth_dev->intr_handle, 1258 virtio_interrupt_handler, 1259 eth_dev) != 1) 1260 PMD_DRV_LOG(ERR, "interrupt unregister failed"); 1261 1262 if (dev->is_server) { 1263 if (dev->ops->server_disconnect) 1264 dev->ops->server_disconnect(dev); 1265 1266 rte_intr_fd_set(eth_dev->intr_handle, 1267 dev->ops->get_intr_fd(dev)); 1268 1269 PMD_DRV_LOG(DEBUG, "Registering intr fd: %d", 1270 rte_intr_fd_get(eth_dev->intr_handle)); 1271 1272 if (rte_intr_callback_register(eth_dev->intr_handle, 1273 virtio_interrupt_handler, 1274 eth_dev)) 1275 PMD_DRV_LOG(ERR, "interrupt register failed"); 1276 1277 if (rte_intr_enable(eth_dev->intr_handle) < 0) { 1278 PMD_DRV_LOG(ERR, "interrupt enable failed"); 1279 return; 1280 } 1281 } 1282 } 1283 1284 static void 1285 virtio_user_dev_delayed_intr_reconfig_handler(void *param) 1286 { 1287 struct virtio_user_dev *dev = param; 1288 struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; 1289 1290 PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d", 1291 rte_intr_fd_get(eth_dev->intr_handle)); 1292 1293 if (rte_intr_callback_unregister(eth_dev->intr_handle, 1294 virtio_interrupt_handler, 1295 eth_dev) != 1) 1296 PMD_DRV_LOG(ERR, "interrupt unregister failed"); 1297 1298 rte_intr_fd_set(eth_dev->intr_handle, dev->ops->get_intr_fd(dev)); 1299 1300 PMD_DRV_LOG(DEBUG, "Registering intr fd: %d", 1301 rte_intr_fd_get(eth_dev->intr_handle)); 1302 1303 if (rte_intr_callback_register(eth_dev->intr_handle, 1304 virtio_interrupt_handler, eth_dev)) 1305 PMD_DRV_LOG(ERR, "interrupt register failed"); 1306 1307 if (rte_intr_enable(eth_dev->intr_handle) < 0) 1308 PMD_DRV_LOG(ERR, "interrupt enable failed"); 1309 } 1310 1311 int 1312 virtio_user_dev_server_reconnect(struct virtio_user_dev *dev) 1313 { 1314 int ret, old_status; 1315 struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; 1316 struct virtio_hw *hw = &dev->hw; 1317 1318 if (!dev->ops->server_reconnect) { 1319 PMD_DRV_LOG(ERR, "(%s) Missing server reconnect callback", dev->path); 1320 return -1; 1321 } 1322 1323 if (dev->ops->server_reconnect(dev)) { 1324 PMD_DRV_LOG(ERR, "(%s) Reconnect callback call failed", dev->path); 1325 return -1; 1326 } 1327 1328 old_status = dev->status; 1329 1330 virtio_reset(hw); 1331 1332 virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); 1333 1334 virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); 1335 1336 if (dev->ops->get_features(dev, &dev->device_features) < 0) { 1337 PMD_INIT_LOG(ERR, "get_features failed: %s", 1338 strerror(errno)); 1339 return -1; 1340 } 1341 1342 /* unmask vhost-user unsupported features */ 1343 dev->device_features &= ~(dev->unsupported_features); 1344 1345 dev->features &= (dev->device_features | dev->frontend_features); 1346 1347 /* For packed ring, resetting queues is required in reconnection. */ 1348 if (virtio_with_packed_queue(hw) && 1349 (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) { 1350 PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped" 1351 " when packed ring reconnecting."); 1352 virtio_user_dev_reset_queues_packed(eth_dev); 1353 } 1354 1355 virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK); 1356 1357 /* Start the device */ 1358 virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK); 1359 if (!dev->started) 1360 return -1; 1361 1362 if (dev->queue_pairs > 1) { 1363 ret = virtio_user_handle_mq(dev, dev->queue_pairs); 1364 if (ret != 0) { 1365 PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!"); 1366 return -1; 1367 } 1368 } 1369 if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) { 1370 if (rte_intr_disable(eth_dev->intr_handle) < 0) { 1371 PMD_DRV_LOG(ERR, "interrupt disable failed"); 1372 return -1; 1373 } 1374 /* 1375 * This function can be called from the interrupt handler, so 1376 * we can't unregister interrupt handler here. Setting 1377 * alarm to do that later. 1378 */ 1379 rte_eal_alarm_set(1, 1380 virtio_user_dev_delayed_intr_reconfig_handler, 1381 (void *)dev); 1382 } 1383 PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!"); 1384 return 0; 1385 } 1386