1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016 Cavium, Inc 3 */ 4 5 #include <stdalign.h> 6 #include <ctype.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <errno.h> 11 #include <stdint.h> 12 #include <inttypes.h> 13 14 #include <rte_string_fns.h> 15 #include <rte_log.h> 16 #include <dev_driver.h> 17 #include <rte_memzone.h> 18 #include <rte_eal.h> 19 #include <rte_common.h> 20 #include <rte_malloc.h> 21 #include <rte_errno.h> 22 #include <ethdev_driver.h> 23 #include <rte_cryptodev.h> 24 #include <rte_dmadev.h> 25 #include <cryptodev_pmd.h> 26 #include <rte_telemetry.h> 27 28 #include "rte_eventdev.h" 29 #include "eventdev_pmd.h" 30 #include "eventdev_trace.h" 31 32 RTE_LOG_REGISTER_DEFAULT(rte_event_logtype, INFO); 33 34 static struct rte_eventdev rte_event_devices[RTE_EVENT_MAX_DEVS]; 35 36 struct rte_eventdev *rte_eventdevs = rte_event_devices; 37 38 static struct rte_eventdev_global eventdev_globals = { 39 .nb_devs = 0 40 }; 41 42 /* Public fastpath APIs. */ 43 struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; 44 45 /* Event dev north bound API implementation */ 46 47 uint8_t 48 rte_event_dev_count(void) 49 { 50 return eventdev_globals.nb_devs; 51 } 52 53 int 54 rte_event_dev_get_dev_id(const char *name) 55 { 56 int i; 57 uint8_t cmp; 58 59 if (!name) 60 return -EINVAL; 61 62 for (i = 0; i < eventdev_globals.nb_devs; i++) { 63 cmp = (strncmp(rte_event_devices[i].data->name, name, 64 RTE_EVENTDEV_NAME_MAX_LEN) == 0) || 65 (rte_event_devices[i].dev ? (strncmp( 66 rte_event_devices[i].dev->driver->name, name, 67 RTE_EVENTDEV_NAME_MAX_LEN) == 0) : 0); 68 if (cmp && (rte_event_devices[i].attached == 69 RTE_EVENTDEV_ATTACHED)) { 70 rte_eventdev_trace_get_dev_id(name, i); 71 return i; 72 } 73 } 74 return -ENODEV; 75 } 76 77 int 78 rte_event_dev_socket_id(uint8_t dev_id) 79 { 80 struct rte_eventdev *dev; 81 82 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 83 dev = &rte_eventdevs[dev_id]; 84 85 rte_eventdev_trace_socket_id(dev_id, dev, dev->data->socket_id); 86 87 return dev->data->socket_id; 88 } 89 90 int 91 rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info) 92 { 93 struct rte_eventdev *dev; 94 95 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 96 dev = &rte_eventdevs[dev_id]; 97 98 if (dev_info == NULL) 99 return -EINVAL; 100 101 memset(dev_info, 0, sizeof(struct rte_event_dev_info)); 102 103 if (*dev->dev_ops->dev_infos_get == NULL) 104 return -ENOTSUP; 105 (*dev->dev_ops->dev_infos_get)(dev, dev_info); 106 107 dev_info->dequeue_timeout_ns = dev->data->dev_conf.dequeue_timeout_ns; 108 109 dev_info->dev = dev->dev; 110 if (dev->dev != NULL && dev->dev->driver != NULL) 111 dev_info->driver_name = dev->dev->driver->name; 112 113 rte_eventdev_trace_info_get(dev_id, dev_info, dev_info->dev); 114 115 return 0; 116 } 117 118 int 119 rte_event_eth_rx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id, 120 uint32_t *caps) 121 { 122 struct rte_eventdev *dev; 123 124 rte_eventdev_trace_eth_rx_adapter_caps_get(dev_id, eth_port_id); 125 126 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 127 RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_port_id, -EINVAL); 128 129 dev = &rte_eventdevs[dev_id]; 130 131 if (caps == NULL) 132 return -EINVAL; 133 134 if (dev->dev_ops->eth_rx_adapter_caps_get == NULL) 135 *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP; 136 else 137 *caps = 0; 138 139 return dev->dev_ops->eth_rx_adapter_caps_get ? 140 (*dev->dev_ops->eth_rx_adapter_caps_get)(dev, 141 &rte_eth_devices[eth_port_id], 142 caps) 143 : 0; 144 } 145 146 int 147 rte_event_timer_adapter_caps_get(uint8_t dev_id, uint32_t *caps) 148 { 149 struct rte_eventdev *dev; 150 const struct event_timer_adapter_ops *ops; 151 152 rte_eventdev_trace_timer_adapter_caps_get(dev_id); 153 154 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 155 156 dev = &rte_eventdevs[dev_id]; 157 158 if (caps == NULL) 159 return -EINVAL; 160 161 if (dev->dev_ops->timer_adapter_caps_get == NULL) 162 *caps = RTE_EVENT_TIMER_ADAPTER_SW_CAP; 163 else 164 *caps = 0; 165 166 return dev->dev_ops->timer_adapter_caps_get ? 167 (*dev->dev_ops->timer_adapter_caps_get)(dev, 168 0, 169 caps, 170 &ops) 171 : 0; 172 } 173 174 int 175 rte_event_crypto_adapter_caps_get(uint8_t dev_id, uint8_t cdev_id, 176 uint32_t *caps) 177 { 178 struct rte_eventdev *dev; 179 struct rte_cryptodev *cdev; 180 181 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 182 if (!rte_cryptodev_is_valid_dev(cdev_id)) 183 return -EINVAL; 184 185 dev = &rte_eventdevs[dev_id]; 186 cdev = rte_cryptodev_pmd_get_dev(cdev_id); 187 188 rte_eventdev_trace_crypto_adapter_caps_get(dev_id, dev, cdev_id, cdev); 189 190 if (caps == NULL) 191 return -EINVAL; 192 193 if (dev->dev_ops->crypto_adapter_caps_get == NULL) 194 *caps = RTE_EVENT_CRYPTO_ADAPTER_SW_CAP; 195 else 196 *caps = 0; 197 198 return dev->dev_ops->crypto_adapter_caps_get ? 199 (*dev->dev_ops->crypto_adapter_caps_get) 200 (dev, cdev, caps) : 0; 201 } 202 203 int 204 rte_event_eth_tx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id, 205 uint32_t *caps) 206 { 207 struct rte_eventdev *dev; 208 struct rte_eth_dev *eth_dev; 209 210 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 211 RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_port_id, -EINVAL); 212 213 dev = &rte_eventdevs[dev_id]; 214 eth_dev = &rte_eth_devices[eth_port_id]; 215 216 rte_eventdev_trace_eth_tx_adapter_caps_get(dev_id, dev, eth_port_id, eth_dev); 217 218 if (caps == NULL) 219 return -EINVAL; 220 221 if (dev->dev_ops->eth_tx_adapter_caps_get == NULL) 222 *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_EVENT_VECTOR; 223 else 224 *caps = 0; 225 226 return dev->dev_ops->eth_tx_adapter_caps_get ? 227 (*dev->dev_ops->eth_tx_adapter_caps_get)(dev, 228 eth_dev, 229 caps) 230 : 0; 231 } 232 233 int 234 rte_event_dma_adapter_caps_get(uint8_t dev_id, uint8_t dma_dev_id, uint32_t *caps) 235 { 236 struct rte_eventdev *dev; 237 238 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 239 if (!rte_dma_is_valid(dma_dev_id)) 240 return -EINVAL; 241 242 dev = &rte_eventdevs[dev_id]; 243 244 if (caps == NULL) 245 return -EINVAL; 246 247 *caps = 0; 248 249 if (dev->dev_ops->dma_adapter_caps_get) 250 return (*dev->dev_ops->dma_adapter_caps_get)(dev, dma_dev_id, caps); 251 252 return 0; 253 } 254 255 static inline int 256 event_dev_queue_config(struct rte_eventdev *dev, uint8_t nb_queues) 257 { 258 uint8_t old_nb_queues = dev->data->nb_queues; 259 struct rte_event_queue_conf *queues_cfg; 260 unsigned int i; 261 262 RTE_EDEV_LOG_DEBUG("Setup %d queues on device %u", nb_queues, 263 dev->data->dev_id); 264 265 if (nb_queues != 0) { 266 queues_cfg = dev->data->queues_cfg; 267 if (*dev->dev_ops->queue_release == NULL) 268 return -ENOTSUP; 269 270 for (i = nb_queues; i < old_nb_queues; i++) 271 (*dev->dev_ops->queue_release)(dev, i); 272 273 274 if (nb_queues > old_nb_queues) { 275 uint8_t new_qs = nb_queues - old_nb_queues; 276 277 memset(queues_cfg + old_nb_queues, 0, 278 sizeof(queues_cfg[0]) * new_qs); 279 } 280 } else { 281 if (*dev->dev_ops->queue_release == NULL) 282 return -ENOTSUP; 283 284 for (i = nb_queues; i < old_nb_queues; i++) 285 (*dev->dev_ops->queue_release)(dev, i); 286 } 287 288 dev->data->nb_queues = nb_queues; 289 return 0; 290 } 291 292 #define EVENT_QUEUE_SERVICE_PRIORITY_INVALID (0xdead) 293 294 static inline int 295 event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports) 296 { 297 uint8_t old_nb_ports = dev->data->nb_ports; 298 void **ports; 299 uint16_t *links_map; 300 struct rte_event_port_conf *ports_cfg; 301 unsigned int i, j; 302 303 RTE_EDEV_LOG_DEBUG("Setup %d ports on device %u", nb_ports, 304 dev->data->dev_id); 305 306 if (nb_ports != 0) { /* re-config */ 307 if (*dev->dev_ops->port_release == NULL) 308 return -ENOTSUP; 309 310 ports = dev->data->ports; 311 ports_cfg = dev->data->ports_cfg; 312 313 for (i = nb_ports; i < old_nb_ports; i++) 314 (*dev->dev_ops->port_release)(ports[i]); 315 316 if (nb_ports > old_nb_ports) { 317 uint8_t new_ps = nb_ports - old_nb_ports; 318 unsigned int old_links_map_end = 319 old_nb_ports * RTE_EVENT_MAX_QUEUES_PER_DEV; 320 unsigned int links_map_end = 321 nb_ports * RTE_EVENT_MAX_QUEUES_PER_DEV; 322 323 memset(ports + old_nb_ports, 0, 324 sizeof(ports[0]) * new_ps); 325 memset(ports_cfg + old_nb_ports, 0, 326 sizeof(ports_cfg[0]) * new_ps); 327 for (i = 0; i < RTE_EVENT_MAX_PROFILES_PER_PORT; i++) { 328 links_map = dev->data->links_map[i]; 329 for (j = old_links_map_end; j < links_map_end; j++) 330 links_map[j] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID; 331 } 332 } 333 } else { 334 if (*dev->dev_ops->port_release == NULL) 335 return -ENOTSUP; 336 337 ports = dev->data->ports; 338 for (i = nb_ports; i < old_nb_ports; i++) { 339 (*dev->dev_ops->port_release)(ports[i]); 340 ports[i] = NULL; 341 } 342 } 343 344 dev->data->nb_ports = nb_ports; 345 return 0; 346 } 347 348 int 349 rte_event_dev_configure(uint8_t dev_id, 350 const struct rte_event_dev_config *dev_conf) 351 { 352 struct rte_event_dev_info info; 353 struct rte_eventdev *dev; 354 int diag; 355 356 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 357 dev = &rte_eventdevs[dev_id]; 358 359 if (*dev->dev_ops->dev_infos_get == NULL) 360 return -ENOTSUP; 361 if (*dev->dev_ops->dev_configure == NULL) 362 return -ENOTSUP; 363 364 if (dev->data->dev_started) { 365 RTE_EDEV_LOG_ERR( 366 "device %d must be stopped to allow configuration", dev_id); 367 return -EBUSY; 368 } 369 370 if (dev_conf == NULL) 371 return -EINVAL; 372 373 (*dev->dev_ops->dev_infos_get)(dev, &info); 374 375 /* Check dequeue_timeout_ns value is in limit */ 376 if (!(dev_conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT)) { 377 if (dev_conf->dequeue_timeout_ns && 378 (dev_conf->dequeue_timeout_ns < info.min_dequeue_timeout_ns 379 || dev_conf->dequeue_timeout_ns > 380 info.max_dequeue_timeout_ns)) { 381 RTE_EDEV_LOG_ERR("dev%d invalid dequeue_timeout_ns=%d" 382 " min_dequeue_timeout_ns=%d max_dequeue_timeout_ns=%d", 383 dev_id, dev_conf->dequeue_timeout_ns, 384 info.min_dequeue_timeout_ns, 385 info.max_dequeue_timeout_ns); 386 return -EINVAL; 387 } 388 } 389 390 /* Check nb_events_limit is in limit */ 391 if (dev_conf->nb_events_limit > info.max_num_events) { 392 RTE_EDEV_LOG_ERR("dev%d nb_events_limit=%d > max_num_events=%d", 393 dev_id, dev_conf->nb_events_limit, info.max_num_events); 394 return -EINVAL; 395 } 396 397 /* Check nb_event_queues is in limit */ 398 if (!dev_conf->nb_event_queues) { 399 RTE_EDEV_LOG_ERR("dev%d nb_event_queues cannot be zero", 400 dev_id); 401 return -EINVAL; 402 } 403 if (dev_conf->nb_event_queues > info.max_event_queues + 404 info.max_single_link_event_port_queue_pairs) { 405 RTE_EDEV_LOG_ERR("%d nb_event_queues=%d > max_event_queues=%d + max_single_link_event_port_queue_pairs=%d", 406 dev_id, dev_conf->nb_event_queues, 407 info.max_event_queues, 408 info.max_single_link_event_port_queue_pairs); 409 return -EINVAL; 410 } 411 if (dev_conf->nb_event_queues - 412 dev_conf->nb_single_link_event_port_queues > 413 info.max_event_queues) { 414 RTE_EDEV_LOG_ERR("id%d nb_event_queues=%d - nb_single_link_event_port_queues=%d > max_event_queues=%d", 415 dev_id, dev_conf->nb_event_queues, 416 dev_conf->nb_single_link_event_port_queues, 417 info.max_event_queues); 418 return -EINVAL; 419 } 420 if (dev_conf->nb_single_link_event_port_queues > 421 dev_conf->nb_event_queues) { 422 RTE_EDEV_LOG_ERR("dev%d nb_single_link_event_port_queues=%d > nb_event_queues=%d", 423 dev_id, 424 dev_conf->nb_single_link_event_port_queues, 425 dev_conf->nb_event_queues); 426 return -EINVAL; 427 } 428 429 /* Check nb_event_ports is in limit */ 430 if (!dev_conf->nb_event_ports) { 431 RTE_EDEV_LOG_ERR("dev%d nb_event_ports cannot be zero", dev_id); 432 return -EINVAL; 433 } 434 if (dev_conf->nb_event_ports > info.max_event_ports + 435 info.max_single_link_event_port_queue_pairs) { 436 RTE_EDEV_LOG_ERR("id%d nb_event_ports=%d > max_event_ports=%d + max_single_link_event_port_queue_pairs=%d", 437 dev_id, dev_conf->nb_event_ports, 438 info.max_event_ports, 439 info.max_single_link_event_port_queue_pairs); 440 return -EINVAL; 441 } 442 if (dev_conf->nb_event_ports - 443 dev_conf->nb_single_link_event_port_queues 444 > info.max_event_ports) { 445 RTE_EDEV_LOG_ERR("id%d nb_event_ports=%d - nb_single_link_event_port_queues=%d > max_event_ports=%d", 446 dev_id, dev_conf->nb_event_ports, 447 dev_conf->nb_single_link_event_port_queues, 448 info.max_event_ports); 449 return -EINVAL; 450 } 451 452 if (dev_conf->nb_single_link_event_port_queues > 453 dev_conf->nb_event_ports) { 454 RTE_EDEV_LOG_ERR( 455 "dev%d nb_single_link_event_port_queues=%d > nb_event_ports=%d", 456 dev_id, 457 dev_conf->nb_single_link_event_port_queues, 458 dev_conf->nb_event_ports); 459 return -EINVAL; 460 } 461 462 /* Check nb_event_queue_flows is in limit */ 463 if (!dev_conf->nb_event_queue_flows) { 464 RTE_EDEV_LOG_ERR("dev%d nb_flows cannot be zero", dev_id); 465 return -EINVAL; 466 } 467 if (dev_conf->nb_event_queue_flows > info.max_event_queue_flows) { 468 RTE_EDEV_LOG_ERR("dev%d nb_flows=%x > max_flows=%x", 469 dev_id, dev_conf->nb_event_queue_flows, 470 info.max_event_queue_flows); 471 return -EINVAL; 472 } 473 474 /* Check nb_event_port_dequeue_depth is in limit */ 475 if (!dev_conf->nb_event_port_dequeue_depth) { 476 RTE_EDEV_LOG_ERR("dev%d nb_dequeue_depth cannot be zero", 477 dev_id); 478 return -EINVAL; 479 } 480 if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) && 481 (dev_conf->nb_event_port_dequeue_depth > 482 info.max_event_port_dequeue_depth)) { 483 RTE_EDEV_LOG_ERR("dev%d nb_dq_depth=%d > max_dq_depth=%d", 484 dev_id, dev_conf->nb_event_port_dequeue_depth, 485 info.max_event_port_dequeue_depth); 486 return -EINVAL; 487 } 488 489 /* Check nb_event_port_enqueue_depth is in limit */ 490 if (!dev_conf->nb_event_port_enqueue_depth) { 491 RTE_EDEV_LOG_ERR("dev%d nb_enqueue_depth cannot be zero", 492 dev_id); 493 return -EINVAL; 494 } 495 if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) && 496 (dev_conf->nb_event_port_enqueue_depth > 497 info.max_event_port_enqueue_depth)) { 498 RTE_EDEV_LOG_ERR("dev%d nb_enq_depth=%d > max_enq_depth=%d", 499 dev_id, dev_conf->nb_event_port_enqueue_depth, 500 info.max_event_port_enqueue_depth); 501 return -EINVAL; 502 } 503 504 /* Copy the dev_conf parameter into the dev structure */ 505 memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf)); 506 507 /* Setup new number of queues and reconfigure device. */ 508 diag = event_dev_queue_config(dev, dev_conf->nb_event_queues); 509 if (diag != 0) { 510 RTE_EDEV_LOG_ERR("dev%d event_dev_queue_config = %d", dev_id, 511 diag); 512 return diag; 513 } 514 515 /* Setup new number of ports and reconfigure device. */ 516 diag = event_dev_port_config(dev, dev_conf->nb_event_ports); 517 if (diag != 0) { 518 event_dev_queue_config(dev, 0); 519 RTE_EDEV_LOG_ERR("dev%d event_dev_port_config = %d", dev_id, 520 diag); 521 return diag; 522 } 523 524 event_dev_fp_ops_reset(rte_event_fp_ops + dev_id); 525 526 /* Configure the device */ 527 diag = (*dev->dev_ops->dev_configure)(dev); 528 if (diag != 0) { 529 RTE_EDEV_LOG_ERR("dev%d dev_configure = %d", dev_id, diag); 530 event_dev_fp_ops_reset(rte_event_fp_ops + dev_id); 531 event_dev_queue_config(dev, 0); 532 event_dev_port_config(dev, 0); 533 } 534 535 dev->data->event_dev_cap = info.event_dev_cap; 536 rte_eventdev_trace_configure(dev_id, dev_conf, diag); 537 return diag; 538 } 539 540 static inline int 541 is_valid_queue(struct rte_eventdev *dev, uint8_t queue_id) 542 { 543 if (queue_id < dev->data->nb_queues && queue_id < 544 RTE_EVENT_MAX_QUEUES_PER_DEV) 545 return 1; 546 else 547 return 0; 548 } 549 550 int 551 rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id, 552 struct rte_event_queue_conf *queue_conf) 553 { 554 struct rte_eventdev *dev; 555 556 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 557 dev = &rte_eventdevs[dev_id]; 558 559 if (queue_conf == NULL) 560 return -EINVAL; 561 562 if (!is_valid_queue(dev, queue_id)) { 563 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id); 564 return -EINVAL; 565 } 566 567 if (*dev->dev_ops->queue_def_conf == NULL) 568 return -ENOTSUP; 569 memset(queue_conf, 0, sizeof(struct rte_event_queue_conf)); 570 (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf); 571 572 rte_eventdev_trace_queue_default_conf_get(dev_id, dev, queue_id, queue_conf); 573 574 return 0; 575 } 576 577 static inline int 578 is_valid_atomic_queue_conf(const struct rte_event_queue_conf *queue_conf) 579 { 580 if (queue_conf && 581 !(queue_conf->event_queue_cfg & 582 RTE_EVENT_QUEUE_CFG_SINGLE_LINK) && 583 ((queue_conf->event_queue_cfg & 584 RTE_EVENT_QUEUE_CFG_ALL_TYPES) || 585 (queue_conf->schedule_type 586 == RTE_SCHED_TYPE_ATOMIC) 587 )) 588 return 1; 589 else 590 return 0; 591 } 592 593 static inline int 594 is_valid_ordered_queue_conf(const struct rte_event_queue_conf *queue_conf) 595 { 596 if (queue_conf && 597 !(queue_conf->event_queue_cfg & 598 RTE_EVENT_QUEUE_CFG_SINGLE_LINK) && 599 ((queue_conf->event_queue_cfg & 600 RTE_EVENT_QUEUE_CFG_ALL_TYPES) || 601 (queue_conf->schedule_type 602 == RTE_SCHED_TYPE_ORDERED) 603 )) 604 return 1; 605 else 606 return 0; 607 } 608 609 610 int 611 rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id, 612 const struct rte_event_queue_conf *queue_conf) 613 { 614 struct rte_eventdev *dev; 615 struct rte_event_queue_conf def_conf; 616 617 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 618 dev = &rte_eventdevs[dev_id]; 619 620 if (!is_valid_queue(dev, queue_id)) { 621 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id); 622 return -EINVAL; 623 } 624 625 /* Check nb_atomic_flows limit */ 626 if (is_valid_atomic_queue_conf(queue_conf)) { 627 if (queue_conf->nb_atomic_flows == 0 || 628 queue_conf->nb_atomic_flows > 629 dev->data->dev_conf.nb_event_queue_flows) { 630 RTE_EDEV_LOG_ERR( 631 "dev%d queue%d Invalid nb_atomic_flows=%d max_flows=%d", 632 dev_id, queue_id, queue_conf->nb_atomic_flows, 633 dev->data->dev_conf.nb_event_queue_flows); 634 return -EINVAL; 635 } 636 } 637 638 /* Check nb_atomic_order_sequences limit */ 639 if (is_valid_ordered_queue_conf(queue_conf)) { 640 if (queue_conf->nb_atomic_order_sequences == 0 || 641 queue_conf->nb_atomic_order_sequences > 642 dev->data->dev_conf.nb_event_queue_flows) { 643 RTE_EDEV_LOG_ERR( 644 "dev%d queue%d Invalid nb_atomic_order_seq=%d max_flows=%d", 645 dev_id, queue_id, queue_conf->nb_atomic_order_sequences, 646 dev->data->dev_conf.nb_event_queue_flows); 647 return -EINVAL; 648 } 649 } 650 651 if (dev->data->dev_started) { 652 RTE_EDEV_LOG_ERR( 653 "device %d must be stopped to allow queue setup", dev_id); 654 return -EBUSY; 655 } 656 657 if (*dev->dev_ops->queue_setup == NULL) 658 return -ENOTSUP; 659 660 if (queue_conf == NULL) { 661 if (*dev->dev_ops->queue_def_conf == NULL) 662 return -ENOTSUP; 663 (*dev->dev_ops->queue_def_conf)(dev, queue_id, &def_conf); 664 queue_conf = &def_conf; 665 } 666 667 dev->data->queues_cfg[queue_id] = *queue_conf; 668 rte_eventdev_trace_queue_setup(dev_id, queue_id, queue_conf); 669 return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf); 670 } 671 672 static inline int 673 is_valid_port(struct rte_eventdev *dev, uint8_t port_id) 674 { 675 if (port_id < dev->data->nb_ports) 676 return 1; 677 else 678 return 0; 679 } 680 681 int 682 rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id, 683 struct rte_event_port_conf *port_conf) 684 { 685 struct rte_eventdev *dev; 686 687 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 688 dev = &rte_eventdevs[dev_id]; 689 690 if (port_conf == NULL) 691 return -EINVAL; 692 693 if (!is_valid_port(dev, port_id)) { 694 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 695 return -EINVAL; 696 } 697 698 if (*dev->dev_ops->port_def_conf == NULL) 699 return -ENOTSUP; 700 memset(port_conf, 0, sizeof(struct rte_event_port_conf)); 701 (*dev->dev_ops->port_def_conf)(dev, port_id, port_conf); 702 703 rte_eventdev_trace_port_default_conf_get(dev_id, dev, port_id, port_conf); 704 705 return 0; 706 } 707 708 int 709 rte_event_port_setup(uint8_t dev_id, uint8_t port_id, 710 const struct rte_event_port_conf *port_conf) 711 { 712 struct rte_eventdev *dev; 713 struct rte_event_port_conf def_conf; 714 int diag; 715 716 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 717 dev = &rte_eventdevs[dev_id]; 718 719 if (!is_valid_port(dev, port_id)) { 720 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 721 return -EINVAL; 722 } 723 724 /* Check new_event_threshold limit */ 725 if ((port_conf && !port_conf->new_event_threshold) || 726 (port_conf && port_conf->new_event_threshold > 727 dev->data->dev_conf.nb_events_limit)) { 728 RTE_EDEV_LOG_ERR( 729 "dev%d port%d Invalid event_threshold=%d nb_events_limit=%d", 730 dev_id, port_id, port_conf->new_event_threshold, 731 dev->data->dev_conf.nb_events_limit); 732 return -EINVAL; 733 } 734 735 /* Check dequeue_depth limit */ 736 if ((port_conf && !port_conf->dequeue_depth) || 737 (port_conf && port_conf->dequeue_depth > 738 dev->data->dev_conf.nb_event_port_dequeue_depth)) { 739 RTE_EDEV_LOG_ERR( 740 "dev%d port%d Invalid dequeue depth=%d max_dequeue_depth=%d", 741 dev_id, port_id, port_conf->dequeue_depth, 742 dev->data->dev_conf.nb_event_port_dequeue_depth); 743 return -EINVAL; 744 } 745 746 /* Check enqueue_depth limit */ 747 if ((port_conf && !port_conf->enqueue_depth) || 748 (port_conf && port_conf->enqueue_depth > 749 dev->data->dev_conf.nb_event_port_enqueue_depth)) { 750 RTE_EDEV_LOG_ERR( 751 "dev%d port%d Invalid enqueue depth=%d max_enqueue_depth=%d", 752 dev_id, port_id, port_conf->enqueue_depth, 753 dev->data->dev_conf.nb_event_port_enqueue_depth); 754 return -EINVAL; 755 } 756 757 if (port_conf && 758 (port_conf->event_port_cfg & RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL) && 759 !(dev->data->event_dev_cap & 760 RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE)) { 761 RTE_EDEV_LOG_ERR( 762 "dev%d port%d Implicit release disable not supported", 763 dev_id, port_id); 764 return -EINVAL; 765 } 766 767 if (dev->data->dev_started) { 768 RTE_EDEV_LOG_ERR( 769 "device %d must be stopped to allow port setup", dev_id); 770 return -EBUSY; 771 } 772 773 if (*dev->dev_ops->port_setup == NULL) 774 return -ENOTSUP; 775 776 if (port_conf == NULL) { 777 if (*dev->dev_ops->port_def_conf == NULL) 778 return -ENOTSUP; 779 (*dev->dev_ops->port_def_conf)(dev, port_id, &def_conf); 780 port_conf = &def_conf; 781 } 782 783 dev->data->ports_cfg[port_id] = *port_conf; 784 785 diag = (*dev->dev_ops->port_setup)(dev, port_id, port_conf); 786 787 /* Unlink all the queues from this port(default state after setup) */ 788 if (!diag) 789 diag = rte_event_port_unlink(dev_id, port_id, NULL, 0); 790 791 rte_eventdev_trace_port_setup(dev_id, port_id, port_conf, diag); 792 if (diag < 0) 793 return diag; 794 795 return 0; 796 } 797 798 void 799 rte_event_port_quiesce(uint8_t dev_id, uint8_t port_id, 800 rte_eventdev_port_flush_t release_cb, void *args) 801 { 802 struct rte_eventdev *dev; 803 804 RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id); 805 dev = &rte_eventdevs[dev_id]; 806 807 rte_eventdev_trace_port_quiesce(dev_id, dev, port_id, args); 808 809 if (!is_valid_port(dev, port_id)) { 810 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 811 return; 812 } 813 814 if (dev->dev_ops->port_quiesce) 815 (*dev->dev_ops->port_quiesce)(dev, dev->data->ports[port_id], 816 release_cb, args); 817 } 818 819 int 820 rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, 821 uint32_t *attr_value) 822 { 823 struct rte_eventdev *dev; 824 825 if (!attr_value) 826 return -EINVAL; 827 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 828 dev = &rte_eventdevs[dev_id]; 829 830 switch (attr_id) { 831 case RTE_EVENT_DEV_ATTR_PORT_COUNT: 832 *attr_value = dev->data->nb_ports; 833 break; 834 case RTE_EVENT_DEV_ATTR_QUEUE_COUNT: 835 *attr_value = dev->data->nb_queues; 836 break; 837 case RTE_EVENT_DEV_ATTR_STARTED: 838 *attr_value = dev->data->dev_started; 839 break; 840 default: 841 return -EINVAL; 842 } 843 844 rte_eventdev_trace_attr_get(dev_id, dev, attr_id, *attr_value); 845 846 return 0; 847 } 848 849 int 850 rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id, 851 uint32_t *attr_value) 852 { 853 struct rte_eventdev *dev; 854 855 if (!attr_value) 856 return -EINVAL; 857 858 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 859 dev = &rte_eventdevs[dev_id]; 860 if (!is_valid_port(dev, port_id)) { 861 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 862 return -EINVAL; 863 } 864 865 switch (attr_id) { 866 case RTE_EVENT_PORT_ATTR_ENQ_DEPTH: 867 *attr_value = dev->data->ports_cfg[port_id].enqueue_depth; 868 break; 869 case RTE_EVENT_PORT_ATTR_DEQ_DEPTH: 870 *attr_value = dev->data->ports_cfg[port_id].dequeue_depth; 871 break; 872 case RTE_EVENT_PORT_ATTR_NEW_EVENT_THRESHOLD: 873 *attr_value = dev->data->ports_cfg[port_id].new_event_threshold; 874 break; 875 case RTE_EVENT_PORT_ATTR_IMPLICIT_RELEASE_DISABLE: 876 { 877 uint32_t config; 878 879 config = dev->data->ports_cfg[port_id].event_port_cfg; 880 *attr_value = !!(config & RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL); 881 break; 882 } 883 default: 884 return -EINVAL; 885 }; 886 887 rte_eventdev_trace_port_attr_get(dev_id, dev, port_id, attr_id, *attr_value); 888 889 return 0; 890 } 891 892 int 893 rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id, 894 uint32_t *attr_value) 895 { 896 struct rte_event_queue_conf *conf; 897 struct rte_eventdev *dev; 898 899 if (!attr_value) 900 return -EINVAL; 901 902 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 903 dev = &rte_eventdevs[dev_id]; 904 if (!is_valid_queue(dev, queue_id)) { 905 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id); 906 return -EINVAL; 907 } 908 909 conf = &dev->data->queues_cfg[queue_id]; 910 911 switch (attr_id) { 912 case RTE_EVENT_QUEUE_ATTR_PRIORITY: 913 *attr_value = RTE_EVENT_DEV_PRIORITY_NORMAL; 914 if (dev->data->event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS) 915 *attr_value = conf->priority; 916 break; 917 case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_FLOWS: 918 *attr_value = conf->nb_atomic_flows; 919 break; 920 case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_ORDER_SEQUENCES: 921 *attr_value = conf->nb_atomic_order_sequences; 922 break; 923 case RTE_EVENT_QUEUE_ATTR_EVENT_QUEUE_CFG: 924 *attr_value = conf->event_queue_cfg; 925 break; 926 case RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE: 927 if (conf->event_queue_cfg & RTE_EVENT_QUEUE_CFG_ALL_TYPES) 928 return -EOVERFLOW; 929 930 *attr_value = conf->schedule_type; 931 break; 932 case RTE_EVENT_QUEUE_ATTR_WEIGHT: 933 *attr_value = RTE_EVENT_QUEUE_WEIGHT_LOWEST; 934 if (dev->data->event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS) 935 *attr_value = conf->weight; 936 break; 937 case RTE_EVENT_QUEUE_ATTR_AFFINITY: 938 *attr_value = RTE_EVENT_QUEUE_AFFINITY_LOWEST; 939 if (dev->data->event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS) 940 *attr_value = conf->affinity; 941 break; 942 default: 943 return -EINVAL; 944 }; 945 946 rte_eventdev_trace_queue_attr_get(dev_id, dev, queue_id, attr_id, *attr_value); 947 948 return 0; 949 } 950 951 int 952 rte_event_queue_attr_set(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id, 953 uint64_t attr_value) 954 { 955 struct rte_eventdev *dev; 956 957 rte_eventdev_trace_queue_attr_set(dev_id, queue_id, attr_id, attr_value); 958 959 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 960 dev = &rte_eventdevs[dev_id]; 961 if (!is_valid_queue(dev, queue_id)) { 962 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id); 963 return -EINVAL; 964 } 965 966 if (!(dev->data->event_dev_cap & 967 RTE_EVENT_DEV_CAP_RUNTIME_QUEUE_ATTR)) { 968 RTE_EDEV_LOG_ERR( 969 "Device %" PRIu8 "does not support changing queue attributes at runtime", 970 dev_id); 971 return -ENOTSUP; 972 } 973 974 if (*dev->dev_ops->queue_attr_set == NULL) 975 return -ENOTSUP; 976 return (*dev->dev_ops->queue_attr_set)(dev, queue_id, attr_id, 977 attr_value); 978 } 979 980 int 981 rte_event_port_link(uint8_t dev_id, uint8_t port_id, 982 const uint8_t queues[], const uint8_t priorities[], 983 uint16_t nb_links) 984 { 985 return rte_event_port_profile_links_set(dev_id, port_id, queues, priorities, nb_links, 0); 986 } 987 988 int 989 rte_event_port_profile_links_set(uint8_t dev_id, uint8_t port_id, const uint8_t queues[], 990 const uint8_t priorities[], uint16_t nb_links, uint8_t profile_id) 991 { 992 uint8_t priorities_list[RTE_EVENT_MAX_QUEUES_PER_DEV]; 993 uint8_t queues_list[RTE_EVENT_MAX_QUEUES_PER_DEV]; 994 struct rte_event_dev_info info; 995 struct rte_eventdev *dev; 996 uint16_t *links_map; 997 int i, diag; 998 999 RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0); 1000 dev = &rte_eventdevs[dev_id]; 1001 1002 if (*dev->dev_ops->dev_infos_get == NULL) 1003 return -ENOTSUP; 1004 1005 (*dev->dev_ops->dev_infos_get)(dev, &info); 1006 if (profile_id >= RTE_EVENT_MAX_PROFILES_PER_PORT || 1007 profile_id >= info.max_profiles_per_port) { 1008 RTE_EDEV_LOG_ERR("Invalid profile_id=%" PRIu8, profile_id); 1009 return -EINVAL; 1010 } 1011 1012 if (*dev->dev_ops->port_link == NULL) { 1013 RTE_EDEV_LOG_ERR("Function not supported"); 1014 rte_errno = ENOTSUP; 1015 return 0; 1016 } 1017 1018 if (profile_id && *dev->dev_ops->port_link_profile == NULL) { 1019 RTE_EDEV_LOG_ERR("Function not supported"); 1020 rte_errno = ENOTSUP; 1021 return 0; 1022 } 1023 1024 if (!is_valid_port(dev, port_id)) { 1025 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 1026 rte_errno = EINVAL; 1027 return 0; 1028 } 1029 1030 if (queues == NULL) { 1031 for (i = 0; i < dev->data->nb_queues; i++) 1032 queues_list[i] = i; 1033 1034 queues = queues_list; 1035 nb_links = dev->data->nb_queues; 1036 } 1037 1038 if (priorities == NULL) { 1039 for (i = 0; i < nb_links; i++) 1040 priorities_list[i] = RTE_EVENT_DEV_PRIORITY_NORMAL; 1041 1042 priorities = priorities_list; 1043 } 1044 1045 for (i = 0; i < nb_links; i++) 1046 if (queues[i] >= dev->data->nb_queues) { 1047 rte_errno = EINVAL; 1048 return 0; 1049 } 1050 1051 if (profile_id) 1052 diag = (*dev->dev_ops->port_link_profile)(dev, dev->data->ports[port_id], queues, 1053 priorities, nb_links, profile_id); 1054 else 1055 diag = (*dev->dev_ops->port_link)(dev, dev->data->ports[port_id], queues, 1056 priorities, nb_links); 1057 if (diag < 0) 1058 return diag; 1059 1060 links_map = dev->data->links_map[profile_id]; 1061 /* Point links_map to this port specific area */ 1062 links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV); 1063 for (i = 0; i < diag; i++) 1064 links_map[queues[i]] = (uint8_t)priorities[i]; 1065 1066 rte_eventdev_trace_port_profile_links_set(dev_id, port_id, nb_links, profile_id, diag); 1067 return diag; 1068 } 1069 1070 int 1071 rte_event_port_unlink(uint8_t dev_id, uint8_t port_id, 1072 uint8_t queues[], uint16_t nb_unlinks) 1073 { 1074 return rte_event_port_profile_unlink(dev_id, port_id, queues, nb_unlinks, 0); 1075 } 1076 1077 int 1078 rte_event_port_profile_unlink(uint8_t dev_id, uint8_t port_id, uint8_t queues[], 1079 uint16_t nb_unlinks, uint8_t profile_id) 1080 { 1081 uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; 1082 struct rte_event_dev_info info; 1083 struct rte_eventdev *dev; 1084 uint16_t *links_map; 1085 int i, diag, j; 1086 1087 RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0); 1088 dev = &rte_eventdevs[dev_id]; 1089 1090 if (*dev->dev_ops->dev_infos_get == NULL) 1091 return -ENOTSUP; 1092 1093 (*dev->dev_ops->dev_infos_get)(dev, &info); 1094 if (profile_id >= RTE_EVENT_MAX_PROFILES_PER_PORT || 1095 profile_id >= info.max_profiles_per_port) { 1096 RTE_EDEV_LOG_ERR("Invalid profile_id=%" PRIu8, profile_id); 1097 return -EINVAL; 1098 } 1099 1100 if (*dev->dev_ops->port_unlink == NULL) { 1101 RTE_EDEV_LOG_ERR("Function not supported"); 1102 rte_errno = ENOTSUP; 1103 return 0; 1104 } 1105 1106 if (profile_id && *dev->dev_ops->port_unlink_profile == NULL) { 1107 RTE_EDEV_LOG_ERR("Function not supported"); 1108 rte_errno = ENOTSUP; 1109 return 0; 1110 } 1111 1112 if (!is_valid_port(dev, port_id)) { 1113 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 1114 rte_errno = EINVAL; 1115 return 0; 1116 } 1117 1118 links_map = dev->data->links_map[profile_id]; 1119 /* Point links_map to this port specific area */ 1120 links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV); 1121 1122 if (queues == NULL) { 1123 j = 0; 1124 for (i = 0; i < dev->data->nb_queues; i++) { 1125 if (links_map[i] != 1126 EVENT_QUEUE_SERVICE_PRIORITY_INVALID) { 1127 all_queues[j] = i; 1128 j++; 1129 } 1130 } 1131 queues = all_queues; 1132 } else { 1133 for (j = 0; j < nb_unlinks; j++) { 1134 if (links_map[queues[j]] == 1135 EVENT_QUEUE_SERVICE_PRIORITY_INVALID) 1136 break; 1137 } 1138 } 1139 1140 nb_unlinks = j; 1141 for (i = 0; i < nb_unlinks; i++) 1142 if (queues[i] >= dev->data->nb_queues) { 1143 rte_errno = EINVAL; 1144 return 0; 1145 } 1146 1147 if (profile_id) 1148 diag = (*dev->dev_ops->port_unlink_profile)(dev, dev->data->ports[port_id], queues, 1149 nb_unlinks, profile_id); 1150 else 1151 diag = (*dev->dev_ops->port_unlink)(dev, dev->data->ports[port_id], queues, 1152 nb_unlinks); 1153 if (diag < 0) 1154 return diag; 1155 1156 for (i = 0; i < diag; i++) 1157 links_map[queues[i]] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID; 1158 1159 rte_eventdev_trace_port_profile_unlink(dev_id, port_id, nb_unlinks, profile_id, diag); 1160 return diag; 1161 } 1162 1163 int 1164 rte_event_port_unlinks_in_progress(uint8_t dev_id, uint8_t port_id) 1165 { 1166 struct rte_eventdev *dev; 1167 1168 rte_eventdev_trace_port_unlinks_in_progress(dev_id, port_id); 1169 1170 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1171 dev = &rte_eventdevs[dev_id]; 1172 if (!is_valid_port(dev, port_id)) { 1173 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 1174 return -EINVAL; 1175 } 1176 1177 /* Return 0 if the PMD does not implement unlinks in progress. 1178 * This allows PMDs which handle unlink synchronously to not implement 1179 * this function at all. 1180 */ 1181 if (*dev->dev_ops->port_unlinks_in_progress == NULL) 1182 return 0; 1183 1184 return (*dev->dev_ops->port_unlinks_in_progress)(dev, 1185 dev->data->ports[port_id]); 1186 } 1187 1188 int 1189 rte_event_port_links_get(uint8_t dev_id, uint8_t port_id, 1190 uint8_t queues[], uint8_t priorities[]) 1191 { 1192 struct rte_eventdev *dev; 1193 uint16_t *links_map; 1194 int i, count = 0; 1195 1196 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1197 dev = &rte_eventdevs[dev_id]; 1198 if (!is_valid_port(dev, port_id)) { 1199 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 1200 return -EINVAL; 1201 } 1202 1203 /* Use the default profile_id. */ 1204 links_map = dev->data->links_map[0]; 1205 /* Point links_map to this port specific area */ 1206 links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV); 1207 for (i = 0; i < dev->data->nb_queues; i++) { 1208 if (links_map[i] != EVENT_QUEUE_SERVICE_PRIORITY_INVALID) { 1209 queues[count] = i; 1210 priorities[count] = (uint8_t)links_map[i]; 1211 ++count; 1212 } 1213 } 1214 1215 rte_eventdev_trace_port_links_get(dev_id, port_id, count); 1216 1217 return count; 1218 } 1219 1220 int 1221 rte_event_port_profile_links_get(uint8_t dev_id, uint8_t port_id, uint8_t queues[], 1222 uint8_t priorities[], uint8_t profile_id) 1223 { 1224 struct rte_event_dev_info info; 1225 struct rte_eventdev *dev; 1226 uint16_t *links_map; 1227 int i, count = 0; 1228 1229 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1230 1231 dev = &rte_eventdevs[dev_id]; 1232 if (*dev->dev_ops->dev_infos_get == NULL) 1233 return -ENOTSUP; 1234 1235 (*dev->dev_ops->dev_infos_get)(dev, &info); 1236 if (profile_id >= RTE_EVENT_MAX_PROFILES_PER_PORT || 1237 profile_id >= info.max_profiles_per_port) { 1238 RTE_EDEV_LOG_ERR("Invalid profile_id=%" PRIu8, profile_id); 1239 return -EINVAL; 1240 } 1241 1242 if (!is_valid_port(dev, port_id)) { 1243 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id); 1244 return -EINVAL; 1245 } 1246 1247 links_map = dev->data->links_map[profile_id]; 1248 /* Point links_map to this port specific area */ 1249 links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV); 1250 for (i = 0; i < dev->data->nb_queues; i++) { 1251 if (links_map[i] != EVENT_QUEUE_SERVICE_PRIORITY_INVALID) { 1252 queues[count] = i; 1253 priorities[count] = (uint8_t)links_map[i]; 1254 ++count; 1255 } 1256 } 1257 1258 rte_eventdev_trace_port_profile_links_get(dev_id, port_id, profile_id, count); 1259 1260 return count; 1261 } 1262 1263 int 1264 rte_event_dequeue_timeout_ticks(uint8_t dev_id, uint64_t ns, 1265 uint64_t *timeout_ticks) 1266 { 1267 struct rte_eventdev *dev; 1268 1269 rte_eventdev_trace_dequeue_timeout_ticks(dev_id, ns, timeout_ticks); 1270 1271 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1272 dev = &rte_eventdevs[dev_id]; 1273 if (*dev->dev_ops->timeout_ticks == NULL) 1274 return -ENOTSUP; 1275 1276 if (timeout_ticks == NULL) 1277 return -EINVAL; 1278 1279 return (*dev->dev_ops->timeout_ticks)(dev, ns, timeout_ticks); 1280 } 1281 1282 int 1283 rte_event_dev_service_id_get(uint8_t dev_id, uint32_t *service_id) 1284 { 1285 struct rte_eventdev *dev; 1286 1287 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1288 dev = &rte_eventdevs[dev_id]; 1289 1290 if (service_id == NULL) 1291 return -EINVAL; 1292 1293 if (dev->data->service_inited) 1294 *service_id = dev->data->service_id; 1295 1296 rte_eventdev_trace_service_id_get(dev_id, *service_id); 1297 1298 return dev->data->service_inited ? 0 : -ESRCH; 1299 } 1300 1301 int 1302 rte_event_dev_dump(uint8_t dev_id, FILE *f) 1303 { 1304 struct rte_eventdev *dev; 1305 1306 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1307 dev = &rte_eventdevs[dev_id]; 1308 if (*dev->dev_ops->dump == NULL) 1309 return -ENOTSUP; 1310 if (f == NULL) 1311 return -EINVAL; 1312 1313 (*dev->dev_ops->dump)(dev, f); 1314 return 0; 1315 1316 } 1317 1318 static int 1319 xstats_get_count(uint8_t dev_id, enum rte_event_dev_xstats_mode mode, 1320 uint8_t queue_port_id) 1321 { 1322 struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1323 if (dev->dev_ops->xstats_get_names != NULL) 1324 return (*dev->dev_ops->xstats_get_names)(dev, mode, 1325 queue_port_id, 1326 NULL, NULL, 0); 1327 return 0; 1328 } 1329 1330 int 1331 rte_event_dev_xstats_names_get(uint8_t dev_id, 1332 enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id, 1333 struct rte_event_dev_xstats_name *xstats_names, 1334 uint64_t *ids, unsigned int size) 1335 { 1336 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); 1337 const int cnt_expected_entries = xstats_get_count(dev_id, mode, 1338 queue_port_id); 1339 if (xstats_names == NULL || cnt_expected_entries < 0 || 1340 (int)size < cnt_expected_entries) 1341 return cnt_expected_entries; 1342 1343 /* dev_id checked above */ 1344 const struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1345 1346 if (dev->dev_ops->xstats_get_names != NULL) 1347 return (*dev->dev_ops->xstats_get_names)(dev, mode, 1348 queue_port_id, xstats_names, ids, size); 1349 1350 return -ENOTSUP; 1351 } 1352 1353 /* retrieve eventdev extended statistics */ 1354 int 1355 rte_event_dev_xstats_get(uint8_t dev_id, enum rte_event_dev_xstats_mode mode, 1356 uint8_t queue_port_id, const uint64_t ids[], 1357 uint64_t values[], unsigned int n) 1358 { 1359 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); 1360 const struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1361 1362 /* implemented by the driver */ 1363 if (dev->dev_ops->xstats_get != NULL) 1364 return (*dev->dev_ops->xstats_get)(dev, mode, queue_port_id, 1365 ids, values, n); 1366 return -ENOTSUP; 1367 } 1368 1369 uint64_t 1370 rte_event_dev_xstats_by_name_get(uint8_t dev_id, const char *name, 1371 uint64_t *id) 1372 { 1373 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0); 1374 const struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1375 uint64_t temp = -1; 1376 1377 if (id != NULL) 1378 *id = (unsigned int)-1; 1379 else 1380 id = &temp; /* ensure driver never gets a NULL value */ 1381 1382 /* implemented by driver */ 1383 if (dev->dev_ops->xstats_get_by_name != NULL) 1384 return (*dev->dev_ops->xstats_get_by_name)(dev, name, id); 1385 return -ENOTSUP; 1386 } 1387 1388 int rte_event_dev_xstats_reset(uint8_t dev_id, 1389 enum rte_event_dev_xstats_mode mode, int16_t queue_port_id, 1390 const uint64_t ids[], uint32_t nb_ids) 1391 { 1392 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1393 struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1394 1395 if (dev->dev_ops->xstats_reset != NULL) 1396 return (*dev->dev_ops->xstats_reset)(dev, mode, queue_port_id, 1397 ids, nb_ids); 1398 return -ENOTSUP; 1399 } 1400 1401 int rte_event_pmd_selftest_seqn_dynfield_offset = -1; 1402 1403 int rte_event_dev_selftest(uint8_t dev_id) 1404 { 1405 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1406 static const struct rte_mbuf_dynfield test_seqn_dynfield_desc = { 1407 .name = "rte_event_pmd_selftest_seqn_dynfield", 1408 .size = sizeof(rte_event_pmd_selftest_seqn_t), 1409 .align = alignof(rte_event_pmd_selftest_seqn_t), 1410 }; 1411 struct rte_eventdev *dev = &rte_eventdevs[dev_id]; 1412 1413 if (dev->dev_ops->dev_selftest != NULL) { 1414 rte_event_pmd_selftest_seqn_dynfield_offset = 1415 rte_mbuf_dynfield_register(&test_seqn_dynfield_desc); 1416 if (rte_event_pmd_selftest_seqn_dynfield_offset < 0) 1417 return -ENOMEM; 1418 return (*dev->dev_ops->dev_selftest)(); 1419 } 1420 return -ENOTSUP; 1421 } 1422 1423 struct rte_mempool * 1424 rte_event_vector_pool_create(const char *name, unsigned int n, 1425 unsigned int cache_size, uint16_t nb_elem, 1426 int socket_id) 1427 { 1428 const char *mp_ops_name; 1429 struct rte_mempool *mp; 1430 unsigned int elt_sz; 1431 int ret; 1432 1433 if (!nb_elem) { 1434 RTE_EDEV_LOG_ERR("Invalid number of elements=%d requested", 1435 nb_elem); 1436 rte_errno = EINVAL; 1437 return NULL; 1438 } 1439 1440 elt_sz = 1441 sizeof(struct rte_event_vector) + (nb_elem * sizeof(uintptr_t)); 1442 mp = rte_mempool_create_empty(name, n, elt_sz, cache_size, 0, socket_id, 1443 0); 1444 if (mp == NULL) 1445 return NULL; 1446 1447 mp_ops_name = rte_mbuf_best_mempool_ops(); 1448 ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL); 1449 if (ret != 0) { 1450 RTE_EDEV_LOG_ERR("error setting mempool handler"); 1451 goto err; 1452 } 1453 1454 ret = rte_mempool_populate_default(mp); 1455 if (ret < 0) 1456 goto err; 1457 1458 rte_eventdev_trace_vector_pool_create(mp, mp->name, mp->socket_id, 1459 mp->size, mp->cache_size, mp->elt_size); 1460 1461 return mp; 1462 err: 1463 rte_mempool_free(mp); 1464 rte_errno = -ret; 1465 return NULL; 1466 } 1467 1468 int 1469 rte_event_dev_start(uint8_t dev_id) 1470 { 1471 struct rte_eventdev *dev; 1472 int diag; 1473 1474 RTE_EDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id); 1475 1476 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1477 dev = &rte_eventdevs[dev_id]; 1478 if (*dev->dev_ops->dev_start == NULL) 1479 return -ENOTSUP; 1480 1481 if (dev->data->dev_started != 0) { 1482 RTE_EDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already started", 1483 dev_id); 1484 return 0; 1485 } 1486 1487 diag = (*dev->dev_ops->dev_start)(dev); 1488 rte_eventdev_trace_start(dev_id, diag); 1489 if (diag == 0) 1490 dev->data->dev_started = 1; 1491 else 1492 return diag; 1493 1494 event_dev_fp_ops_set(rte_event_fp_ops + dev_id, dev); 1495 1496 return 0; 1497 } 1498 1499 int 1500 rte_event_dev_stop_flush_callback_register(uint8_t dev_id, 1501 rte_eventdev_stop_flush_t callback, 1502 void *userdata) 1503 { 1504 struct rte_eventdev *dev; 1505 1506 RTE_EDEV_LOG_DEBUG("Stop flush register dev_id=%" PRIu8, dev_id); 1507 1508 rte_eventdev_trace_stop_flush_callback_register(dev_id, callback, userdata); 1509 1510 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1511 dev = &rte_eventdevs[dev_id]; 1512 1513 dev->dev_ops->dev_stop_flush = callback; 1514 dev->data->dev_stop_flush_arg = userdata; 1515 1516 return 0; 1517 } 1518 1519 void 1520 rte_event_dev_stop(uint8_t dev_id) 1521 { 1522 struct rte_eventdev *dev; 1523 1524 RTE_EDEV_LOG_DEBUG("Stop dev_id=%" PRIu8, dev_id); 1525 1526 RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id); 1527 dev = &rte_eventdevs[dev_id]; 1528 if (*dev->dev_ops->dev_stop == NULL) 1529 return; 1530 1531 if (dev->data->dev_started == 0) { 1532 RTE_EDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already stopped", 1533 dev_id); 1534 return; 1535 } 1536 1537 dev->data->dev_started = 0; 1538 (*dev->dev_ops->dev_stop)(dev); 1539 rte_eventdev_trace_stop(dev_id); 1540 event_dev_fp_ops_reset(rte_event_fp_ops + dev_id); 1541 } 1542 1543 int 1544 rte_event_dev_close(uint8_t dev_id) 1545 { 1546 struct rte_eventdev *dev; 1547 1548 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1549 dev = &rte_eventdevs[dev_id]; 1550 if (*dev->dev_ops->dev_close == NULL) 1551 return -ENOTSUP; 1552 1553 /* Device must be stopped before it can be closed */ 1554 if (dev->data->dev_started == 1) { 1555 RTE_EDEV_LOG_ERR("Device %u must be stopped before closing", 1556 dev_id); 1557 return -EBUSY; 1558 } 1559 1560 event_dev_fp_ops_reset(rte_event_fp_ops + dev_id); 1561 rte_eventdev_trace_close(dev_id); 1562 return (*dev->dev_ops->dev_close)(dev); 1563 } 1564 1565 static inline int 1566 eventdev_data_alloc(uint8_t dev_id, struct rte_eventdev_data **data, 1567 int socket_id) 1568 { 1569 char mz_name[RTE_EVENTDEV_NAME_MAX_LEN]; 1570 const struct rte_memzone *mz; 1571 int i, n; 1572 1573 /* Generate memzone name */ 1574 n = snprintf(mz_name, sizeof(mz_name), "rte_eventdev_data_%u", dev_id); 1575 if (n >= (int)sizeof(mz_name)) 1576 return -EINVAL; 1577 1578 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1579 mz = rte_memzone_reserve(mz_name, 1580 sizeof(struct rte_eventdev_data), 1581 socket_id, 0); 1582 } else 1583 mz = rte_memzone_lookup(mz_name); 1584 1585 if (mz == NULL) 1586 return -ENOMEM; 1587 1588 *data = mz->addr; 1589 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1590 memset(*data, 0, sizeof(struct rte_eventdev_data)); 1591 for (i = 0; i < RTE_EVENT_MAX_PROFILES_PER_PORT; i++) 1592 for (n = 0; n < RTE_EVENT_MAX_PORTS_PER_DEV * RTE_EVENT_MAX_QUEUES_PER_DEV; 1593 n++) 1594 (*data)->links_map[i][n] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID; 1595 } 1596 1597 return 0; 1598 } 1599 1600 static inline uint8_t 1601 eventdev_find_free_device_index(void) 1602 { 1603 uint8_t dev_id; 1604 1605 for (dev_id = 0; dev_id < RTE_EVENT_MAX_DEVS; dev_id++) { 1606 if (rte_eventdevs[dev_id].attached == 1607 RTE_EVENTDEV_DETACHED) 1608 return dev_id; 1609 } 1610 return RTE_EVENT_MAX_DEVS; 1611 } 1612 1613 struct rte_eventdev * 1614 rte_event_pmd_allocate(const char *name, int socket_id) 1615 { 1616 struct rte_eventdev *eventdev; 1617 uint8_t dev_id; 1618 1619 if (rte_event_pmd_get_named_dev(name) != NULL) { 1620 RTE_EDEV_LOG_ERR("Event device with name %s already " 1621 "allocated!", name); 1622 return NULL; 1623 } 1624 1625 dev_id = eventdev_find_free_device_index(); 1626 if (dev_id == RTE_EVENT_MAX_DEVS) { 1627 RTE_EDEV_LOG_ERR("Reached maximum number of event devices"); 1628 return NULL; 1629 } 1630 1631 eventdev = &rte_eventdevs[dev_id]; 1632 1633 if (eventdev->data == NULL) { 1634 struct rte_eventdev_data *eventdev_data = NULL; 1635 1636 int retval = 1637 eventdev_data_alloc(dev_id, &eventdev_data, socket_id); 1638 1639 if (retval < 0 || eventdev_data == NULL) 1640 return NULL; 1641 1642 eventdev->data = eventdev_data; 1643 1644 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1645 1646 strlcpy(eventdev->data->name, name, 1647 RTE_EVENTDEV_NAME_MAX_LEN); 1648 1649 eventdev->data->dev_id = dev_id; 1650 eventdev->data->socket_id = socket_id; 1651 eventdev->data->dev_started = 0; 1652 } 1653 1654 eventdev->attached = RTE_EVENTDEV_ATTACHED; 1655 eventdev_globals.nb_devs++; 1656 } 1657 1658 return eventdev; 1659 } 1660 1661 int 1662 rte_event_pmd_release(struct rte_eventdev *eventdev) 1663 { 1664 int ret; 1665 char mz_name[RTE_EVENTDEV_NAME_MAX_LEN]; 1666 const struct rte_memzone *mz; 1667 1668 if (eventdev == NULL) 1669 return -EINVAL; 1670 1671 event_dev_fp_ops_reset(rte_event_fp_ops + eventdev->data->dev_id); 1672 eventdev->attached = RTE_EVENTDEV_DETACHED; 1673 eventdev_globals.nb_devs--; 1674 1675 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1676 rte_free(eventdev->data->dev_private); 1677 1678 /* Generate memzone name */ 1679 ret = snprintf(mz_name, sizeof(mz_name), "rte_eventdev_data_%u", 1680 eventdev->data->dev_id); 1681 if (ret >= (int)sizeof(mz_name)) 1682 return -EINVAL; 1683 1684 mz = rte_memzone_lookup(mz_name); 1685 if (mz == NULL) 1686 return -ENOMEM; 1687 1688 ret = rte_memzone_free(mz); 1689 if (ret) 1690 return ret; 1691 } 1692 1693 eventdev->data = NULL; 1694 return 0; 1695 } 1696 1697 void 1698 event_dev_probing_finish(struct rte_eventdev *eventdev) 1699 { 1700 if (eventdev == NULL) 1701 return; 1702 1703 event_dev_fp_ops_set(rte_event_fp_ops + eventdev->data->dev_id, 1704 eventdev); 1705 } 1706 1707 static int 1708 handle_dev_list(const char *cmd __rte_unused, 1709 const char *params __rte_unused, 1710 struct rte_tel_data *d) 1711 { 1712 uint8_t dev_id; 1713 int ndev = rte_event_dev_count(); 1714 1715 if (ndev < 1) 1716 return -1; 1717 1718 rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 1719 for (dev_id = 0; dev_id < RTE_EVENT_MAX_DEVS; dev_id++) { 1720 if (rte_eventdevs[dev_id].attached == 1721 RTE_EVENTDEV_ATTACHED) 1722 rte_tel_data_add_array_int(d, dev_id); 1723 } 1724 1725 return 0; 1726 } 1727 1728 static int 1729 handle_port_list(const char *cmd __rte_unused, 1730 const char *params, 1731 struct rte_tel_data *d) 1732 { 1733 int i; 1734 uint8_t dev_id; 1735 struct rte_eventdev *dev; 1736 char *end_param; 1737 1738 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1739 return -1; 1740 1741 dev_id = strtoul(params, &end_param, 10); 1742 if (*end_param != '\0') 1743 RTE_EDEV_LOG_DEBUG( 1744 "Extra parameters passed to eventdev telemetry command, ignoring"); 1745 1746 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1747 dev = &rte_eventdevs[dev_id]; 1748 1749 rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 1750 for (i = 0; i < dev->data->nb_ports; i++) 1751 rte_tel_data_add_array_int(d, i); 1752 1753 return 0; 1754 } 1755 1756 static int 1757 handle_queue_list(const char *cmd __rte_unused, 1758 const char *params, 1759 struct rte_tel_data *d) 1760 { 1761 int i; 1762 uint8_t dev_id; 1763 struct rte_eventdev *dev; 1764 char *end_param; 1765 1766 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1767 return -1; 1768 1769 dev_id = strtoul(params, &end_param, 10); 1770 if (*end_param != '\0') 1771 RTE_EDEV_LOG_DEBUG( 1772 "Extra parameters passed to eventdev telemetry command, ignoring"); 1773 1774 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1775 dev = &rte_eventdevs[dev_id]; 1776 1777 rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 1778 for (i = 0; i < dev->data->nb_queues; i++) 1779 rte_tel_data_add_array_int(d, i); 1780 1781 return 0; 1782 } 1783 1784 static int 1785 handle_queue_links(const char *cmd __rte_unused, 1786 const char *params, 1787 struct rte_tel_data *d) 1788 { 1789 int i, ret, port_id = 0; 1790 char *end_param; 1791 uint8_t dev_id; 1792 uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; 1793 uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; 1794 const char *p_param; 1795 1796 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1797 return -1; 1798 1799 /* Get dev ID from parameter string */ 1800 dev_id = strtoul(params, &end_param, 10); 1801 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1802 1803 p_param = strtok(end_param, ","); 1804 if (p_param == NULL || strlen(p_param) == 0 || !isdigit(*p_param)) 1805 return -1; 1806 1807 port_id = strtoul(p_param, &end_param, 10); 1808 p_param = strtok(NULL, "\0"); 1809 if (p_param != NULL) 1810 RTE_EDEV_LOG_DEBUG( 1811 "Extra parameters passed to eventdev telemetry command, ignoring"); 1812 1813 ret = rte_event_port_links_get(dev_id, port_id, queues, priorities); 1814 if (ret < 0) 1815 return -1; 1816 1817 rte_tel_data_start_dict(d); 1818 for (i = 0; i < ret; i++) { 1819 char qid_name[32]; 1820 1821 snprintf(qid_name, 31, "qid_%u", queues[i]); 1822 rte_tel_data_add_dict_uint(d, qid_name, priorities[i]); 1823 } 1824 1825 return 0; 1826 } 1827 1828 static int 1829 eventdev_build_telemetry_data(int dev_id, 1830 enum rte_event_dev_xstats_mode mode, 1831 int port_queue_id, 1832 struct rte_tel_data *d) 1833 { 1834 struct rte_event_dev_xstats_name *xstat_names; 1835 uint64_t *ids; 1836 uint64_t *values; 1837 int i, ret, num_xstats; 1838 1839 num_xstats = rte_event_dev_xstats_names_get(dev_id, 1840 mode, 1841 port_queue_id, 1842 NULL, 1843 NULL, 1844 0); 1845 1846 if (num_xstats < 0) 1847 return -1; 1848 1849 /* use one malloc for names */ 1850 xstat_names = malloc((sizeof(struct rte_event_dev_xstats_name)) 1851 * num_xstats); 1852 if (xstat_names == NULL) 1853 return -1; 1854 1855 ids = malloc((sizeof(uint64_t)) * num_xstats); 1856 if (ids == NULL) { 1857 free(xstat_names); 1858 return -1; 1859 } 1860 1861 values = malloc((sizeof(uint64_t)) * num_xstats); 1862 if (values == NULL) { 1863 free(xstat_names); 1864 free(ids); 1865 return -1; 1866 } 1867 1868 ret = rte_event_dev_xstats_names_get(dev_id, mode, port_queue_id, 1869 xstat_names, ids, num_xstats); 1870 if (ret < 0 || ret > num_xstats) { 1871 free(xstat_names); 1872 free(ids); 1873 free(values); 1874 return -1; 1875 } 1876 1877 ret = rte_event_dev_xstats_get(dev_id, mode, port_queue_id, 1878 ids, values, num_xstats); 1879 if (ret < 0 || ret > num_xstats) { 1880 free(xstat_names); 1881 free(ids); 1882 free(values); 1883 return -1; 1884 } 1885 1886 rte_tel_data_start_dict(d); 1887 for (i = 0; i < num_xstats; i++) 1888 rte_tel_data_add_dict_uint(d, xstat_names[i].name, values[i]); 1889 1890 free(xstat_names); 1891 free(ids); 1892 free(values); 1893 return 0; 1894 } 1895 1896 static int 1897 handle_dev_xstats(const char *cmd __rte_unused, 1898 const char *params, 1899 struct rte_tel_data *d) 1900 { 1901 int dev_id; 1902 enum rte_event_dev_xstats_mode mode; 1903 char *end_param; 1904 1905 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1906 return -1; 1907 1908 /* Get dev ID from parameter string */ 1909 dev_id = strtoul(params, &end_param, 10); 1910 if (*end_param != '\0') 1911 RTE_EDEV_LOG_DEBUG( 1912 "Extra parameters passed to eventdev telemetry command, ignoring"); 1913 1914 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1915 1916 mode = RTE_EVENT_DEV_XSTATS_DEVICE; 1917 return eventdev_build_telemetry_data(dev_id, mode, 0, d); 1918 } 1919 1920 static int 1921 handle_port_xstats(const char *cmd __rte_unused, 1922 const char *params, 1923 struct rte_tel_data *d) 1924 { 1925 int dev_id; 1926 int port_queue_id = 0; 1927 enum rte_event_dev_xstats_mode mode; 1928 char *end_param; 1929 const char *p_param; 1930 1931 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1932 return -1; 1933 1934 /* Get dev ID from parameter string */ 1935 dev_id = strtoul(params, &end_param, 10); 1936 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1937 1938 p_param = strtok(end_param, ","); 1939 mode = RTE_EVENT_DEV_XSTATS_PORT; 1940 1941 if (p_param == NULL || strlen(p_param) == 0 || !isdigit(*p_param)) 1942 return -1; 1943 1944 port_queue_id = strtoul(p_param, &end_param, 10); 1945 1946 p_param = strtok(NULL, "\0"); 1947 if (p_param != NULL) 1948 RTE_EDEV_LOG_DEBUG( 1949 "Extra parameters passed to eventdev telemetry command, ignoring"); 1950 1951 return eventdev_build_telemetry_data(dev_id, mode, port_queue_id, d); 1952 } 1953 1954 static int 1955 handle_queue_xstats(const char *cmd __rte_unused, 1956 const char *params, 1957 struct rte_tel_data *d) 1958 { 1959 int dev_id; 1960 int port_queue_id = 0; 1961 enum rte_event_dev_xstats_mode mode; 1962 char *end_param; 1963 const char *p_param; 1964 1965 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1966 return -1; 1967 1968 /* Get dev ID from parameter string */ 1969 dev_id = strtoul(params, &end_param, 10); 1970 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 1971 1972 p_param = strtok(end_param, ","); 1973 mode = RTE_EVENT_DEV_XSTATS_QUEUE; 1974 1975 if (p_param == NULL || strlen(p_param) == 0 || !isdigit(*p_param)) 1976 return -1; 1977 1978 port_queue_id = strtoul(p_param, &end_param, 10); 1979 1980 p_param = strtok(NULL, "\0"); 1981 if (p_param != NULL) 1982 RTE_EDEV_LOG_DEBUG( 1983 "Extra parameters passed to eventdev telemetry command, ignoring"); 1984 1985 return eventdev_build_telemetry_data(dev_id, mode, port_queue_id, d); 1986 } 1987 1988 static int 1989 handle_dev_dump(const char *cmd __rte_unused, 1990 const char *params, 1991 struct rte_tel_data *d) 1992 { 1993 char *buf, *end_param; 1994 int dev_id, ret; 1995 FILE *f; 1996 1997 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 1998 return -1; 1999 2000 /* Get dev ID from parameter string */ 2001 dev_id = strtoul(params, &end_param, 10); 2002 if (*end_param != '\0') 2003 RTE_EDEV_LOG_DEBUG( 2004 "Extra parameters passed to eventdev telemetry command, ignoring"); 2005 2006 RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 2007 2008 buf = calloc(RTE_TEL_MAX_SINGLE_STRING_LEN, sizeof(char)); 2009 if (buf == NULL) 2010 return -ENOMEM; 2011 2012 f = fmemopen(buf, RTE_TEL_MAX_SINGLE_STRING_LEN - 1, "w+"); 2013 if (f == NULL) { 2014 free(buf); 2015 return -EINVAL; 2016 } 2017 2018 ret = rte_event_dev_dump(dev_id, f); 2019 fclose(f); 2020 if (ret == 0) { 2021 rte_tel_data_start_dict(d); 2022 rte_tel_data_string(d, buf); 2023 } 2024 2025 free(buf); 2026 return ret; 2027 } 2028 2029 RTE_INIT(eventdev_init_telemetry) 2030 { 2031 rte_telemetry_register_cmd("/eventdev/dev_list", handle_dev_list, 2032 "Returns list of available eventdevs. Takes no parameters"); 2033 rte_telemetry_register_cmd("/eventdev/port_list", handle_port_list, 2034 "Returns list of available ports. Parameter: DevID"); 2035 rte_telemetry_register_cmd("/eventdev/queue_list", handle_queue_list, 2036 "Returns list of available queues. Parameter: DevID"); 2037 2038 rte_telemetry_register_cmd("/eventdev/dev_xstats", handle_dev_xstats, 2039 "Returns stats for an eventdev. Parameter: DevID"); 2040 rte_telemetry_register_cmd("/eventdev/port_xstats", handle_port_xstats, 2041 "Returns stats for an eventdev port. Params: DevID,PortID"); 2042 rte_telemetry_register_cmd("/eventdev/queue_xstats", 2043 handle_queue_xstats, 2044 "Returns stats for an eventdev queue. Params: DevID,QueueID"); 2045 rte_telemetry_register_cmd("/eventdev/dev_dump", handle_dev_dump, 2046 "Returns dump information for an eventdev. Parameter: DevID"); 2047 rte_telemetry_register_cmd("/eventdev/queue_links", handle_queue_links, 2048 "Returns links for an eventdev port. Params: DevID,QueueID"); 2049 } 2050