xref: /dpdk/drivers/net/softnic/rte_eth_softnic_thread.c (revision 202905f3ee4db9df45f00da90da99e0655e60ef6)
1bd2fbb62SJasvinder Singh /* SPDX-License-Identifier: BSD-3-Clause
2bd2fbb62SJasvinder Singh  * Copyright(c) 2010-2018 Intel Corporation
3bd2fbb62SJasvinder Singh  */
4bd2fbb62SJasvinder Singh 
5bd2fbb62SJasvinder Singh #include <stdlib.h>
6bd2fbb62SJasvinder Singh 
7bd2fbb62SJasvinder Singh #include <rte_cycles.h>
8bd2fbb62SJasvinder Singh #include <rte_lcore.h>
9bd2fbb62SJasvinder Singh #include <rte_ring.h>
10bd2fbb62SJasvinder Singh 
11bd2fbb62SJasvinder Singh #include "rte_eth_softnic_internals.h"
12bd2fbb62SJasvinder Singh 
13bd2fbb62SJasvinder Singh /**
14bd2fbb62SJasvinder Singh  * Master thread: data plane thread init
15bd2fbb62SJasvinder Singh  */
16bd2fbb62SJasvinder Singh void
17bd2fbb62SJasvinder Singh softnic_thread_free(struct pmd_internals *softnic)
18bd2fbb62SJasvinder Singh {
19bd2fbb62SJasvinder Singh 	uint32_t i;
20bd2fbb62SJasvinder Singh 
21bd2fbb62SJasvinder Singh 	RTE_LCORE_FOREACH_SLAVE(i) {
22bd2fbb62SJasvinder Singh 		struct softnic_thread *t = &softnic->thread[i];
23bd2fbb62SJasvinder Singh 
24bd2fbb62SJasvinder Singh 		/* MSGQs */
25bd2fbb62SJasvinder Singh 		if (t->msgq_req)
26bd2fbb62SJasvinder Singh 			rte_ring_free(t->msgq_req);
27bd2fbb62SJasvinder Singh 
28bd2fbb62SJasvinder Singh 		if (t->msgq_rsp)
29bd2fbb62SJasvinder Singh 			rte_ring_free(t->msgq_rsp);
30bd2fbb62SJasvinder Singh 	}
31bd2fbb62SJasvinder Singh }
32bd2fbb62SJasvinder Singh 
33bd2fbb62SJasvinder Singh int
34bd2fbb62SJasvinder Singh softnic_thread_init(struct pmd_internals *softnic)
35bd2fbb62SJasvinder Singh {
36bd2fbb62SJasvinder Singh 	uint32_t i;
37bd2fbb62SJasvinder Singh 
38bd2fbb62SJasvinder Singh 	RTE_LCORE_FOREACH_SLAVE(i) {
39bd2fbb62SJasvinder Singh 		char ring_name[NAME_MAX];
40bd2fbb62SJasvinder Singh 		struct rte_ring *msgq_req, *msgq_rsp;
41bd2fbb62SJasvinder Singh 		struct softnic_thread *t = &softnic->thread[i];
42bd2fbb62SJasvinder Singh 		struct softnic_thread_data *t_data = &softnic->thread_data[i];
43bd2fbb62SJasvinder Singh 		uint32_t cpu_id = rte_lcore_to_socket_id(i);
44bd2fbb62SJasvinder Singh 
45bd2fbb62SJasvinder Singh 		/* MSGQs */
46bd2fbb62SJasvinder Singh 		snprintf(ring_name, sizeof(ring_name), "%s-TH%u-REQ",
47bd2fbb62SJasvinder Singh 			softnic->params.name,
48bd2fbb62SJasvinder Singh 			i);
49bd2fbb62SJasvinder Singh 
50bd2fbb62SJasvinder Singh 		msgq_req = rte_ring_create(ring_name,
51bd2fbb62SJasvinder Singh 			THREAD_MSGQ_SIZE,
52bd2fbb62SJasvinder Singh 			cpu_id,
53bd2fbb62SJasvinder Singh 			RING_F_SP_ENQ | RING_F_SC_DEQ);
54bd2fbb62SJasvinder Singh 
55bd2fbb62SJasvinder Singh 		if (msgq_req == NULL) {
56bd2fbb62SJasvinder Singh 			softnic_thread_free(softnic);
57bd2fbb62SJasvinder Singh 			return -1;
58bd2fbb62SJasvinder Singh 		}
59bd2fbb62SJasvinder Singh 
60bd2fbb62SJasvinder Singh 		snprintf(ring_name, sizeof(ring_name), "%s-TH%u-RSP",
61bd2fbb62SJasvinder Singh 			softnic->params.name,
62bd2fbb62SJasvinder Singh 			i);
63bd2fbb62SJasvinder Singh 
64bd2fbb62SJasvinder Singh 		msgq_rsp = rte_ring_create(ring_name,
65bd2fbb62SJasvinder Singh 			THREAD_MSGQ_SIZE,
66bd2fbb62SJasvinder Singh 			cpu_id,
67bd2fbb62SJasvinder Singh 			RING_F_SP_ENQ | RING_F_SC_DEQ);
68bd2fbb62SJasvinder Singh 
69bd2fbb62SJasvinder Singh 		if (msgq_rsp == NULL) {
70bd2fbb62SJasvinder Singh 			softnic_thread_free(softnic);
71bd2fbb62SJasvinder Singh 			return -1;
72bd2fbb62SJasvinder Singh 		}
73bd2fbb62SJasvinder Singh 
74bd2fbb62SJasvinder Singh 		/* Master thread records */
75bd2fbb62SJasvinder Singh 		t->msgq_req = msgq_req;
76bd2fbb62SJasvinder Singh 		t->msgq_rsp = msgq_rsp;
77bd2fbb62SJasvinder Singh 		t->enabled = 1;
78bd2fbb62SJasvinder Singh 
79bd2fbb62SJasvinder Singh 		/* Data plane thread records */
80bd2fbb62SJasvinder Singh 		t_data->n_pipelines = 0;
81bd2fbb62SJasvinder Singh 		t_data->msgq_req = msgq_req;
82bd2fbb62SJasvinder Singh 		t_data->msgq_rsp = msgq_rsp;
83bd2fbb62SJasvinder Singh 		t_data->timer_period =
84bd2fbb62SJasvinder Singh 			(rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
85bd2fbb62SJasvinder Singh 		t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
86bd2fbb62SJasvinder Singh 		t_data->time_next_min = t_data->time_next;
87bd2fbb62SJasvinder Singh 	}
88bd2fbb62SJasvinder Singh 
89bd2fbb62SJasvinder Singh 	return 0;
90bd2fbb62SJasvinder Singh }
915719a615SCristian Dumitrescu 
92*202905f3SJasvinder Singh static inline int
93*202905f3SJasvinder Singh thread_is_running(uint32_t thread_id)
94*202905f3SJasvinder Singh {
95*202905f3SJasvinder Singh 	enum rte_lcore_state_t thread_state;
96*202905f3SJasvinder Singh 
97*202905f3SJasvinder Singh 	thread_state = rte_eal_get_lcore_state(thread_id);
98*202905f3SJasvinder Singh 	return (thread_state == RUNNING)? 1 : 0;
99*202905f3SJasvinder Singh }
100*202905f3SJasvinder Singh 
101*202905f3SJasvinder Singh /**
102*202905f3SJasvinder Singh  * Pipeline is running when:
103*202905f3SJasvinder Singh  *    (A) Pipeline is mapped to a data plane thread AND
104*202905f3SJasvinder Singh  *    (B) Its data plane thread is in RUNNING state.
105*202905f3SJasvinder Singh  */
106*202905f3SJasvinder Singh static inline int
107*202905f3SJasvinder Singh pipeline_is_running(struct pipeline *p)
108*202905f3SJasvinder Singh {
109*202905f3SJasvinder Singh 	if (p->enabled == 0)
110*202905f3SJasvinder Singh 		return 0;
111*202905f3SJasvinder Singh 
112*202905f3SJasvinder Singh 	return thread_is_running(p->thread_id);
113*202905f3SJasvinder Singh }
114*202905f3SJasvinder Singh 
1155719a615SCristian Dumitrescu /**
1165719a615SCristian Dumitrescu  * Master thread & data plane threads: message passing
1175719a615SCristian Dumitrescu  */
1185719a615SCristian Dumitrescu enum thread_req_type {
1195719a615SCristian Dumitrescu 	THREAD_REQ_MAX
1205719a615SCristian Dumitrescu };
1215719a615SCristian Dumitrescu 
1225719a615SCristian Dumitrescu struct thread_msg_req {
1235719a615SCristian Dumitrescu 	enum thread_req_type type;
1245719a615SCristian Dumitrescu };
1255719a615SCristian Dumitrescu 
1265719a615SCristian Dumitrescu struct thread_msg_rsp {
1275719a615SCristian Dumitrescu 	int status;
1285719a615SCristian Dumitrescu };
1295719a615SCristian Dumitrescu 
1305719a615SCristian Dumitrescu /**
1315719a615SCristian Dumitrescu  * Data plane threads: message handling
1325719a615SCristian Dumitrescu  */
1335719a615SCristian Dumitrescu static inline struct thread_msg_req *
1345719a615SCristian Dumitrescu thread_msg_recv(struct rte_ring *msgq_req)
1355719a615SCristian Dumitrescu {
1365719a615SCristian Dumitrescu 	struct thread_msg_req *req;
1375719a615SCristian Dumitrescu 
1385719a615SCristian Dumitrescu 	int status = rte_ring_sc_dequeue(msgq_req, (void **)&req);
1395719a615SCristian Dumitrescu 
1405719a615SCristian Dumitrescu 	if (status != 0)
1415719a615SCristian Dumitrescu 		return NULL;
1425719a615SCristian Dumitrescu 
1435719a615SCristian Dumitrescu 	return req;
1445719a615SCristian Dumitrescu }
1455719a615SCristian Dumitrescu 
1465719a615SCristian Dumitrescu static inline void
1475719a615SCristian Dumitrescu thread_msg_send(struct rte_ring *msgq_rsp,
1485719a615SCristian Dumitrescu 	struct thread_msg_rsp *rsp)
1495719a615SCristian Dumitrescu {
1505719a615SCristian Dumitrescu 	int status;
1515719a615SCristian Dumitrescu 
1525719a615SCristian Dumitrescu 	do {
1535719a615SCristian Dumitrescu 		status = rte_ring_sp_enqueue(msgq_rsp, rsp);
1545719a615SCristian Dumitrescu 	} while (status == -ENOBUFS);
1555719a615SCristian Dumitrescu }
1565719a615SCristian Dumitrescu 
1575719a615SCristian Dumitrescu static void
1585719a615SCristian Dumitrescu thread_msg_handle(struct softnic_thread_data *t)
1595719a615SCristian Dumitrescu {
1605719a615SCristian Dumitrescu 	for ( ; ; ) {
1615719a615SCristian Dumitrescu 		struct thread_msg_req *req;
1625719a615SCristian Dumitrescu 		struct thread_msg_rsp *rsp;
1635719a615SCristian Dumitrescu 
1645719a615SCristian Dumitrescu 		req = thread_msg_recv(t->msgq_req);
1655719a615SCristian Dumitrescu 		if (req == NULL)
1665719a615SCristian Dumitrescu 			break;
1675719a615SCristian Dumitrescu 
1685719a615SCristian Dumitrescu 		switch (req->type) {
1695719a615SCristian Dumitrescu 		default:
1705719a615SCristian Dumitrescu 			rsp = (struct thread_msg_rsp *)req;
1715719a615SCristian Dumitrescu 			rsp->status = -1;
1725719a615SCristian Dumitrescu 		}
1735719a615SCristian Dumitrescu 
1745719a615SCristian Dumitrescu 		thread_msg_send(t->msgq_rsp, rsp);
1755719a615SCristian Dumitrescu 	}
1765719a615SCristian Dumitrescu }
1775719a615SCristian Dumitrescu 
1785719a615SCristian Dumitrescu /**
1795719a615SCristian Dumitrescu  * Master thread & data plane threads: message passing
1805719a615SCristian Dumitrescu  */
1815719a615SCristian Dumitrescu enum pipeline_req_type {
182*202905f3SJasvinder Singh 	/* Port IN */
183*202905f3SJasvinder Singh 	PIPELINE_REQ_PORT_IN_ENABLE,
184*202905f3SJasvinder Singh 	PIPELINE_REQ_PORT_IN_DISABLE,
185*202905f3SJasvinder Singh 
1865719a615SCristian Dumitrescu 	PIPELINE_REQ_MAX
1875719a615SCristian Dumitrescu };
1885719a615SCristian Dumitrescu 
1895719a615SCristian Dumitrescu struct pipeline_msg_req {
1905719a615SCristian Dumitrescu 	enum pipeline_req_type type;
191*202905f3SJasvinder Singh 	uint32_t id; /* Port IN, port OUT or table ID */
1925719a615SCristian Dumitrescu };
1935719a615SCristian Dumitrescu 
1945719a615SCristian Dumitrescu struct pipeline_msg_rsp {
1955719a615SCristian Dumitrescu 	int status;
1965719a615SCristian Dumitrescu };
1975719a615SCristian Dumitrescu 
1985719a615SCristian Dumitrescu /**
199*202905f3SJasvinder Singh  * Master thread
200*202905f3SJasvinder Singh  */
201*202905f3SJasvinder Singh static struct pipeline_msg_req *
202*202905f3SJasvinder Singh pipeline_msg_alloc(void)
203*202905f3SJasvinder Singh {
204*202905f3SJasvinder Singh 	size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
205*202905f3SJasvinder Singh 		sizeof(struct pipeline_msg_rsp));
206*202905f3SJasvinder Singh 
207*202905f3SJasvinder Singh 	return calloc(1, size);
208*202905f3SJasvinder Singh }
209*202905f3SJasvinder Singh 
210*202905f3SJasvinder Singh static void
211*202905f3SJasvinder Singh pipeline_msg_free(struct pipeline_msg_rsp *rsp)
212*202905f3SJasvinder Singh {
213*202905f3SJasvinder Singh 	free(rsp);
214*202905f3SJasvinder Singh }
215*202905f3SJasvinder Singh 
216*202905f3SJasvinder Singh static struct pipeline_msg_rsp *
217*202905f3SJasvinder Singh pipeline_msg_send_recv(struct pipeline *p,
218*202905f3SJasvinder Singh 	struct pipeline_msg_req *req)
219*202905f3SJasvinder Singh {
220*202905f3SJasvinder Singh 	struct rte_ring *msgq_req = p->msgq_req;
221*202905f3SJasvinder Singh 	struct rte_ring *msgq_rsp = p->msgq_rsp;
222*202905f3SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
223*202905f3SJasvinder Singh 	int status;
224*202905f3SJasvinder Singh 
225*202905f3SJasvinder Singh 	/* send */
226*202905f3SJasvinder Singh 	do {
227*202905f3SJasvinder Singh 		status = rte_ring_sp_enqueue(msgq_req, req);
228*202905f3SJasvinder Singh 	} while (status == -ENOBUFS);
229*202905f3SJasvinder Singh 
230*202905f3SJasvinder Singh 	/* recv */
231*202905f3SJasvinder Singh 	do {
232*202905f3SJasvinder Singh 		status = rte_ring_sc_dequeue(msgq_rsp, (void **)&rsp);
233*202905f3SJasvinder Singh 	} while (status != 0);
234*202905f3SJasvinder Singh 
235*202905f3SJasvinder Singh 	return rsp;
236*202905f3SJasvinder Singh }
237*202905f3SJasvinder Singh 
238*202905f3SJasvinder Singh int
239*202905f3SJasvinder Singh softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
240*202905f3SJasvinder Singh 	const char *pipeline_name,
241*202905f3SJasvinder Singh 	uint32_t port_id)
242*202905f3SJasvinder Singh {
243*202905f3SJasvinder Singh 	struct pipeline *p;
244*202905f3SJasvinder Singh 	struct pipeline_msg_req *req;
245*202905f3SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
246*202905f3SJasvinder Singh 	int status;
247*202905f3SJasvinder Singh 
248*202905f3SJasvinder Singh 	/* Check input params */
249*202905f3SJasvinder Singh 	if (pipeline_name == NULL)
250*202905f3SJasvinder Singh 		return -1;
251*202905f3SJasvinder Singh 
252*202905f3SJasvinder Singh 	p = softnic_pipeline_find(softnic, pipeline_name);
253*202905f3SJasvinder Singh 	if (p == NULL ||
254*202905f3SJasvinder Singh 		port_id >= p->n_ports_in)
255*202905f3SJasvinder Singh 		return -1;
256*202905f3SJasvinder Singh 
257*202905f3SJasvinder Singh 	if (!pipeline_is_running(p)) {
258*202905f3SJasvinder Singh 		status = rte_pipeline_port_in_enable(p->p, port_id);
259*202905f3SJasvinder Singh 		return status;
260*202905f3SJasvinder Singh 	}
261*202905f3SJasvinder Singh 
262*202905f3SJasvinder Singh 	/* Allocate request */
263*202905f3SJasvinder Singh 	req = pipeline_msg_alloc();
264*202905f3SJasvinder Singh 	if (req == NULL)
265*202905f3SJasvinder Singh 		return -1;
266*202905f3SJasvinder Singh 
267*202905f3SJasvinder Singh 	/* Write request */
268*202905f3SJasvinder Singh 	req->type = PIPELINE_REQ_PORT_IN_ENABLE;
269*202905f3SJasvinder Singh 	req->id = port_id;
270*202905f3SJasvinder Singh 
271*202905f3SJasvinder Singh 	/* Send request and wait for response */
272*202905f3SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
273*202905f3SJasvinder Singh 	if (rsp == NULL)
274*202905f3SJasvinder Singh 		return -1;
275*202905f3SJasvinder Singh 
276*202905f3SJasvinder Singh 	/* Read response */
277*202905f3SJasvinder Singh 	status = rsp->status;
278*202905f3SJasvinder Singh 
279*202905f3SJasvinder Singh 	/* Free response */
280*202905f3SJasvinder Singh 	pipeline_msg_free(rsp);
281*202905f3SJasvinder Singh 
282*202905f3SJasvinder Singh 	return status;
283*202905f3SJasvinder Singh }
284*202905f3SJasvinder Singh 
285*202905f3SJasvinder Singh int
286*202905f3SJasvinder Singh softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
287*202905f3SJasvinder Singh 	const char *pipeline_name,
288*202905f3SJasvinder Singh 	uint32_t port_id)
289*202905f3SJasvinder Singh {
290*202905f3SJasvinder Singh 	struct pipeline *p;
291*202905f3SJasvinder Singh 	struct pipeline_msg_req *req;
292*202905f3SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
293*202905f3SJasvinder Singh 	int status;
294*202905f3SJasvinder Singh 
295*202905f3SJasvinder Singh 	/* Check input params */
296*202905f3SJasvinder Singh 	if (pipeline_name == NULL)
297*202905f3SJasvinder Singh 		return -1;
298*202905f3SJasvinder Singh 
299*202905f3SJasvinder Singh 	p = softnic_pipeline_find(softnic, pipeline_name);
300*202905f3SJasvinder Singh 	if (p == NULL ||
301*202905f3SJasvinder Singh 		port_id >= p->n_ports_in)
302*202905f3SJasvinder Singh 		return -1;
303*202905f3SJasvinder Singh 
304*202905f3SJasvinder Singh 	if (!pipeline_is_running(p)) {
305*202905f3SJasvinder Singh 		status = rte_pipeline_port_in_disable(p->p, port_id);
306*202905f3SJasvinder Singh 		return status;
307*202905f3SJasvinder Singh 	}
308*202905f3SJasvinder Singh 
309*202905f3SJasvinder Singh 	/* Allocate request */
310*202905f3SJasvinder Singh 	req = pipeline_msg_alloc();
311*202905f3SJasvinder Singh 	if (req == NULL)
312*202905f3SJasvinder Singh 		return -1;
313*202905f3SJasvinder Singh 
314*202905f3SJasvinder Singh 	/* Write request */
315*202905f3SJasvinder Singh 	req->type = PIPELINE_REQ_PORT_IN_DISABLE;
316*202905f3SJasvinder Singh 	req->id = port_id;
317*202905f3SJasvinder Singh 
318*202905f3SJasvinder Singh 	/* Send request and wait for response */
319*202905f3SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
320*202905f3SJasvinder Singh 	if (rsp == NULL)
321*202905f3SJasvinder Singh 		return -1;
322*202905f3SJasvinder Singh 
323*202905f3SJasvinder Singh 	/* Read response */
324*202905f3SJasvinder Singh 	status = rsp->status;
325*202905f3SJasvinder Singh 
326*202905f3SJasvinder Singh 	/* Free response */
327*202905f3SJasvinder Singh 	pipeline_msg_free(rsp);
328*202905f3SJasvinder Singh 
329*202905f3SJasvinder Singh 	return status;
330*202905f3SJasvinder Singh }
331*202905f3SJasvinder Singh 
332*202905f3SJasvinder Singh /**
3335719a615SCristian Dumitrescu  * Data plane threads: message handling
3345719a615SCristian Dumitrescu  */
3355719a615SCristian Dumitrescu static inline struct pipeline_msg_req *
3365719a615SCristian Dumitrescu pipeline_msg_recv(struct rte_ring *msgq_req)
3375719a615SCristian Dumitrescu {
3385719a615SCristian Dumitrescu 	struct pipeline_msg_req *req;
3395719a615SCristian Dumitrescu 
3405719a615SCristian Dumitrescu 	int status = rte_ring_sc_dequeue(msgq_req, (void **)&req);
3415719a615SCristian Dumitrescu 
3425719a615SCristian Dumitrescu 	if (status != 0)
3435719a615SCristian Dumitrescu 		return NULL;
3445719a615SCristian Dumitrescu 
3455719a615SCristian Dumitrescu 	return req;
3465719a615SCristian Dumitrescu }
3475719a615SCristian Dumitrescu 
3485719a615SCristian Dumitrescu static inline void
3495719a615SCristian Dumitrescu pipeline_msg_send(struct rte_ring *msgq_rsp,
3505719a615SCristian Dumitrescu 	struct pipeline_msg_rsp *rsp)
3515719a615SCristian Dumitrescu {
3525719a615SCristian Dumitrescu 	int status;
3535719a615SCristian Dumitrescu 
3545719a615SCristian Dumitrescu 	do {
3555719a615SCristian Dumitrescu 		status = rte_ring_sp_enqueue(msgq_rsp, rsp);
3565719a615SCristian Dumitrescu 	} while (status == -ENOBUFS);
3575719a615SCristian Dumitrescu }
3585719a615SCristian Dumitrescu 
359*202905f3SJasvinder Singh static struct pipeline_msg_rsp *
360*202905f3SJasvinder Singh pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
361*202905f3SJasvinder Singh 	struct pipeline_msg_req *req)
362*202905f3SJasvinder Singh {
363*202905f3SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;
364*202905f3SJasvinder Singh 	uint32_t port_id = req->id;
365*202905f3SJasvinder Singh 
366*202905f3SJasvinder Singh 	rsp->status = rte_pipeline_port_in_enable(p->p,
367*202905f3SJasvinder Singh 		port_id);
368*202905f3SJasvinder Singh 
369*202905f3SJasvinder Singh 	return rsp;
370*202905f3SJasvinder Singh }
371*202905f3SJasvinder Singh 
372*202905f3SJasvinder Singh static struct pipeline_msg_rsp *
373*202905f3SJasvinder Singh pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
374*202905f3SJasvinder Singh 	struct pipeline_msg_req *req)
375*202905f3SJasvinder Singh {
376*202905f3SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;
377*202905f3SJasvinder Singh 	uint32_t port_id = req->id;
378*202905f3SJasvinder Singh 
379*202905f3SJasvinder Singh 	rsp->status = rte_pipeline_port_in_disable(p->p,
380*202905f3SJasvinder Singh 		port_id);
381*202905f3SJasvinder Singh 
382*202905f3SJasvinder Singh 	return rsp;
383*202905f3SJasvinder Singh }
384*202905f3SJasvinder Singh 
3855719a615SCristian Dumitrescu static void
3865719a615SCristian Dumitrescu pipeline_msg_handle(struct pipeline_data *p)
3875719a615SCristian Dumitrescu {
3885719a615SCristian Dumitrescu 	for ( ; ; ) {
3895719a615SCristian Dumitrescu 		struct pipeline_msg_req *req;
3905719a615SCristian Dumitrescu 		struct pipeline_msg_rsp *rsp;
3915719a615SCristian Dumitrescu 
3925719a615SCristian Dumitrescu 		req = pipeline_msg_recv(p->msgq_req);
3935719a615SCristian Dumitrescu 		if (req == NULL)
3945719a615SCristian Dumitrescu 			break;
3955719a615SCristian Dumitrescu 
3965719a615SCristian Dumitrescu 		switch (req->type) {
397*202905f3SJasvinder Singh 		case PIPELINE_REQ_PORT_IN_ENABLE:
398*202905f3SJasvinder Singh 			rsp = pipeline_msg_handle_port_in_enable(p, req);
399*202905f3SJasvinder Singh 			break;
400*202905f3SJasvinder Singh 
401*202905f3SJasvinder Singh 		case PIPELINE_REQ_PORT_IN_DISABLE:
402*202905f3SJasvinder Singh 			rsp = pipeline_msg_handle_port_in_disable(p, req);
403*202905f3SJasvinder Singh 			break;
404*202905f3SJasvinder Singh 
4055719a615SCristian Dumitrescu 		default:
4065719a615SCristian Dumitrescu 			rsp = (struct pipeline_msg_rsp *)req;
4075719a615SCristian Dumitrescu 			rsp->status = -1;
4085719a615SCristian Dumitrescu 		}
4095719a615SCristian Dumitrescu 
4105719a615SCristian Dumitrescu 		pipeline_msg_send(p->msgq_rsp, rsp);
4115719a615SCristian Dumitrescu 	}
4125719a615SCristian Dumitrescu }
4135719a615SCristian Dumitrescu 
4145719a615SCristian Dumitrescu /**
4155719a615SCristian Dumitrescu  * Data plane threads: main
4165719a615SCristian Dumitrescu  */
4175719a615SCristian Dumitrescu int
4185719a615SCristian Dumitrescu rte_pmd_softnic_run(uint16_t port_id)
4195719a615SCristian Dumitrescu {
4205719a615SCristian Dumitrescu 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
4215719a615SCristian Dumitrescu 	struct pmd_internals *softnic;
4225719a615SCristian Dumitrescu 	struct softnic_thread_data *t;
4235719a615SCristian Dumitrescu 	uint32_t thread_id, j;
4245719a615SCristian Dumitrescu 
4255719a615SCristian Dumitrescu #ifdef RTE_LIBRTE_ETHDEV_DEBUG
4265719a615SCristian Dumitrescu 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
4275719a615SCristian Dumitrescu #endif
4285719a615SCristian Dumitrescu 
4295719a615SCristian Dumitrescu 	softnic = dev->data->dev_private;
4305719a615SCristian Dumitrescu 	thread_id = rte_lcore_id();
4315719a615SCristian Dumitrescu 	t = &softnic->thread_data[thread_id];
4325719a615SCristian Dumitrescu 	t->iter++;
4335719a615SCristian Dumitrescu 
4345719a615SCristian Dumitrescu 	/* Data Plane */
4355719a615SCristian Dumitrescu 	for (j = 0; j < t->n_pipelines; j++)
4365719a615SCristian Dumitrescu 		rte_pipeline_run(t->p[j]);
4375719a615SCristian Dumitrescu 
4385719a615SCristian Dumitrescu 	/* Control Plane */
4395719a615SCristian Dumitrescu 	if ((t->iter & 0xFLLU) == 0) {
4405719a615SCristian Dumitrescu 		uint64_t time = rte_get_tsc_cycles();
4415719a615SCristian Dumitrescu 		uint64_t time_next_min = UINT64_MAX;
4425719a615SCristian Dumitrescu 
4435719a615SCristian Dumitrescu 		if (time < t->time_next_min)
4445719a615SCristian Dumitrescu 			return 0;
4455719a615SCristian Dumitrescu 
4465719a615SCristian Dumitrescu 		/* Pipeline message queues */
4475719a615SCristian Dumitrescu 		for (j = 0; j < t->n_pipelines; j++) {
4485719a615SCristian Dumitrescu 			struct pipeline_data *p =
4495719a615SCristian Dumitrescu 				&t->pipeline_data[j];
4505719a615SCristian Dumitrescu 			uint64_t time_next = p->time_next;
4515719a615SCristian Dumitrescu 
4525719a615SCristian Dumitrescu 			if (time_next <= time) {
4535719a615SCristian Dumitrescu 				pipeline_msg_handle(p);
4545719a615SCristian Dumitrescu 				rte_pipeline_flush(p->p);
4555719a615SCristian Dumitrescu 				time_next = time + p->timer_period;
4565719a615SCristian Dumitrescu 				p->time_next = time_next;
4575719a615SCristian Dumitrescu 			}
4585719a615SCristian Dumitrescu 
4595719a615SCristian Dumitrescu 			if (time_next < time_next_min)
4605719a615SCristian Dumitrescu 				time_next_min = time_next;
4615719a615SCristian Dumitrescu 		}
4625719a615SCristian Dumitrescu 
4635719a615SCristian Dumitrescu 		/* Thread message queues */
4645719a615SCristian Dumitrescu 		{
4655719a615SCristian Dumitrescu 			uint64_t time_next = t->time_next;
4665719a615SCristian Dumitrescu 
4675719a615SCristian Dumitrescu 			if (time_next <= time) {
4685719a615SCristian Dumitrescu 				thread_msg_handle(t);
4695719a615SCristian Dumitrescu 				time_next = time + t->timer_period;
4705719a615SCristian Dumitrescu 				t->time_next = time_next;
4715719a615SCristian Dumitrescu 			}
4725719a615SCristian Dumitrescu 
4735719a615SCristian Dumitrescu 			if (time_next < time_next_min)
4745719a615SCristian Dumitrescu 				time_next_min = time_next;
4755719a615SCristian Dumitrescu 		}
4765719a615SCristian Dumitrescu 
4775719a615SCristian Dumitrescu 		t->time_next_min = time_next_min;
4785719a615SCristian Dumitrescu 	}
4795719a615SCristian Dumitrescu 
4805719a615SCristian Dumitrescu 	return 0;
4815719a615SCristian Dumitrescu }
482