DPDK  22.03.0
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 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
19 #include <stdint.h>
20 #include <limits.h>
21 #include <rte_debug.h>
22 #include <rte_cycles.h>
23 #include <rte_branch_prediction.h>
24 
25 #define RTE_RED_SCALING 10
26 #define RTE_RED_S (1 << 22)
27 #define RTE_RED_MAX_TH_MAX 1023
28 #define RTE_RED_WQ_LOG2_MIN 1
29 #define RTE_RED_WQ_LOG2_MAX 12
30 #define RTE_RED_MAXP_INV_MIN 1
31 #define RTE_RED_MAXP_INV_MAX 255
32 #define RTE_RED_2POW16 (1<<16)
33 #define RTE_RED_INT16_NBITS (sizeof(uint16_t) * CHAR_BIT)
34 #define RTE_RED_WQ_LOG2_NUM (RTE_RED_WQ_LOG2_MAX - RTE_RED_WQ_LOG2_MIN + 1)
35 
40 extern uint32_t rte_red_rand_val;
41 extern uint32_t rte_red_rand_seed;
42 extern uint16_t rte_red_log2_1_minus_Wq[RTE_RED_WQ_LOG2_NUM];
43 extern uint16_t rte_red_pow2_frac_inv[16];
44 
50  uint16_t min_th;
51  uint16_t max_th;
52  uint16_t maxp_inv;
53  uint16_t wq_log2;
54 };
55 
60  uint32_t min_th;
61  uint32_t max_th;
62  uint32_t pa_const;
63  uint8_t maxp_inv;
64  uint8_t wq_log2;
65 };
66 
70 struct rte_red {
71  uint32_t avg;
72  uint32_t count;
73  uint64_t q_time;
74 };
75 
85 int
86 rte_red_rt_data_init(struct rte_red *red);
87 
102 int
103 rte_red_config_init(struct rte_red_config *red_cfg,
104  const uint16_t wq_log2,
105  const uint16_t min_th,
106  const uint16_t max_th,
107  const uint16_t maxp_inv);
108 
119 static inline uint32_t
121 {
122  rte_red_rand_seed = (214013 * rte_red_rand_seed) + 2531011;
123  return rte_red_rand_seed >> 10;
124 }
125 
136 static inline uint16_t
138 {
139  uint32_t n = 0;
140  uint32_t f = 0;
141 
162  n = m * rte_red_log2_1_minus_Wq[wq_log2 - RTE_RED_WQ_LOG2_MIN];
163 
176  f = (n >> 6) & 0xf;
177  n >>= 10;
178 
179  if (n < RTE_RED_SCALING)
180  return (uint16_t) ((rte_red_pow2_frac_inv[f] + (1 << (n - 1))) >> n);
181 
182  return 0;
183 }
184 
199 static inline int
200 rte_red_enqueue_empty(const struct rte_red_config *red_cfg,
201  struct rte_red *red,
202  const uint64_t time)
203 {
204  uint64_t time_diff = 0, m = 0;
205 
206  RTE_ASSERT(red_cfg != NULL);
207  RTE_ASSERT(red != NULL);
208 
209  red->count ++;
210 
215  time_diff = time - red->q_time;
216 
223  m = time_diff / RTE_RED_S;
224 
228  if (m >= RTE_RED_2POW16) {
229  red->avg = 0;
230  } else {
231  red->avg = (red->avg >> RTE_RED_SCALING) * __rte_red_calc_qempty_factor(red_cfg->wq_log2, (uint16_t) m);
232  }
233 
234  return 0;
235 }
236 
277 static inline int
278 __rte_red_drop(const struct rte_red_config *red_cfg, struct rte_red *red)
279 {
280  uint32_t pa_num = 0; /* numerator of drop-probability */
281  uint32_t pa_den = 0; /* denominator of drop-probability */
282  uint32_t pa_num_count = 0;
283 
284  pa_num = (red->avg - red_cfg->min_th) >> (red_cfg->wq_log2);
285 
286  pa_num_count = red->count * pa_num;
287 
288  if (red_cfg->pa_const <= pa_num_count)
289  return 1;
290 
291  pa_den = red_cfg->pa_const - pa_num_count;
292 
293  /* If drop, generate and save random number to be used next time */
294  if (unlikely((rte_red_rand_val % pa_den) < pa_num)) {
295  rte_red_rand_val = rte_fast_rand();
296 
297  return 1;
298  }
299 
300  /* No drop */
301  return 0;
302 }
303 
316 static inline int
318  struct rte_red *red,
319  const unsigned q)
320 {
321  RTE_ASSERT(red_cfg != NULL);
322  RTE_ASSERT(red != NULL);
323 
337  /* avg update */
338  red->avg += (q << RTE_RED_SCALING) - (red->avg >> red_cfg->wq_log2);
339 
340  /* avg < min_th: do not mark the packet */
341  if (red->avg < red_cfg->min_th) {
342  red->count ++;
343  return 0;
344  }
345 
346  /* min_th <= avg < max_th: mark the packet with pa probability */
347  if (red->avg < red_cfg->max_th) {
348  if (!__rte_red_drop(red_cfg, red)) {
349  red->count ++;
350  return 0;
351  }
352 
353  red->count = 0;
354  return 2;
355  }
356 
357  /* max_th <= avg: always mark the packet */
358  red->count = 0;
359  return 1;
360 }
361 
378 static inline int
379 rte_red_enqueue(const struct rte_red_config *red_cfg,
380  struct rte_red *red,
381  const unsigned q,
382  const uint64_t time)
383 {
384  RTE_ASSERT(red_cfg != NULL);
385  RTE_ASSERT(red != NULL);
386 
387  if (q != 0) {
388  return rte_red_enqueue_nonempty(red_cfg, red, q);
389  } else {
390  return rte_red_enqueue_empty(red_cfg, red, time);
391  }
392 }
393 
400 static inline void
401 rte_red_mark_queue_empty(struct rte_red *red, const uint64_t time)
402 {
403  red->q_time = time;
404 }
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 
410 #endif /* __RTE_RED_H_INCLUDED__ */
#define RTE_RED_SCALING
Definition: rte_red.h:25
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:401
static uint32_t rte_fast_rand(void)
Generate random number for RED.
Definition: rte_red.h:120
uint32_t avg
Definition: rte_red.h:71
uint16_t max_th
Definition: rte_red.h:51
#define RTE_RED_2POW16
Definition: rte_red.h:32
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:278
uint32_t max_th
Definition: rte_red.h:61
uint32_t rte_red_rand_val
#define RTE_RED_S
Definition: rte_red.h:26
uint32_t pa_const
Definition: rte_red.h:62
uint16_t min_th
Definition: rte_red.h:50
#define unlikely(x)
uint16_t wq_log2
Definition: rte_red.h:53
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_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:200
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:137
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:317
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:379
int rte_red_rt_data_init(struct rte_red *red)
Initialises run-time data.
uint32_t min_th
Definition: rte_red.h:60
uint16_t maxp_inv
Definition: rte_red.h:52
uint32_t count
Definition: rte_red.h:72
uint64_t q_time
Definition: rte_red.h:73
#define RTE_RED_WQ_LOG2_MIN
Definition: rte_red.h:28
uint8_t maxp_inv
Definition: rte_red.h:63
uint8_t wq_log2
Definition: rte_red.h:64