1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
5 #include <rte_common.h>
6 #include <rte_ethdev.h>
7 #include <rte_malloc.h>
8 #include <rte_metrics.h>
9 #include <rte_bitrate.h>
11 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
14 * Persistent bit-rate data.
17 struct rte_stats_bitrate
{
28 struct rte_stats_bitrates
{
29 struct rte_stats_bitrate port_stats
[RTE_MAX_ETHPORTS
];
30 uint16_t id_stats_set
;
33 struct rte_stats_bitrates
*
34 rte_stats_bitrate_create(void)
36 return rte_zmalloc(NULL
, sizeof(struct rte_stats_bitrates
),
41 rte_stats_bitrate_reg(struct rte_stats_bitrates
*bitrate_data
)
43 const char * const names
[] = {
44 "ewma_bits_in", "ewma_bits_out",
45 "mean_bits_in", "mean_bits_out",
46 "peak_bits_in", "peak_bits_out",
50 if (bitrate_data
== NULL
)
53 return_value
= rte_metrics_reg_names(&names
[0], ARRAY_SIZE(names
));
54 if (return_value
>= 0)
55 bitrate_data
->id_stats_set
= return_value
;
60 rte_stats_bitrate_calc(struct rte_stats_bitrates
*bitrate_data
,
63 struct rte_stats_bitrate
*port_data
;
64 struct rte_eth_stats eth_stats
;
68 const int64_t alpha_percent
= 20;
72 if (bitrate_data
== NULL
)
75 ret_code
= rte_eth_stats_get(port_id
, ð_stats
);
79 port_data
= &bitrate_data
->port_stats
[port_id
];
81 /* Incoming bitrate. This is an iteratively calculated EWMA
82 * (Exponentially Weighted Moving Average) that uses a
83 * weighting factor of alpha_percent. An unsmoothed mean
84 * for just the current time delta is also calculated for the
85 * benefit of people who don't understand signal processing.
87 cnt_bits
= (eth_stats
.ibytes
- port_data
->last_ibytes
) << 3;
88 port_data
->last_ibytes
= eth_stats
.ibytes
;
89 if (cnt_bits
> port_data
->peak_ibits
)
90 port_data
->peak_ibits
= cnt_bits
;
92 delta
-= port_data
->ewma_ibits
;
93 /* The +-50 fixes integer rounding during division */
95 delta
= (delta
* alpha_percent
+ 50) / 100;
97 delta
= (delta
* alpha_percent
- 50) / 100;
98 port_data
->ewma_ibits
+= delta
;
99 /* Integer roundoff prevents EWMA between 0 and (100/alpha_percent)
100 * ever reaching zero in no-traffic conditions
102 if (cnt_bits
== 0 && delta
== 0)
103 port_data
->ewma_ibits
= 0;
104 port_data
->mean_ibits
= cnt_bits
;
106 /* Outgoing bitrate (also EWMA) */
107 cnt_bits
= (eth_stats
.obytes
- port_data
->last_obytes
) << 3;
108 port_data
->last_obytes
= eth_stats
.obytes
;
109 if (cnt_bits
> port_data
->peak_obits
)
110 port_data
->peak_obits
= cnt_bits
;
112 delta
-= port_data
->ewma_obits
;
114 delta
= (delta
* alpha_percent
+ 50) / 100;
116 delta
= (delta
* alpha_percent
- 50) / 100;
117 port_data
->ewma_obits
+= delta
;
118 if (cnt_bits
== 0 && delta
== 0)
119 port_data
->ewma_obits
= 0;
120 port_data
->mean_obits
= cnt_bits
;
122 values
[0] = port_data
->ewma_ibits
;
123 values
[1] = port_data
->ewma_obits
;
124 values
[2] = port_data
->mean_ibits
;
125 values
[3] = port_data
->mean_obits
;
126 values
[4] = port_data
->peak_ibits
;
127 values
[5] = port_data
->peak_obits
;
128 ret
= rte_metrics_update_values(port_id
, bitrate_data
->id_stats_set
,
129 values
, ARRAY_SIZE(values
));