dpdk/drivers/event/opdl/opdl_ring.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Intel Corporation
   3 */
   4
   5#ifndef _OPDL_H_
   6#define _OPDL_H_
   7
   8/**
   9 * @file
  10 * The "opdl_ring" is a data structure that contains a fixed number of slots,
  11 * with each slot having the same, but configurable, size. Entries are input
  12 * into the opdl_ring by copying into available slots. Once in the opdl_ring,
  13 * an entry is processed by a number of stages, with the ordering of stage
  14 * processing controlled by making stages dependent on one or more other stages.
  15 * An entry is not available for a stage to process until it has been processed
  16 * by that stages dependencies. Entries are always made available for
  17 * processing in the same order that they were input in to the opdl_ring.
  18 * Inputting is considered as a stage that depends on all other stages,
  19 * and is also a dependency of all stages.
  20 *
  21 * Inputting and processing in a stage can support multi-threading. Note that
  22 * multi-thread processing can also be done by making stages co-operate e.g. two
  23 * stages where one processes the even packets and the other processes odd
  24 * packets.
  25 *
  26 * A opdl_ring can be used as the basis for pipeline based applications. Instead
  27 * of each stage in a pipeline dequeuing from a ring, processing and enqueuing
  28 * to another ring, it can process entries in-place on the ring. If stages do
  29 * not depend on each other, they can run in parallel.
  30 *
  31 * The opdl_ring works with entries of configurable size, these could be
  32 * pointers to mbufs, pointers to mbufs with application specific meta-data,
  33 * tasks etc.
  34 */
  35
  36#include <stdbool.h>
  37#include <stdint.h>
  38#include <stdio.h>
  39
  40#include <rte_eventdev.h>
  41#ifdef __cplusplus
  42extern "C" {
  43#endif
  44
  45#ifndef OPDL_DISCLAIMS_PER_LCORE
  46/** Multi-threaded processing allows one thread to process multiple batches in a
  47 * stage, while another thread is processing a single large batch. This number
  48 * controls how many non-contiguous batches one stage can process before being
  49 * blocked by the other stage.
  50 */
  51#define OPDL_DISCLAIMS_PER_LCORE 8
  52#endif
  53
  54/** Opaque handle to a opdl_ring instance */
  55struct opdl_ring;
  56
  57/** Opaque handle to a single stage in a opdl_ring */
  58struct opdl_stage;
  59
  60/**
  61 * Create a new instance of a opdl_ring.
  62 *
  63 * @param name
  64 *   String containing the name to give the new opdl_ring instance.
  65 * @param num_slots
  66 *   How many slots the opdl_ring contains. Must be a power a 2!
  67 * @param slot_size
  68 *   How many bytes in each slot.
  69 * @param max_num_stages
  70 *   Maximum number of stages.
  71 * @param socket
  72 *   The NUMA socket (or SOCKET_ID_ANY) to allocate the memory used for this
  73 *   opdl_ring instance.
  74 * @param threadsafe
  75 *   Whether to support multiple threads inputting to the opdl_ring or not.
  76 *   Enabling this may have a negative impact on performance if only one thread
  77 *   will be inputting.
  78 *
  79 * @return
  80 *   A pointer to a new opdl_ring instance, or NULL on error.
  81 */
  82struct opdl_ring *
  83opdl_ring_create(const char *name, uint32_t num_slots, uint32_t slot_size,
  84                uint32_t max_num_stages, int socket);
  85
  86/**
  87 * Get pointer to individual slot in a opdl_ring.
  88 *
  89 * @param t
  90 *   The opdl_ring.
  91 * @param index
  92 *   Index of slot. If greater than the number of slots it will be masked to be
  93 *   within correct range.
  94 *
  95 * @return
  96 *   A pointer to that slot.
  97 */
  98void *
  99opdl_ring_get_slot(const struct opdl_ring *t, uint32_t index);
 100
 101/**
 102 * Get NUMA socket used by a opdl_ring.
 103 *
 104 * @param t
 105 *   The opdl_ring.
 106 *
 107 * @return
 108 *   NUMA socket.
 109 */
 110int
 111opdl_ring_get_socket(const struct opdl_ring *t);
 112
 113/**
 114 * Get number of slots in a opdl_ring.
 115 *
 116 * @param t
 117 *   The opdl_ring.
 118 *
 119 * @return
 120 *   Number of slots.
 121 */
 122uint32_t
 123opdl_ring_get_num_slots(const struct opdl_ring *t);
 124
 125/**
 126 * Get name of a opdl_ring.
 127 *
 128 * @param t
 129 *   The opdl_ring.
 130 *
 131 * @return
 132 *   Name string.
 133 */
 134const char *
 135opdl_ring_get_name(const struct opdl_ring *t);
 136
 137/**
 138 * Adds a new processing stage to a specified opdl_ring instance. Adding a stage
 139 * while there are entries in the opdl_ring being processed will cause undefined
 140 * behaviour.
 141 *
 142 * @param t
 143 *   The opdl_ring to add the stage to.
 144 * @param deps
 145 *   An array of pointers to other stages that this stage depends on. The other
 146 *   stages must be part of the same opdl_ring! Note that input is an implied
 147 *   dependency. This can be NULL if num_deps is 0.
 148 * @param num_deps
 149 *   The size of the deps array.
 150 * @param threadsafe
 151 *   Whether to support multiple threads processing this stage or  not.
 152 *   Enabling this may have a negative impact on performance if only one thread
 153 *   will be processing this stage.
 154 * @param is_input
 155 *   Indication to initialise the stage with all slots available or none
 156 *
 157 * @return
 158 *   A pointer to the new stage, or NULL on error.
 159 */
 160struct opdl_stage *
 161opdl_stage_add(struct opdl_ring *t, bool threadsafe, bool is_input);
 162
 163/**
 164 * Returns the input stage of a opdl_ring to be used by other API functions.
 165 *
 166 * @param t
 167 *   The opdl_ring.
 168 *
 169 * @return
 170 *   A pointer to the input stage.
 171 */
 172struct opdl_stage *
 173opdl_ring_get_input_stage(const struct opdl_ring *t);
 174
 175/**
 176 * Sets the dependencies for a stage (clears all the previous deps!). Changing
 177 * dependencies while there are entries in the opdl_ring being processed will
 178 * cause undefined behaviour.
 179 *
 180 * @param s
 181 *   The stage to set the dependencies for.
 182 * @param deps
 183 *   An array of pointers to other stages that this stage will depends on. The
 184 *   other stages must be part of the same opdl_ring!
 185 * @param num_deps
 186 *   The size of the deps array. This must be > 0.
 187 *
 188 * @return
 189 *   0 on success, a negative value on error.
 190 */
 191int
 192opdl_stage_set_deps(struct opdl_stage *s, struct opdl_stage *deps[],
 193                uint32_t num_deps);
 194
 195/**
 196 * Returns the opdl_ring that a stage belongs to.
 197 *
 198 * @param s
 199 *   The stage
 200 *
 201 * @return
 202 *   A pointer to the opdl_ring that the stage belongs to.
 203 */
 204struct opdl_ring *
 205opdl_stage_get_opdl_ring(const struct opdl_stage *s);
 206
 207/**
 208 * Inputs a new batch of entries into the opdl_ring. This function is only
 209 * threadsafe (with the same opdl_ring parameter) if the threadsafe parameter of
 210 * opdl_ring_create() was true. For performance reasons, this function does not
 211 * check input parameters.
 212 *
 213 * @param t
 214 *   The opdl_ring to input entries in to.
 215 * @param entries
 216 *   An array of entries that will be copied in to the opdl_ring.
 217 * @param num_entries
 218 *   The size of the entries array.
 219 * @param block
 220 *   If this is true, the function blocks until enough slots are available to
 221 *   input all the requested entries. If false, then the function inputs as
 222 *   many entries as currently possible.
 223 *
 224 * @return
 225 *   The number of entries successfully input.
 226 */
 227uint32_t
 228opdl_ring_input(struct opdl_ring *t, const void *entries, uint32_t num_entries,
 229                bool block);
 230
 231/**
 232 * Inputs a new batch of entries into a opdl stage. This function is only
 233 * threadsafe (with the same opdl parameter) if the threadsafe parameter of
 234 * opdl_create() was true. For performance reasons, this function does not
 235 * check input parameters.
 236 *
 237 * @param t
 238 *   The opdl ring to input entries in to.
 239 * @param s
 240 *   The stage to copy entries to.
 241 * @param entries
 242 *   An array of entries that will be copied in to the opdl ring.
 243 * @param num_entries
 244 *   The size of the entries array.
 245 * @param block
 246 *   If this is true, the function blocks until enough slots are available to
 247 *   input all the requested entries. If false, then the function inputs as
 248 *   many entries as currently possible.
 249 *
 250 * @return
 251 *   The number of entries successfully input.
 252 */
 253uint32_t
 254opdl_ring_copy_from_burst(struct opdl_ring *t, struct opdl_stage *s,
 255                        const void *entries, uint32_t num_entries, bool block);
 256
 257/**
 258 * Copy a batch of entries from the opdl ring. This function is only
 259 * threadsafe (with the same opdl parameter) if the threadsafe parameter of
 260 * opdl_create() was true. For performance reasons, this function does not
 261 * check input parameters.
 262 *
 263 * @param t
 264 *   The opdl ring to copy entries from.
 265 * @param s
 266 *   The stage to copy entries from.
 267 * @param entries
 268 *   An array of entries that will be copied from the opdl ring.
 269 * @param num_entries
 270 *   The size of the entries array.
 271 * @param block
 272 *   If this is true, the function blocks until enough slots are available to
 273 *   input all the requested entries. If false, then the function inputs as
 274 *   many entries as currently possible.
 275 *
 276 * @return
 277 *   The number of entries successfully input.
 278 */
 279uint32_t
 280opdl_ring_copy_to_burst(struct opdl_ring *t, struct opdl_stage *s,
 281                void *entries, uint32_t num_entries, bool block);
 282
 283/**
 284 * Before processing a batch of entries, a stage must first claim them to get
 285 * access. This function is threadsafe using same opdl_stage parameter if
 286 * the stage was created with threadsafe set to true, otherwise it is only
 287 * threadsafe with a different opdl_stage per thread. For performance
 288 * reasons, this function does not check input parameters.
 289 *
 290 * @param s
 291 *   The opdl_ring stage to read entries in.
 292 * @param entries
 293 *   An array of pointers to entries that will be filled in by this function.
 294 * @param num_entries
 295 *   The number of entries to attempt to claim for processing (and the size of
 296 *   the entries array).
 297 * @param seq
 298 *   If not NULL, this is set to the value of the internal stage sequence number
 299 *   associated with the first entry returned.
 300 * @param block
 301 *   If this is true, the function blocks until num_entries slots are available
 302 *   to process. If false, then the function claims as many entries as
 303 *   currently possible.
 304 *
 305 * @param atomic
 306 *   if this is true, the function will return event according to event flow id
 307 * @return
 308 *   The number of pointers to entries filled in to the entries array.
 309 */
 310uint32_t
 311opdl_stage_claim(struct opdl_stage *s, void *entries,
 312                uint32_t num_entries, uint32_t *seq, bool block, bool atomic);
 313
 314uint32_t
 315opdl_stage_deps_add(struct opdl_ring *t, struct opdl_stage *s,
 316                uint32_t nb_instance, uint32_t instance_id,
 317                struct opdl_stage *deps[], uint32_t num_deps);
 318
 319/**
 320 * A function to check how many entries are ready to be claimed.
 321 *
 322 * @param entries
 323 *   An array of pointers to entries.
 324 * @param num_entries
 325 *   Number of entries in an array.
 326 * @param arg
 327 *   An opaque pointer to data passed to the claim function.
 328 * @param block
 329 *   When set to true, the function should wait until num_entries are ready to
 330 *   be processed. Otherwise it should return immediately.
 331 *
 332 * @return
 333 *   Number of entries ready to be claimed.
 334 */
 335typedef uint32_t (opdl_ring_check_entries_t)(void *entries[],
 336                uint32_t num_entries, void *arg, bool block);
 337
 338/**
 339 * Before processing a batch of entries, a stage must first claim them to get
 340 * access. Each entry is checked by the passed check() function and depending
 341 * on block value, it waits until num_entries are ready or returns immediately.
 342 * This function is only threadsafe with a different opdl_stage per thread.
 343 *
 344 * @param s
 345 *   The opdl_ring stage to read entries in.
 346 * @param entries
 347 *   An array of pointers to entries that will be filled in by this function.
 348 * @param num_entries
 349 *   The number of entries to attempt to claim for processing (and the size of
 350 *   the entries array).
 351 * @param seq
 352 *   If not NULL, this is set to the value of the internal stage sequence number
 353 *   associated with the first entry returned.
 354 * @param block
 355 *   If this is true, the function blocks until num_entries ready slots are
 356 *   available to process. If false, then the function claims as many ready
 357 *   entries as currently possible.
 358 * @param check
 359 *   Pointer to a function called to check entries.
 360 * @param arg
 361 *   Opaque data passed to check() function.
 362 *
 363 * @return
 364 *   The number of pointers to ready entries filled in to the entries array.
 365 */
 366uint32_t
 367opdl_stage_claim_check(struct opdl_stage *s, void **entries,
 368                uint32_t num_entries, uint32_t *seq, bool block,
 369                opdl_ring_check_entries_t *check, void *arg);
 370
 371/**
 372 * Before processing a batch of entries, a stage must first claim them to get
 373 * access. This function is threadsafe using same opdl_stage parameter if
 374 * the stage was created with threadsafe set to true, otherwise it is only
 375 * threadsafe with a different opdl_stage per thread.
 376 *
 377 * The difference between this function and opdl_stage_claim() is that this
 378 * function copies the entries from the opdl_ring. Note that any changes made to
 379 * the copied entries will not be reflected back in to the entries in the
 380 * opdl_ring, so this function probably only makes sense if the entries are
 381 * pointers to other data. For performance reasons, this function does not check
 382 * input parameters.
 383 *
 384 * @param s
 385 *   The opdl_ring stage to read entries in.
 386 * @param entries
 387 *   An array of entries that will be filled in by this function.
 388 * @param num_entries
 389 *   The number of entries to attempt to claim for processing (and the size of
 390 *   the entries array).
 391 * @param seq
 392 *   If not NULL, this is set to the value of the internal stage sequence number
 393 *   associated with the first entry returned.
 394 * @param block
 395 *   If this is true, the function blocks until num_entries slots are available
 396 *   to process. If false, then the function claims as many entries as
 397 *   currently possible.
 398 *
 399 * @return
 400 *   The number of entries copied in to the entries array.
 401 */
 402uint32_t
 403opdl_stage_claim_copy(struct opdl_stage *s, void *entries,
 404                uint32_t num_entries, uint32_t *seq, bool block);
 405
 406/**
 407 * This function must be called when a stage has finished its processing of
 408 * entries, to make them available to any dependent stages. All entries that are
 409 * claimed by the calling thread in the stage will be disclaimed. It is possible
 410 * to claim multiple batches before disclaiming. For performance reasons, this
 411 * function does not check input parameters.
 412 *
 413 * @param s
 414 *   The opdl_ring stage in which to disclaim all claimed entries.
 415 *
 416 * @param block
 417 *   Entries are always made available to a stage in the same order that they
 418 *   were input in the stage. If a stage is multithread safe, this may mean that
 419 *   full disclaiming of a batch of entries can not be considered complete until
 420 *   all earlier threads in the stage have disclaimed. If this parameter is true
 421 *   then the function blocks until all entries are fully disclaimed, otherwise
 422 *   it disclaims as many as currently possible, with non fully disclaimed
 423 *   batches stored until the next call to a claim or disclaim function for this
 424 *   stage on this thread.
 425 *
 426 *   If a thread is not going to process any more entries in this stage, it
 427 *   *must* first call this function with this parameter set to true to ensure
 428 *   it does not block the entire opdl_ring.
 429 *
 430 *   In a single threaded stage, this parameter has no effect.
 431 */
 432int
 433opdl_stage_disclaim(struct opdl_stage *s, uint32_t num_entries,
 434                bool block);
 435
 436/**
 437 * This function can be called when a stage has finished its processing of
 438 * entries, to make them available to any dependent stages. The difference
 439 * between this function and opdl_stage_disclaim() is that here only a
 440 * portion of entries are disclaimed, not all of them. For performance reasons,
 441 * this function does not check input parameters.
 442 *
 443 * @param s
 444 *   The opdl_ring stage in which to disclaim entries.
 445 *
 446 * @param num_entries
 447 *   The number of entries to disclaim.
 448 *
 449 * @param block
 450 *   Entries are always made available to a stage in the same order that they
 451 *   were input in the stage. If a stage is multithread safe, this may mean that
 452 *   full disclaiming of a batch of entries can not be considered complete until
 453 *   all earlier threads in the stage have disclaimed. If this parameter is true
 454 *   then the function blocks until the specified number of entries has been
 455 *   disclaimed (or there are no more entries to disclaim). Otherwise it
 456 *   disclaims as many claims as currently possible and an attempt to disclaim
 457 *   them is made the next time a claim or disclaim function for this stage on
 458 *   this thread is called.
 459 *
 460 *   In a single threaded stage, this parameter has no effect.
 461 */
 462void
 463opdl_stage_disclaim_n(struct opdl_stage *s, uint32_t num_entries,
 464                bool block);
 465
 466/**
 467 * Check how many entries can be input.
 468 *
 469 * @param t
 470 *   The opdl_ring instance to check.
 471 *
 472 * @return
 473 *   The number of new entries currently allowed to be input.
 474 */
 475uint32_t
 476opdl_ring_available(struct opdl_ring *t);
 477
 478/**
 479 * Check how many entries can be processed in a stage.
 480 *
 481 * @param s
 482 *   The stage to check.
 483 *
 484 * @return
 485 *   The number of entries currently available to be processed in this stage.
 486 */
 487uint32_t
 488opdl_stage_available(struct opdl_stage *s);
 489
 490/**
 491 * Check how many entries are available to be processed.
 492 *
 493 * NOTE : DOES NOT CHANGE ANY STATE WITHIN THE STAGE
 494 *
 495 * @param s
 496 *   The stage to check.
 497 *
 498 * @param num_entries
 499 *   The number of entries to check for availability.
 500 *
 501 * @return
 502 *   The number of entries currently available to be processed in this stage.
 503 */
 504uint32_t
 505opdl_stage_find_num_available(struct opdl_stage *s, uint32_t num_entries);
 506
 507/**
 508 * Create empty stage instance and return the pointer.
 509 *
 510 * @param t
 511 *   The pointer of  opdl_ring.
 512 *
 513 * @param threadsafe
 514 *    enable multiple thread or not.
 515 * @return
 516 *   The pointer of one empty stage instance.
 517 */
 518struct opdl_stage *
 519opdl_stage_create(struct opdl_ring *t,  bool threadsafe);
 520
 521
 522/**
 523 * Set the internal queue id for each stage instance.
 524 *
 525 * @param s
 526 *   The pointer of  stage instance.
 527 *
 528 * @param queue_id
 529 *    The value of internal queue id.
 530 */
 531void
 532opdl_stage_set_queue_id(struct opdl_stage *s,
 533                uint32_t queue_id);
 534
 535/**
 536 * Prints information on opdl_ring instance and all its stages
 537 *
 538 * @param t
 539 *   The stage to print info on.
 540 * @param f
 541 *   Where to print the info.
 542 */
 543void
 544opdl_ring_dump(const struct opdl_ring *t, FILE *f);
 545
 546/**
 547 * Blocks until all entries in a opdl_ring have been processed by all stages.
 548 *
 549 * @param t
 550 *   The opdl_ring instance to flush.
 551 */
 552void
 553opdl_ring_flush(struct opdl_ring *t);
 554
 555/**
 556 * Deallocates all resources used by a opdl_ring instance
 557 *
 558 * @param t
 559 *   The opdl_ring instance to free.
 560 */
 561void
 562opdl_ring_free(struct opdl_ring *t);
 563
 564/**
 565 * Search for a opdl_ring by its name
 566 *
 567 * @param name
 568 *   The name of the opdl_ring.
 569 * @return
 570 *   The pointer to the opdl_ring matching the name, or NULL if not found.
 571 *
 572 */
 573struct opdl_ring *
 574opdl_ring_lookup(const char *name);
 575
 576/**
 577 * Set a opdl_stage to threadsafe variable.
 578 *
 579 * @param s
 580 *   The opdl_stage.
 581 * @param threadsafe
 582 *   Threadsafe value.
 583 */
 584void
 585opdl_ring_set_stage_threadsafe(struct opdl_stage *s, bool threadsafe);
 586
 587
 588/**
 589 * Compare the event descriptor with original version in the ring.
 590 * if key field event descriptor is changed by application, then
 591 * update the slot in the ring otherwise do nothing with it.
 592 * the key field is flow_id, priority, mbuf, impl_opaque
 593 *
 594 * @param s
 595 *   The opdl_stage.
 596 * @param ev
 597 *   pointer of the event descriptor.
 598 * @param index
 599 *   index of the event descriptor.
 600 * @param atomic
 601 *   queue type associate with the stage.
 602 * @return
 603 *   if the event key field is changed compare with previous record.
 604 */
 605
 606bool
 607opdl_ring_cas_slot(struct opdl_stage *s, const struct rte_event *ev,
 608                uint32_t index, bool atomic);
 609
 610#ifdef __cplusplus
 611}
 612#endif
 613
 614#endif  /* _OPDL_H_ */
 615