]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/event/dsw/dsw_xstats.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / dpdk / drivers / event / dsw / dsw_xstats.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Ericsson AB
3 */
4
5 #include "dsw_evdev.h"
6
7 #include <stdbool.h>
8 #include <string.h>
9
10 #include <rte_debug.h>
11
12 /* The high bits in the xstats id is used to store an additional
13 * parameter (beyond the queue or port id already in the xstats
14 * interface).
15 */
16 #define DSW_XSTATS_ID_PARAM_BITS (8)
17 #define DSW_XSTATS_ID_STAT_BITS \
18 (sizeof(unsigned int)*CHAR_BIT - DSW_XSTATS_ID_PARAM_BITS)
19 #define DSW_XSTATS_ID_STAT_MASK ((1 << DSW_XSTATS_ID_STAT_BITS) - 1)
20
21 #define DSW_XSTATS_ID_GET_PARAM(id) \
22 ((id)>>DSW_XSTATS_ID_STAT_BITS)
23
24 #define DSW_XSTATS_ID_GET_STAT(id) \
25 ((id) & DSW_XSTATS_ID_STAT_MASK)
26
27 #define DSW_XSTATS_ID_CREATE(id, param_value) \
28 (((param_value) << DSW_XSTATS_ID_STAT_BITS) | id)
29
30 typedef
31 uint64_t (*dsw_xstats_dev_get_value_fn)(struct dsw_evdev *dsw);
32
33 struct dsw_xstat_dev {
34 const char *name;
35 dsw_xstats_dev_get_value_fn get_value_fn;
36 };
37
38 typedef
39 uint64_t (*dsw_xstats_port_get_value_fn)(struct dsw_evdev *dsw,
40 uint8_t port_id, uint8_t queue_id);
41
42 struct dsw_xstats_port {
43 const char *name_fmt;
44 dsw_xstats_port_get_value_fn get_value_fn;
45 bool per_queue;
46 };
47
48 static uint64_t
49 dsw_xstats_dev_credits_on_loan(struct dsw_evdev *dsw)
50 {
51 return rte_atomic32_read(&dsw->credits_on_loan);
52 }
53
54 static struct dsw_xstat_dev dsw_dev_xstats[] = {
55 { "dev_credits_on_loan", dsw_xstats_dev_credits_on_loan }
56 };
57
58 #define DSW_GEN_PORT_ACCESS_FN(_variable) \
59 static uint64_t \
60 dsw_xstats_port_get_ ## _variable(struct dsw_evdev *dsw, \
61 uint8_t port_id, \
62 uint8_t queue_id __rte_unused) \
63 { \
64 return dsw->ports[port_id]._variable; \
65 }
66
67 DSW_GEN_PORT_ACCESS_FN(new_enqueued)
68 DSW_GEN_PORT_ACCESS_FN(forward_enqueued)
69 DSW_GEN_PORT_ACCESS_FN(release_enqueued)
70
71 static uint64_t
72 dsw_xstats_port_get_queue_enqueued(struct dsw_evdev *dsw, uint8_t port_id,
73 uint8_t queue_id)
74 {
75 return dsw->ports[port_id].queue_enqueued[queue_id];
76 }
77
78 DSW_GEN_PORT_ACCESS_FN(dequeued)
79
80 static uint64_t
81 dsw_xstats_port_get_queue_dequeued(struct dsw_evdev *dsw, uint8_t port_id,
82 uint8_t queue_id)
83 {
84 return dsw->ports[port_id].queue_dequeued[queue_id];
85 }
86
87 DSW_GEN_PORT_ACCESS_FN(migrations)
88
89 static uint64_t
90 dsw_xstats_port_get_migration_latency(struct dsw_evdev *dsw, uint8_t port_id,
91 uint8_t queue_id __rte_unused)
92 {
93 uint64_t total_latency = dsw->ports[port_id].migration_latency;
94 uint64_t num_migrations = dsw->ports[port_id].migrations;
95
96 return num_migrations > 0 ? total_latency / num_migrations : 0;
97 }
98
99 static uint64_t
100 dsw_xstats_port_get_event_proc_latency(struct dsw_evdev *dsw, uint8_t port_id,
101 uint8_t queue_id __rte_unused)
102 {
103 uint64_t total_busy_cycles =
104 dsw->ports[port_id].total_busy_cycles;
105 uint64_t dequeued =
106 dsw->ports[port_id].dequeued;
107
108 return dequeued > 0 ? total_busy_cycles / dequeued : 0;
109 }
110
111 DSW_GEN_PORT_ACCESS_FN(inflight_credits)
112
113 static uint64_t
114 dsw_xstats_port_get_load(struct dsw_evdev *dsw, uint8_t port_id,
115 uint8_t queue_id __rte_unused)
116 {
117 int16_t load;
118
119 load = rte_atomic16_read(&dsw->ports[port_id].load);
120
121 return DSW_LOAD_TO_PERCENT(load);
122 }
123
124 DSW_GEN_PORT_ACCESS_FN(last_bg)
125
126 static struct dsw_xstats_port dsw_port_xstats[] = {
127 { "port_%u_new_enqueued", dsw_xstats_port_get_new_enqueued,
128 false },
129 { "port_%u_forward_enqueued", dsw_xstats_port_get_forward_enqueued,
130 false },
131 { "port_%u_release_enqueued", dsw_xstats_port_get_release_enqueued,
132 false },
133 { "port_%u_queue_%u_enqueued", dsw_xstats_port_get_queue_enqueued,
134 true },
135 { "port_%u_dequeued", dsw_xstats_port_get_dequeued,
136 false },
137 { "port_%u_queue_%u_dequeued", dsw_xstats_port_get_queue_dequeued,
138 true },
139 { "port_%u_migrations", dsw_xstats_port_get_migrations,
140 false },
141 { "port_%u_migration_latency", dsw_xstats_port_get_migration_latency,
142 false },
143 { "port_%u_event_proc_latency", dsw_xstats_port_get_event_proc_latency,
144 false },
145 { "port_%u_inflight_credits", dsw_xstats_port_get_inflight_credits,
146 false },
147 { "port_%u_load", dsw_xstats_port_get_load,
148 false },
149 { "port_%u_last_bg", dsw_xstats_port_get_last_bg,
150 false }
151 };
152
153 static int
154 dsw_xstats_dev_get_names(struct rte_event_dev_xstats_name *xstats_names,
155 unsigned int *ids, unsigned int size)
156 {
157 unsigned int i;
158
159 for (i = 0; i < RTE_DIM(dsw_dev_xstats) && i < size; i++) {
160 ids[i] = i;
161 strcpy(xstats_names[i].name, dsw_dev_xstats[i].name);
162 }
163
164 return i;
165 }
166
167 static int
168 dsw_xstats_port_get_names(struct dsw_evdev *dsw, uint8_t port_id,
169 struct rte_event_dev_xstats_name *xstats_names,
170 unsigned int *ids, unsigned int size)
171 {
172 uint8_t queue_id = 0;
173 unsigned int id_idx;
174 unsigned int stat_idx;
175
176 for (id_idx = 0, stat_idx = 0;
177 id_idx < size && stat_idx < RTE_DIM(dsw_port_xstats);
178 id_idx++) {
179 struct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];
180
181 if (xstat->per_queue) {
182 ids[id_idx] = DSW_XSTATS_ID_CREATE(stat_idx, queue_id);
183 snprintf(xstats_names[id_idx].name,
184 RTE_EVENT_DEV_XSTATS_NAME_SIZE,
185 dsw_port_xstats[stat_idx].name_fmt, port_id,
186 queue_id);
187 queue_id++;
188 } else {
189 ids[id_idx] = stat_idx;
190 snprintf(xstats_names[id_idx].name,
191 RTE_EVENT_DEV_XSTATS_NAME_SIZE,
192 dsw_port_xstats[stat_idx].name_fmt, port_id);
193 }
194
195 if (!(xstat->per_queue && queue_id < dsw->num_queues)) {
196 stat_idx++;
197 queue_id = 0;
198 }
199 }
200 return id_idx;
201 }
202
203 int
204 dsw_xstats_get_names(const struct rte_eventdev *dev,
205 enum rte_event_dev_xstats_mode mode,
206 uint8_t queue_port_id,
207 struct rte_event_dev_xstats_name *xstats_names,
208 unsigned int *ids, unsigned int size)
209 {
210 struct dsw_evdev *dsw = dsw_pmd_priv(dev);
211
212 switch (mode) {
213 case RTE_EVENT_DEV_XSTATS_DEVICE:
214 return dsw_xstats_dev_get_names(xstats_names, ids, size);
215 case RTE_EVENT_DEV_XSTATS_PORT:
216 return dsw_xstats_port_get_names(dsw, queue_port_id,
217 xstats_names, ids, size);
218 case RTE_EVENT_DEV_XSTATS_QUEUE:
219 return 0;
220 default:
221 RTE_ASSERT(false);
222 return -1;
223 }
224 }
225
226 static int
227 dsw_xstats_dev_get(const struct rte_eventdev *dev,
228 const unsigned int ids[], uint64_t values[], unsigned int n)
229 {
230 struct dsw_evdev *dsw = dsw_pmd_priv(dev);
231 unsigned int i;
232
233 for (i = 0; i < n; i++) {
234 unsigned int id = ids[i];
235 struct dsw_xstat_dev *xstat = &dsw_dev_xstats[id];
236 values[i] = xstat->get_value_fn(dsw);
237 }
238 return n;
239 }
240
241 static int
242 dsw_xstats_port_get(const struct rte_eventdev *dev, uint8_t port_id,
243 const unsigned int ids[], uint64_t values[], unsigned int n)
244 {
245 struct dsw_evdev *dsw = dsw_pmd_priv(dev);
246 unsigned int i;
247
248 for (i = 0; i < n; i++) {
249 unsigned int id = ids[i];
250 unsigned int stat_idx = DSW_XSTATS_ID_GET_STAT(id);
251 struct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];
252 uint8_t queue_id = 0;
253
254 if (xstat->per_queue)
255 queue_id = DSW_XSTATS_ID_GET_PARAM(id);
256
257 values[i] = xstat->get_value_fn(dsw, port_id, queue_id);
258 }
259 return n;
260 }
261
262 int
263 dsw_xstats_get(const struct rte_eventdev *dev,
264 enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,
265 const unsigned int ids[], uint64_t values[], unsigned int n)
266 {
267 switch (mode) {
268 case RTE_EVENT_DEV_XSTATS_DEVICE:
269 return dsw_xstats_dev_get(dev, ids, values, n);
270 case RTE_EVENT_DEV_XSTATS_PORT:
271 return dsw_xstats_port_get(dev, queue_port_id, ids, values, n);
272 case RTE_EVENT_DEV_XSTATS_QUEUE:
273 return 0;
274 default:
275 RTE_ASSERT(false);
276 return -1;
277 }
278 return 0;
279 }
280
281 uint64_t dsw_xstats_get_by_name(const struct rte_eventdev *dev,
282 const char *name, unsigned int *id)
283 {
284 RTE_SET_USED(dev);
285 RTE_SET_USED(name);
286 RTE_SET_USED(id);
287 return 0;
288 }