]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/examples/ip_pipeline/thread_fe.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / dpdk / examples / ip_pipeline / thread_fe.c
1 #include <rte_common.h>
2 #include <rte_ring.h>
3 #include <rte_malloc.h>
4 #include <cmdline_rdline.h>
5 #include <cmdline_parse.h>
6 #include <cmdline_parse_num.h>
7 #include <cmdline_parse_string.h>
8
9 #include "thread.h"
10 #include "thread_fe.h"
11 #include "pipeline.h"
12 #include "pipeline_common_fe.h"
13 #include "app.h"
14
15 static inline void *
16 thread_msg_send_recv(struct app_params *app,
17 uint32_t socket_id, uint32_t core_id, uint32_t ht_id,
18 void *msg,
19 uint32_t timeout_ms)
20 {
21 struct rte_ring *r_req = app_thread_msgq_in_get(app,
22 socket_id, core_id, ht_id);
23 struct rte_ring *r_rsp = app_thread_msgq_out_get(app,
24 socket_id, core_id, ht_id);
25 uint64_t hz = rte_get_tsc_hz();
26 void *msg_recv;
27 uint64_t deadline;
28 int status;
29
30 /* send */
31 do {
32 status = rte_ring_sp_enqueue(r_req, (void *) msg);
33 } while (status == -ENOBUFS);
34
35 /* recv */
36 deadline = (timeout_ms) ?
37 (rte_rdtsc() + ((hz * timeout_ms) / 1000)) :
38 UINT64_MAX;
39
40 do {
41 if (rte_rdtsc() > deadline)
42 return NULL;
43
44 status = rte_ring_sc_dequeue(r_rsp, &msg_recv);
45 } while (status != 0);
46
47 return msg_recv;
48 }
49
50 int
51 app_pipeline_enable(struct app_params *app,
52 uint32_t socket_id,
53 uint32_t core_id,
54 uint32_t hyper_th_id,
55 uint32_t pipeline_id)
56 {
57 struct thread_pipeline_enable_msg_req *req;
58 struct thread_pipeline_enable_msg_rsp *rsp;
59 int thread_id;
60 struct app_pipeline_data *p;
61 struct app_pipeline_params *p_params;
62 struct pipeline_type *p_type;
63 int status;
64
65 if (app == NULL)
66 return -1;
67
68 thread_id = cpu_core_map_get_lcore_id(app->core_map,
69 socket_id,
70 core_id,
71 hyper_th_id);
72
73 if ((thread_id < 0) ||
74 ((app->core_mask & (1LLU << thread_id)) == 0))
75 return -1;
76
77 if (app_pipeline_data(app, pipeline_id) == NULL)
78 return -1;
79
80 p = &app->pipeline_data[pipeline_id];
81 p_params = &app->pipeline_params[pipeline_id];
82 p_type = app_pipeline_type_find(app, p_params->type);
83
84 if (p_type == NULL)
85 return -1;
86
87 if (p->enabled == 1)
88 return -1;
89
90 req = app_msg_alloc(app);
91 if (req == NULL)
92 return -1;
93
94 req->type = THREAD_MSG_REQ_PIPELINE_ENABLE;
95 req->pipeline_id = pipeline_id;
96 req->be = p->be;
97 req->f_run = p_type->be_ops->f_run;
98 req->f_timer = p_type->be_ops->f_timer;
99 req->timer_period = p->timer_period;
100
101 rsp = thread_msg_send_recv(app,
102 socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
103 if (rsp == NULL)
104 return -1;
105
106 status = rsp->status;
107 app_msg_free(app, rsp);
108
109 if (status != 0)
110 return -1;
111
112 p->enabled = 1;
113 return 0;
114 }
115
116 int
117 app_pipeline_disable(struct app_params *app,
118 uint32_t socket_id,
119 uint32_t core_id,
120 uint32_t hyper_th_id,
121 uint32_t pipeline_id)
122 {
123 struct thread_pipeline_disable_msg_req *req;
124 struct thread_pipeline_disable_msg_rsp *rsp;
125 int thread_id;
126 struct app_pipeline_data *p;
127 int status;
128
129 if (app == NULL)
130 return -1;
131
132 thread_id = cpu_core_map_get_lcore_id(app->core_map,
133 socket_id,
134 core_id,
135 hyper_th_id);
136
137 if ((thread_id < 0) ||
138 ((app->core_mask & (1LLU << thread_id)) == 0))
139 return -1;
140
141 if (app_pipeline_data(app, pipeline_id) == NULL)
142 return -1;
143
144 p = &app->pipeline_data[pipeline_id];
145
146 if (p->enabled == 0)
147 return -1;
148
149 req = app_msg_alloc(app);
150 if (req == NULL)
151 return -1;
152
153 req->type = THREAD_MSG_REQ_PIPELINE_DISABLE;
154 req->pipeline_id = pipeline_id;
155
156 rsp = thread_msg_send_recv(app,
157 socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
158
159 if (rsp == NULL)
160 return -1;
161
162 status = rsp->status;
163 app_msg_free(app, rsp);
164
165 if (status != 0)
166 return -1;
167
168 p->enabled = 0;
169 return 0;
170 }
171
172 int
173 app_thread_headroom(struct app_params *app,
174 uint32_t socket_id,
175 uint32_t core_id,
176 uint32_t hyper_th_id)
177 {
178 struct thread_headroom_read_msg_req *req;
179 struct thread_headroom_read_msg_rsp *rsp;
180 int thread_id;
181 int status;
182
183 if (app == NULL)
184 return -1;
185
186 thread_id = cpu_core_map_get_lcore_id(app->core_map,
187 socket_id,
188 core_id,
189 hyper_th_id);
190
191 if ((thread_id < 0) ||
192 ((app->core_mask & (1LLU << thread_id)) == 0))
193 return -1;
194
195 req = app_msg_alloc(app);
196 if (req == NULL)
197 return -1;
198
199 req->type = THREAD_MSG_REQ_HEADROOM_READ;
200
201 rsp = thread_msg_send_recv(app,
202 socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
203
204 if (rsp == NULL)
205 return -1;
206
207 status = rsp->status;
208
209 if (status != 0)
210 return -1;
211
212 printf("%.3f%%\n", rsp->headroom_ratio * 100);
213
214
215 app_msg_free(app, rsp);
216
217 return 0;
218 }
219
220 /*
221 * pipeline enable
222 */
223
224 struct cmd_pipeline_enable_result {
225 cmdline_fixed_string_t t_string;
226 cmdline_fixed_string_t t_id_string;
227 cmdline_fixed_string_t pipeline_string;
228 uint32_t pipeline_id;
229 cmdline_fixed_string_t enable_string;
230 };
231
232 static void
233 cmd_pipeline_enable_parsed(
234 void *parsed_result,
235 __rte_unused struct cmdline *cl,
236 void *data)
237 {
238 struct cmd_pipeline_enable_result *params = parsed_result;
239 struct app_params *app = data;
240 int status;
241 uint32_t core_id, socket_id, hyper_th_id;
242
243 if (parse_pipeline_core(&socket_id,
244 &core_id,
245 &hyper_th_id,
246 params->t_id_string) != 0) {
247 printf("Command failed\n");
248 return;
249 }
250
251 status = app_pipeline_enable(app,
252 socket_id,
253 core_id,
254 hyper_th_id,
255 params->pipeline_id);
256
257 if (status != 0)
258 printf("Command failed\n");
259 }
260
261 static cmdline_parse_token_string_t cmd_pipeline_enable_t_string =
262 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_string, "t");
263
264 static cmdline_parse_token_string_t cmd_pipeline_enable_t_id_string =
265 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_id_string,
266 NULL);
267
268 static cmdline_parse_token_string_t cmd_pipeline_enable_pipeline_string =
269 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_string,
270 "pipeline");
271
272 static cmdline_parse_token_num_t cmd_pipeline_enable_pipeline_id =
273 TOKEN_NUM_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_id,
274 UINT32);
275
276 static cmdline_parse_token_string_t cmd_pipeline_enable_enable_string =
277 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, enable_string,
278 "enable");
279
280 static cmdline_parse_inst_t cmd_pipeline_enable = {
281 .f = cmd_pipeline_enable_parsed,
282 .data = NULL,
283 .help_str = "Enable pipeline on specified core",
284 .tokens = {
285 (void *)&cmd_pipeline_enable_t_string,
286 (void *)&cmd_pipeline_enable_t_id_string,
287 (void *)&cmd_pipeline_enable_pipeline_string,
288 (void *)&cmd_pipeline_enable_pipeline_id,
289 (void *)&cmd_pipeline_enable_enable_string,
290 NULL,
291 },
292 };
293
294 /*
295 * pipeline disable
296 */
297
298 struct cmd_pipeline_disable_result {
299 cmdline_fixed_string_t t_string;
300 cmdline_fixed_string_t t_id_string;
301 cmdline_fixed_string_t pipeline_string;
302 uint32_t pipeline_id;
303 cmdline_fixed_string_t disable_string;
304 };
305
306 static void
307 cmd_pipeline_disable_parsed(
308 void *parsed_result,
309 __rte_unused struct cmdline *cl,
310 void *data)
311 {
312 struct cmd_pipeline_disable_result *params = parsed_result;
313 struct app_params *app = data;
314 int status;
315 uint32_t core_id, socket_id, hyper_th_id;
316
317 if (parse_pipeline_core(&socket_id,
318 &core_id,
319 &hyper_th_id,
320 params->t_id_string) != 0) {
321 printf("Command failed\n");
322 return;
323 }
324
325 status = app_pipeline_disable(app,
326 socket_id,
327 core_id,
328 hyper_th_id,
329 params->pipeline_id);
330
331 if (status != 0)
332 printf("Command failed\n");
333 }
334
335 static cmdline_parse_token_string_t cmd_pipeline_disable_t_string =
336 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_string, "t");
337
338 static cmdline_parse_token_string_t cmd_pipeline_disable_t_id_string =
339 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_id_string,
340 NULL);
341
342 static cmdline_parse_token_string_t cmd_pipeline_disable_pipeline_string =
343 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result,
344 pipeline_string, "pipeline");
345
346 static cmdline_parse_token_num_t cmd_pipeline_disable_pipeline_id =
347 TOKEN_NUM_INITIALIZER(struct cmd_pipeline_disable_result, pipeline_id,
348 UINT32);
349
350 static cmdline_parse_token_string_t cmd_pipeline_disable_disable_string =
351 TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, disable_string,
352 "disable");
353
354 static cmdline_parse_inst_t cmd_pipeline_disable = {
355 .f = cmd_pipeline_disable_parsed,
356 .data = NULL,
357 .help_str = "Disable pipeline on specified core",
358 .tokens = {
359 (void *)&cmd_pipeline_disable_t_string,
360 (void *)&cmd_pipeline_disable_t_id_string,
361 (void *)&cmd_pipeline_disable_pipeline_string,
362 (void *)&cmd_pipeline_disable_pipeline_id,
363 (void *)&cmd_pipeline_disable_disable_string,
364 NULL,
365 },
366 };
367
368
369 /*
370 * thread headroom
371 */
372
373 struct cmd_thread_headroom_result {
374 cmdline_fixed_string_t t_string;
375 cmdline_fixed_string_t t_id_string;
376 cmdline_fixed_string_t headroom_string;
377 };
378
379 static void
380 cmd_thread_headroom_parsed(
381 void *parsed_result,
382 __rte_unused struct cmdline *cl,
383 void *data)
384 {
385 struct cmd_thread_headroom_result *params = parsed_result;
386 struct app_params *app = data;
387 int status;
388 uint32_t core_id, socket_id, hyper_th_id;
389
390 if (parse_pipeline_core(&socket_id,
391 &core_id,
392 &hyper_th_id,
393 params->t_id_string) != 0) {
394 printf("Command failed\n");
395 return;
396 }
397
398 status = app_thread_headroom(app,
399 socket_id,
400 core_id,
401 hyper_th_id);
402
403 if (status != 0)
404 printf("Command failed\n");
405 }
406
407 static cmdline_parse_token_string_t cmd_thread_headroom_t_string =
408 TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
409 t_string, "t");
410
411 static cmdline_parse_token_string_t cmd_thread_headroom_t_id_string =
412 TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
413 t_id_string, NULL);
414
415 static cmdline_parse_token_string_t cmd_thread_headroom_headroom_string =
416 TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
417 headroom_string, "headroom");
418
419 static cmdline_parse_inst_t cmd_thread_headroom = {
420 .f = cmd_thread_headroom_parsed,
421 .data = NULL,
422 .help_str = "Display thread headroom",
423 .tokens = {
424 (void *)&cmd_thread_headroom_t_string,
425 (void *)&cmd_thread_headroom_t_id_string,
426 (void *)&cmd_thread_headroom_headroom_string,
427 NULL,
428 },
429 };
430
431
432 static cmdline_parse_ctx_t thread_cmds[] = {
433 (cmdline_parse_inst_t *) &cmd_pipeline_enable,
434 (cmdline_parse_inst_t *) &cmd_pipeline_disable,
435 (cmdline_parse_inst_t *) &cmd_thread_headroom,
436 NULL,
437 };
438
439 int
440 app_pipeline_thread_cmd_push(struct app_params *app)
441 {
442 uint32_t n_cmds, i;
443
444 /* Check for available slots in the application commands array */
445 n_cmds = RTE_DIM(thread_cmds) - 1;
446 if (n_cmds > APP_MAX_CMDS - app->n_cmds)
447 return -ENOMEM;
448
449 /* Push thread commands into the application */
450 memcpy(&app->cmds[app->n_cmds], thread_cmds,
451 n_cmds * sizeof(cmdline_parse_ctx_t));
452
453 for (i = 0; i < n_cmds; i++)
454 app->cmds[app->n_cmds + i]->data = app;
455
456 app->n_cmds += n_cmds;
457 app->cmds[app->n_cmds] = NULL;
458
459 return 0;
460 }