1 .. SPDX-License-Identifier: BSD-3-Clause
2 Copyright(c) 2017 Intel Corporation.
9 The Metrics library implements a mechanism by which *producers* can
10 publish numeric information for later querying by *consumers*. In
11 practice producers will typically be other libraries or primary
12 processes, whereas consumers will typically be applications.
14 Metrics themselves are statistics that are not generated by PMDs. Metric
15 information is populated using a push model, where producers update the
16 values contained within the metric library by calling an update function
17 on the relevant metrics. Consumers receive metric information by querying
18 the central metric data, which is held in shared memory.
20 For each metric, a separate value is maintained for each port id, and
21 when publishing metric values the producers need to specify which port is
22 being updated. In addition there is a special id ``RTE_METRICS_GLOBAL``
23 that is intended for global statistics that are not associated with any
24 individual device. Since the metrics library is self-contained, the only
25 restriction on port numbers is that they are less than ``RTE_MAX_ETHPORTS``
26 - there is no requirement for the ports to actually exist.
28 Initializing the library
29 ------------------------
31 Before the library can be used, it has to be initialized by calling
32 ``rte_metrics_init()`` which sets up the metric store in shared memory.
33 This is where producers will publish metric information to, and where
34 consumers will query it from.
38 rte_metrics_init(rte_socket_id());
40 This function **must** be called from a primary process, but otherwise
41 producers and consumers can be in either primary or secondary processes.
46 Metrics must first be *registered*, which is the way producers declare
47 the names of the metrics they will be publishing. Registration can either
48 be done individually, or a set of metrics can be registered as a group.
49 Individual registration is done using ``rte_metrics_reg_name()``:
53 id_1 = rte_metrics_reg_name("mean_bits_in");
54 id_2 = rte_metrics_reg_name("mean_bits_out");
55 id_3 = rte_metrics_reg_name("peak_bits_in");
56 id_4 = rte_metrics_reg_name("peak_bits_out");
58 or alternatively, a set of metrics can be registered together using
59 ``rte_metrics_reg_names()``:
63 const char * const names[] = {
64 "mean_bits_in", "mean_bits_out",
65 "peak_bits_in", "peak_bits_out",
67 id_set = rte_metrics_reg_names(&names[0], 4);
69 If the return value is negative, it means registration failed. Otherwise
70 the return value is the *key* for the metric, which is used when updating
71 values. A table mapping together these key values and the metrics' names
72 can be obtained using ``rte_metrics_get_names()``.
74 Updating metric values
75 ----------------------
77 Once registered, producers can update the metric for a given port using
78 the ``rte_metrics_update_value()`` function. This uses the metric key
79 that is returned when registering the metric, and can also be looked up
80 using ``rte_metrics_get_names()``.
84 rte_metrics_update_value(port_id, id_1, values[0]);
85 rte_metrics_update_value(port_id, id_2, values[1]);
86 rte_metrics_update_value(port_id, id_3, values[2]);
87 rte_metrics_update_value(port_id, id_4, values[3]);
89 if metrics were registered as a single set, they can either be updated
90 individually using ``rte_metrics_update_value()``, or updated together
91 using the ``rte_metrics_update_values()`` function:
95 rte_metrics_update_value(port_id, id_set, values[0]);
96 rte_metrics_update_value(port_id, id_set + 1, values[1]);
97 rte_metrics_update_value(port_id, id_set + 2, values[2]);
98 rte_metrics_update_value(port_id, id_set + 3, values[3]);
100 rte_metrics_update_values(port_id, id_set, values, 4);
102 Note that ``rte_metrics_update_values()`` cannot be used to update
103 metric values from *multiple* *sets*, as there is no guarantee two
104 sets registered one after the other have contiguous id values.
109 Consumers can obtain metric values by querying the metrics library using
110 the ``rte_metrics_get_values()`` function that return an array of
111 ``struct rte_metric_value``. Each entry within this array contains a metric
112 value and its associated key. A key-name mapping can be obtained using the
113 ``rte_metrics_get_names()`` function that returns an array of
114 ``struct rte_metric_name`` that is indexed by the key. The following will
115 print out all metrics for a given port:
119 void print_metrics() {
120 struct rte_metric_value *metrics;
121 struct rte_metric_name *names;
124 len = rte_metrics_get_names(NULL, 0);
126 printf("Cannot get metrics count\n");
130 printf("No metrics to display (none have been registered)\n");
133 metrics = malloc(sizeof(struct rte_metric_value) * len);
134 names = malloc(sizeof(struct rte_metric_name) * len);
135 if (metrics == NULL || names == NULL) {
136 printf("Cannot allocate memory\n");
141 ret = rte_metrics_get_values(port_id, metrics, len);
142 if (ret < 0 || ret > len) {
143 printf("Cannot get metrics values\n");
148 printf("Metrics for port %i:\n", port_id);
149 for (i = 0; i < len; i++)
150 printf(" %s: %"PRIu64"\n",
151 names[metrics[i].key].name, metrics[i].value);
157 Deinitialising the library
158 --------------------------
160 Once the library usage is done, it must be deinitialized by calling
161 ``rte_metrics_deinit()`` which will free the shared memory reserved
162 during initialization.
166 err = rte_metrics_deinit(void);
168 If the return value is negative, it means deinitialization failed.
169 This function **must** be called from a primary process.
171 Bit-rate statistics library
172 ---------------------------
174 The bit-rate library calculates the exponentially-weighted moving
175 average and peak bit-rates for each active port (i.e. network device).
176 These statistics are reported via the metrics library using the
179 - ``mean_bits_in``: Average inbound bit-rate
180 - ``mean_bits_out``: Average outbound bit-rate
181 - ``ewma_bits_in``: Average inbound bit-rate (EWMA smoothed)
182 - ``ewma_bits_out``: Average outbound bit-rate (EWMA smoothed)
183 - ``peak_bits_in``: Peak inbound bit-rate
184 - ``peak_bits_out``: Peak outbound bit-rate
186 Once initialised and clocked at the appropriate frequency, these
187 statistics can be obtained by querying the metrics library.
192 Before the library can be used, it has to be initialised by calling
193 ``rte_stats_bitrate_create()``, which will return a bit-rate
194 calculation object. Since the bit-rate library uses the metrics library
195 to report the calculated statistics, the bit-rate library then needs to
196 register the calculated statistics with the metrics library. This is
197 done using the helper function ``rte_stats_bitrate_reg()``.
201 struct rte_stats_bitrates *bitrate_data;
203 bitrate_data = rte_stats_bitrate_create();
204 if (bitrate_data == NULL)
205 rte_exit(EXIT_FAILURE, "Could not allocate bit-rate data.\n");
206 rte_stats_bitrate_reg(bitrate_data);
208 Controlling the sampling rate
209 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211 Since the library works by periodic sampling but does not use an
212 internal thread, the application has to periodically call
213 ``rte_stats_bitrate_calc()``. The frequency at which this function
214 is called should be the intended sampling rate required for the
215 calculated statistics. For instance if per-second statistics are
216 desired, this function should be called once a second.
220 tics_datum = rte_rdtsc();
221 tics_per_1sec = rte_get_timer_hz();
225 tics_current = rte_rdtsc();
226 if (tics_current - tics_datum >= tics_per_1sec) {
227 /* Periodic bitrate calculation */
228 for (idx_port = 0; idx_port < cnt_ports; idx_port++)
229 rte_stats_bitrate_calc(bitrate_data, idx_port);
230 tics_datum = tics_current;
236 Latency statistics library
237 --------------------------
239 The latency statistics library calculates the latency of packet
240 processing by a DPDK application, reporting the minimum, average,
241 and maximum nano-seconds that packet processing takes, as well as
242 the jitter in processing delay. These statistics are then reported
243 via the metrics library using the following names:
245 - ``min_latency_ns``: Minimum processing latency (nano-seconds)
246 - ``avg_latency_ns``: Average processing latency (nano-seconds)
247 - ``mac_latency_ns``: Maximum processing latency (nano-seconds)
248 - ``jitter_ns``: Variance in processing latency (nano-seconds)
250 Once initialised and clocked at the appropriate frequency, these
251 statistics can be obtained by querying the metrics library.
256 Before the library can be used, it has to be initialised by calling
257 ``rte_latencystats_init()``.
261 lcoreid_t latencystats_lcore_id = -1;
263 int ret = rte_latencystats_init(1, NULL);
265 rte_exit(EXIT_FAILURE, "Could not allocate latency data.\n");
268 Triggering statistic updates
269 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271 The ``rte_latencystats_update()`` function needs to be called
272 periodically so that latency statistics can be updated.
276 if (latencystats_lcore_id == rte_lcore_id())
277 rte_latencystats_update();
282 When finished, ``rte_latencystats_uninit()`` needs to be called to
283 de-initialise the latency library.
287 rte_latencystats_uninit();
289 Timestamp and latency calculation
290 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
292 The Latency stats library marks the time in the timestamp field of the
293 mbuf for the ingress packets and sets the ``PKT_RX_TIMESTAMP`` flag of
294 ``ol_flags`` for the mbuf to indicate the marked time as a valid one.
295 At the egress, the mbufs with the flag set are considered having valid
296 timestamp and are used for the latency calculation.