sched: update subport rate dynamically
[dpdk.git] / examples / ip_pipeline / tmgr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4
5 #include <stdlib.h>
6
7 #include <rte_string_fns.h>
8
9 #include "tmgr.h"
10
11 static struct rte_sched_subport_params
12         subport_profile[TMGR_SUBPORT_PROFILE_MAX];
13
14 static uint32_t n_subport_profiles;
15
16 static struct rte_sched_pipe_params
17         pipe_profile[TMGR_PIPE_PROFILE_MAX];
18
19 static uint32_t n_pipe_profiles;
20
21 static struct tmgr_port_list tmgr_port_list;
22
23 int
24 tmgr_init(void)
25 {
26         TAILQ_INIT(&tmgr_port_list);
27
28         return 0;
29 }
30
31 struct tmgr_port *
32 tmgr_port_find(const char *name)
33 {
34         struct tmgr_port *tmgr_port;
35
36         if (name == NULL)
37                 return NULL;
38
39         TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node)
40                 if (strcmp(tmgr_port->name, name) == 0)
41                         return tmgr_port;
42
43         return NULL;
44 }
45
46 int
47 tmgr_subport_profile_add(struct rte_sched_subport_params *p)
48 {
49         /* Check input params */
50         if (p == NULL ||
51                 p->n_pipes_per_subport_enabled == 0)
52                 return -1;
53
54         /* Save profile */
55         memcpy(&subport_profile[n_subport_profiles],
56                 p,
57                 sizeof(*p));
58
59         n_subport_profiles++;
60
61         return 0;
62 }
63
64 int
65 tmgr_pipe_profile_add(struct rte_sched_pipe_params *p)
66 {
67         /* Check input params */
68         if (p == NULL)
69                 return -1;
70
71         /* Save profile */
72         memcpy(&pipe_profile[n_pipe_profiles],
73                 p,
74                 sizeof(*p));
75
76         n_pipe_profiles++;
77
78         return 0;
79 }
80
81 struct tmgr_port *
82 tmgr_port_create(const char *name, struct tmgr_port_params *params)
83 {
84         struct rte_sched_port_params p;
85         struct tmgr_port *tmgr_port;
86         struct rte_sched_port *s;
87         uint32_t i, j;
88
89         /* Check input params */
90         if ((name == NULL) ||
91                 tmgr_port_find(name) ||
92                 (params == NULL) ||
93                 (params->n_subports_per_port == 0) ||
94                 (params->cpu_id >= RTE_MAX_NUMA_NODES) ||
95                 (n_subport_profiles == 0) ||
96                 (n_pipe_profiles == 0))
97                 return NULL;
98
99         /* Resource create */
100         p.name = name;
101         p.socket = (int) params->cpu_id;
102         p.rate = params->rate;
103         p.mtu = params->mtu;
104         p.frame_overhead = params->frame_overhead;
105         p.n_subports_per_port = params->n_subports_per_port;
106         p.n_pipes_per_subport = TMGR_PIPE_SUBPORT_MAX;
107
108         s = rte_sched_port_config(&p);
109         if (s == NULL)
110                 return NULL;
111
112         subport_profile[0].pipe_profiles = pipe_profile;
113         subport_profile[0].n_pipe_profiles = n_pipe_profiles;
114         subport_profile[0].n_max_pipe_profiles = TMGR_PIPE_PROFILE_MAX;
115
116         for (i = 0; i < params->n_subports_per_port; i++) {
117                 int status;
118
119                 status = rte_sched_subport_config(
120                         s,
121                         i,
122                         &subport_profile[0],
123                         0);
124
125                 if (status) {
126                         rte_sched_port_free(s);
127                         return NULL;
128                 }
129
130                 for (j = 0; j < subport_profile[0].n_pipes_per_subport_enabled; j++) {
131                         status = rte_sched_pipe_config(
132                                 s,
133                                 i,
134                                 j,
135                                 0);
136
137                         if (status) {
138                                 rte_sched_port_free(s);
139                                 return NULL;
140                         }
141                 }
142         }
143
144         /* Node allocation */
145         tmgr_port = calloc(1, sizeof(struct tmgr_port));
146         if (tmgr_port == NULL) {
147                 rte_sched_port_free(s);
148                 return NULL;
149         }
150
151         /* Node fill in */
152         strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name));
153         tmgr_port->s = s;
154         tmgr_port->n_subports_per_port = params->n_subports_per_port;
155
156         /* Node add to list */
157         TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node);
158
159         return tmgr_port;
160 }
161
162 int
163 tmgr_subport_config(const char *port_name,
164         uint32_t subport_id,
165         uint32_t subport_profile_id)
166 {
167         struct tmgr_port *port;
168         int status;
169
170         /* Check input params */
171         if (port_name == NULL)
172                 return -1;
173
174         port = tmgr_port_find(port_name);
175         if ((port == NULL) ||
176                 (subport_id >= port->n_subports_per_port) ||
177                 (subport_profile_id >= n_subport_profiles))
178                 return -1;
179
180         /* Resource config */
181         status = rte_sched_subport_config(
182                 port->s,
183                 subport_id,
184                 &subport_profile[subport_profile_id],
185                 0);
186
187         return status;
188 }
189
190 int
191 tmgr_pipe_config(const char *port_name,
192         uint32_t subport_id,
193         uint32_t pipe_id_first,
194         uint32_t pipe_id_last,
195         uint32_t pipe_profile_id)
196 {
197         struct tmgr_port *port;
198         uint32_t i;
199
200         /* Check input params */
201         if (port_name == NULL)
202                 return -1;
203
204         port = tmgr_port_find(port_name);
205         if ((port == NULL) ||
206                 (subport_id >= port->n_subports_per_port) ||
207                 (pipe_id_first >=
208                         subport_profile[subport_id].n_pipes_per_subport_enabled) ||
209                 (pipe_id_last >=
210                         subport_profile[subport_id].n_pipes_per_subport_enabled) ||
211                 (pipe_id_first > pipe_id_last) ||
212                 (pipe_profile_id >= n_pipe_profiles))
213                 return -1;
214
215         /* Resource config */
216         for (i = pipe_id_first; i <= pipe_id_last; i++) {
217                 int status;
218
219                 status = rte_sched_pipe_config(
220                         port->s,
221                         subport_id,
222                         i,
223                         (int) pipe_profile_id);
224
225                 if (status)
226                         return status;
227         }
228
229         return 0;
230 }