rte_sched.h(3)
πΈ rte_sched.h(3) β Library Functions Manual πΈ
bestie. sit down. hydrate. because we are about to talk about the RTE Hierarchical Scheduler, and it is a lot in the best way. this is the header that lives in rte_sched.h, straight out of the Library Functions Manual, and it is giving main character energy for anyone who has ever needed to make a NIC behave itself and respect a bunch of SLAs. π
β¨ NAME β¨
rte_sched.h
no cap, that's it. just the header. iconic of it tbh. π
β¨ SYNOPSIS β¨
the includes you need, okay, so:
#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_meter.h>
#include 'rte_red.h'
#include 'rte_pie.h'
π Data Structures
struct rte_sched_subport_statsstruct rte_sched_queue_statsstruct rte_sched_port_params
π Macros
#define RTE_SCHED_QUEUES_PER_PIPE 16
#define RTE_SCHED_BE_QUEUES_PER_PIPE 4
#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE (RTE_SCHED_QUEUES_PER_PIPE
- RTE_SCHED_BE_QUEUES_PER_PIPE + 1)
#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE
- 1)
π Enumerations
enum rte_sched_cman_mode { RTE_SCHED_CMAN_RED, RTE_SCHED_CMAN_PIE }
π Functions
void rte_sched_port_free (struct rte_sched_port *port)
struct rte_sched_port * rte_sched_port_config (struct
rte_sched_port_params *params) __rte_malloc
__rte_dealloc(rte_sched_port_free
struct rte_sched_port int rte_sched_subport_pipe_profile_add (struct
rte_sched_port *port, uint32_t subport_id, struct
rte_sched_pipe_params *params, uint32_t *pipe_profile_id)
int rte_sched_port_subport_profile_add (struct rte_sched_port *port,
struct rte_sched_subport_profile_params *profile, uint32_t
*subport_profile_id)
int rte_sched_subport_config (struct rte_sched_port *port, uint32_t
subport_id, struct rte_sched_subport_params *params, uint32_t
subport_profile_id)
int rte_sched_pipe_config (struct rte_sched_port *port, uint32_t
subport_id, uint32_t pipe_id, int32_t pipe_profile)
uint32_t rte_sched_port_get_memory_footprint (struct
rte_sched_port_params *port_params, struct rte_sched_subport_params
**subport_params)
int rte_sched_subport_read_stats (struct rte_sched_port *port, uint32_t
subport_id, struct rte_sched_subport_stats *stats, uint32_t *tc_ov)
int rte_sched_queue_read_stats (struct rte_sched_port *port, uint32_t
queue_id, struct rte_sched_queue_stats *stats, uint16_t *qlen)
void rte_sched_port_pkt_write (struct rte_sched_port *port, struct
rte_mbuf *pkt, uint32_t subport, uint32_t pipe, uint32_t
traffic_class, uint32_t queue, enum rte_color color)
void rte_sched_port_pkt_read_tree_path (struct rte_sched_port *port,
const struct rte_mbuf *pkt, uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
int rte_sched_port_enqueue (struct rte_sched_port *port, struct rte_mbuf
**pkts, uint32_t n_pkts)
int rte_sched_port_dequeue (struct rte_sched_port *port, struct rte_mbuf
**pkts, uint32_t n_pkts)
int rte_sched_subport_tc_ov_config (struct rte_sched_port *port,
uint32_t subport_id, bool tc_ov_enable)
look at all those functions. so many. we love a full roster. π«Ά
β¨ Detailed Description β¨
π¦ RTE Hierarchical Scheduler
okay so here's the vibe. the hierarchical scheduler prioritizes the transmission of packets from different users and different traffic classes, and it does it according to the Service Level Agreements (SLAs) that are defined for the current network node. it's basically the bouncer at the club of your network, except the bouncer knows every single guest by name and exactly how much bandwidth they're contractually allowed to have. π
and it's not small. the scheduler supports thousands of packet queues, all grouped under a 5-level hierarchy. five. levels. let's walk it like a runway. π
- Port:
- Typical usage: output Ethernet port;
- Multiple ports are scheduled in round robin order with equal priority;
- Subport:
- Typical usage: group of users;
- Traffic shaping using the token bucket algorithm (one bucket per subport);
- Upper limit enforced per traffic class at subport level;
- Lower priority traffic classes able to reuse subport bandwidth currently unused by higher priority traffic classes of the same subport;
- When any subport traffic class is oversubscribed (configuration time event), the usage of subport member pipes with high demand for that traffic class pipes is truncated to a dynamically adjusted value with no impact to low demand pipes;
- Pipe:
- Typical usage: individual user/subscriber;
- Traffic shaping using the token bucket algorithm (one bucket per pipe);
- Traffic class:
- Traffic classes of the same pipe handled in strict priority order;
- Upper limit enforced per traffic class at the pipe level;
- Lower priority traffic classes able to reuse pipe bandwidth currently unused by higher priority traffic classes of the same pipe;
- Queue:
- Typical usage: queue hosting packets from one or multiple connections of same traffic class belonging to the same user;
- Weighted Round Robin (WRR) is used to service the queues within same pipe lowest priority traffic class (best-effort).
not the token buckets. not the strict priority order. this whole thing is highkey a masterpiece of queueing theory and i'm obsessed. π
Definition in file rte_sched.h.
β¨ Macro Definition Documentation β¨
π #define RTE_SCHED_QUEUES_PER_PIPE 16
Congestion Management Maximum number of queues per pipe. Note that the multiple queues (power of 2) can only be assigned to lowest priority (best-effort) traffic class. Other higher priority traffic classes can only have one queue. Can not change.
See also
struct rte_sched_port_params
Definition at line 74 of file rte_sched.h.
π #define RTE_SCHED_BE_QUEUES_PER_PIPE 4
Number of WRR queues for best-effort traffic class per pipe.
See also
struct rte_sched_pipe_params
Definition at line 80 of file rte_sched.h.
π #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1)
Number of traffic classes per pipe (as well as subport).
See also
struct rte_sched_subport_paramsstruct rte_sched_pipe_params
Definition at line 86 of file rte_sched.h.
π #define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)
Best-effort traffic class ID Can not change.
Definition at line 92 of file rte_sched.h.
β¨ Enumeration Type Documentation β¨
π¦ enum rte_sched_cman_mode
Congestion Management (CMAN) mode
This is used for controlling the admission of packets into a packet queue or group of packet queues on congestion.
The Random Early Detection (RED) algorithm works by proactively dropping more and more input packets as the queue occupancy builds up. When the queue is full or almost full, RED effectively works as tail drop. The Weighted RED algorithm uses a separate set of RED thresholds for each packet color.
Similar to RED, Proportional Integral Controller Enhanced (PIE) randomly drops a packet at the onset of the congestion and tries to control the latency around the target value. The congestion detection, however, is based on the queueing latency instead of the queue length like RED. For more information, refer RFC8033.
Enumerator
RTE_SCHED_CMAN_REDβ Random Early Detection (RED)RTE_SCHED_CMAN_PIEβ Proportional Integral Controller Enhanced (PIE)
Definition at line 127 of file rte_sched.h.
okay bestie that's the macro and enum lore covered, and there's so much more coming β the structs, the params, all the function details β so don't go anywhere. π§
β¨ FUNCTION DOCUMENTATION β¨
okay bestie, this is the part where we actually meet the functions π every single one of them, no skips, no cap.
void rte_sched_port_free (struct rte_sched_port * port)
Hierarchical scheduler port free β aka yeet the whole port scheduler into the void π«Ά
Parameters
portβ Handle to port scheduler instance. IfportisNULL, no operation is performed. literally nothing happens, it's giving "no thoughts, head empty" π
struct rte_sched_port * rte_sched_port_config (struct rte_sched_port_params * params)
Hierarchical scheduler port configuration β setting the whole vibe up β¨
Parameters
paramsβ Port scheduler configuration parameter structure
Returns
Handle to port scheduler instance upon success or NULL otherwise. so if it's NULL, it did NOT slay π
struct rte_sched_port int rte_sched_subport_pipe_profile_add (struct rte_sched_port * port, uint32_t subport_id, struct rte_sched_pipe_params * params, uint32_t * pipe_profile_id)
Hierarchical scheduler pipe profile add π (yes, that return type up there is exactly what the page says, we do not fix, we do not question, we report π)
Parameters
portβ Handle to port scheduler instancesubport_idβ Subport IDparamsβ Pipe profile parameterspipe_profile_idβ Set to valid profile id when profile is added successfully
Returns
0 upon success, error code otherwise
int rte_sched_port_subport_profile_add (struct rte_sched_port * port, struct rte_sched_subport_profile_params * profile, uint32_t * subport_profile_id)
Hierarchical scheduler subport bandwidth profile add π¦
Note that this function is safe to use in runtime for adding new subport bandwidth profile as it doesn't have any impact on hierarchical structure of the scheduler. no cap, you can call it while everything's live and it won't wreck the tree π
Parameters
portβ Handle to port scheduler instanceprofileβ Subport bandwidth profilesubport_profile_idβ Subport profile id
Returns
0 upon success, error code otherwise
int rte_sched_subport_config (struct rte_sched_port * port, uint32_t subport_id, struct rte_sched_subport_params * params, uint32_t subport_profile_id)
Hierarchical scheduler subport configuration π
Note that this function is safe to use at runtime to configure subport bandwidth profile. runtime glow-up, we love to see it β¨
Parameters
portβ Handle to port scheduler instancesubport_idβ Subport IDparamsβ Subport configuration parameters. Must be non-NULLfor first invocation (i.e initialization) for a given subport. Ignored (recommended value isNULL) for all subsequent invocation on the same subport. so first time bestie you MUST bring it, every time after just leave it atNULLπ«Άsubport_profile_idβ ID of subport bandwidth profile
Returns
0 upon success, error code otherwise
int rte_sched_pipe_config (struct rte_sched_port * port, uint32_t subport_id, uint32_t pipe_id, int32_t pipe_profile)
Hierarchical scheduler pipe configuration π
Parameters
portβ Handle to port scheduler instancesubport_idβ Subport IDpipe_idβ Pipe ID within subportpipe_profileβ ID of subport-level pre-configured pipe profile
Returns
0 upon success, error code otherwise
uint32_t rte_sched_port_get_memory_footprint (struct rte_sched_port_params * port_params, struct rte_sched_subport_params ** subport_params)
Hierarchical scheduler memory footprint size per port β how much RAM is this whole thing about to eat π
Parameters
port_paramsβ Port scheduler configuration parameter structuresubport_paramsβ Array of subport parameter structures
Returns
Memory footprint size in bytes upon success, 0 otherwise
int rte_sched_subport_read_stats (struct rte_sched_port * port, uint32_t subport_id, struct rte_sched_subport_stats * stats, uint32_t * tc_ov)
Hierarchical scheduler subport statistics read π the receipts, fr fr
Parameters
portβ Handle to port scheduler instancesubport_idβ Subport IDstatsβ Pointer to pre-allocated subport statistics structure where the statistics counters should be storedtc_ovβ Pointer to pre-allocatedRTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-entry array where the oversubscription status for each of the subport traffic classes should be stored.
Returns
0 upon success, error code otherwise
int rte_sched_queue_read_stats (struct rte_sched_port * port, uint32_t queue_id, struct rte_sched_queue_stats * stats, uint16_t * qlen)
Hierarchical scheduler queue statistics read πΈ
Parameters
portβ Handle to port scheduler instancequeue_idβ Queue ID within port schedulerstatsβ Pointer to pre-allocated subport statistics structure where the statistics counters should be storedqlenβ Pointer to pre-allocated variable where the current queue length should be stored.
Returns
0 upon success, error code otherwise
void rte_sched_port_pkt_write (struct rte_sched_port * port, struct rte_mbuf * pkt, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue, enum rte_color color)
Scheduler hierarchy path write to packet descriptor. Typically called by the packet classification stage. βοΈ it's stamping the whole route onto the packet like a little name tag π·οΈ
Parameters
portβ Handle to port scheduler instancepktβ Packet descriptor handlesubportβ Subport IDpipeβ Pipe ID within subporttraffic_classβ Traffic class ID within pipe (0..RTE_SCHED_TRAFFIC_CLASS_BE)queueβ Queue ID within pipe traffic class,0for high priority TCs, and0.. (RTE_SCHED_BE_QUEUES_PER_PIPE-1) for best-effort TCcolorβ Packet color set π¨
void rte_sched_port_pkt_read_tree_path (struct rte_sched_port * port, const struct rte_mbuf * pkt, uint32_t * subport, uint32_t * pipe, uint32_t * traffic_class, uint32_t * queue)
Scheduler hierarchy path read from packet descriptor (struct rte_mbuf). Typically called as part of the hierarchical scheduler enqueue operation. The subport, pipe, traffic_class and queue parameters need to be pre-allocated by the caller. π so bestie, YOU bring the storage, this function just fills it in
Parameters
portβ Handle to port scheduler instancepktβ Packet descriptor handlesubportβ Subport IDpipeβ Pipe ID within subporttraffic_classβ Traffic class ID within pipe (0..RTE_SCHED_TRAFFIC_CLASS_BE)queueβ Queue ID within pipe traffic class,0for high priority TCs, and0.. (RTE_SCHED_BE_QUEUES_PER_PIPE-1) for best-effort TC
int rte_sched_port_enqueue (struct rte_sched_port * port, struct rte_mbuf ** pkts, uint32_t n_pkts)
Hierarchical scheduler port enqueue. Writes up to n_pkts to port scheduler and returns the number of packets actually written. For each packet, the port scheduler queue to write the packet to is identified by reading the hierarchy path from the packet descriptor; if the queue is full or congested and the packet is not written to the queue, then the packet is automatically dropped without any action required from the caller. π yeah it just gets dropped, no dramatic goodbye, no callback, nothing. that's the deal.
Parameters
portβ Handle to port scheduler instancepktsβ Array storing the packet descriptor handlesn_pktsβ Number of packets to enqueue from thepktsarray into the port scheduler
Returns
Number of packets successfully enqueued
int rte_sched_port_dequeue (struct rte_sched_port * port, struct rte_mbuf ** pkts, uint32_t n_pkts)
Hierarchical scheduler port dequeue. Reads up to n_pkts from the port scheduler and stores them in the pkts array and returns the number of packets actually read. The pkts array needs to be pre-allocated by the caller with at least n_pkts entries. π«Ά pre-allocate bestie, it's not gonna do it for you
Parameters
portβ Handle to port scheduler instancepktsβ Pre-allocated packet descriptor array where the packets dequeued from the port scheduler should be storedn_pktsβ Number of packets to dequeue from the port scheduler
Returns
Number of packets successfully dequeued and placed in the pkts array
int rte_sched_subport_tc_ov_config (struct rte_sched_port * port, uint32_t subport_id, bool tc_ov_enable)
Hierarchical scheduler subport traffic class oversubscription enable/disable. This function should be called at the time of subport initialization. β° timing matters, do it at init time, periodt.
Parameters
portβ Handle to port scheduler instancesubport_idβ Subport IDtc_ov_enableβ Boolean flag to enable/disable TC OV
Returns
0 upon success, error code otherwise
π AUTHOR π
Generated automatically by Doxygen for DPDK from the source code. π€ yes the robot wrote it, and the robot ate, honestly.
and that's a wrap bestie!! π this whole page lives in DPDK, Version 25.11.3, and it's the manual page for rte_sched.h(3) β go build something iconic with it, i'm obsessed, bye π
β¨π¦
π¦ 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