rte_rcu_qsbr.h(3)
π rte_rcu_qsbr.h π
okay bestie, sit down, hydrate, and let me tell you about rte_rcu_qsbr.h(3) β that's the Library Functions Manual entry, and it's genuinely one of the most iconic files in the whole DPDK-adjacent universe. no cap. we're doing RCU and we're doing it correctly π
β¨ NAME β¨
rte_rcu_qsbr.h
πΈ SYNOPSIS πΈ
lowkey just the receipts, here's what you pull in:
#include <inttypes.h>
#include <stdalign.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_atomic.h>
#include <rte_ring.h>
π Data Structures π
the one and only queen in this part of the closet:
struct rte_rcu_qsbr_dq_parameters
π Macros π
#define RTE_RCU_QSBR_DQ_MT_UNSAFE 1
π¦ Typedefs π¦
typedef void(* rte_rcu_qsbr_free_resource_t) (void *p, void *e, unsigned int n)
β Functions β
okay here's the whole friend group, in order, exactly as they're declared:
size_t rte_rcu_qsbr_get_memsize (uint32_t max_threads)int rte_rcu_qsbr_init (struct rte_rcu_qsbr *v, uint32_t max_threads)int rte_rcu_qsbr_thread_register (struct rte_rcu_qsbr *v, unsigned int thread_id)int rte_rcu_qsbr_thread_unregister (struct rte_rcu_qsbr *v, unsigned int thread_id)static __rte_always_inline void rte_rcu_qsbr_thread_online (struct rte_rcu_qsbr *v, unsigned int thread_id)static __rte_always_inline void rte_rcu_qsbr_thread_offline (struct rte_rcu_qsbr *v, unsigned int thread_id)static __rte_always_inline void rte_rcu_qsbr_lock (__rte_unused struct rte_rcu_qsbr *v, __rte_unused unsigned int thread_id)static __rte_always_inline void rte_rcu_qsbr_unlock (__rte_unused struct rte_rcu_qsbr *v, __rte_unused unsigned int thread_id)static __rte_always_inline uint64_t rte_rcu_qsbr_start (struct rte_rcu_qsbr *v)static __rte_always_inline void rte_rcu_qsbr_quiescent (struct rte_rcu_qsbr *v, unsigned int thread_id)static __rte_always_inline int rte_rcu_qsbr_check (struct rte_rcu_qsbr *v, uint64_t t, bool wait)void rte_rcu_qsbr_synchronize (struct rte_rcu_qsbr *v, unsigned int thread_id)int rte_rcu_qsbr_dump (FILE *f, struct rte_rcu_qsbr *v)struct rte_rcu_qsbr_dq * rte_rcu_qsbr_dq_create (const struct rte_rcu_qsbr_dq_parameters *params)int rte_rcu_qsbr_dq_enqueue (struct rte_rcu_qsbr_dq *dq, void *e)int rte_rcu_qsbr_dq_reclaim (struct rte_rcu_qsbr_dq *dq, unsigned int n, unsigned int *freed, unsigned int *pending, unsigned int *available)int rte_rcu_qsbr_dq_delete (struct rte_rcu_qsbr_dq *dq)
π Detailed Description π
RTE Quiescent State Based Reclamation (QSBR).
okay so. A Quiescent State (QS) is literally any point in the thread execution where the thread does not hold a reference to a data structure in shared memory. that's it, that's the whole vibe. and the way that while you're using lock-less data structures, the writer can safely free memory once all the reader threads have entered quiescent state? yeah. iconic.
This library provides the ability for the readers to report quiescent state and for the writers to identify when all the readers have entered quiescent state. π«Ά
Definition in file rte_rcu_qsbr.h.
π§ Macro Definition Documentation π§
π #define RTE_RCU_QSBR_DQ_MT_UNSAFE 1
Various flags supported. < Enqueue and reclaim operations are multi-thread safe by default. The call back functions registered to free the resources are assumed to be multi-thread safe. Set this flag if multi-thread safety is not required.
Definition at line 143 of file rte_rcu_qsbr.h.
π Typedef Documentation π
β¨ typedef void(* rte_rcu_qsbr_free_resource_t) (void *p, void *e, unsigned int n)
Call back function called to free the resources. yes bestie, you write this one, the library just calls it when it's time.
Parameters
pβ Pointer provided while creating the defer queueeβ Pointer to the resource data stored on the defer queuenβ Number of resources to free. Currently, this is set to1.
Returns
- None
Definition at line 131 of file rte_rcu_qsbr.h.
π Function Documentation π
π size_t rte_rcu_qsbr_get_memsize (uint32_t max_threads)
Return the size of the memory occupied by a Quiescent State variable. like, how much room does this thing need, bestie.
Parameters
max_threadsβ Maximum number of threads reporting quiescent state on this variable.
Returns
- On success - size of memory in bytes required for this QS variable.
- On error -
1with error code set inrte_errno. Possiblerte_errnocodes are:EINVALβmax_threadsis0
π int rte_rcu_qsbr_init (struct rte_rcu_qsbr * v, uint32_t max_threads)
Initialize a Quiescent State (QS) variable.
Parameters
vβ QS variablemax_threadsβ Maximum number of threads reporting quiescent state on this variable. This should be the same value as passed torte_rcu_qsbr_get_memsize.
Returns
- On success -
0 - On error -
1with error code set inrte_errno. Possiblerte_errnocodes are:EINVALβmax_threadsis0or'v'is NULL.
π int rte_rcu_qsbr_thread_register (struct rte_rcu_qsbr * v, unsigned int thread_id)
Register a reader thread to report its quiescent state on a QS variable.
This is implemented as a lock-free function. It is multi-thread safe. Any reader thread that wants to report its quiescent state must call this API. This can be called during initialization or as part of the packet processing loop.
not me reminding you:rte_rcu_qsbr_thread_onlinemust be called before the thread updates its quiescent state usingrte_rcu_qsbr_quiescent. π
Parameters
vβ QS variablethread_idβ Reader thread with this thread ID will report its quiescent state on the QS variable.thread_idis a value between0and(max_threads - 1).'max_threads'is the parameter passed in'rte_rcu_qsbr_init'API.
π int rte_rcu_qsbr_thread_unregister (struct rte_rcu_qsbr * v, unsigned int thread_id)
Remove a reader thread, from the list of threads reporting their quiescent state on a QS variable. it's the unfollow, but for threads. π
This is implemented as a lock-free function. It is multi-thread safe. This API can be called from the reader threads during shutdown. Ongoing quiescent state queries will stop waiting for the status from this unregistered reader thread.
Parameters
vβ QS variablethread_idβ Reader thread with this thread ID will stop reporting its quiescent state on the QS variable.
π __rte_always_inline void rte_rcu_qsbr_thread_online (struct rte_rcu_qsbr * v, unsigned int thread_id) [static]
Add a registered reader thread, to the list of threads reporting their quiescent state on a QS variable.
This is implemented as a lock-free function. It is multi-thread safe.
Any registered reader thread that wants to report its quiescent state must call this API before calling rte_rcu_qsbr_quiescent. This can be called during initialization or as part of the packet processing loop.
The reader thread must call rte_rcu_qsbr_thread_offline API, before calling any functions that block, to ensure that rte_rcu_qsbr_check API does not wait indefinitely for the reader thread to update its QS.
The reader thread must call rte_rcu_thread_online API, after the blocking function call returns, to ensure that rte_rcu_qsbr_check API waits for the reader thread to update its quiescent state.
Parameters
vβ QS variablethread_idβ Reader thread with this thread ID will report its quiescent state on the QS variable.
Definition at line 296 of file rte_rcu_qsbr.h.
π __rte_always_inline void rte_rcu_qsbr_thread_offline (struct rte_rcu_qsbr * v, unsigned int thread_id) [static]
Remove a registered reader thread from the list of threads reporting their quiescent state on a QS variable.
This is implemented as a lock-free function. It is multi-thread safe.
This can be called during initialization or as part of the packet processing loop.
The reader thread must call rte_rcu_qsbr_thread_offline API, before calling any functions that block, to ensure that rte_rcu_qsbr_check API does not wait indefinitely for the reader thread to update its QS.
Parameters
vβ QS variablethread_idβrte_rcu_qsbr_checkAPI will not wait for the reader thread with this thread ID to report its quiescent state on the QS variable.
Definition at line 349 of file rte_rcu_qsbr.h.
π __rte_always_inline void rte_rcu_qsbr_lock (__rte_unused struct rte_rcu_qsbr * v, __rte_unused unsigned int thread_id) [static]
Acquire a lock for accessing a shared data structure.
This is implemented as a lock-free function. It is multi-thread safe.
This API is provided to aid debugging. This should be called before accessing a shared data structure.
When RTE_LIBRTE_RCU_DEBUG is enabled a lock counter is incremented. Similarly rte_rcu_qsbr_unlock will decrement the counter. When the rte_rcu_qsbr_check API will verify that this counter is 0.
When RTE_LIBRTE_RCU_DEBUG is disabled, this API will do nothing.
Parameters
vβ QS variablethread_idβ Reader thread id
Definition at line 386 of file rte_rcu_qsbr.h.
π __rte_always_inline void rte_rcu_qsbr_unlock (__rte_unused struct rte_rcu_qsbr * v, __rte_unused unsigned int thread_id) [static]
Release a lock after accessing a shared data structure.
This is implemented as a lock-free function. It is multi-thread safe.
This API is provided to aid debugging. This should be called after accessing a shared data structure.
When RTE_LIBRTE_RCU_DEBUG is enabled, rte_rcu_qsbr_unlock will decrement a lock counter. rte_rcu_qsbr_check API will verify that this counter is 0.
When RTE_LIBRTE_RCU_DEBUG is disabled, this API will do nothing.
Parameters
vβ QS variablethread_idβ Reader thread id
Definition at line 419 of file rte_rcu_qsbr.h.
π __rte_always_inline uint64_t rte_rcu_qsbr_start (struct rte_rcu_qsbr * v) [static]
Ask the reader threads to report the quiescent state status.
This is implemented as a lock-free function. It is multi-thread safe and can be called from worker threads.
Parameters
vβ QS variable
Returns
- This is the token for this call of the API. This should be passed to
rte_rcu_qsbr_checkAPI.
Definition at line 449 of file rte_rcu_qsbr.h.
π __rte_always_inline void rte_rcu_qsbr_quiescent (struct rte_rcu_qsbr * v, unsigned int thread_id) [static]
Update quiescent state for a reader thread.
This is implemented as a lock-free function. It is multi-thread safe. All the reader threads registered to report their quiescent state on the QS variable must call this API.
Parameters
vβ QS variablethread_idβ Update the quiescent state for the reader with this thread ID.
Definition at line 478 of file rte_rcu_qsbr.h.
π __rte_always_inline int rte_rcu_qsbr_check (struct rte_rcu_qsbr * v, uint64_t t, bool wait) [static]
Checks if all the reader threads have entered the quiescent state referenced by token.
This is implemented as a lock-free function. It is multi-thread safe and can be called from the worker threads as well.
okay bestie, important one: if this API is called with 'wait' set to true, the following factors must be considered:
- If the calling thread is also reporting the status on the same QS variable, it must update the quiescent state status, before calling this API.
- also, when you're calling from multiple threads, only one of those threads gets to be the one reporting the quiescent state status on a given QS variable. one job, one thread bestie, that's the rule π
Parameters
vβ the QS variable πΈtβ the token thatrte_rcu_qsbr_starthanded you backwaitβ if it's true, you block until every single reader thread has finished entering the quiescent state that tokentpoints at. no sneaking past it π«Ά
Returns
0if all the reader threads have NOT passed through the specified number of quiescent states. (not yet!! π)1if all the reader threads HAVE passed through the specified number of quiescent states. (slay β¨)
Definition at line 665 of file rte_rcu_qsbr.h.
rte_rcu_qsbr_synchronize
void rte_rcu_qsbr_synchronize (struct rte_rcu_qsbr * v, unsigned int
thread_id)
Wait till the reader threads have entered quiescent state. it's giving "chill, they'll get there" π¦
It's implemented as a lock-free function, and it is multi-thread safe. You can lowkey think of this API as a lil wrapper around rte_rcu_qsbr_start and rte_rcu_qsbr_check β that's literally the vibe it's serving.
If this API gets called from multiple threads, only one of those threads can be the one reporting the quiescent state status on a given QS variable. single reporter energy only, no cap
Parameters
vβ the QS variable πthread_idβ the Thread ID of the caller, but only if it's registered to report quiescent state on this QS variable (i.e. the calling thread is also part of the readside critical section). If it's not, passRTE_QSBR_THRID_INVALIDinstead. π©
rte_rcu_qsbr_dump
int rte_rcu_qsbr_dump (FILE * f, struct rte_rcu_qsbr * v)
Dumps the details of a single QS variables to a file. receipts, bestie π§Ύ
It is NOT multi-thread safe. do not bring friends to this one. π
Parameters
fβ a pointer to a file for outputvβ the QS variable
Returns
On success β 0. On error β 1 with the error code set in rte_errno. Possible rte_errno codes are:
EINVALβ NULL parameters were passed π
rte_rcu_qsbr_dq_create
struct rte_rcu_qsbr_dq * rte_rcu_qsbr_dq_create (const struct
rte_rcu_qsbr_dq_parameters * params)
Creates a queue used to store the data structure elements that can be freed later. This queue is referred to as the 'defer queue'. it's the β¨later pileβ¨ π
Parameters
paramsβ the parameters used to create a defer queue
Returns
On success β a valid pointer to the defer queue. On error β NULL. Possible rte_errno codes are:
EINVALβ NULL parameters were passedENOMEMβ not enough memory π
rte_rcu_qsbr_dq_enqueue
int rte_rcu_qsbr_dq_enqueue (struct rte_rcu_qsbr_dq * dq, void * e)
Enqueues one resource onto the defer queue and starts the grace period. That resource will get freed later, after at least one grace period is over. patience is a virtue fr fr π§
If the defer queue is full, it'll attempt to reclaim resources. It'll also reclaim resources at regular intervals, so the defer queue doesn't grow too big. self-care for your queue π
Multi-thread safety is provided exactly as the defer queue configuration says. When multi-thread safety is requested, it's possible that the resources are not stored in their order of deletion. Which means resources end up held in the defer queue longer than they should be. just so you know, that's a real tradeoff, not a vibe.
Parameters
dqβ the defer queue to allocate an entry fromeβ a pointer to the resource data to copy to the defer queue. The size of the data copied is equal to the element size you provided back when the defer queue was created. π
Returns
On success β 0. On error β 1 with rte_errno set to:
EINVALβ NULL parameters were passedENOSPCβ the defer queue is full. This condition can not happen if the defer queue size is equal to (or larger than) the number of elements in the data structure. so size it right and you'll never see this one π
rte_rcu_qsbr_dq_reclaim
int rte_rcu_qsbr_dq_reclaim (struct rte_rcu_qsbr_dq * dq, unsigned int n,
unsigned int * freed, unsigned int * pending, unsigned int * available)
Frees resources from the defer queue. spring cleaning but make it multithreaded π§Ήβ¨
This API is multi-thread safe. π«Ά
Parameters
dqβ the defer queue to free an entry fromnβ the maximum number of resources to freefreedβ the number of resources that were actually freedpendingβ the number of resources pending on the defer queue. This number might not be accurate if multi-thread safety is configured. πavailableβ the number of resources that can be added to the defer queue. This number might not be accurate if multi-thread safety is configured either. the numbers are just doing their best ok π
Returns
On successful reclamation of at least 1 resource β 0. On error β 1 with rte_errno set to:
EINVALβ NULL parameters were passed
rte_rcu_qsbr_dq_delete
int rte_rcu_qsbr_dq_delete (struct rte_rcu_qsbr_dq * dq)
Deletes a defer queue. bye bestie π¦
It tries to reclaim all the resources on the defer queue. But if any of the resources haven't completed the grace period, the reclamation stops and returns immediately. The rest of the resources are not reclaimed, and the defer queue is not freed. so it's a β¨partial goodbyeβ¨, dramatic but true π
Parameters
dqβ the defer queue to delete
Returns
On success β 0. On error β 1. Possible rte_errno codes are:
EAGAINβ some of the resources haven't completed at least 1 grace period. try again. π
β¨ AUTHOR β¨
Generated automatically by Doxygen for DPDK from the source code. π€ (not a human girlie, a robot girlie, and honestly? ate.)
okay that's the whole page, you made it to the end π this one's from DPDK, Version 25.11.3, and it's page rte_rcu_qsbr.h(3) β go forth and quiesce, bestie. periodt πβ¨
π¦ where this page comes from
- ubuntu resolute: dpdk-doc 25.11.3-0ubuntu0.26.04.1 Β· BSD-3-Clause
- ubuntu stonking: dpdk-doc 25.11.3-1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms