1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
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.
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
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.
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,
40 #include <rte_eventdev.h>
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.
51 #define OPDL_DISCLAIMS_PER_LCORE 8
54 /** Opaque handle to a opdl_ring instance */
57 /** Opaque handle to a single stage in a opdl_ring */
61 * Create a new instance of a opdl_ring.
64 * String containing the name to give the new opdl_ring instance.
66 * How many slots the opdl_ring contains. Must be a power a 2!
68 * How many bytes in each slot.
69 * @param max_num_stages
70 * Maximum number of stages.
72 * The NUMA socket (or SOCKET_ID_ANY) to allocate the memory used for this
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
80 * A pointer to a new opdl_ring instance, or NULL on error.
83 opdl_ring_create(const char *name, uint32_t num_slots, uint32_t slot_size,
84 uint32_t max_num_stages, int socket);
87 * Get pointer to individual slot in a opdl_ring.
92 * Index of slot. If greater than the number of slots it will be masked to be
93 * within correct range.
96 * A pointer to that slot.
99 opdl_ring_get_slot(const struct opdl_ring *t, uint32_t index);
102 * Get NUMA socket used by a opdl_ring.
111 opdl_ring_get_socket(const struct opdl_ring *t);
114 * Get number of slots in a opdl_ring.
123 opdl_ring_get_num_slots(const struct opdl_ring *t);
126 * Get name of a opdl_ring.
135 opdl_ring_get_name(const struct opdl_ring *t);
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
143 * The opdl_ring to add the stage to.
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.
149 * The size of the deps array.
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.
155 * Indication to initialise the stage with all slots available or none
158 * A pointer to the new stage, or NULL on error.
161 opdl_stage_add(struct opdl_ring *t, bool threadsafe, bool is_input);
164 * Returns the input stage of a opdl_ring to be used by other API functions.
170 * A pointer to the input stage.
173 opdl_ring_get_input_stage(const struct opdl_ring *t);
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.
181 * The stage to set the dependencies for.
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!
186 * The size of the deps array. This must be > 0.
189 * 0 on success, a negative value on error.
192 opdl_stage_set_deps(struct opdl_stage *s, struct opdl_stage *deps[],
196 * Returns the opdl_ring that a stage belongs to.
202 * A pointer to the opdl_ring that the stage belongs to.
205 opdl_stage_get_opdl_ring(const struct opdl_stage *s);
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.
214 * The opdl_ring to input entries in to.
216 * An array of entries that will be copied in to the opdl_ring.
218 * The size of the entries array.
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.
225 * The number of entries successfully input.
228 opdl_ring_input(struct opdl_ring *t, const void *entries, uint32_t num_entries,
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.
238 * The opdl ring to input entries in to.
240 * The stage to copy entries to.
242 * An array of entries that will be copied in to the opdl ring.
244 * The size of the entries array.
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.
251 * The number of entries successfully input.
254 opdl_ring_copy_from_burst(struct opdl_ring *t, struct opdl_stage *s,
255 const void *entries, uint32_t num_entries, bool block);
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.
264 * The opdl ring to copy entries from.
266 * The stage to copy entries from.
268 * An array of entries that will be copied from the opdl ring.
270 * The size of the entries array.
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.
277 * The number of entries successfully input.
280 opdl_ring_copy_to_burst(struct opdl_ring *t, struct opdl_stage *s,
281 void *entries, uint32_t num_entries, bool block);
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.
291 * The opdl_ring stage to read entries in.
293 * An array of pointers to entries that will be filled in by this function.
295 * The number of entries to attempt to claim for processing (and the size of
296 * the entries array).
298 * If not NULL, this is set to the value of the internal stage sequence number
299 * associated with the first entry returned.
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.
306 * if this is true, the function will return event according to event flow id
308 * The number of pointers to entries filled in to the entries array.
311 opdl_stage_claim(struct opdl_stage *s, void *entries,
312 uint32_t num_entries, uint32_t *seq, bool block, bool atomic);
315 opdl_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);
320 * A function to check how many entries are ready to be claimed.
323 * An array of pointers to entries.
325 * Number of entries in an array.
327 * An opaque pointer to data passed to the claim function.
329 * When set to true, the function should wait until num_entries are ready to
330 * be processed. Otherwise it should return immediately.
333 * Number of entries ready to be claimed.
335 typedef uint32_t (opdl_ring_check_entries_t)(void *entries[],
336 uint32_t num_entries, void *arg, bool block);
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.
345 * The opdl_ring stage to read entries in.
347 * An array of pointers to entries that will be filled in by this function.
349 * The number of entries to attempt to claim for processing (and the size of
350 * the entries array).
352 * If not NULL, this is set to the value of the internal stage sequence number
353 * associated with the first entry returned.
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.
359 * Pointer to a function called to check entries.
361 * Opaque data passed to check() function.
364 * The number of pointers to ready entries filled in to the entries array.
367 opdl_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);
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.
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
385 * The opdl_ring stage to read entries in.
387 * An array of entries that will be filled in by this function.
389 * The number of entries to attempt to claim for processing (and the size of
390 * the entries array).
392 * If not NULL, this is set to the value of the internal stage sequence number
393 * associated with the first entry returned.
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.
400 * The number of entries copied in to the entries array.
403 opdl_stage_claim_copy(struct opdl_stage *s, void *entries,
404 uint32_t num_entries, uint32_t *seq, bool block);
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.
414 * The opdl_ring stage in which to disclaim all claimed entries.
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.
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.
430 * In a single threaded stage, this parameter has no effect.
433 opdl_stage_disclaim(struct opdl_stage *s, uint32_t num_entries,
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.
444 * The opdl_ring stage in which to disclaim entries.
447 * The number of entries to disclaim.
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.
460 * In a single threaded stage, this parameter has no effect.
463 opdl_stage_disclaim_n(struct opdl_stage *s, uint32_t num_entries,
467 * Check how many entries can be input.
470 * The opdl_ring instance to check.
473 * The number of new entries currently allowed to be input.
476 opdl_ring_available(struct opdl_ring *t);
479 * Check how many entries can be processed in a stage.
482 * The stage to check.
485 * The number of entries currently available to be processed in this stage.
488 opdl_stage_available(struct opdl_stage *s);
491 * Check how many entries are available to be processed.
493 * NOTE : DOES NOT CHANGE ANY STATE WITHIN THE STAGE
496 * The stage to check.
499 * The number of entries to check for availability.
502 * The number of entries currently available to be processed in this stage.
505 opdl_stage_find_num_available(struct opdl_stage *s, uint32_t num_entries);
508 * Create empty stage instance and return the pointer.
511 * The pointer of opdl_ring.
514 * enable multiple thread or not.
516 * The pointer of one empty stage instance.
519 opdl_stage_create(struct opdl_ring *t, bool threadsafe);
523 * Set the internal queue id for each stage instance.
526 * The pointer of stage instance.
529 * The value of internal queue id.
532 opdl_stage_set_queue_id(struct opdl_stage *s,
536 * Prints information on opdl_ring instance and all its stages
539 * The stage to print info on.
541 * Where to print the info.
544 opdl_ring_dump(const struct opdl_ring *t, FILE *f);
547 * Blocks until all entries in a opdl_ring have been processed by all stages.
550 * The opdl_ring instance to flush.
553 opdl_ring_flush(struct opdl_ring *t);
556 * Deallocates all resources used by a opdl_ring instance
559 * The opdl_ring instance to free.
562 opdl_ring_free(struct opdl_ring *t);
565 * Search for a opdl_ring by its name
568 * The name of the opdl_ring.
570 * The pointer to the opdl_ring matching the name, or NULL if not found.
574 opdl_ring_lookup(const char *name);
577 * Set a opdl_stage to threadsafe variable.
585 opdl_ring_set_stage_threadsafe(struct opdl_stage *s, bool threadsafe);
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
597 * pointer of the event descriptor.
599 * index of the event descriptor.
601 * queue type associate with the stage.
603 * if the event key field is changed compare with previous record.
607 opdl_ring_cas_slot(struct opdl_stage *s, const struct rte_event *ev,
608 uint32_t index, bool atomic);
614 #endif /* _OPDL_H_ */