DPDK  19.08.0-rc0
Functions
rte_rcu_qsbr.h File Reference
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_lcore.h>
#include <rte_debug.h>
#include <rte_atomic.h>

Go to the source code of this file.

Functions

size_t __rte_experimental rte_rcu_qsbr_get_memsize (uint32_t max_threads)
 
int __rte_experimental rte_rcu_qsbr_init (struct rte_rcu_qsbr *v, uint32_t max_threads)
 
int __rte_experimental rte_rcu_qsbr_thread_register (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
int __rte_experimental rte_rcu_qsbr_thread_unregister (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
static __rte_always_inline void __rte_experimental rte_rcu_qsbr_thread_online (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
static __rte_always_inline void __rte_experimental rte_rcu_qsbr_thread_offline (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
static __rte_always_inline void __rte_experimental rte_rcu_qsbr_lock (__rte_unused struct rte_rcu_qsbr *v, __rte_unused unsigned int thread_id)
 
static __rte_always_inline void __rte_experimental rte_rcu_qsbr_unlock (__rte_unused struct rte_rcu_qsbr *v, __rte_unused unsigned int thread_id)
 
static __rte_always_inline uint64_t __rte_experimental rte_rcu_qsbr_start (struct rte_rcu_qsbr *v)
 
static __rte_always_inline void __rte_experimental rte_rcu_qsbr_quiescent (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
static __rte_always_inline int __rte_experimental rte_rcu_qsbr_check (struct rte_rcu_qsbr *v, uint64_t t, bool wait)
 
void __rte_experimental rte_rcu_qsbr_synchronize (struct rte_rcu_qsbr *v, unsigned int thread_id)
 
int __rte_experimental rte_rcu_qsbr_dump (FILE *f, struct rte_rcu_qsbr *v)
 

Detailed Description

RTE Quiescent State Based Reclamation (QSBR)

Quiescent State (QS) is any point in the thread execution where the thread does not hold a reference to a data structure in shared memory. While using lock-less data structures, the writer can safely free memory once all the reader threads have entered quiescent state.

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.

Function Documentation

◆ rte_rcu_qsbr_get_memsize()

size_t __rte_experimental rte_rcu_qsbr_get_memsize ( uint32_t  max_threads)
Warning
EXPERIMENTAL: this API may change without prior notice

Return the size of the memory occupied by a Quiescent State variable.

Parameters
max_threadsMaximum number of threads reporting quiescent state on this variable.
Returns
On success - size of memory in bytes required for this QS variable. On error - 1 with error code set in rte_errno. Possible rte_errno codes are:
  • EINVAL - max_threads is 0

◆ rte_rcu_qsbr_init()

int __rte_experimental rte_rcu_qsbr_init ( struct rte_rcu_qsbr *  v,
uint32_t  max_threads 
)
Warning
EXPERIMENTAL: this API may change without prior notice

Initialize a Quiescent State (QS) variable.

Parameters
vQS variable
max_threadsMaximum number of threads reporting quiescent state on this variable. This should be the same value as passed to rte_rcu_qsbr_get_memsize.
Returns
On success - 0 On error - 1 with error code set in rte_errno. Possible rte_errno codes are:
  • EINVAL - max_threads is 0 or 'v' is NULL.

◆ rte_rcu_qsbr_thread_register()

int __rte_experimental rte_rcu_qsbr_thread_register ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
Warning
EXPERIMENTAL: this API may change without prior notice

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.

Note that rte_rcu_qsbr_thread_online must be called before the thread updates its quiescent state using rte_rcu_qsbr_quiescent.

Parameters
vQS variable
thread_idReader thread with this thread ID will report its quiescent state on the QS variable. thread_id is a value between 0 and (max_threads - 1). 'max_threads' is the parameter passed in 'rte_rcu_qsbr_init' API.

◆ rte_rcu_qsbr_thread_unregister()

int __rte_experimental rte_rcu_qsbr_thread_unregister ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
Warning
EXPERIMENTAL: this API may change without prior notice

Remove a 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 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
vQS variable
thread_idReader thread with this thread ID will stop reporting its quiescent state on the QS variable.

◆ rte_rcu_qsbr_thread_online()

static __rte_always_inline void __rte_experimental rte_rcu_qsbr_thread_online ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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_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
vQS variable
thread_idReader thread with this thread ID will report its quiescent state on the QS variable.

Definition at line 225 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_thread_offline()

static __rte_always_inline void __rte_experimental rte_rcu_qsbr_thread_offline ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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_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
vQS variable
thread_idrte_rcu_qsbr_check API will not wait for the reader thread with this thread ID to report its quiescent state on the QS variable.

Definition at line 286 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_lock()

static __rte_always_inline void __rte_experimental rte_rcu_qsbr_lock ( __rte_unused struct rte_rcu_qsbr *  v,
__rte_unused unsigned int  thread_id 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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 CONFIG_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 CONFIG_RTE_LIBRTE_RCU_DEBUG is disabled, this API will do nothing.

Parameters
vQS variable
thread_idReader thread id

Definition at line 326 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_unlock()

static __rte_always_inline void __rte_experimental rte_rcu_qsbr_unlock ( __rte_unused struct rte_rcu_qsbr *  v,
__rte_unused unsigned int  thread_id 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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 CONFIG_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 CONFIG_RTE_LIBRTE_RCU_DEBUG is disabled, this API will do nothing.

Parameters
vQS variable
thread_idReader thread id

Definition at line 362 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_start()

static __rte_always_inline uint64_t __rte_experimental rte_rcu_qsbr_start ( struct rte_rcu_qsbr *  v)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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
vQS variable
Returns
  • This is the token for this call of the API. This should be passed to rte_rcu_qsbr_check API.

Definition at line 395 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_quiescent()

static __rte_always_inline void __rte_experimental rte_rcu_qsbr_quiescent ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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
vQS variable
thread_idUpdate the quiescent state for the reader with this thread ID.

Definition at line 427 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_check()

static __rte_always_inline int __rte_experimental rte_rcu_qsbr_check ( struct rte_rcu_qsbr *  v,
uint64_t  t,
bool  wait 
)
static
Warning
EXPERIMENTAL: this API may change without prior notice

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.

If this API is called with 'wait' set to true, the following factors must be considered:

1) 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.

2) In addition, while calling from multiple threads, only one of those threads can be reporting the quiescent state status on a given QS variable.

Parameters
vQS variable
tToken returned by rte_rcu_qsbr_start API
waitIf true, block till all the reader threads have completed entering the quiescent state referenced by token 't'.
Returns
  • 0 if all reader threads have NOT passed through specified number of quiescent states.
  • 1 if all reader threads have passed through specified number of quiescent states.

Definition at line 582 of file rte_rcu_qsbr.h.

◆ rte_rcu_qsbr_synchronize()

void __rte_experimental rte_rcu_qsbr_synchronize ( struct rte_rcu_qsbr *  v,
unsigned int  thread_id 
)
Warning
EXPERIMENTAL: this API may change without prior notice

Wait till the reader threads have entered quiescent state.

This is implemented as a lock-free function. It is multi-thread safe. This API can be thought of as a wrapper around rte_rcu_qsbr_start and rte_rcu_qsbr_check APIs.

If this API is called from multiple threads, only one of those threads can be reporting the quiescent state status on a given QS variable.

Parameters
vQS variable
thread_idThread ID of the caller if it is registered to report quiescent state on this QS variable (i.e. the calling thread is also part of the readside critical section). If not, pass RTE_QSBR_THRID_INVALID.

◆ rte_rcu_qsbr_dump()

int __rte_experimental rte_rcu_qsbr_dump ( FILE *  f,
struct rte_rcu_qsbr *  v 
)
Warning
EXPERIMENTAL: this API may change without prior notice

Dump the details of a single QS variables to a file.

It is NOT multi-thread safe.

Parameters
fA pointer to a file for output
vQS variable
Returns
On success - 0 On error - 1 with error code set in rte_errno. Possible rte_errno codes are:
  • EINVAL - NULL parameters are passed