1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017-2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include <string.h> 7 #include <inttypes.h> 8 #include <stdbool.h> 9 #include <sys/queue.h> 10 11 #include <rte_memzone.h> 12 #include <rte_memory.h> 13 #include <rte_dev.h> 14 #include <rte_errno.h> 15 #include <rte_malloc.h> 16 #include <rte_ring.h> 17 #include <rte_mempool.h> 18 #include <rte_common.h> 19 #include <rte_timer.h> 20 #include <rte_service_component.h> 21 #include <rte_cycles.h> 22 23 #include "event_timer_adapter_pmd.h" 24 #include "eventdev_pmd.h" 25 #include "rte_event_timer_adapter.h" 26 #include "rte_eventdev.h" 27 #include "eventdev_trace.h" 28 29 #define DATA_MZ_NAME_MAX_LEN 64 30 #define DATA_MZ_NAME_FORMAT "rte_event_timer_adapter_data_%d" 31 32 RTE_LOG_REGISTER_SUFFIX(evtim_logtype, adapter.timer, NOTICE); 33 RTE_LOG_REGISTER_SUFFIX(evtim_buffer_logtype, adapter.timer, NOTICE); 34 RTE_LOG_REGISTER_SUFFIX(evtim_svc_logtype, adapter.timer.svc, NOTICE); 35 36 static struct rte_event_timer_adapter *adapters; 37 38 static const struct event_timer_adapter_ops swtim_ops; 39 40 #define EVTIM_LOG(level, logtype, ...) \ 41 rte_log(RTE_LOG_ ## level, logtype, \ 42 RTE_FMT("EVTIMER: %s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) \ 43 "\n", __func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,))) 44 45 #define EVTIM_LOG_ERR(...) EVTIM_LOG(ERR, evtim_logtype, __VA_ARGS__) 46 47 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG 48 #define EVTIM_LOG_DBG(...) \ 49 EVTIM_LOG(DEBUG, evtim_logtype, __VA_ARGS__) 50 #define EVTIM_BUF_LOG_DBG(...) \ 51 EVTIM_LOG(DEBUG, evtim_buffer_logtype, __VA_ARGS__) 52 #define EVTIM_SVC_LOG_DBG(...) \ 53 EVTIM_LOG(DEBUG, evtim_svc_logtype, __VA_ARGS__) 54 #else 55 #define EVTIM_LOG_DBG(...) (void)0 56 #define EVTIM_BUF_LOG_DBG(...) (void)0 57 #define EVTIM_SVC_LOG_DBG(...) (void)0 58 #endif 59 60 static int 61 default_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id, 62 void *conf_arg) 63 { 64 struct rte_event_timer_adapter *adapter; 65 struct rte_eventdev *dev; 66 struct rte_event_dev_config dev_conf; 67 struct rte_event_port_conf *port_conf, def_port_conf = {0}; 68 int started; 69 uint8_t port_id; 70 uint8_t dev_id; 71 int ret; 72 73 RTE_SET_USED(event_dev_id); 74 75 adapter = &adapters[id]; 76 dev = &rte_eventdevs[adapter->data->event_dev_id]; 77 dev_id = dev->data->dev_id; 78 dev_conf = dev->data->dev_conf; 79 80 started = dev->data->dev_started; 81 if (started) 82 rte_event_dev_stop(dev_id); 83 84 port_id = dev_conf.nb_event_ports; 85 dev_conf.nb_event_ports += 1; 86 ret = rte_event_dev_configure(dev_id, &dev_conf); 87 if (ret < 0) { 88 EVTIM_LOG_ERR("failed to configure event dev %u\n", dev_id); 89 if (started) 90 if (rte_event_dev_start(dev_id)) 91 return -EIO; 92 93 return ret; 94 } 95 96 if (conf_arg != NULL) 97 port_conf = conf_arg; 98 else { 99 port_conf = &def_port_conf; 100 ret = rte_event_port_default_conf_get(dev_id, port_id, 101 port_conf); 102 if (ret < 0) 103 return ret; 104 } 105 106 ret = rte_event_port_setup(dev_id, port_id, port_conf); 107 if (ret < 0) { 108 EVTIM_LOG_ERR("failed to setup event port %u on event dev %u\n", 109 port_id, dev_id); 110 return ret; 111 } 112 113 *event_port_id = port_id; 114 115 if (started) 116 ret = rte_event_dev_start(dev_id); 117 118 return ret; 119 } 120 121 struct rte_event_timer_adapter * 122 rte_event_timer_adapter_create(const struct rte_event_timer_adapter_conf *conf) 123 { 124 return rte_event_timer_adapter_create_ext(conf, default_port_conf_cb, 125 NULL); 126 } 127 128 struct rte_event_timer_adapter * 129 rte_event_timer_adapter_create_ext( 130 const struct rte_event_timer_adapter_conf *conf, 131 rte_event_timer_adapter_port_conf_cb_t conf_cb, 132 void *conf_arg) 133 { 134 uint16_t adapter_id; 135 struct rte_event_timer_adapter *adapter; 136 const struct rte_memzone *mz; 137 char mz_name[DATA_MZ_NAME_MAX_LEN]; 138 int n, ret; 139 struct rte_eventdev *dev; 140 141 if (adapters == NULL) { 142 adapters = rte_zmalloc("Eventdev", 143 sizeof(struct rte_event_timer_adapter) * 144 RTE_EVENT_TIMER_ADAPTER_NUM_MAX, 145 RTE_CACHE_LINE_SIZE); 146 if (adapters == NULL) { 147 rte_errno = ENOMEM; 148 return NULL; 149 } 150 } 151 152 if (conf == NULL) { 153 rte_errno = EINVAL; 154 return NULL; 155 } 156 157 /* Check eventdev ID */ 158 if (!rte_event_pmd_is_valid_dev(conf->event_dev_id)) { 159 rte_errno = EINVAL; 160 return NULL; 161 } 162 dev = &rte_eventdevs[conf->event_dev_id]; 163 164 adapter_id = conf->timer_adapter_id; 165 166 /* Check that adapter_id is in range */ 167 if (adapter_id >= RTE_EVENT_TIMER_ADAPTER_NUM_MAX) { 168 rte_errno = EINVAL; 169 return NULL; 170 } 171 172 /* Check adapter ID not already allocated */ 173 adapter = &adapters[adapter_id]; 174 if (adapter->allocated) { 175 rte_errno = EEXIST; 176 return NULL; 177 } 178 179 /* Create shared data area. */ 180 n = snprintf(mz_name, sizeof(mz_name), DATA_MZ_NAME_FORMAT, adapter_id); 181 if (n >= (int)sizeof(mz_name)) { 182 rte_errno = EINVAL; 183 return NULL; 184 } 185 mz = rte_memzone_reserve(mz_name, 186 sizeof(struct rte_event_timer_adapter_data), 187 conf->socket_id, 0); 188 if (mz == NULL) 189 /* rte_errno set by rte_memzone_reserve */ 190 return NULL; 191 192 adapter->data = mz->addr; 193 memset(adapter->data, 0, sizeof(struct rte_event_timer_adapter_data)); 194 195 adapter->data->mz = mz; 196 adapter->data->event_dev_id = conf->event_dev_id; 197 adapter->data->id = adapter_id; 198 adapter->data->socket_id = conf->socket_id; 199 adapter->data->conf = *conf; /* copy conf structure */ 200 201 /* Query eventdev PMD for timer adapter capabilities and ops */ 202 ret = dev->dev_ops->timer_adapter_caps_get(dev, 203 adapter->data->conf.flags, 204 &adapter->data->caps, 205 &adapter->ops); 206 if (ret < 0) { 207 rte_errno = -ret; 208 goto free_memzone; 209 } 210 211 if (!(adapter->data->caps & 212 RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) { 213 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(conf_cb, EINVAL); 214 ret = conf_cb(adapter->data->id, adapter->data->event_dev_id, 215 &adapter->data->event_port_id, conf_arg); 216 if (ret < 0) { 217 rte_errno = -ret; 218 goto free_memzone; 219 } 220 } 221 222 /* If eventdev PMD did not provide ops, use default software 223 * implementation. 224 */ 225 if (adapter->ops == NULL) 226 adapter->ops = &swtim_ops; 227 228 /* Allow driver to do some setup */ 229 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(adapter->ops->init, ENOTSUP); 230 ret = adapter->ops->init(adapter); 231 if (ret < 0) { 232 rte_errno = -ret; 233 goto free_memzone; 234 } 235 236 /* Set fast-path function pointers */ 237 adapter->arm_burst = adapter->ops->arm_burst; 238 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst; 239 adapter->cancel_burst = adapter->ops->cancel_burst; 240 241 adapter->allocated = 1; 242 243 rte_eventdev_trace_timer_adapter_create(adapter_id, adapter, conf, 244 conf_cb); 245 return adapter; 246 247 free_memzone: 248 rte_memzone_free(adapter->data->mz); 249 return NULL; 250 } 251 252 int 253 rte_event_timer_adapter_get_info(const struct rte_event_timer_adapter *adapter, 254 struct rte_event_timer_adapter_info *adapter_info) 255 { 256 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 257 258 if (adapter->ops->get_info) 259 /* let driver set values it knows */ 260 adapter->ops->get_info(adapter, adapter_info); 261 262 /* Set common values */ 263 adapter_info->conf = adapter->data->conf; 264 adapter_info->event_dev_port_id = adapter->data->event_port_id; 265 adapter_info->caps = adapter->data->caps; 266 267 return 0; 268 } 269 270 int 271 rte_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter) 272 { 273 int ret; 274 275 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 276 FUNC_PTR_OR_ERR_RET(adapter->ops->start, -EINVAL); 277 278 if (adapter->data->started) { 279 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already started", 280 adapter->data->id); 281 return -EALREADY; 282 } 283 284 ret = adapter->ops->start(adapter); 285 if (ret < 0) 286 return ret; 287 288 adapter->data->started = 1; 289 rte_eventdev_trace_timer_adapter_start(adapter); 290 return 0; 291 } 292 293 int 294 rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter) 295 { 296 int ret; 297 298 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 299 FUNC_PTR_OR_ERR_RET(adapter->ops->stop, -EINVAL); 300 301 if (adapter->data->started == 0) { 302 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already stopped", 303 adapter->data->id); 304 return 0; 305 } 306 307 ret = adapter->ops->stop(adapter); 308 if (ret < 0) 309 return ret; 310 311 adapter->data->started = 0; 312 rte_eventdev_trace_timer_adapter_stop(adapter); 313 return 0; 314 } 315 316 struct rte_event_timer_adapter * 317 rte_event_timer_adapter_lookup(uint16_t adapter_id) 318 { 319 char name[DATA_MZ_NAME_MAX_LEN]; 320 const struct rte_memzone *mz; 321 struct rte_event_timer_adapter_data *data; 322 struct rte_event_timer_adapter *adapter; 323 int ret; 324 struct rte_eventdev *dev; 325 326 if (adapters == NULL) { 327 adapters = rte_zmalloc("Eventdev", 328 sizeof(struct rte_event_timer_adapter) * 329 RTE_EVENT_TIMER_ADAPTER_NUM_MAX, 330 RTE_CACHE_LINE_SIZE); 331 if (adapters == NULL) { 332 rte_errno = ENOMEM; 333 return NULL; 334 } 335 } 336 337 if (adapters[adapter_id].allocated) 338 return &adapters[adapter_id]; /* Adapter is already loaded */ 339 340 snprintf(name, DATA_MZ_NAME_MAX_LEN, DATA_MZ_NAME_FORMAT, adapter_id); 341 mz = rte_memzone_lookup(name); 342 if (mz == NULL) { 343 rte_errno = ENOENT; 344 return NULL; 345 } 346 347 data = mz->addr; 348 349 adapter = &adapters[data->id]; 350 adapter->data = data; 351 352 dev = &rte_eventdevs[adapter->data->event_dev_id]; 353 354 /* Query eventdev PMD for timer adapter capabilities and ops */ 355 ret = dev->dev_ops->timer_adapter_caps_get(dev, 356 adapter->data->conf.flags, 357 &adapter->data->caps, 358 &adapter->ops); 359 if (ret < 0) { 360 rte_errno = EINVAL; 361 return NULL; 362 } 363 364 /* If eventdev PMD did not provide ops, use default software 365 * implementation. 366 */ 367 if (adapter->ops == NULL) 368 adapter->ops = &swtim_ops; 369 370 /* Set fast-path function pointers */ 371 adapter->arm_burst = adapter->ops->arm_burst; 372 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst; 373 adapter->cancel_burst = adapter->ops->cancel_burst; 374 375 adapter->allocated = 1; 376 377 return adapter; 378 } 379 380 int 381 rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter) 382 { 383 int i, ret; 384 385 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 386 FUNC_PTR_OR_ERR_RET(adapter->ops->uninit, -EINVAL); 387 388 if (adapter->data->started == 1) { 389 EVTIM_LOG_ERR("event timer adapter %"PRIu8" must be stopped " 390 "before freeing", adapter->data->id); 391 return -EBUSY; 392 } 393 394 /* free impl priv data */ 395 ret = adapter->ops->uninit(adapter); 396 if (ret < 0) 397 return ret; 398 399 /* free shared data area */ 400 ret = rte_memzone_free(adapter->data->mz); 401 if (ret < 0) 402 return ret; 403 404 adapter->data = NULL; 405 adapter->allocated = 0; 406 407 ret = 0; 408 for (i = 0; i < RTE_EVENT_TIMER_ADAPTER_NUM_MAX; i++) 409 if (adapters[i].allocated) 410 ret = adapters[i].allocated; 411 412 if (!ret) { 413 rte_free(adapters); 414 adapters = NULL; 415 } 416 417 rte_eventdev_trace_timer_adapter_free(adapter); 418 return 0; 419 } 420 421 int 422 rte_event_timer_adapter_service_id_get(struct rte_event_timer_adapter *adapter, 423 uint32_t *service_id) 424 { 425 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 426 427 if (adapter->data->service_inited && service_id != NULL) 428 *service_id = adapter->data->service_id; 429 430 return adapter->data->service_inited ? 0 : -ESRCH; 431 } 432 433 int 434 rte_event_timer_adapter_stats_get(struct rte_event_timer_adapter *adapter, 435 struct rte_event_timer_adapter_stats *stats) 436 { 437 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 438 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_get, -EINVAL); 439 if (stats == NULL) 440 return -EINVAL; 441 442 return adapter->ops->stats_get(adapter, stats); 443 } 444 445 int 446 rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter) 447 { 448 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL); 449 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_reset, -EINVAL); 450 return adapter->ops->stats_reset(adapter); 451 } 452 453 /* 454 * Software event timer adapter buffer helper functions 455 */ 456 457 #define NSECPERSEC 1E9 458 459 /* Optimizations used to index into the buffer require that the buffer size 460 * be a power of 2. 461 */ 462 #define EVENT_BUFFER_SZ 4096 463 #define EVENT_BUFFER_BATCHSZ 32 464 #define EVENT_BUFFER_MASK (EVENT_BUFFER_SZ - 1) 465 466 #define EXP_TIM_BUF_SZ 128 467 468 struct event_buffer { 469 size_t head; 470 size_t tail; 471 struct rte_event events[EVENT_BUFFER_SZ]; 472 } __rte_cache_aligned; 473 474 static inline bool 475 event_buffer_full(struct event_buffer *bufp) 476 { 477 return (bufp->head - bufp->tail) == EVENT_BUFFER_SZ; 478 } 479 480 static inline bool 481 event_buffer_batch_ready(struct event_buffer *bufp) 482 { 483 return (bufp->head - bufp->tail) >= EVENT_BUFFER_BATCHSZ; 484 } 485 486 static void 487 event_buffer_init(struct event_buffer *bufp) 488 { 489 bufp->head = bufp->tail = 0; 490 memset(&bufp->events, 0, sizeof(struct rte_event) * EVENT_BUFFER_SZ); 491 } 492 493 static int 494 event_buffer_add(struct event_buffer *bufp, struct rte_event *eventp) 495 { 496 size_t head_idx; 497 struct rte_event *buf_eventp; 498 499 if (event_buffer_full(bufp)) 500 return -1; 501 502 /* Instead of modulus, bitwise AND with mask to get head_idx. */ 503 head_idx = bufp->head & EVENT_BUFFER_MASK; 504 buf_eventp = &bufp->events[head_idx]; 505 rte_memcpy(buf_eventp, eventp, sizeof(struct rte_event)); 506 507 /* Wrap automatically when overflow occurs. */ 508 bufp->head++; 509 510 return 0; 511 } 512 513 static void 514 event_buffer_flush(struct event_buffer *bufp, uint8_t dev_id, uint8_t port_id, 515 uint16_t *nb_events_flushed, 516 uint16_t *nb_events_inv) 517 { 518 struct rte_event *events = bufp->events; 519 size_t head_idx, tail_idx; 520 uint16_t n = 0; 521 522 /* Instead of modulus, bitwise AND with mask to get index. */ 523 head_idx = bufp->head & EVENT_BUFFER_MASK; 524 tail_idx = bufp->tail & EVENT_BUFFER_MASK; 525 526 RTE_ASSERT(head_idx < EVENT_BUFFER_SZ && tail_idx < EVENT_BUFFER_SZ); 527 528 /* Determine the largest contiguous run we can attempt to enqueue to the 529 * event device. 530 */ 531 if (head_idx > tail_idx) 532 n = head_idx - tail_idx; 533 else if (head_idx < tail_idx) 534 n = EVENT_BUFFER_SZ - tail_idx; 535 else if (event_buffer_full(bufp)) 536 n = EVENT_BUFFER_SZ - tail_idx; 537 else { 538 *nb_events_flushed = 0; 539 return; 540 } 541 542 n = RTE_MIN(EVENT_BUFFER_BATCHSZ, n); 543 *nb_events_inv = 0; 544 545 *nb_events_flushed = rte_event_enqueue_burst(dev_id, port_id, 546 &events[tail_idx], n); 547 if (*nb_events_flushed != n) { 548 if (rte_errno == EINVAL) { 549 EVTIM_LOG_ERR("failed to enqueue invalid event - " 550 "dropping it"); 551 (*nb_events_inv)++; 552 } else if (rte_errno == ENOSPC) 553 rte_pause(); 554 } 555 556 if (*nb_events_flushed > 0) 557 EVTIM_BUF_LOG_DBG("enqueued %"PRIu16" timer events to event " 558 "device", *nb_events_flushed); 559 560 bufp->tail = bufp->tail + *nb_events_flushed + *nb_events_inv; 561 } 562 563 /* 564 * Software event timer adapter implementation 565 */ 566 struct swtim { 567 /* Identifier of service executing timer management logic. */ 568 uint32_t service_id; 569 /* The cycle count at which the adapter should next tick */ 570 uint64_t next_tick_cycles; 571 /* The tick resolution used by adapter instance. May have been 572 * adjusted from what user requested 573 */ 574 uint64_t timer_tick_ns; 575 /* Maximum timeout in nanoseconds allowed by adapter instance. */ 576 uint64_t max_tmo_ns; 577 /* Buffered timer expiry events to be enqueued to an event device. */ 578 struct event_buffer buffer; 579 /* Statistics */ 580 struct rte_event_timer_adapter_stats stats; 581 /* Mempool of timer objects */ 582 struct rte_mempool *tim_pool; 583 /* Back pointer for convenience */ 584 struct rte_event_timer_adapter *adapter; 585 /* Identifier of timer data instance */ 586 uint32_t timer_data_id; 587 /* Track which cores have actually armed a timer */ 588 struct { 589 uint16_t v; 590 } __rte_cache_aligned in_use[RTE_MAX_LCORE]; 591 /* Track which cores' timer lists should be polled */ 592 unsigned int poll_lcores[RTE_MAX_LCORE]; 593 /* The number of lists that should be polled */ 594 int n_poll_lcores; 595 /* Timers which have expired and can be returned to a mempool */ 596 struct rte_timer *expired_timers[EXP_TIM_BUF_SZ]; 597 /* The number of timers that can be returned to a mempool */ 598 size_t n_expired_timers; 599 }; 600 601 static inline struct swtim * 602 swtim_pmd_priv(const struct rte_event_timer_adapter *adapter) 603 { 604 return adapter->data->adapter_priv; 605 } 606 607 static void 608 swtim_callback(struct rte_timer *tim) 609 { 610 struct rte_event_timer *evtim = tim->arg; 611 struct rte_event_timer_adapter *adapter; 612 unsigned int lcore = rte_lcore_id(); 613 struct swtim *sw; 614 uint16_t nb_evs_flushed = 0; 615 uint16_t nb_evs_invalid = 0; 616 uint64_t opaque; 617 int ret; 618 int n_lcores; 619 620 opaque = evtim->impl_opaque[1]; 621 adapter = (struct rte_event_timer_adapter *)(uintptr_t)opaque; 622 sw = swtim_pmd_priv(adapter); 623 624 ret = event_buffer_add(&sw->buffer, &evtim->ev); 625 if (ret < 0) { 626 /* If event buffer is full, put timer back in list with 627 * immediate expiry value, so that we process it again on the 628 * next iteration. 629 */ 630 ret = rte_timer_alt_reset(sw->timer_data_id, tim, 0, SINGLE, 631 lcore, NULL, evtim); 632 if (ret < 0) { 633 EVTIM_LOG_DBG("event buffer full, failed to reset " 634 "timer with immediate expiry value"); 635 } else { 636 sw->stats.evtim_retry_count++; 637 EVTIM_LOG_DBG("event buffer full, resetting rte_timer " 638 "with immediate expiry value"); 639 } 640 641 if (unlikely(sw->in_use[lcore].v == 0)) { 642 sw->in_use[lcore].v = 1; 643 n_lcores = __atomic_fetch_add(&sw->n_poll_lcores, 1, 644 __ATOMIC_RELAXED); 645 __atomic_store_n(&sw->poll_lcores[n_lcores], lcore, 646 __ATOMIC_RELAXED); 647 } 648 } else { 649 EVTIM_BUF_LOG_DBG("buffered an event timer expiry event"); 650 651 /* Empty the buffer here, if necessary, to free older expired 652 * timers only 653 */ 654 if (unlikely(sw->n_expired_timers == EXP_TIM_BUF_SZ)) { 655 rte_mempool_put_bulk(sw->tim_pool, 656 (void **)sw->expired_timers, 657 sw->n_expired_timers); 658 sw->n_expired_timers = 0; 659 } 660 661 sw->expired_timers[sw->n_expired_timers++] = tim; 662 sw->stats.evtim_exp_count++; 663 664 __atomic_store_n(&evtim->state, RTE_EVENT_TIMER_NOT_ARMED, 665 __ATOMIC_RELEASE); 666 } 667 668 if (event_buffer_batch_ready(&sw->buffer)) { 669 event_buffer_flush(&sw->buffer, 670 adapter->data->event_dev_id, 671 adapter->data->event_port_id, 672 &nb_evs_flushed, 673 &nb_evs_invalid); 674 675 sw->stats.ev_enq_count += nb_evs_flushed; 676 sw->stats.ev_inv_count += nb_evs_invalid; 677 } 678 } 679 680 static __rte_always_inline uint64_t 681 get_timeout_cycles(struct rte_event_timer *evtim, 682 const struct rte_event_timer_adapter *adapter) 683 { 684 struct swtim *sw = swtim_pmd_priv(adapter); 685 uint64_t timeout_ns = evtim->timeout_ticks * sw->timer_tick_ns; 686 return timeout_ns * rte_get_timer_hz() / NSECPERSEC; 687 } 688 689 /* This function returns true if one or more (adapter) ticks have occurred since 690 * the last time it was called. 691 */ 692 static inline bool 693 swtim_did_tick(struct swtim *sw) 694 { 695 uint64_t cycles_per_adapter_tick, start_cycles; 696 uint64_t *next_tick_cyclesp; 697 698 next_tick_cyclesp = &sw->next_tick_cycles; 699 cycles_per_adapter_tick = sw->timer_tick_ns * 700 (rte_get_timer_hz() / NSECPERSEC); 701 start_cycles = rte_get_timer_cycles(); 702 703 /* Note: initially, *next_tick_cyclesp == 0, so the clause below will 704 * execute, and set things going. 705 */ 706 707 if (start_cycles >= *next_tick_cyclesp) { 708 /* Snap the current cycle count to the preceding adapter tick 709 * boundary. 710 */ 711 start_cycles -= start_cycles % cycles_per_adapter_tick; 712 *next_tick_cyclesp = start_cycles + cycles_per_adapter_tick; 713 714 return true; 715 } 716 717 return false; 718 } 719 720 /* Check that event timer timeout value is in range */ 721 static __rte_always_inline int 722 check_timeout(struct rte_event_timer *evtim, 723 const struct rte_event_timer_adapter *adapter) 724 { 725 uint64_t tmo_nsec; 726 struct swtim *sw = swtim_pmd_priv(adapter); 727 728 tmo_nsec = evtim->timeout_ticks * sw->timer_tick_ns; 729 if (tmo_nsec > sw->max_tmo_ns) 730 return -1; 731 if (tmo_nsec < sw->timer_tick_ns) 732 return -2; 733 734 return 0; 735 } 736 737 /* Check that event timer event queue sched type matches destination event queue 738 * sched type 739 */ 740 static __rte_always_inline int 741 check_destination_event_queue(struct rte_event_timer *evtim, 742 const struct rte_event_timer_adapter *adapter) 743 { 744 int ret; 745 uint32_t sched_type; 746 747 ret = rte_event_queue_attr_get(adapter->data->event_dev_id, 748 evtim->ev.queue_id, 749 RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE, 750 &sched_type); 751 752 if ((ret == 0 && evtim->ev.sched_type == sched_type) || 753 ret == -EOVERFLOW) 754 return 0; 755 756 return -1; 757 } 758 759 static int 760 swtim_service_func(void *arg) 761 { 762 struct rte_event_timer_adapter *adapter = arg; 763 struct swtim *sw = swtim_pmd_priv(adapter); 764 uint16_t nb_evs_flushed = 0; 765 uint16_t nb_evs_invalid = 0; 766 767 if (swtim_did_tick(sw)) { 768 rte_timer_alt_manage(sw->timer_data_id, 769 sw->poll_lcores, 770 sw->n_poll_lcores, 771 swtim_callback); 772 773 /* Return expired timer objects back to mempool */ 774 rte_mempool_put_bulk(sw->tim_pool, (void **)sw->expired_timers, 775 sw->n_expired_timers); 776 sw->n_expired_timers = 0; 777 778 event_buffer_flush(&sw->buffer, 779 adapter->data->event_dev_id, 780 adapter->data->event_port_id, 781 &nb_evs_flushed, 782 &nb_evs_invalid); 783 784 sw->stats.ev_enq_count += nb_evs_flushed; 785 sw->stats.ev_inv_count += nb_evs_invalid; 786 sw->stats.adapter_tick_count++; 787 } 788 789 rte_event_maintain(adapter->data->event_dev_id, 790 adapter->data->event_port_id, 0); 791 792 return 0; 793 } 794 795 /* The adapter initialization function rounds the mempool size up to the next 796 * power of 2, so we can take the difference between that value and what the 797 * user requested, and use the space for caches. This avoids a scenario where a 798 * user can't arm the number of timers the adapter was configured with because 799 * mempool objects have been lost to caches. 800 * 801 * nb_actual should always be a power of 2, so we can iterate over the powers 802 * of 2 to see what the largest cache size we can use is. 803 */ 804 static int 805 compute_msg_mempool_cache_size(uint64_t nb_requested, uint64_t nb_actual) 806 { 807 int i; 808 int size; 809 int cache_size = 0; 810 811 for (i = 0;; i++) { 812 size = 1 << i; 813 814 if (RTE_MAX_LCORE * size < (int)(nb_actual - nb_requested) && 815 size < RTE_MEMPOOL_CACHE_MAX_SIZE && 816 size <= nb_actual / 1.5) 817 cache_size = size; 818 else 819 break; 820 } 821 822 return cache_size; 823 } 824 825 static int 826 swtim_init(struct rte_event_timer_adapter *adapter) 827 { 828 int i, ret; 829 struct swtim *sw; 830 unsigned int flags; 831 struct rte_service_spec service; 832 833 /* Allocate storage for private data area */ 834 #define SWTIM_NAMESIZE 32 835 char swtim_name[SWTIM_NAMESIZE]; 836 snprintf(swtim_name, SWTIM_NAMESIZE, "swtim_%"PRIu8, 837 adapter->data->id); 838 sw = rte_zmalloc_socket(swtim_name, sizeof(*sw), RTE_CACHE_LINE_SIZE, 839 adapter->data->socket_id); 840 if (sw == NULL) { 841 EVTIM_LOG_ERR("failed to allocate space for private data"); 842 rte_errno = ENOMEM; 843 return -1; 844 } 845 846 /* Connect storage to adapter instance */ 847 adapter->data->adapter_priv = sw; 848 sw->adapter = adapter; 849 850 sw->timer_tick_ns = adapter->data->conf.timer_tick_ns; 851 sw->max_tmo_ns = adapter->data->conf.max_tmo_ns; 852 853 /* Create a timer pool */ 854 char pool_name[SWTIM_NAMESIZE]; 855 snprintf(pool_name, SWTIM_NAMESIZE, "swtim_pool_%"PRIu8, 856 adapter->data->id); 857 /* Optimal mempool size is a power of 2 minus one */ 858 uint64_t nb_timers = rte_align64pow2(adapter->data->conf.nb_timers); 859 int pool_size = nb_timers - 1; 860 int cache_size = compute_msg_mempool_cache_size( 861 adapter->data->conf.nb_timers, nb_timers); 862 flags = 0; /* pool is multi-producer, multi-consumer */ 863 sw->tim_pool = rte_mempool_create(pool_name, pool_size, 864 sizeof(struct rte_timer), cache_size, 0, NULL, NULL, 865 NULL, NULL, adapter->data->socket_id, flags); 866 if (sw->tim_pool == NULL) { 867 EVTIM_LOG_ERR("failed to create timer object mempool"); 868 rte_errno = ENOMEM; 869 goto free_alloc; 870 } 871 872 /* Initialize the variables that track in-use timer lists */ 873 for (i = 0; i < RTE_MAX_LCORE; i++) 874 sw->in_use[i].v = 0; 875 876 /* Initialize the timer subsystem and allocate timer data instance */ 877 ret = rte_timer_subsystem_init(); 878 if (ret < 0) { 879 if (ret != -EALREADY) { 880 EVTIM_LOG_ERR("failed to initialize timer subsystem"); 881 rte_errno = -ret; 882 goto free_mempool; 883 } 884 } 885 886 ret = rte_timer_data_alloc(&sw->timer_data_id); 887 if (ret < 0) { 888 EVTIM_LOG_ERR("failed to allocate timer data instance"); 889 rte_errno = -ret; 890 goto free_mempool; 891 } 892 893 /* Initialize timer event buffer */ 894 event_buffer_init(&sw->buffer); 895 896 sw->adapter = adapter; 897 898 /* Register a service component to run adapter logic */ 899 memset(&service, 0, sizeof(service)); 900 snprintf(service.name, RTE_SERVICE_NAME_MAX, 901 "swtim_svc_%"PRIu8, adapter->data->id); 902 service.socket_id = adapter->data->socket_id; 903 service.callback = swtim_service_func; 904 service.callback_userdata = adapter; 905 service.capabilities &= ~(RTE_SERVICE_CAP_MT_SAFE); 906 ret = rte_service_component_register(&service, &sw->service_id); 907 if (ret < 0) { 908 EVTIM_LOG_ERR("failed to register service %s with id %"PRIu32 909 ": err = %d", service.name, sw->service_id, 910 ret); 911 912 rte_errno = ENOSPC; 913 goto free_mempool; 914 } 915 916 EVTIM_LOG_DBG("registered service %s with id %"PRIu32, service.name, 917 sw->service_id); 918 919 adapter->data->service_id = sw->service_id; 920 adapter->data->service_inited = 1; 921 922 return 0; 923 free_mempool: 924 rte_mempool_free(sw->tim_pool); 925 free_alloc: 926 rte_free(sw); 927 return -1; 928 } 929 930 static void 931 swtim_free_tim(struct rte_timer *tim, void *arg) 932 { 933 struct swtim *sw = arg; 934 935 rte_mempool_put(sw->tim_pool, tim); 936 } 937 938 /* Traverse the list of outstanding timers and put them back in the mempool 939 * before freeing the adapter to avoid leaking the memory. 940 */ 941 static int 942 swtim_uninit(struct rte_event_timer_adapter *adapter) 943 { 944 int ret; 945 struct swtim *sw = swtim_pmd_priv(adapter); 946 947 /* Free outstanding timers */ 948 rte_timer_stop_all(sw->timer_data_id, 949 sw->poll_lcores, 950 sw->n_poll_lcores, 951 swtim_free_tim, 952 sw); 953 954 ret = rte_service_component_unregister(sw->service_id); 955 if (ret < 0) { 956 EVTIM_LOG_ERR("failed to unregister service component"); 957 return ret; 958 } 959 960 rte_mempool_free(sw->tim_pool); 961 rte_free(sw); 962 adapter->data->adapter_priv = NULL; 963 964 return 0; 965 } 966 967 static inline int32_t 968 get_mapped_count_for_service(uint32_t service_id) 969 { 970 int32_t core_count, i, mapped_count = 0; 971 uint32_t lcore_arr[RTE_MAX_LCORE]; 972 973 core_count = rte_service_lcore_list(lcore_arr, RTE_MAX_LCORE); 974 975 for (i = 0; i < core_count; i++) 976 if (rte_service_map_lcore_get(service_id, lcore_arr[i]) == 1) 977 mapped_count++; 978 979 return mapped_count; 980 } 981 982 static int 983 swtim_start(const struct rte_event_timer_adapter *adapter) 984 { 985 int mapped_count; 986 struct swtim *sw = swtim_pmd_priv(adapter); 987 988 /* Mapping the service to more than one service core can introduce 989 * delays while one thread is waiting to acquire a lock, so only allow 990 * one core to be mapped to the service. 991 * 992 * Note: the service could be modified such that it spreads cores to 993 * poll over multiple service instances. 994 */ 995 mapped_count = get_mapped_count_for_service(sw->service_id); 996 997 if (mapped_count != 1) 998 return mapped_count < 1 ? -ENOENT : -ENOTSUP; 999 1000 return rte_service_component_runstate_set(sw->service_id, 1); 1001 } 1002 1003 static int 1004 swtim_stop(const struct rte_event_timer_adapter *adapter) 1005 { 1006 int ret; 1007 struct swtim *sw = swtim_pmd_priv(adapter); 1008 1009 ret = rte_service_component_runstate_set(sw->service_id, 0); 1010 if (ret < 0) 1011 return ret; 1012 1013 /* Wait for the service to complete its final iteration */ 1014 while (rte_service_may_be_active(sw->service_id)) 1015 rte_pause(); 1016 1017 return 0; 1018 } 1019 1020 static void 1021 swtim_get_info(const struct rte_event_timer_adapter *adapter, 1022 struct rte_event_timer_adapter_info *adapter_info) 1023 { 1024 struct swtim *sw = swtim_pmd_priv(adapter); 1025 adapter_info->min_resolution_ns = sw->timer_tick_ns; 1026 adapter_info->max_tmo_ns = sw->max_tmo_ns; 1027 } 1028 1029 static int 1030 swtim_stats_get(const struct rte_event_timer_adapter *adapter, 1031 struct rte_event_timer_adapter_stats *stats) 1032 { 1033 struct swtim *sw = swtim_pmd_priv(adapter); 1034 *stats = sw->stats; /* structure copy */ 1035 return 0; 1036 } 1037 1038 static int 1039 swtim_stats_reset(const struct rte_event_timer_adapter *adapter) 1040 { 1041 struct swtim *sw = swtim_pmd_priv(adapter); 1042 memset(&sw->stats, 0, sizeof(sw->stats)); 1043 return 0; 1044 } 1045 1046 static uint16_t 1047 __swtim_arm_burst(const struct rte_event_timer_adapter *adapter, 1048 struct rte_event_timer **evtims, 1049 uint16_t nb_evtims) 1050 { 1051 int i, ret; 1052 struct swtim *sw = swtim_pmd_priv(adapter); 1053 uint32_t lcore_id = rte_lcore_id(); 1054 struct rte_timer *tim, *tims[nb_evtims]; 1055 uint64_t cycles; 1056 int n_lcores; 1057 /* Timer list for this lcore is not in use. */ 1058 uint16_t exp_state = 0; 1059 enum rte_event_timer_state n_state; 1060 1061 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG 1062 /* Check that the service is running. */ 1063 if (rte_service_runstate_get(adapter->data->service_id) != 1) { 1064 rte_errno = EINVAL; 1065 return 0; 1066 } 1067 #endif 1068 1069 /* Adjust lcore_id if non-EAL thread. Arbitrarily pick the timer list of 1070 * the highest lcore to insert such timers into 1071 */ 1072 if (lcore_id == LCORE_ID_ANY) 1073 lcore_id = RTE_MAX_LCORE - 1; 1074 1075 /* If this is the first time we're arming an event timer on this lcore, 1076 * mark this lcore as "in use"; this will cause the service 1077 * function to process the timer list that corresponds to this lcore. 1078 * The atomic compare-and-swap operation can prevent the race condition 1079 * on in_use flag between multiple non-EAL threads. 1080 */ 1081 if (unlikely(__atomic_compare_exchange_n(&sw->in_use[lcore_id].v, 1082 &exp_state, 1, 0, 1083 __ATOMIC_RELAXED, __ATOMIC_RELAXED))) { 1084 EVTIM_LOG_DBG("Adding lcore id = %u to list of lcores to poll", 1085 lcore_id); 1086 n_lcores = __atomic_fetch_add(&sw->n_poll_lcores, 1, 1087 __ATOMIC_RELAXED); 1088 __atomic_store_n(&sw->poll_lcores[n_lcores], lcore_id, 1089 __ATOMIC_RELAXED); 1090 } 1091 1092 ret = rte_mempool_get_bulk(sw->tim_pool, (void **)tims, 1093 nb_evtims); 1094 if (ret < 0) { 1095 rte_errno = ENOSPC; 1096 return 0; 1097 } 1098 1099 for (i = 0; i < nb_evtims; i++) { 1100 n_state = __atomic_load_n(&evtims[i]->state, __ATOMIC_ACQUIRE); 1101 if (n_state == RTE_EVENT_TIMER_ARMED) { 1102 rte_errno = EALREADY; 1103 break; 1104 } else if (!(n_state == RTE_EVENT_TIMER_NOT_ARMED || 1105 n_state == RTE_EVENT_TIMER_CANCELED)) { 1106 rte_errno = EINVAL; 1107 break; 1108 } 1109 1110 ret = check_timeout(evtims[i], adapter); 1111 if (unlikely(ret == -1)) { 1112 __atomic_store_n(&evtims[i]->state, 1113 RTE_EVENT_TIMER_ERROR_TOOLATE, 1114 __ATOMIC_RELAXED); 1115 rte_errno = EINVAL; 1116 break; 1117 } else if (unlikely(ret == -2)) { 1118 __atomic_store_n(&evtims[i]->state, 1119 RTE_EVENT_TIMER_ERROR_TOOEARLY, 1120 __ATOMIC_RELAXED); 1121 rte_errno = EINVAL; 1122 break; 1123 } 1124 1125 if (unlikely(check_destination_event_queue(evtims[i], 1126 adapter) < 0)) { 1127 __atomic_store_n(&evtims[i]->state, 1128 RTE_EVENT_TIMER_ERROR, 1129 __ATOMIC_RELAXED); 1130 rte_errno = EINVAL; 1131 break; 1132 } 1133 1134 tim = tims[i]; 1135 rte_timer_init(tim); 1136 1137 evtims[i]->impl_opaque[0] = (uintptr_t)tim; 1138 evtims[i]->impl_opaque[1] = (uintptr_t)adapter; 1139 1140 cycles = get_timeout_cycles(evtims[i], adapter); 1141 ret = rte_timer_alt_reset(sw->timer_data_id, tim, cycles, 1142 SINGLE, lcore_id, NULL, evtims[i]); 1143 if (ret < 0) { 1144 /* tim was in RUNNING or CONFIG state */ 1145 __atomic_store_n(&evtims[i]->state, 1146 RTE_EVENT_TIMER_ERROR, 1147 __ATOMIC_RELEASE); 1148 break; 1149 } 1150 1151 EVTIM_LOG_DBG("armed an event timer"); 1152 /* RELEASE ordering guarantees the adapter specific value 1153 * changes observed before the update of state. 1154 */ 1155 __atomic_store_n(&evtims[i]->state, RTE_EVENT_TIMER_ARMED, 1156 __ATOMIC_RELEASE); 1157 } 1158 1159 if (i < nb_evtims) 1160 rte_mempool_put_bulk(sw->tim_pool, 1161 (void **)&tims[i], nb_evtims - i); 1162 1163 return i; 1164 } 1165 1166 static uint16_t 1167 swtim_arm_burst(const struct rte_event_timer_adapter *adapter, 1168 struct rte_event_timer **evtims, 1169 uint16_t nb_evtims) 1170 { 1171 return __swtim_arm_burst(adapter, evtims, nb_evtims); 1172 } 1173 1174 static uint16_t 1175 swtim_cancel_burst(const struct rte_event_timer_adapter *adapter, 1176 struct rte_event_timer **evtims, 1177 uint16_t nb_evtims) 1178 { 1179 int i, ret; 1180 struct rte_timer *timp; 1181 uint64_t opaque; 1182 struct swtim *sw = swtim_pmd_priv(adapter); 1183 enum rte_event_timer_state n_state; 1184 1185 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG 1186 /* Check that the service is running. */ 1187 if (rte_service_runstate_get(adapter->data->service_id) != 1) { 1188 rte_errno = EINVAL; 1189 return 0; 1190 } 1191 #endif 1192 1193 for (i = 0; i < nb_evtims; i++) { 1194 /* Don't modify the event timer state in these cases */ 1195 /* ACQUIRE ordering guarantees the access of implementation 1196 * specific opaque data under the correct state. 1197 */ 1198 n_state = __atomic_load_n(&evtims[i]->state, __ATOMIC_ACQUIRE); 1199 if (n_state == RTE_EVENT_TIMER_CANCELED) { 1200 rte_errno = EALREADY; 1201 break; 1202 } else if (n_state != RTE_EVENT_TIMER_ARMED) { 1203 rte_errno = EINVAL; 1204 break; 1205 } 1206 1207 opaque = evtims[i]->impl_opaque[0]; 1208 timp = (struct rte_timer *)(uintptr_t)opaque; 1209 RTE_ASSERT(timp != NULL); 1210 1211 ret = rte_timer_alt_stop(sw->timer_data_id, timp); 1212 if (ret < 0) { 1213 /* Timer is running or being configured */ 1214 rte_errno = EAGAIN; 1215 break; 1216 } 1217 1218 rte_mempool_put(sw->tim_pool, (void **)timp); 1219 1220 /* The RELEASE ordering here pairs with atomic ordering 1221 * to make sure the state update data observed between 1222 * threads. 1223 */ 1224 __atomic_store_n(&evtims[i]->state, RTE_EVENT_TIMER_CANCELED, 1225 __ATOMIC_RELEASE); 1226 } 1227 1228 return i; 1229 } 1230 1231 static uint16_t 1232 swtim_arm_tmo_tick_burst(const struct rte_event_timer_adapter *adapter, 1233 struct rte_event_timer **evtims, 1234 uint64_t timeout_ticks, 1235 uint16_t nb_evtims) 1236 { 1237 int i; 1238 1239 for (i = 0; i < nb_evtims; i++) 1240 evtims[i]->timeout_ticks = timeout_ticks; 1241 1242 return __swtim_arm_burst(adapter, evtims, nb_evtims); 1243 } 1244 1245 static const struct event_timer_adapter_ops swtim_ops = { 1246 .init = swtim_init, 1247 .uninit = swtim_uninit, 1248 .start = swtim_start, 1249 .stop = swtim_stop, 1250 .get_info = swtim_get_info, 1251 .stats_get = swtim_stats_get, 1252 .stats_reset = swtim_stats_reset, 1253 .arm_burst = swtim_arm_burst, 1254 .arm_tmo_tick_burst = swtim_arm_tmo_tick_burst, 1255 .cancel_burst = swtim_cancel_burst, 1256 }; 1257