---
name: "rte_rcu_qsbr.h"
section: "3"
platform: "linux"
package: "dpdk-doc"
version: "24.11.4-0+deb13u1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/rte_rcu_qsbr.h"
---

# rte\_rcu\_qsbr.h(3)

## NAME

rte\_rcu\_qsbr.h

## SYNOPSIS

`#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

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

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

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**.

## 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.

**Parameters**

*p* Pointer provided while creating the defer queue \
 *e* Pointer to the resource data stored on the defer queue \
 *n* Number of resources to free. Currently, this is set to 1.

**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.

**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 - 1 with error code set in rte\_errno. Possible rte\_errno codes are:

- •

  EINVAL - max\_threads is 0

### int rte\_rcu\_qsbr\_init (struct rte\_rcu\_qsbr \* v, uint32\_t max\_threads)

Initialize a Quiescent State (QS) variable.

**Parameters**

*v* QS variable \
 *max\_threads* Maximum 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.

### 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.

Note that rte\_rcu\_qsbr\_thread\_online must be called before the thread updates its quiescent state using rte\_rcu\_qsbr\_quiescent.

**Parameters**

*v* QS variable \
 *thread\_id* Reader 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.

### 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.

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 variable \
 *thread\_id* Reader thread with this thread ID will stop reporting its quiescent state on the QS variable.

### static \_\_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 variable \
 *thread\_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**.

### static \_\_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 variable \
 *thread\_id* rte\_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 **349** of file **rte\_rcu\_qsbr.h**.

### static \_\_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 variable \
 *thread\_id* Reader thread id

Definition at line **386** of file **rte\_rcu\_qsbr.h**.

### static \_\_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 variable \
 *thread\_id* Reader thread id

Definition at line **419** of file **rte\_rcu\_qsbr.h**.

### static \_\_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\_check API.

Definition at line **449** of file **rte\_rcu\_qsbr.h**.

### static \_\_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 variable \
 *thread\_id* Update the quiescent state for the reader with this thread ID.

Definition at line **478** of file **rte\_rcu\_qsbr.h**.

### static \_\_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.

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**

*v* QS variable \
 *t* Token returned by rte\_rcu\_qsbr\_start API \
 *wait* If 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 **665** of file **rte\_rcu\_qsbr.h**.

### void rte\_rcu\_qsbr\_synchronize (struct rte\_rcu\_qsbr \* v, unsigned int thread\_id)

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**

*v* QS variable \
 *thread\_id* Thread 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.

### int rte\_rcu\_qsbr\_dump (FILE \* f, struct rte\_rcu\_qsbr \* v)

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

It is NOT multi-thread safe.

**Parameters**

*f* A pointer to a file for output \
 *v* QS 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

### struct rte\_rcu\_qsbr\_dq \* rte\_rcu\_qsbr\_dq\_create (const struct rte\_rcu\_qsbr\_dq\_parameters \* params)

Create a queue used to store the data structure elements that can be freed later. This queue is referred to as 'defer queue'.

**Parameters**

*params* Parameters to create a defer queue.

**Returns**

On success - Valid pointer to defer queue On error - NULL Possible rte\_errno codes are:

- •

  EINVAL - NULL parameters are passed

- •

  ENOMEM - Not enough memory

### int rte\_rcu\_qsbr\_dq\_enqueue (struct rte\_rcu\_qsbr\_dq \* dq, void \* e)

Enqueue one resource to the defer queue and start the grace period. The resource will be freed later after at least one grace period is over.

If the defer queue is full, it will attempt to reclaim resources. It will also reclaim resources at regular intervals to avoid the defer queue from growing too big.

Multi-thread safety is provided as the defer queue configuration. When multi-thread safety is requested, it is possible that the resources are not stored in their order of deletion. This results in resources being held in the defer queue longer than they should.

**Parameters**

*dq* Defer queue to allocate an entry from. \
 *e* Pointer to resource data to copy to the defer queue. The size of the data to copy is equal to the element size provided when the defer queue was created.

**Returns**

On success - 0 On error - 1 with rte\_errno set to

- •

  EINVAL - NULL parameters are passed

- •

  ENOSPC - Defer queue is full. This condition can not happen if the defer queue size is equal (or larger) than the number of elements in the data structure.

### int rte\_rcu\_qsbr\_dq\_reclaim (struct rte\_rcu\_qsbr\_dq \* dq, unsigned int n, unsigned int \* freed, unsigned int \* pending, unsigned int \* available)

Free resources from the defer queue.

This API is multi-thread safe.

**Parameters**

*dq* Defer queue to free an entry from. \
 *n* Maximum number of resources to free. \
 *freed* Number of resources that were freed. \
 *pending* Number of resources pending on the defer queue. This number might not be accurate if multi-thread safety is configured. \
 *available* Number of resources that can be added to the defer queue. This number might not be accurate if multi-thread safety is configured.

**Returns**

On successful reclamation of at least 1 resource - 0 On error - 1 with rte\_errno set to

- •

  EINVAL - NULL parameters are passed

### int rte\_rcu\_qsbr\_dq\_delete (struct rte\_rcu\_qsbr\_dq \* dq)

Delete a defer queue.

It tries to reclaim all the resources on the defer queue. If any of the resources have not 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.

**Parameters**

*dq* Defer queue to delete.

**Returns**

On success - 0 On error - 1 Possible rte\_errno codes are:

- •

  EAGAIN - Some of the resources have not completed at least 1 grace period, try again.

## Author

Generated automatically by Doxygen for DPDK from the source code.
