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