46401f87236767131d96f7d0a312df867994e811
[dpdk.git] / drivers / event / sw / sw_evdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <string.h>
34
35 #include <rte_vdev.h>
36 #include <rte_memzone.h>
37 #include <rte_kvargs.h>
38 #include <rte_ring.h>
39
40 #include "sw_evdev.h"
41
42 #define EVENTDEV_NAME_SW_PMD event_sw
43 #define NUMA_NODE_ARG "numa_node"
44 #define SCHED_QUANTA_ARG "sched_quanta"
45 #define CREDIT_QUANTA_ARG "credit_quanta"
46
47 static int
48 assign_numa_node(const char *key __rte_unused, const char *value, void *opaque)
49 {
50         int *socket_id = opaque;
51         *socket_id = atoi(value);
52         if (*socket_id >= RTE_MAX_NUMA_NODES)
53                 return -1;
54         return 0;
55 }
56
57 static int
58 set_sched_quanta(const char *key __rte_unused, const char *value, void *opaque)
59 {
60         int *quanta = opaque;
61         *quanta = atoi(value);
62         if (*quanta < 0 || *quanta >= 4096)
63                 return -1;
64         return 0;
65 }
66
67 static int
68 set_credit_quanta(const char *key __rte_unused, const char *value, void *opaque)
69 {
70         int *credit = opaque;
71         *credit = atoi(value);
72         if (*credit < 0 || *credit >= 128)
73                 return -1;
74         return 0;
75 }
76
77 static int
78 sw_probe(const char *name, const char *params)
79 {
80         static const struct rte_eventdev_ops evdev_sw_ops = {
81         };
82
83         static const char *const args[] = {
84                 NUMA_NODE_ARG,
85                 SCHED_QUANTA_ARG,
86                 CREDIT_QUANTA_ARG,
87                 NULL
88         };
89         struct rte_eventdev *dev;
90         struct sw_evdev *sw;
91         int socket_id = rte_socket_id();
92         int sched_quanta  = SW_DEFAULT_SCHED_QUANTA;
93         int credit_quanta = SW_DEFAULT_CREDIT_QUANTA;
94
95         if (params != NULL && params[0] != '\0') {
96                 struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
97
98                 if (!kvlist) {
99                         SW_LOG_INFO(
100                                 "Ignoring unsupported parameters when creating device '%s'\n",
101                                 name);
102                 } else {
103                         int ret = rte_kvargs_process(kvlist, NUMA_NODE_ARG,
104                                         assign_numa_node, &socket_id);
105                         if (ret != 0) {
106                                 SW_LOG_ERR(
107                                         "%s: Error parsing numa node parameter",
108                                         name);
109                                 rte_kvargs_free(kvlist);
110                                 return ret;
111                         }
112
113                         ret = rte_kvargs_process(kvlist, SCHED_QUANTA_ARG,
114                                         set_sched_quanta, &sched_quanta);
115                         if (ret != 0) {
116                                 SW_LOG_ERR(
117                                         "%s: Error parsing sched quanta parameter",
118                                         name);
119                                 rte_kvargs_free(kvlist);
120                                 return ret;
121                         }
122
123                         ret = rte_kvargs_process(kvlist, CREDIT_QUANTA_ARG,
124                                         set_credit_quanta, &credit_quanta);
125                         if (ret != 0) {
126                                 SW_LOG_ERR(
127                                         "%s: Error parsing credit quanta parameter",
128                                         name);
129                                 rte_kvargs_free(kvlist);
130                                 return ret;
131                         }
132
133                         rte_kvargs_free(kvlist);
134                 }
135         }
136
137         SW_LOG_INFO(
138                         "Creating eventdev sw device %s, numa_node=%d, sched_quanta=%d, credit_quanta=%d\n",
139                         name, socket_id, sched_quanta, credit_quanta);
140
141         dev = rte_event_pmd_vdev_init(name,
142                         sizeof(struct sw_evdev), socket_id);
143         if (dev == NULL) {
144                 SW_LOG_ERR("eventdev vdev init() failed");
145                 return -EFAULT;
146         }
147         dev->dev_ops = &evdev_sw_ops;
148
149         sw = dev->data->dev_private;
150         sw->data = dev->data;
151
152         /* copy values passed from vdev command line to instance */
153         sw->credit_update_quanta = credit_quanta;
154         sw->sched_quanta = sched_quanta;
155
156         return 0;
157 }
158
159 static int
160 sw_remove(const char *name)
161 {
162         if (name == NULL)
163                 return -EINVAL;
164
165         SW_LOG_INFO("Closing eventdev sw device %s\n", name);
166
167         return rte_event_pmd_vdev_uninit(name);
168 }
169
170 static struct rte_vdev_driver evdev_sw_pmd_drv = {
171         .probe = sw_probe,
172         .remove = sw_remove
173 };
174
175 RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_SW_PMD, evdev_sw_pmd_drv);
176 RTE_PMD_REGISTER_PARAM_STRING(event_sw, NUMA_NODE_ARG "=<int> "
177                 SCHED_QUANTA_ARG "=<int>" CREDIT_QUANTA_ARG "=<int>");