1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation. 3 * Copyright(c) 2014 6WIND S.A. 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <sys/queue.h> 10 11 #include <bus_driver.h> 12 #include <rte_class.h> 13 #include <rte_dev.h> 14 #include <rte_devargs.h> 15 #include <rte_errno.h> 16 #include <rte_log.h> 17 #include <rte_spinlock.h> 18 #include <rte_string_fns.h> 19 20 #include "eal_private.h" 21 #include "hotplug_mp.h" 22 23 const char * 24 rte_driver_name(const struct rte_driver *driver) 25 { 26 return driver->name; 27 } 28 29 /** 30 * The device event callback description. 31 * 32 * It contains callback address to be registered by user application, 33 * the pointer to the parameters for callback, and the device name. 34 */ 35 struct dev_event_callback { 36 TAILQ_ENTRY(dev_event_callback) next; /**< Callbacks list */ 37 rte_dev_event_cb_fn cb_fn; /**< Callback address */ 38 void *cb_arg; /**< Callback parameter */ 39 char *dev_name; /**< Callback device name, NULL is for all device */ 40 uint32_t active; /**< Callback is executing */ 41 }; 42 43 /** @internal Structure to keep track of registered callbacks */ 44 TAILQ_HEAD(dev_event_cb_list, dev_event_callback); 45 46 /* The device event callback list for all registered callbacks. */ 47 static struct dev_event_cb_list dev_event_cbs; 48 49 /* spinlock for device callbacks */ 50 static rte_spinlock_t dev_event_lock = RTE_SPINLOCK_INITIALIZER; 51 52 struct dev_next_ctx { 53 struct rte_dev_iterator *it; 54 const char *bus_str; 55 const char *cls_str; 56 }; 57 58 #define CTX(it, bus_str, cls_str) \ 59 (&(const struct dev_next_ctx){ \ 60 .it = it, \ 61 .bus_str = bus_str, \ 62 .cls_str = cls_str, \ 63 }) 64 65 #define ITCTX(ptr) \ 66 (((struct dev_next_ctx *)(intptr_t)ptr)->it) 67 68 #define BUSCTX(ptr) \ 69 (((struct dev_next_ctx *)(intptr_t)ptr)->bus_str) 70 71 #define CLSCTX(ptr) \ 72 (((struct dev_next_ctx *)(intptr_t)ptr)->cls_str) 73 74 static int cmp_dev_name(const struct rte_device *dev, const void *_name) 75 { 76 const char *name = _name; 77 78 return strcmp(dev->name, name); 79 } 80 81 int 82 rte_dev_is_probed(const struct rte_device *dev) 83 { 84 /* The field driver should be set only when the probe is successful. */ 85 return dev->driver != NULL; 86 } 87 88 /* helper function to build devargs, caller should free the memory */ 89 static int 90 build_devargs(const char *busname, const char *devname, 91 const char *drvargs, char **devargs) 92 { 93 int length; 94 95 length = snprintf(NULL, 0, "%s:%s,%s", busname, devname, drvargs); 96 if (length < 0) 97 return -EINVAL; 98 99 *devargs = malloc(length + 1); 100 if (*devargs == NULL) 101 return -ENOMEM; 102 103 length = snprintf(*devargs, length + 1, "%s:%s,%s", 104 busname, devname, drvargs); 105 if (length < 0) { 106 free(*devargs); 107 return -EINVAL; 108 } 109 110 return 0; 111 } 112 113 int 114 rte_eal_hotplug_add(const char *busname, const char *devname, 115 const char *drvargs) 116 { 117 118 char *devargs; 119 int ret; 120 121 ret = build_devargs(busname, devname, drvargs, &devargs); 122 if (ret != 0) 123 return ret; 124 125 ret = rte_dev_probe(devargs); 126 free(devargs); 127 128 return ret; 129 } 130 131 /* probe device at local process. */ 132 int 133 local_dev_probe(const char *devargs, struct rte_device **new_dev) 134 { 135 struct rte_device *dev; 136 struct rte_devargs *da; 137 int ret; 138 139 *new_dev = NULL; 140 da = calloc(1, sizeof(*da)); 141 if (da == NULL) 142 return -ENOMEM; 143 144 ret = rte_devargs_parse(da, devargs); 145 if (ret) 146 goto err_devarg; 147 148 if (da->bus->plug == NULL) { 149 RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n", 150 da->bus->name); 151 ret = -ENOTSUP; 152 goto err_devarg; 153 } 154 155 ret = rte_devargs_insert(&da); 156 if (ret) 157 goto err_devarg; 158 159 /* the rte_devargs will be referenced in the matching rte_device */ 160 ret = da->bus->scan(); 161 if (ret) 162 goto err_devarg; 163 164 dev = da->bus->find_device(NULL, cmp_dev_name, da->name); 165 if (dev == NULL) { 166 RTE_LOG(ERR, EAL, "Cannot find device (%s)\n", 167 da->name); 168 ret = -ENODEV; 169 goto err_devarg; 170 } 171 /* Since there is a matching device, it is now its responsibility 172 * to manage the devargs we've just inserted. From this point 173 * those devargs shouldn't be removed manually anymore. 174 */ 175 176 ret = dev->bus->plug(dev); 177 if (ret > 0) 178 ret = -ENOTSUP; 179 180 if (ret && !rte_dev_is_probed(dev)) { /* if hasn't ever succeeded */ 181 RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n", 182 dev->name); 183 return ret; 184 } 185 186 *new_dev = dev; 187 return ret; 188 189 err_devarg: 190 if (rte_devargs_remove(da) != 0) { 191 rte_devargs_reset(da); 192 free(da); 193 } 194 return ret; 195 } 196 197 int 198 rte_dev_probe(const char *devargs) 199 { 200 struct eal_dev_mp_req req; 201 struct rte_device *dev; 202 int ret; 203 204 memset(&req, 0, sizeof(req)); 205 req.t = EAL_DEV_REQ_TYPE_ATTACH; 206 strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN); 207 208 if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 209 /** 210 * If in secondary process, just send IPC request to 211 * primary process. 212 */ 213 ret = eal_dev_hotplug_request_to_primary(&req); 214 if (ret != 0) { 215 RTE_LOG(ERR, EAL, 216 "Failed to send hotplug request to primary\n"); 217 return -ENOMSG; 218 } 219 if (req.result != 0) 220 RTE_LOG(ERR, EAL, 221 "Failed to hotplug add device\n"); 222 return req.result; 223 } 224 225 /* attach a shared device from primary start from here: */ 226 227 /* primary attach the new device itself. */ 228 ret = local_dev_probe(devargs, &dev); 229 230 if (ret != 0) { 231 RTE_LOG(ERR, EAL, 232 "Failed to attach device on primary process\n"); 233 234 /** 235 * it is possible that secondary process failed to attached a 236 * device that primary process have during initialization, 237 * so for -EEXIST case, we still need to sync with secondary 238 * process. 239 */ 240 if (ret != -EEXIST) 241 return ret; 242 } 243 244 /* primary send attach sync request to secondary. */ 245 ret = eal_dev_hotplug_request_to_secondary(&req); 246 247 /* if any communication error, we need to rollback. */ 248 if (ret != 0) { 249 RTE_LOG(ERR, EAL, 250 "Failed to send hotplug add request to secondary\n"); 251 ret = -ENOMSG; 252 goto rollback; 253 } 254 255 /** 256 * if any secondary failed to attach, we need to consider if rollback 257 * is necessary. 258 */ 259 if (req.result != 0) { 260 RTE_LOG(ERR, EAL, 261 "Failed to attach device on secondary process\n"); 262 ret = req.result; 263 264 /* for -EEXIST, we don't need to rollback. */ 265 if (ret == -EEXIST) 266 return ret; 267 goto rollback; 268 } 269 270 return 0; 271 272 rollback: 273 req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK; 274 275 /* primary send rollback request to secondary. */ 276 if (eal_dev_hotplug_request_to_secondary(&req) != 0) 277 RTE_LOG(WARNING, EAL, 278 "Failed to rollback device attach on secondary." 279 "Devices in secondary may not sync with primary\n"); 280 281 /* primary rollback itself. */ 282 if (local_dev_remove(dev) != 0) 283 RTE_LOG(WARNING, EAL, 284 "Failed to rollback device attach on primary." 285 "Devices in secondary may not sync with primary\n"); 286 287 return ret; 288 } 289 290 int 291 rte_eal_hotplug_remove(const char *busname, const char *devname) 292 { 293 struct rte_device *dev; 294 struct rte_bus *bus; 295 296 bus = rte_bus_find_by_name(busname); 297 if (bus == NULL) { 298 RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname); 299 return -ENOENT; 300 } 301 302 dev = bus->find_device(NULL, cmp_dev_name, devname); 303 if (dev == NULL) { 304 RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname); 305 return -EINVAL; 306 } 307 308 return rte_dev_remove(dev); 309 } 310 311 /* remove device at local process. */ 312 int 313 local_dev_remove(struct rte_device *dev) 314 { 315 int ret; 316 317 if (dev->bus->unplug == NULL) { 318 RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n", 319 dev->bus->name); 320 return -ENOTSUP; 321 } 322 323 ret = dev->bus->unplug(dev); 324 if (ret) { 325 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", 326 dev->name); 327 return (ret < 0) ? ret : -ENOENT; 328 } 329 330 return 0; 331 } 332 333 int 334 rte_dev_remove(struct rte_device *dev) 335 { 336 struct eal_dev_mp_req req; 337 char *devargs; 338 int ret; 339 340 if (!rte_dev_is_probed(dev)) { 341 RTE_LOG(ERR, EAL, "Device is not probed\n"); 342 return -ENOENT; 343 } 344 345 ret = build_devargs(dev->bus->name, dev->name, "", &devargs); 346 if (ret != 0) 347 return ret; 348 349 memset(&req, 0, sizeof(req)); 350 req.t = EAL_DEV_REQ_TYPE_DETACH; 351 strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN); 352 free(devargs); 353 354 if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 355 /** 356 * If in secondary process, just send IPC request to 357 * primary process. 358 */ 359 ret = eal_dev_hotplug_request_to_primary(&req); 360 if (ret != 0) { 361 RTE_LOG(ERR, EAL, 362 "Failed to send hotplug request to primary\n"); 363 return -ENOMSG; 364 } 365 if (req.result != 0) 366 RTE_LOG(ERR, EAL, 367 "Failed to hotplug remove device\n"); 368 return req.result; 369 } 370 371 /* detach a device from primary start from here: */ 372 373 /* primary send detach sync request to secondary */ 374 ret = eal_dev_hotplug_request_to_secondary(&req); 375 376 /** 377 * if communication error, we need to rollback, because it is possible 378 * part of the secondary processes still detached it successfully. 379 */ 380 if (ret != 0) { 381 RTE_LOG(ERR, EAL, 382 "Failed to send device detach request to secondary\n"); 383 ret = -ENOMSG; 384 goto rollback; 385 } 386 387 /** 388 * if any secondary failed to detach, we need to consider if rollback 389 * is necessary. 390 */ 391 if (req.result != 0) { 392 RTE_LOG(ERR, EAL, 393 "Failed to detach device on secondary process\n"); 394 ret = req.result; 395 /** 396 * if -ENOENT, we don't need to rollback, since devices is 397 * already detached on secondary process. 398 */ 399 if (ret != -ENOENT) 400 goto rollback; 401 } 402 403 /* primary detach the device itself. */ 404 ret = local_dev_remove(dev); 405 406 /* if primary failed, still need to consider if rollback is necessary */ 407 if (ret != 0) { 408 RTE_LOG(ERR, EAL, 409 "Failed to detach device on primary process\n"); 410 /* if -ENOENT, we don't need to rollback */ 411 if (ret == -ENOENT) 412 return ret; 413 goto rollback; 414 } 415 416 return 0; 417 418 rollback: 419 req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK; 420 421 /* primary send rollback request to secondary. */ 422 if (eal_dev_hotplug_request_to_secondary(&req) != 0) 423 RTE_LOG(WARNING, EAL, 424 "Failed to rollback device detach on secondary." 425 "Devices in secondary may not sync with primary\n"); 426 427 return ret; 428 } 429 430 int 431 rte_dev_event_callback_register(const char *device_name, 432 rte_dev_event_cb_fn cb_fn, 433 void *cb_arg) 434 { 435 struct dev_event_callback *event_cb; 436 int ret; 437 438 if (!cb_fn) 439 return -EINVAL; 440 441 rte_spinlock_lock(&dev_event_lock); 442 443 if (TAILQ_EMPTY(&dev_event_cbs)) 444 TAILQ_INIT(&dev_event_cbs); 445 446 TAILQ_FOREACH(event_cb, &dev_event_cbs, next) { 447 if (event_cb->cb_fn == cb_fn && event_cb->cb_arg == cb_arg) { 448 if (device_name == NULL && event_cb->dev_name == NULL) 449 break; 450 if (device_name == NULL || event_cb->dev_name == NULL) 451 continue; 452 if (!strcmp(event_cb->dev_name, device_name)) 453 break; 454 } 455 } 456 457 /* create a new callback. */ 458 if (event_cb == NULL) { 459 event_cb = malloc(sizeof(struct dev_event_callback)); 460 if (event_cb != NULL) { 461 event_cb->cb_fn = cb_fn; 462 event_cb->cb_arg = cb_arg; 463 event_cb->active = 0; 464 if (!device_name) { 465 event_cb->dev_name = NULL; 466 } else { 467 event_cb->dev_name = strdup(device_name); 468 if (event_cb->dev_name == NULL) { 469 ret = -ENOMEM; 470 goto error; 471 } 472 } 473 TAILQ_INSERT_TAIL(&dev_event_cbs, event_cb, next); 474 } else { 475 RTE_LOG(ERR, EAL, 476 "Failed to allocate memory for device " 477 "event callback."); 478 ret = -ENOMEM; 479 goto error; 480 } 481 } else { 482 RTE_LOG(ERR, EAL, 483 "The callback is already exist, no need " 484 "to register again.\n"); 485 event_cb = NULL; 486 ret = -EEXIST; 487 goto error; 488 } 489 490 rte_spinlock_unlock(&dev_event_lock); 491 return 0; 492 error: 493 free(event_cb); 494 rte_spinlock_unlock(&dev_event_lock); 495 return ret; 496 } 497 498 int 499 rte_dev_event_callback_unregister(const char *device_name, 500 rte_dev_event_cb_fn cb_fn, 501 void *cb_arg) 502 { 503 int ret = 0; 504 struct dev_event_callback *event_cb, *next; 505 506 if (!cb_fn) 507 return -EINVAL; 508 509 rte_spinlock_lock(&dev_event_lock); 510 /*walk through the callbacks and remove all that match. */ 511 for (event_cb = TAILQ_FIRST(&dev_event_cbs); event_cb != NULL; 512 event_cb = next) { 513 514 next = TAILQ_NEXT(event_cb, next); 515 516 if (device_name != NULL && event_cb->dev_name != NULL) { 517 if (!strcmp(event_cb->dev_name, device_name)) { 518 if (event_cb->cb_fn != cb_fn || 519 (cb_arg != (void *)-1 && 520 event_cb->cb_arg != cb_arg)) 521 continue; 522 } 523 } else if (device_name != NULL) { 524 continue; 525 } 526 527 /* 528 * if this callback is not executing right now, 529 * then remove it. 530 */ 531 if (event_cb->active == 0) { 532 TAILQ_REMOVE(&dev_event_cbs, event_cb, next); 533 free(event_cb->dev_name); 534 free(event_cb); 535 ret++; 536 } else { 537 ret = -EAGAIN; 538 break; 539 } 540 } 541 542 /* this callback is not be registered */ 543 if (ret == 0) 544 ret = -ENOENT; 545 546 rte_spinlock_unlock(&dev_event_lock); 547 return ret; 548 } 549 550 void 551 rte_dev_event_callback_process(const char *device_name, 552 enum rte_dev_event_type event) 553 { 554 struct dev_event_callback *cb_lst; 555 556 if (device_name == NULL) 557 return; 558 559 rte_spinlock_lock(&dev_event_lock); 560 561 TAILQ_FOREACH(cb_lst, &dev_event_cbs, next) { 562 if (cb_lst->dev_name) { 563 if (strcmp(cb_lst->dev_name, device_name)) 564 continue; 565 } 566 cb_lst->active = 1; 567 rte_spinlock_unlock(&dev_event_lock); 568 cb_lst->cb_fn(device_name, event, 569 cb_lst->cb_arg); 570 rte_spinlock_lock(&dev_event_lock); 571 cb_lst->active = 0; 572 } 573 rte_spinlock_unlock(&dev_event_lock); 574 } 575 576 int 577 rte_dev_iterator_init(struct rte_dev_iterator *it, 578 const char *dev_str) 579 { 580 struct rte_devargs devargs = { .bus = NULL }; 581 struct rte_class *cls = NULL; 582 struct rte_bus *bus = NULL; 583 584 /* Having both bus_str and cls_str NULL is illegal, 585 * marking this iterator as invalid unless 586 * everything goes well. 587 */ 588 it->bus_str = NULL; 589 it->cls_str = NULL; 590 591 /* Setting data field implies no malloc in parsing. */ 592 devargs.data = (void *)(intptr_t)dev_str; 593 if (rte_devargs_layers_parse(&devargs, dev_str)) 594 goto get_out; 595 596 bus = devargs.bus; 597 cls = devargs.cls; 598 /* The string should have at least 599 * one layer specified. 600 */ 601 if (bus == NULL && cls == NULL) { 602 RTE_LOG(DEBUG, EAL, "Either bus or class must be specified.\n"); 603 rte_errno = EINVAL; 604 goto get_out; 605 } 606 if (bus != NULL && bus->dev_iterate == NULL) { 607 RTE_LOG(DEBUG, EAL, "Bus %s not supported\n", bus->name); 608 rte_errno = ENOTSUP; 609 goto get_out; 610 } 611 if (cls != NULL && cls->dev_iterate == NULL) { 612 RTE_LOG(DEBUG, EAL, "Class %s not supported\n", cls->name); 613 rte_errno = ENOTSUP; 614 goto get_out; 615 } 616 it->bus_str = devargs.bus_str; 617 it->cls_str = devargs.cls_str; 618 it->dev_str = dev_str; 619 it->bus = bus; 620 it->cls = cls; 621 it->device = NULL; 622 it->class_device = NULL; 623 get_out: 624 return -rte_errno; 625 } 626 627 static char * 628 dev_str_sane_copy(const char *str) 629 { 630 size_t end; 631 char *copy; 632 633 end = strcspn(str, ",/"); 634 if (str[end] == ',') { 635 copy = strdup(&str[end + 1]); 636 } else { 637 /* '/' or '\0' */ 638 copy = strdup(""); 639 } 640 if (copy == NULL) { 641 rte_errno = ENOMEM; 642 } else { 643 char *slash; 644 645 slash = strchr(copy, '/'); 646 if (slash != NULL) 647 slash[0] = '\0'; 648 } 649 return copy; 650 } 651 652 static int 653 class_next_dev_cmp(const struct rte_class *cls, 654 const void *ctx) 655 { 656 struct rte_dev_iterator *it; 657 const char *cls_str = NULL; 658 void *dev; 659 660 if (cls->dev_iterate == NULL) 661 return 1; 662 it = ITCTX(ctx); 663 cls_str = CLSCTX(ctx); 664 dev = it->class_device; 665 /* it->cls_str != NULL means a class 666 * was specified in the devstr. 667 */ 668 if (it->cls_str != NULL && cls != it->cls) 669 return 1; 670 /* If an error occurred previously, 671 * no need to test further. 672 */ 673 if (rte_errno != 0) 674 return -1; 675 dev = cls->dev_iterate(dev, cls_str, it); 676 it->class_device = dev; 677 return dev == NULL; 678 } 679 680 static int 681 bus_next_dev_cmp(const struct rte_bus *bus, 682 const void *ctx) 683 { 684 struct rte_device *dev = NULL; 685 struct rte_class *cls = NULL; 686 struct rte_dev_iterator *it; 687 const char *bus_str = NULL; 688 689 if (bus->dev_iterate == NULL) 690 return 1; 691 it = ITCTX(ctx); 692 bus_str = BUSCTX(ctx); 693 dev = it->device; 694 /* it->bus_str != NULL means a bus 695 * was specified in the devstr. 696 */ 697 if (it->bus_str != NULL && bus != it->bus) 698 return 1; 699 /* If an error occurred previously, 700 * no need to test further. 701 */ 702 if (rte_errno != 0) 703 return -1; 704 if (it->cls_str == NULL) { 705 dev = bus->dev_iterate(dev, bus_str, it); 706 goto end; 707 } 708 /* cls_str != NULL */ 709 if (dev == NULL) { 710 next_dev_on_bus: 711 dev = bus->dev_iterate(dev, bus_str, it); 712 it->device = dev; 713 } 714 if (dev == NULL) 715 return 1; 716 if (it->cls != NULL) 717 cls = TAILQ_PREV(it->cls, rte_class_list, next); 718 cls = rte_class_find(cls, class_next_dev_cmp, ctx); 719 if (cls != NULL) { 720 it->cls = cls; 721 goto end; 722 } 723 goto next_dev_on_bus; 724 end: 725 it->device = dev; 726 return dev == NULL; 727 } 728 struct rte_device * 729 rte_dev_iterator_next(struct rte_dev_iterator *it) 730 { 731 struct rte_bus *bus = NULL; 732 int old_errno = rte_errno; 733 char *bus_str = NULL; 734 char *cls_str = NULL; 735 736 rte_errno = 0; 737 if (it->bus_str == NULL && it->cls_str == NULL) { 738 /* Invalid iterator. */ 739 rte_errno = EINVAL; 740 return NULL; 741 } 742 if (it->bus != NULL) 743 bus = TAILQ_PREV(it->bus, rte_bus_list, next); 744 if (it->bus_str != NULL) { 745 bus_str = dev_str_sane_copy(it->bus_str); 746 if (bus_str == NULL) 747 goto out; 748 } 749 if (it->cls_str != NULL) { 750 cls_str = dev_str_sane_copy(it->cls_str); 751 if (cls_str == NULL) 752 goto out; 753 } 754 while ((bus = rte_bus_find(bus, bus_next_dev_cmp, 755 CTX(it, bus_str, cls_str)))) { 756 if (it->device != NULL) { 757 it->bus = bus; 758 goto out; 759 } 760 if (it->bus_str != NULL || 761 rte_errno != 0) 762 break; 763 } 764 if (rte_errno == 0) 765 rte_errno = old_errno; 766 out: 767 free(bus_str); 768 free(cls_str); 769 return it->device; 770 } 771 772 int 773 rte_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova, 774 size_t len) 775 { 776 if (dev->bus->dma_map == NULL || len == 0) { 777 rte_errno = ENOTSUP; 778 return -1; 779 } 780 /* Memory must be registered through rte_extmem_* APIs */ 781 if (rte_mem_virt2memseg_list(addr) == NULL) { 782 rte_errno = EINVAL; 783 return -1; 784 } 785 786 return dev->bus->dma_map(dev, addr, iova, len); 787 } 788 789 int 790 rte_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, 791 size_t len) 792 { 793 if (dev->bus->dma_unmap == NULL || len == 0) { 794 rte_errno = ENOTSUP; 795 return -1; 796 } 797 /* Memory must be registered through rte_extmem_* APIs */ 798 if (rte_mem_virt2memseg_list(addr) == NULL) { 799 rte_errno = EINVAL; 800 return -1; 801 } 802 803 return dev->bus->dma_unmap(dev, addr, iova, len); 804 } 805