DPDK 26.11.0-rc1
rte_red.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
3 */
4
5#ifndef __RTE_RED_H_INCLUDED__
6#define __RTE_RED_H_INCLUDED__
7
13#include <stdint.h>
14#include <limits.h>
15#include <rte_debug.h>
16#include <rte_cycles.h>
18#include <rte_random.h>
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#define RTE_RED_SCALING 10
25#define RTE_RED_S (1 << 22)
26#define RTE_RED_MAX_TH_MAX 1023
27#define RTE_RED_WQ_LOG2_MIN 1
28#define RTE_RED_WQ_LOG2_MAX 12
29#define RTE_RED_MAXP_INV_MIN 1
30#define RTE_RED_MAXP_INV_MAX 255
31#define RTE_RED_2POW16 (1<<16)
32#define RTE_RED_INT16_NBITS (sizeof(uint16_t) * CHAR_BIT)
33#define RTE_RED_WQ_LOG2_NUM (RTE_RED_WQ_LOG2_MAX - RTE_RED_WQ_LOG2_MIN + 1)
34
38extern uint16_t rte_red_log2_1_minus_Wq[RTE_RED_WQ_LOG2_NUM];
39extern uint16_t rte_red_pow2_frac_inv[16];
40
45 uint16_t min_th;
46 uint16_t max_th;
47 uint16_t maxp_inv;
48 uint16_t wq_log2;
49};
50
55 uint32_t min_th;
56 uint32_t max_th;
57 uint32_t pa_const;
58 uint8_t maxp_inv;
59 uint8_t wq_log2;
60};
61
65struct rte_red {
66 uint32_t avg;
67 uint32_t count;
68 uint64_t q_time;
69};
70
80int
82
97int
99 const uint16_t wq_log2,
100 const uint16_t min_th,
101 const uint16_t max_th,
102 const uint16_t maxp_inv);
103
114static inline uint16_t
115__rte_red_calc_qempty_factor(uint8_t wq_log2, uint16_t m)
116{
117 uint32_t n = 0;
118 uint32_t f = 0;
119
141
154 f = (n >> 6) & 0xf;
155 n >>= 10;
156
157 if (n < RTE_RED_SCALING) {
158 /* When n == 0, no rounding or shifting needed.
159 * For n > 0, add 2^(n-1) for rounding before right shift.
160 * This avoids UB from (1 << -1) when n == 0.
161 */
162 if (n == 0)
163 return (uint16_t) rte_red_pow2_frac_inv[f];
164 return (uint16_t) ((rte_red_pow2_frac_inv[f] + (1 << (n - 1))) >> n);
165 }
166
167 return 0;
168}
169
184static inline int
186 struct rte_red *red,
187 const uint64_t time)
188{
189 uint64_t time_diff = 0, m = 0;
190
191 RTE_ASSERT(red_cfg != NULL);
192 RTE_ASSERT(red != NULL);
193
194 red->count ++;
195
200 time_diff = time - red->q_time;
201
208 m = time_diff / RTE_RED_S;
209
213 if (m >= RTE_RED_2POW16) {
214 red->avg = 0;
215 } else {
216 red->avg = (red->avg >> RTE_RED_SCALING) * __rte_red_calc_qempty_factor(red_cfg->wq_log2, (uint16_t) m);
217 }
218
219 return 0;
220}
221
262static inline int
263__rte_red_drop(const struct rte_red_config *red_cfg, struct rte_red *red)
264{
265 uint32_t pa_num = 0; /* numerator of drop-probability */
266 uint32_t pa_den = 0; /* denominator of drop-probability */
267 uint32_t pa_num_count = 0;
268
269 pa_num = (red->avg - red_cfg->min_th) >> (red_cfg->wq_log2);
270
271 pa_num_count = red->count * pa_num;
272
273 if (red_cfg->pa_const <= pa_num_count)
274 return 1;
275
276 pa_den = red_cfg->pa_const - pa_num_count;
277
278 if (unlikely((rte_rand() % pa_den) < pa_num))
279 return 1;
280
281 /* No drop */
282 return 0;
283}
284
297static inline int
299 struct rte_red *red,
300 const unsigned q)
301{
302 RTE_ASSERT(red_cfg != NULL);
303 RTE_ASSERT(red != NULL);
304
318 /* avg update */
319 red->avg += (q << RTE_RED_SCALING) - (red->avg >> red_cfg->wq_log2);
320
321 /* avg < min_th: do not mark the packet */
322 if (red->avg < red_cfg->min_th) {
323 red->count ++;
324 return 0;
325 }
326
327 /* min_th <= avg < max_th: mark the packet with pa probability */
328 if (red->avg < red_cfg->max_th) {
329 if (!__rte_red_drop(red_cfg, red)) {
330 red->count ++;
331 return 0;
332 }
333
334 red->count = 0;
335 return 2;
336 }
337
338 /* max_th <= avg: always mark the packet */
339 red->count = 0;
340 return 1;
341}
342
359static inline int
360rte_red_enqueue(const struct rte_red_config *red_cfg,
361 struct rte_red *red,
362 const unsigned q,
363 const uint64_t time)
364{
365 RTE_ASSERT(red_cfg != NULL);
366 RTE_ASSERT(red != NULL);
367
368 if (q != 0) {
369 return rte_red_enqueue_nonempty(red_cfg, red, q);
370 } else {
371 return rte_red_enqueue_empty(red_cfg, red, time);
372 }
373}
374
381static inline void
382rte_red_mark_queue_empty(struct rte_red *red, const uint64_t time)
383{
384 red->q_time = time;
385}
386
387#ifdef __cplusplus
388}
389#endif
390
391#endif /* __RTE_RED_H_INCLUDED__ */
#define unlikely(x)
uint64_t rte_rand(void)
static uint16_t __rte_red_calc_qempty_factor(uint8_t wq_log2, uint16_t m)
calculate factor to scale average queue size when queue becomes empty
Definition: rte_red.h:115
#define RTE_RED_WQ_LOG2_MIN
Definition: rte_red.h:27
int rte_red_config_init(struct rte_red_config *red_cfg, const uint16_t wq_log2, const uint16_t min_th, const uint16_t max_th, const uint16_t maxp_inv)
Configures a single RED configuration parameter structure.
static int rte_red_enqueue_nonempty(const struct rte_red_config *red_cfg, struct rte_red *red, const unsigned q)
Decides if new packet should be enqueued or dropped in queue non-empty case.
Definition: rte_red.h:298
static int rte_red_enqueue_empty(const struct rte_red_config *red_cfg, struct rte_red *red, const uint64_t time)
Updates queue average in condition when queue is empty.
Definition: rte_red.h:185
#define RTE_RED_2POW16
Definition: rte_red.h:31
#define RTE_RED_S
Definition: rte_red.h:25
static int rte_red_enqueue(const struct rte_red_config *red_cfg, struct rte_red *red, const unsigned q, const uint64_t time)
Decides if new packet should be enqueued or dropped Updates run time data based on new queue size val...
Definition: rte_red.h:360
#define RTE_RED_SCALING
Definition: rte_red.h:24
static int __rte_red_drop(const struct rte_red_config *red_cfg, struct rte_red *red)
make a decision to drop or enqueue a packet based on mark probability criteria
Definition: rte_red.h:263
static void rte_red_mark_queue_empty(struct rte_red *red, const uint64_t time)
Callback to records time that queue became empty.
Definition: rte_red.h:382
uint16_t rte_red_log2_1_minus_Wq[RTE_RED_WQ_LOG2_NUM]
int rte_red_rt_data_init(struct rte_red *red)
Initialises run-time data.
uint32_t pa_const
Definition: rte_red.h:57
uint8_t wq_log2
Definition: rte_red.h:59
uint8_t maxp_inv
Definition: rte_red.h:58
uint32_t min_th
Definition: rte_red.h:55
uint32_t max_th
Definition: rte_red.h:56
uint16_t min_th
Definition: rte_red.h:45
uint16_t wq_log2
Definition: rte_red.h:48
uint16_t maxp_inv
Definition: rte_red.h:47
uint16_t max_th
Definition: rte_red.h:46
uint64_t q_time
Definition: rte_red.h:68
uint32_t count
Definition: rte_red.h:67
uint32_t avg
Definition: rte_red.h:66