xref: /dpdk/lib/distributor/rte_distributor.h (revision 99a2dd955fba6e4cc23b77d590a033650ced9c45)
1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*99a2dd95SBruce Richardson  * Copyright(c) 2017 Intel Corporation
3*99a2dd95SBruce Richardson  */
4*99a2dd95SBruce Richardson 
5*99a2dd95SBruce Richardson #ifndef _RTE_DISTRIBUTOR_H_
6*99a2dd95SBruce Richardson #define _RTE_DISTRIBUTOR_H_
7*99a2dd95SBruce Richardson 
8*99a2dd95SBruce Richardson /**
9*99a2dd95SBruce Richardson  * @file
10*99a2dd95SBruce Richardson  * RTE distributor
11*99a2dd95SBruce Richardson  *
12*99a2dd95SBruce Richardson  * The distributor is a component which is designed to pass packets
13*99a2dd95SBruce Richardson  * one-at-a-time to workers, with dynamic load balancing.
14*99a2dd95SBruce Richardson  */
15*99a2dd95SBruce Richardson 
16*99a2dd95SBruce Richardson #ifdef __cplusplus
17*99a2dd95SBruce Richardson extern "C" {
18*99a2dd95SBruce Richardson #endif
19*99a2dd95SBruce Richardson 
20*99a2dd95SBruce Richardson /* Type of distribution (burst/single) */
21*99a2dd95SBruce Richardson enum rte_distributor_alg_type {
22*99a2dd95SBruce Richardson 	RTE_DIST_ALG_BURST = 0,
23*99a2dd95SBruce Richardson 	RTE_DIST_ALG_SINGLE,
24*99a2dd95SBruce Richardson 	RTE_DIST_NUM_ALG_TYPES
25*99a2dd95SBruce Richardson };
26*99a2dd95SBruce Richardson 
27*99a2dd95SBruce Richardson struct rte_distributor;
28*99a2dd95SBruce Richardson struct rte_mbuf;
29*99a2dd95SBruce Richardson 
30*99a2dd95SBruce Richardson /**
31*99a2dd95SBruce Richardson  * Function to create a new distributor instance
32*99a2dd95SBruce Richardson  *
33*99a2dd95SBruce Richardson  * Reserves the memory needed for the distributor operation and
34*99a2dd95SBruce Richardson  * initializes the distributor to work with the configured number of workers.
35*99a2dd95SBruce Richardson  *
36*99a2dd95SBruce Richardson  * @param name
37*99a2dd95SBruce Richardson  *   The name to be given to the distributor instance.
38*99a2dd95SBruce Richardson  * @param socket_id
39*99a2dd95SBruce Richardson  *   The NUMA node on which the memory is to be allocated
40*99a2dd95SBruce Richardson  * @param num_workers
41*99a2dd95SBruce Richardson  *   The maximum number of workers that will request packets from this
42*99a2dd95SBruce Richardson  *   distributor
43*99a2dd95SBruce Richardson  * @param alg_type
44*99a2dd95SBruce Richardson  *   Call the legacy API, or use the new burst API. legacy uses 32-bit
45*99a2dd95SBruce Richardson  *   flow ID, and works on a single packet at a time. Latest uses 15-
46*99a2dd95SBruce Richardson  *   bit flow ID and works on up to 8 packets at a time to workers.
47*99a2dd95SBruce Richardson  * @return
48*99a2dd95SBruce Richardson  *   The newly created distributor instance
49*99a2dd95SBruce Richardson  */
50*99a2dd95SBruce Richardson struct rte_distributor *
51*99a2dd95SBruce Richardson rte_distributor_create(const char *name, unsigned int socket_id,
52*99a2dd95SBruce Richardson 		unsigned int num_workers,
53*99a2dd95SBruce Richardson 		unsigned int alg_type);
54*99a2dd95SBruce Richardson 
55*99a2dd95SBruce Richardson /*  *** APIS to be called on the distributor lcore ***  */
56*99a2dd95SBruce Richardson /*
57*99a2dd95SBruce Richardson  * The following APIs are the public APIs which are designed for use on a
58*99a2dd95SBruce Richardson  * single lcore which acts as the distributor lcore for a given distributor
59*99a2dd95SBruce Richardson  * instance. These functions cannot be called on multiple cores simultaneously
60*99a2dd95SBruce Richardson  * without using locking to protect access to the internals of the distributor.
61*99a2dd95SBruce Richardson  *
62*99a2dd95SBruce Richardson  * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
63*99a2dd95SBruce Richardson  * for the same distributor instance, otherwise deadlock will result.
64*99a2dd95SBruce Richardson  */
65*99a2dd95SBruce Richardson 
66*99a2dd95SBruce Richardson /**
67*99a2dd95SBruce Richardson  * Process a set of packets by distributing them among workers that request
68*99a2dd95SBruce Richardson  * packets. The distributor will ensure that no two packets that have the
69*99a2dd95SBruce Richardson  * same flow id, or tag, in the mbuf will be processed on different cores at
70*99a2dd95SBruce Richardson  * the same time.
71*99a2dd95SBruce Richardson  *
72*99a2dd95SBruce Richardson  * The user is advocated to set tag for each mbuf before calling this function.
73*99a2dd95SBruce Richardson  * If user doesn't set the tag, the tag value can be various values depending on
74*99a2dd95SBruce Richardson  * driver implementation and configuration.
75*99a2dd95SBruce Richardson  *
76*99a2dd95SBruce Richardson  * This is not multi-thread safe and should only be called on a single lcore.
77*99a2dd95SBruce Richardson  *
78*99a2dd95SBruce Richardson  * @param d
79*99a2dd95SBruce Richardson  *   The distributor instance to be used
80*99a2dd95SBruce Richardson  * @param mbufs
81*99a2dd95SBruce Richardson  *   The mbufs to be distributed
82*99a2dd95SBruce Richardson  * @param num_mbufs
83*99a2dd95SBruce Richardson  *   The number of mbufs in the mbufs array
84*99a2dd95SBruce Richardson  * @return
85*99a2dd95SBruce Richardson  *   The number of mbufs processed.
86*99a2dd95SBruce Richardson  */
87*99a2dd95SBruce Richardson int
88*99a2dd95SBruce Richardson rte_distributor_process(struct rte_distributor *d,
89*99a2dd95SBruce Richardson 		struct rte_mbuf **mbufs, unsigned int num_mbufs);
90*99a2dd95SBruce Richardson 
91*99a2dd95SBruce Richardson /**
92*99a2dd95SBruce Richardson  * Get a set of mbufs that have been returned to the distributor by workers
93*99a2dd95SBruce Richardson  *
94*99a2dd95SBruce Richardson  * This should only be called on the same lcore as rte_distributor_process()
95*99a2dd95SBruce Richardson  *
96*99a2dd95SBruce Richardson  * @param d
97*99a2dd95SBruce Richardson  *   The distributor instance to be used
98*99a2dd95SBruce Richardson  * @param mbufs
99*99a2dd95SBruce Richardson  *   The mbufs pointer array to be filled in
100*99a2dd95SBruce Richardson  * @param max_mbufs
101*99a2dd95SBruce Richardson  *   The size of the mbufs array
102*99a2dd95SBruce Richardson  * @return
103*99a2dd95SBruce Richardson  *   The number of mbufs returned in the mbufs array.
104*99a2dd95SBruce Richardson  */
105*99a2dd95SBruce Richardson int
106*99a2dd95SBruce Richardson rte_distributor_returned_pkts(struct rte_distributor *d,
107*99a2dd95SBruce Richardson 		struct rte_mbuf **mbufs, unsigned int max_mbufs);
108*99a2dd95SBruce Richardson 
109*99a2dd95SBruce Richardson /**
110*99a2dd95SBruce Richardson  * Flush the distributor component, so that there are no in-flight or
111*99a2dd95SBruce Richardson  * backlogged packets awaiting processing
112*99a2dd95SBruce Richardson  *
113*99a2dd95SBruce Richardson  * This should only be called on the same lcore as rte_distributor_process()
114*99a2dd95SBruce Richardson  *
115*99a2dd95SBruce Richardson  * @param d
116*99a2dd95SBruce Richardson  *   The distributor instance to be used
117*99a2dd95SBruce Richardson  * @return
118*99a2dd95SBruce Richardson  *   The number of queued/in-flight packets that were completed by this call.
119*99a2dd95SBruce Richardson  */
120*99a2dd95SBruce Richardson int
121*99a2dd95SBruce Richardson rte_distributor_flush(struct rte_distributor *d);
122*99a2dd95SBruce Richardson 
123*99a2dd95SBruce Richardson /**
124*99a2dd95SBruce Richardson  * Clears the array of returned packets used as the source for the
125*99a2dd95SBruce Richardson  * rte_distributor_returned_pkts() API call.
126*99a2dd95SBruce Richardson  *
127*99a2dd95SBruce Richardson  * This should only be called on the same lcore as rte_distributor_process()
128*99a2dd95SBruce Richardson  *
129*99a2dd95SBruce Richardson  * @param d
130*99a2dd95SBruce Richardson  *   The distributor instance to be used
131*99a2dd95SBruce Richardson  */
132*99a2dd95SBruce Richardson void
133*99a2dd95SBruce Richardson rte_distributor_clear_returns(struct rte_distributor *d);
134*99a2dd95SBruce Richardson 
135*99a2dd95SBruce Richardson /*  *** APIS to be called on the worker lcores ***  */
136*99a2dd95SBruce Richardson /*
137*99a2dd95SBruce Richardson  * The following APIs are the public APIs which are designed for use on
138*99a2dd95SBruce Richardson  * multiple lcores which act as workers for a distributor. Each lcore should use
139*99a2dd95SBruce Richardson  * a unique worker id when requesting packets.
140*99a2dd95SBruce Richardson  *
141*99a2dd95SBruce Richardson  * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
142*99a2dd95SBruce Richardson  * for the same distributor instance, otherwise deadlock will result.
143*99a2dd95SBruce Richardson  */
144*99a2dd95SBruce Richardson 
145*99a2dd95SBruce Richardson /**
146*99a2dd95SBruce Richardson  * API called by a worker to get new packets to process. Any previous packets
147*99a2dd95SBruce Richardson  * given to the worker is assumed to have completed processing, and may be
148*99a2dd95SBruce Richardson  * optionally returned to the distributor via the oldpkt parameter.
149*99a2dd95SBruce Richardson  *
150*99a2dd95SBruce Richardson  * @param d
151*99a2dd95SBruce Richardson  *   The distributor instance to be used
152*99a2dd95SBruce Richardson  * @param worker_id
153*99a2dd95SBruce Richardson  *   The worker instance number to use - must be less that num_workers passed
154*99a2dd95SBruce Richardson  *   at distributor creation time.
155*99a2dd95SBruce Richardson  * @param pkts
156*99a2dd95SBruce Richardson  *   The mbufs pointer array to be filled in (up to 8 packets)
157*99a2dd95SBruce Richardson  * @param oldpkt
158*99a2dd95SBruce Richardson  *   The previous packets, if any, being processed by the worker
159*99a2dd95SBruce Richardson  * @param retcount
160*99a2dd95SBruce Richardson  *   The number of packets being returned
161*99a2dd95SBruce Richardson  *
162*99a2dd95SBruce Richardson  * @return
163*99a2dd95SBruce Richardson  *   The number of packets in the pkts array
164*99a2dd95SBruce Richardson  */
165*99a2dd95SBruce Richardson int
166*99a2dd95SBruce Richardson rte_distributor_get_pkt(struct rte_distributor *d,
167*99a2dd95SBruce Richardson 	unsigned int worker_id, struct rte_mbuf **pkts,
168*99a2dd95SBruce Richardson 	struct rte_mbuf **oldpkt, unsigned int retcount);
169*99a2dd95SBruce Richardson 
170*99a2dd95SBruce Richardson /**
171*99a2dd95SBruce Richardson  * API called by a worker to return a completed packet without requesting a
172*99a2dd95SBruce Richardson  * new packet, for example, because a worker thread is shutting down
173*99a2dd95SBruce Richardson  *
174*99a2dd95SBruce Richardson  * @param d
175*99a2dd95SBruce Richardson  *   The distributor instance to be used
176*99a2dd95SBruce Richardson  * @param worker_id
177*99a2dd95SBruce Richardson  *   The worker instance number to use - must be less that num_workers passed
178*99a2dd95SBruce Richardson  *   at distributor creation time.
179*99a2dd95SBruce Richardson  * @param oldpkt
180*99a2dd95SBruce Richardson  *   The previous packets being processed by the worker
181*99a2dd95SBruce Richardson  * @param num
182*99a2dd95SBruce Richardson  *   The number of packets in the oldpkt array
183*99a2dd95SBruce Richardson  */
184*99a2dd95SBruce Richardson int
185*99a2dd95SBruce Richardson rte_distributor_return_pkt(struct rte_distributor *d,
186*99a2dd95SBruce Richardson 	unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
187*99a2dd95SBruce Richardson 
188*99a2dd95SBruce Richardson /**
189*99a2dd95SBruce Richardson  * API called by a worker to request a new packet to process.
190*99a2dd95SBruce Richardson  * Any previous packets given to the worker are assumed to have completed
191*99a2dd95SBruce Richardson  * processing, and may be optionally returned to the distributor via
192*99a2dd95SBruce Richardson  * the oldpkt parameter.
193*99a2dd95SBruce Richardson  * Unlike rte_distributor_get_pkt(), this function does not wait for
194*99a2dd95SBruce Richardson  * new packets to be provided by the distributor.
195*99a2dd95SBruce Richardson  *
196*99a2dd95SBruce Richardson  * NOTE: after calling this function, rte_distributor_poll_pkt() should
197*99a2dd95SBruce Richardson  * be used to poll for the packets requested. The rte_distributor_get_pkt()
198*99a2dd95SBruce Richardson  * API should *not* be used to try and retrieve the new packets.
199*99a2dd95SBruce Richardson  *
200*99a2dd95SBruce Richardson  * @param d
201*99a2dd95SBruce Richardson  *   The distributor instance to be used
202*99a2dd95SBruce Richardson  * @param worker_id
203*99a2dd95SBruce Richardson  *   The worker instance number to use - must be less that num_workers passed
204*99a2dd95SBruce Richardson  *   at distributor creation time.
205*99a2dd95SBruce Richardson  * @param oldpkt
206*99a2dd95SBruce Richardson  *   The returning packets, if any, processed by the worker
207*99a2dd95SBruce Richardson  * @param count
208*99a2dd95SBruce Richardson  *   The number of returning packets
209*99a2dd95SBruce Richardson  */
210*99a2dd95SBruce Richardson void
211*99a2dd95SBruce Richardson rte_distributor_request_pkt(struct rte_distributor *d,
212*99a2dd95SBruce Richardson 		unsigned int worker_id, struct rte_mbuf **oldpkt,
213*99a2dd95SBruce Richardson 		unsigned int count);
214*99a2dd95SBruce Richardson 
215*99a2dd95SBruce Richardson /**
216*99a2dd95SBruce Richardson  * API called by a worker to check for new packets that were previously
217*99a2dd95SBruce Richardson  * requested by a call to rte_distributor_request_pkt(). It does not wait
218*99a2dd95SBruce Richardson  * for the new packets to be available, but returns if the request has
219*99a2dd95SBruce Richardson  * not yet been fulfilled by the distributor.
220*99a2dd95SBruce Richardson  *
221*99a2dd95SBruce Richardson  * @param d
222*99a2dd95SBruce Richardson  *   The distributor instance to be used
223*99a2dd95SBruce Richardson  * @param worker_id
224*99a2dd95SBruce Richardson  *   The worker instance number to use - must be less that num_workers passed
225*99a2dd95SBruce Richardson  *   at distributor creation time.
226*99a2dd95SBruce Richardson  * @param mbufs
227*99a2dd95SBruce Richardson  *   The array of mbufs being given to the worker
228*99a2dd95SBruce Richardson  *
229*99a2dd95SBruce Richardson  * @return
230*99a2dd95SBruce Richardson  *   The number of packets being given to the worker thread,
231*99a2dd95SBruce Richardson  *   -1 if no packets are yet available (burst API - RTE_DIST_ALG_BURST)
232*99a2dd95SBruce Richardson  *   0 if no packets are yet available (legacy single API - RTE_DIST_ALG_SINGLE)
233*99a2dd95SBruce Richardson  */
234*99a2dd95SBruce Richardson int
235*99a2dd95SBruce Richardson rte_distributor_poll_pkt(struct rte_distributor *d,
236*99a2dd95SBruce Richardson 		unsigned int worker_id, struct rte_mbuf **mbufs);
237*99a2dd95SBruce Richardson 
238*99a2dd95SBruce Richardson #ifdef __cplusplus
239*99a2dd95SBruce Richardson }
240*99a2dd95SBruce Richardson #endif
241*99a2dd95SBruce Richardson 
242*99a2dd95SBruce Richardson #endif
243