event/opdl: add event queue config get/set
[dpdk.git] / drivers / event / opdl / opdl_evdev.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright(c) 2010-2014 Intel Corporation
4  */
5
6 #include <inttypes.h>
7 #include <string.h>
8
9 #include <rte_bus_vdev.h>
10 #include <rte_lcore.h>
11 #include <rte_memzone.h>
12 #include <rte_kvargs.h>
13 #include <rte_errno.h>
14 #include <rte_cycles.h>
15
16 #include "opdl_evdev.h"
17 #include "opdl_ring.h"
18 #include "opdl_log.h"
19
20 #define EVENTDEV_NAME_OPDL_PMD event_opdl
21 #define NUMA_NODE_ARG "numa_node"
22 #define DO_VALIDATION_ARG "do_validation"
23 #define DO_TEST_ARG "self_test"
24
25
26 static void
27 opdl_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info);
28
29
30 static int
31 opdl_queue_setup(struct rte_eventdev *dev,
32                  uint8_t queue_id,
33                  const struct rte_event_queue_conf *conf)
34 {
35         enum queue_type type;
36
37         struct opdl_evdev *device = opdl_pmd_priv(dev);
38
39         /* Extra sanity check, probably not needed */
40         if (queue_id == OPDL_INVALID_QID) {
41                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
42                              "Invalid queue id %u requested\n",
43                              dev->data->dev_id,
44                              queue_id);
45                 return -EINVAL;
46         }
47
48         if (device->nb_q_md > device->max_queue_nb) {
49                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
50                              "Max number of queues %u exceeded by request %u\n",
51                              dev->data->dev_id,
52                              device->max_queue_nb,
53                              device->nb_q_md);
54                 return -EINVAL;
55         }
56
57         if (RTE_EVENT_QUEUE_CFG_ALL_TYPES
58             & conf->event_queue_cfg) {
59                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
60                              "QUEUE_CFG_ALL_TYPES not supported\n",
61                              dev->data->dev_id);
62                 return -ENOTSUP;
63         } else if (RTE_EVENT_QUEUE_CFG_SINGLE_LINK
64                    & conf->event_queue_cfg) {
65                 type = OPDL_Q_TYPE_SINGLE_LINK;
66         } else {
67                 switch (conf->schedule_type) {
68                 case RTE_SCHED_TYPE_ORDERED:
69                         type = OPDL_Q_TYPE_ORDERED;
70                         break;
71                 case RTE_SCHED_TYPE_ATOMIC:
72                         type = OPDL_Q_TYPE_ATOMIC;
73                         break;
74                 case RTE_SCHED_TYPE_PARALLEL:
75                         type = OPDL_Q_TYPE_ORDERED;
76                         break;
77                 default:
78                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
79                                      "Unknown queue type %d requested\n",
80                                      dev->data->dev_id,
81                                      conf->event_queue_cfg);
82                         return -EINVAL;
83                 }
84         }
85         /* Check if queue id has been setup already */
86         for (uint32_t i = 0; i < device->nb_q_md; i++) {
87                 if (device->q_md[i].ext_id == queue_id) {
88                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
89                                      "queue id %u already setup\n",
90                                      dev->data->dev_id,
91                                      queue_id);
92                         return -EINVAL;
93                 }
94         }
95
96         device->q_md[device->nb_q_md].ext_id = queue_id;
97         device->q_md[device->nb_q_md].type = type;
98         device->q_md[device->nb_q_md].setup = 1;
99         device->nb_q_md++;
100
101         return 1;
102 }
103
104 static void
105 opdl_queue_release(struct rte_eventdev *dev, uint8_t queue_id)
106 {
107         struct opdl_evdev *device = opdl_pmd_priv(dev);
108
109         RTE_SET_USED(queue_id);
110
111         if (device->data->dev_started)
112                 return;
113
114 }
115
116 static void
117 opdl_queue_def_conf(struct rte_eventdev *dev,
118                     uint8_t queue_id,
119                     struct rte_event_queue_conf *conf)
120 {
121         RTE_SET_USED(dev);
122         RTE_SET_USED(queue_id);
123
124         static const struct rte_event_queue_conf default_conf = {
125                 .nb_atomic_flows = 1024,
126                 .nb_atomic_order_sequences = 1,
127                 .event_queue_cfg = 0,
128                 .schedule_type = RTE_SCHED_TYPE_ORDERED,
129                 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
130         };
131
132         *conf = default_conf;
133 }
134
135
136 static int
137 opdl_dev_configure(const struct rte_eventdev *dev)
138 {
139         struct opdl_evdev *opdl = opdl_pmd_priv(dev);
140         const struct rte_eventdev_data *data = dev->data;
141         const struct rte_event_dev_config *conf = &data->dev_conf;
142
143         opdl->max_queue_nb = conf->nb_event_queues;
144         opdl->max_port_nb = conf->nb_event_ports;
145         opdl->nb_events_limit = conf->nb_events_limit;
146
147         if (conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT) {
148                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
149                              "DEQUEUE_TIMEOUT not supported\n",
150                              dev->data->dev_id);
151                 return -ENOTSUP;
152         }
153
154         return 0;
155 }
156
157 static void
158 opdl_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info)
159 {
160         RTE_SET_USED(dev);
161
162         static const struct rte_event_dev_info evdev_opdl_info = {
163                 .driver_name = OPDL_PMD_NAME,
164                 .max_event_queues = RTE_EVENT_MAX_QUEUES_PER_DEV,
165                 .max_event_queue_flows = OPDL_QID_NUM_FIDS,
166                 .max_event_queue_priority_levels = OPDL_Q_PRIORITY_MAX,
167                 .max_event_priority_levels = OPDL_IQS_MAX,
168                 .max_event_ports = OPDL_PORTS_MAX,
169                 .max_event_port_dequeue_depth = MAX_OPDL_CONS_Q_DEPTH,
170                 .max_event_port_enqueue_depth = MAX_OPDL_CONS_Q_DEPTH,
171                 .max_num_events = OPDL_INFLIGHT_EVENTS_TOTAL,
172                 .event_dev_cap = RTE_EVENT_DEV_CAP_BURST_MODE,
173         };
174
175         *info = evdev_opdl_info;
176 }
177
178 static void
179 opdl_dump(struct rte_eventdev *dev, FILE *f)
180 {
181         struct opdl_evdev *device = opdl_pmd_priv(dev);
182
183         if (!device->do_validation)
184                 return;
185
186         fprintf(f,
187                 "\n\n -- RING STATISTICS --\n");
188
189         for (uint32_t i = 0; i < device->nb_opdls; i++)
190                 opdl_ring_dump(device->opdl[i], f);
191
192         fprintf(f,
193                 "\n\n -- PORT STATISTICS --\n"
194                 "Type Port Index  Port Id  Queue Id     Av. Req Size  "
195                 "Av. Grant Size     Av. Cycles PP"
196                 "      Empty DEQs   Non Empty DEQs   Pkts Processed\n");
197
198         for (uint32_t i = 0; i < device->max_port_nb; i++) {
199                 char queue_id[64];
200                 char total_cyc[64];
201                 const char *p_type;
202
203                 uint64_t cne, cpg;
204                 struct opdl_port *port = &device->ports[i];
205
206                 if (port->initialized) {
207                         cne = port->port_stat[claim_non_empty];
208                         cpg = port->port_stat[claim_pkts_granted];
209                         if (port->p_type == OPDL_REGULAR_PORT)
210                                 p_type = "REG";
211                         else if (port->p_type == OPDL_PURE_RX_PORT)
212                                 p_type = "  RX";
213                         else if (port->p_type == OPDL_PURE_TX_PORT)
214                                 p_type = "  TX";
215                         else if (port->p_type == OPDL_ASYNC_PORT)
216                                 p_type = "SYNC";
217                         else
218                                 p_type = "????";
219
220                         sprintf(queue_id, "%02u", port->external_qid);
221                         if (port->p_type == OPDL_REGULAR_PORT ||
222                                         port->p_type == OPDL_ASYNC_PORT)
223                                 sprintf(total_cyc,
224                                         " %'16"PRIu64"",
225                                         (cpg != 0 ?
226                                          port->port_stat[total_cycles] / cpg
227                                          : 0));
228                         else
229                                 sprintf(total_cyc,
230                                         "             ----");
231                         fprintf(f,
232                                 "%4s %10u %8u %9s %'16"PRIu64" %'16"PRIu64" %s "
233                                 "%'16"PRIu64" %'16"PRIu64" %'16"PRIu64"\n",
234                                 p_type,
235                                 i,
236                                 port->id,
237                                 (port->external_qid == OPDL_INVALID_QID ? "---"
238                                  : queue_id),
239                                 (cne != 0 ?
240                                  port->port_stat[claim_pkts_requested] / cne
241                                  : 0),
242                                 (cne != 0 ?
243                                  port->port_stat[claim_pkts_granted] / cne
244                                  : 0),
245                                 total_cyc,
246                                 port->port_stat[claim_empty],
247                                 port->port_stat[claim_non_empty],
248                                 port->port_stat[claim_pkts_granted]);
249                 }
250         }
251         fprintf(f, "\n");
252 }
253
254
255 static void
256 opdl_stop(struct rte_eventdev *dev)
257 {
258         struct opdl_evdev *device = opdl_pmd_priv(dev);
259
260         opdl_xstats_uninit(dev);
261
262         destroy_queues_and_rings(dev);
263
264
265         device->started = 0;
266
267         rte_smp_wmb();
268 }
269
270 static int
271 opdl_start(struct rte_eventdev *dev)
272 {
273         int err = 0;
274
275         if (!err)
276                 err = create_queues_and_rings(dev);
277
278
279         if (!err)
280                 err = assign_internal_queue_ids(dev);
281
282
283         if (!err)
284                 err = initialise_queue_zero_ports(dev);
285
286
287         if (!err)
288                 err = initialise_all_other_ports(dev);
289
290
291         if (!err)
292                 err = check_queues_linked(dev);
293
294
295         if (!err)
296                 err = opdl_add_event_handlers(dev);
297
298
299         if (!err)
300                 err = build_all_dependencies(dev);
301
302         if (!err) {
303                 opdl_xstats_init(dev);
304
305                 struct opdl_evdev *device = opdl_pmd_priv(dev);
306
307                 PMD_DRV_LOG(INFO, "DEV_ID:[%02d] : "
308                               "SUCCESS : Created %u total queues (%u ex, %u in),"
309                               " %u opdls, %u event_dev ports, %u input ports",
310                               opdl_pmd_dev_id(device),
311                               device->nb_queues,
312                               (device->nb_queues - device->nb_opdls),
313                               device->nb_opdls,
314                               device->nb_opdls,
315                               device->nb_ports,
316                               device->queue[0].nb_ports);
317         } else
318                 opdl_stop(dev);
319
320         return err;
321 }
322
323 static int
324 opdl_close(struct rte_eventdev *dev)
325 {
326         struct opdl_evdev *device = opdl_pmd_priv(dev);
327         uint32_t i;
328
329         for (i = 0; i < device->max_port_nb; i++) {
330                 memset(&device->ports[i],
331                        0,
332                        sizeof(struct opdl_port));
333         }
334
335         memset(&device->s_md,
336                         0x0,
337                         sizeof(struct opdl_stage_meta_data)*OPDL_PORTS_MAX);
338
339         memset(&device->q_md,
340                         0xFF,
341                         sizeof(struct opdl_queue_meta_data)*OPDL_MAX_QUEUES);
342
343
344         memset(device->q_map_ex_to_in,
345                         0,
346                         sizeof(uint8_t)*OPDL_INVALID_QID);
347
348         opdl_xstats_uninit(dev);
349
350         device->max_port_nb = 0;
351
352         device->max_queue_nb = 0;
353
354         device->nb_opdls = 0;
355
356         device->nb_queues   = 0;
357
358         device->nb_ports    = 0;
359
360         device->nb_q_md     = 0;
361
362         dev->data->nb_queues = 0;
363
364         dev->data->nb_ports = 0;
365
366
367         return 0;
368 }
369
370 static int
371 assign_numa_node(const char *key __rte_unused, const char *value, void *opaque)
372 {
373         int *socket_id = opaque;
374         *socket_id = atoi(value);
375         if (*socket_id >= RTE_MAX_NUMA_NODES)
376                 return -1;
377         return 0;
378 }
379
380 static int
381 set_do_validation(const char *key __rte_unused, const char *value, void *opaque)
382 {
383         int *do_val = opaque;
384         *do_val = atoi(value);
385         if (*do_val != 0)
386                 *do_val = 1;
387
388         return 0;
389 }
390 static int
391 set_do_test(const char *key __rte_unused, const char *value, void *opaque)
392 {
393         int *do_test = opaque;
394
395         *do_test = atoi(value);
396
397         if (*do_test != 0)
398                 *do_test = 1;
399         return 0;
400 }
401
402 static int
403 opdl_probe(struct rte_vdev_device *vdev)
404 {
405         static const struct rte_eventdev_ops evdev_opdl_ops = {
406                 .dev_configure = opdl_dev_configure,
407                 .dev_infos_get = opdl_info_get,
408                 .dev_close = opdl_close,
409                 .dev_start = opdl_start,
410                 .dev_stop = opdl_stop,
411                 .dump = opdl_dump,
412
413                 .queue_def_conf = opdl_queue_def_conf,
414                 .queue_setup = opdl_queue_setup,
415                 .queue_release = opdl_queue_release,
416
417                 .xstats_get = opdl_xstats_get,
418                 .xstats_get_names = opdl_xstats_get_names,
419                 .xstats_get_by_name = opdl_xstats_get_by_name,
420                 .xstats_reset = opdl_xstats_reset,
421         };
422
423         static const char *const args[] = {
424                 NUMA_NODE_ARG,
425                 DO_VALIDATION_ARG,
426                 DO_TEST_ARG,
427                 NULL
428         };
429         const char *name;
430         const char *params;
431         struct rte_eventdev *dev;
432         struct opdl_evdev *opdl;
433         int socket_id = rte_socket_id();
434         int do_validation = 0;
435         int do_test = 0;
436         int str_len;
437         int test_result = 0;
438
439         name = rte_vdev_device_name(vdev);
440         params = rte_vdev_device_args(vdev);
441         if (params != NULL && params[0] != '\0') {
442                 struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
443
444                 if (!kvlist) {
445                         PMD_DRV_LOG(INFO,
446                                         "Ignoring unsupported parameters when creating device '%s'\n",
447                                         name);
448                 } else {
449                         int ret = rte_kvargs_process(kvlist, NUMA_NODE_ARG,
450                                         assign_numa_node, &socket_id);
451                         if (ret != 0) {
452                                 PMD_DRV_LOG(ERR,
453                                                 "%s: Error parsing numa node parameter",
454                                                 name);
455
456                                 rte_kvargs_free(kvlist);
457                                 return ret;
458                         }
459
460                         ret = rte_kvargs_process(kvlist, DO_VALIDATION_ARG,
461                                         set_do_validation, &do_validation);
462                         if (ret != 0) {
463                                 PMD_DRV_LOG(ERR,
464                                         "%s: Error parsing do validation parameter",
465                                         name);
466                                 rte_kvargs_free(kvlist);
467                                 return ret;
468                         }
469
470                         ret = rte_kvargs_process(kvlist, DO_TEST_ARG,
471                                         set_do_test, &do_test);
472                         if (ret != 0) {
473                                 PMD_DRV_LOG(ERR,
474                                         "%s: Error parsing do test parameter",
475                                         name);
476                                 rte_kvargs_free(kvlist);
477                                 return ret;
478                         }
479
480                         rte_kvargs_free(kvlist);
481                 }
482         }
483         dev = rte_event_pmd_vdev_init(name,
484                         sizeof(struct opdl_evdev), socket_id);
485
486         if (dev == NULL) {
487                 PMD_DRV_LOG(ERR, "eventdev vdev init() failed");
488                 return -EFAULT;
489         }
490
491         PMD_DRV_LOG(INFO, "DEV_ID:[%02d] : "
492                       "Success - creating eventdev device %s, numa_node:[%d], do_valdation:[%s]"
493                           " , self_test:[%s]\n",
494                       dev->data->dev_id,
495                       name,
496                       socket_id,
497                       (do_validation ? "true" : "false"),
498                           (do_test ? "true" : "false"));
499
500         dev->dev_ops = &evdev_opdl_ops;
501
502         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
503                 return 0;
504
505         opdl = dev->data->dev_private;
506         opdl->data = dev->data;
507         opdl->socket = socket_id;
508         opdl->do_validation = do_validation;
509         opdl->do_test = do_test;
510         str_len = strlen(name);
511         memcpy(opdl->service_name, name, str_len);
512
513         return test_result;
514 }
515
516 static int
517 opdl_remove(struct rte_vdev_device *vdev)
518 {
519         const char *name;
520
521         name = rte_vdev_device_name(vdev);
522         if (name == NULL)
523                 return -EINVAL;
524
525         PMD_DRV_LOG(INFO, "Closing eventdev opdl device %s\n", name);
526
527         return rte_event_pmd_vdev_uninit(name);
528 }
529
530 static struct rte_vdev_driver evdev_opdl_pmd_drv = {
531         .probe = opdl_probe,
532         .remove = opdl_remove
533 };
534
535 RTE_INIT(opdl_init_log);
536
537 static void
538 opdl_init_log(void)
539 {
540         opdl_logtype_driver = rte_log_register("eventdev.opdl.driver");
541         if (opdl_logtype_driver >= 0)
542                 rte_log_set_level(opdl_logtype_driver, RTE_LOG_INFO);
543 }
544
545
546 RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_OPDL_PMD, evdev_opdl_pmd_drv);
547 RTE_PMD_REGISTER_PARAM_STRING(event_opdl, NUMA_NODE_ARG "=<int>"
548                               DO_VALIDATION_ARG "=<int>" DO_TEST_ARG "=<int>");