DPDK  2.2.0
rte_meter.h
Go to the documentation of this file.
1 /*-
2  * BSD LICENSE
3  *
4  * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of Intel Corporation nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef __INCLUDE_RTE_METER_H__
35 #define __INCLUDE_RTE_METER_H__
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
51 #include <stdint.h>
52 
53 /*
54  * Application Programmer's Interface (API)
55  *
56  ***/
57 
64 };
65 
70  uint64_t cir;
71  uint64_t cbs;
72  uint64_t ebs;
73 };
74 
79  uint64_t cir;
80  uint64_t pir;
81  uint64_t cbs;
82  uint64_t pbs;
83 };
84 
86 struct rte_meter_srtcm;
87 
89 struct rte_meter_trtcm;
90 
101 int
102 rte_meter_srtcm_config(struct rte_meter_srtcm *m,
103  struct rte_meter_srtcm_params *params);
104 
115 int
116 rte_meter_trtcm_config(struct rte_meter_trtcm *m,
117  struct rte_meter_trtcm_params *params);
118 
131 static inline enum rte_meter_color
132 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
133  uint64_t time,
134  uint32_t pkt_len);
135 
150 static inline enum rte_meter_color
151 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
152  uint64_t time,
153  uint32_t pkt_len,
154  enum rte_meter_color pkt_color);
155 
168 static inline enum rte_meter_color
169 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
170  uint64_t time,
171  uint32_t pkt_len);
172 
187 static inline enum rte_meter_color
188 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
189  uint64_t time,
190  uint32_t pkt_len,
191  enum rte_meter_color pkt_color);
192 
193 /*
194  * Inline implementation of run-time methods
195  *
196  ***/
197 
198 /* Internal data structure storing the srTCM run-time context per metered traffic flow. */
199 struct rte_meter_srtcm {
200  uint64_t time; /* Time of latest update of C and E token buckets */
201  uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
202  uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
203  uint64_t cbs; /* Upper limit for C token bucket */
204  uint64_t ebs; /* Upper limit for E token bucket */
205  uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
206  uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
207 };
208 
209 /* Internal data structure storing the trTCM run-time context per metered traffic flow. */
210 struct rte_meter_trtcm {
211  uint64_t time_tc; /* Time of latest update of C token bucket */
212  uint64_t time_tp; /* Time of latest update of E token bucket */
213  uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
214  uint64_t tp; /* Number of bytes currently available in the peak (P) token bucket */
215  uint64_t cbs; /* Upper limit for C token bucket */
216  uint64_t pbs; /* Upper limit for P token bucket */
217  uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
218  uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
219  uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
220  uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
221 };
222 
223 static inline enum rte_meter_color
224 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
225  uint64_t time,
226  uint32_t pkt_len)
227 {
228  uint64_t time_diff, n_periods, tc, te;
229 
230  /* Bucket update */
231  time_diff = time - m->time;
232  n_periods = time_diff / m->cir_period;
233  m->time += n_periods * m->cir_period;
234 
235  tc = m->tc + n_periods * m->cir_bytes_per_period;
236  if (tc > m->cbs)
237  tc = m->cbs;
238 
239  te = m->te + n_periods * m->cir_bytes_per_period;
240  if (te > m->ebs)
241  te = m->ebs;
242 
243  /* Color logic */
244  if (tc >= pkt_len) {
245  m->tc = tc - pkt_len;
246  m->te = te;
247  return e_RTE_METER_GREEN;
248  }
249 
250  if (te >= pkt_len) {
251  m->tc = tc;
252  m->te = te - pkt_len;
253  return e_RTE_METER_YELLOW;
254  }
255 
256  m->tc = tc;
257  m->te = te;
258  return e_RTE_METER_RED;
259 }
260 
261 static inline enum rte_meter_color
262 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
263  uint64_t time,
264  uint32_t pkt_len,
265  enum rte_meter_color pkt_color)
266 {
267  uint64_t time_diff, n_periods, tc, te;
268 
269  /* Bucket update */
270  time_diff = time - m->time;
271  n_periods = time_diff / m->cir_period;
272  m->time += n_periods * m->cir_period;
273 
274  tc = m->tc + n_periods * m->cir_bytes_per_period;
275  if (tc > m->cbs)
276  tc = m->cbs;
277 
278  te = m->te + n_periods * m->cir_bytes_per_period;
279  if (te > m->ebs)
280  te = m->ebs;
281 
282  /* Color logic */
283  if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
284  m->tc = tc - pkt_len;
285  m->te = te;
286  return e_RTE_METER_GREEN;
287  }
288 
289  if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
290  m->tc = tc;
291  m->te = te - pkt_len;
292  return e_RTE_METER_YELLOW;
293  }
294 
295  m->tc = tc;
296  m->te = te;
297  return e_RTE_METER_RED;
298 }
299 
300 static inline enum rte_meter_color
301 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
302  uint64_t time,
303  uint32_t pkt_len)
304 {
305  uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
306 
307  /* Bucket update */
308  time_diff_tc = time - m->time_tc;
309  time_diff_tp = time - m->time_tp;
310  n_periods_tc = time_diff_tc / m->cir_period;
311  n_periods_tp = time_diff_tp / m->pir_period;
312  m->time_tc += n_periods_tc * m->cir_period;
313  m->time_tp += n_periods_tp * m->pir_period;
314 
315  tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
316  if (tc > m->cbs)
317  tc = m->cbs;
318 
319  tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
320  if (tp > m->pbs)
321  tp = m->pbs;
322 
323  /* Color logic */
324  if (tp < pkt_len) {
325  m->tc = tc;
326  m->tp = tp;
327  return e_RTE_METER_RED;
328  }
329 
330  if (tc < pkt_len) {
331  m->tc = tc;
332  m->tp = tp - pkt_len;
333  return e_RTE_METER_YELLOW;
334  }
335 
336  m->tc = tc - pkt_len;
337  m->tp = tp - pkt_len;
338  return e_RTE_METER_GREEN;
339 }
340 
341 static inline enum rte_meter_color
342 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
343  uint64_t time,
344  uint32_t pkt_len,
345  enum rte_meter_color pkt_color)
346 {
347  uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
348 
349  /* Bucket update */
350  time_diff_tc = time - m->time_tc;
351  time_diff_tp = time - m->time_tp;
352  n_periods_tc = time_diff_tc / m->cir_period;
353  n_periods_tp = time_diff_tp / m->pir_period;
354  m->time_tc += n_periods_tc * m->cir_period;
355  m->time_tp += n_periods_tp * m->pir_period;
356 
357  tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
358  if (tc > m->cbs)
359  tc = m->cbs;
360 
361  tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
362  if (tp > m->pbs)
363  tp = m->pbs;
364 
365  /* Color logic */
366  if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
367  m->tc = tc;
368  m->tp = tp;
369  return e_RTE_METER_RED;
370  }
371 
372  if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
373  m->tc = tc;
374  m->tp = tp - pkt_len;
375  return e_RTE_METER_YELLOW;
376  }
377 
378  m->tc = tc - pkt_len;
379  m->tp = tp - pkt_len;
380  return e_RTE_METER_GREEN;
381 }
382 
383 #ifdef __cplusplus
384 }
385 #endif
386 
387 #endif /* __INCLUDE_RTE_METER_H__ */