4 * Copyright(c) 2017 Intel Corporation. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 #ifndef _RTE_DISTRIBUTOR_H_
34 #define _RTE_DISTRIBUTOR_H_
40 * The distributor is a component which is designed to pass packets
41 * one-at-a-time to workers, with dynamic load balancing.
48 /* Type of distribution (burst/single) */
49 enum rte_distributor_alg_type {
50 RTE_DIST_ALG_BURST = 0,
52 RTE_DIST_NUM_ALG_TYPES
55 struct rte_distributor;
59 * Function to create a new distributor instance
61 * Reserves the memory needed for the distributor operation and
62 * initializes the distributor to work with the configured number of workers.
65 * The name to be given to the distributor instance.
67 * The NUMA node on which the memory is to be allocated
69 * The maximum number of workers that will request packets from this
72 * Call the legacy API, or use the new burst API. legacy uses 32-bit
73 * flow ID, and works on a single packet at a time. Latest uses 15-
74 * bit flow ID and works on up to 8 packets at a time to worers.
76 * The newly created distributor instance
78 struct rte_distributor *
79 rte_distributor_create(const char *name, unsigned int socket_id,
80 unsigned int num_workers,
81 unsigned int alg_type);
83 /* *** APIS to be called on the distributor lcore *** */
85 * The following APIs are the public APIs which are designed for use on a
86 * single lcore which acts as the distributor lcore for a given distributor
87 * instance. These functions cannot be called on multiple cores simultaneously
88 * without using locking to protect access to the internals of the distributor.
90 * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
91 * for the same distributor instance, otherwise deadlock will result.
95 * Process a set of packets by distributing them among workers that request
96 * packets. The distributor will ensure that no two packets that have the
97 * same flow id, or tag, in the mbuf will be processed on different cores at
100 * The user is advocated to set tag for each mbuf before calling this function.
101 * If user doesn't set the tag, the tag value can be various values depending on
102 * driver implementation and configuration.
104 * This is not multi-thread safe and should only be called on a single lcore.
107 * The distributor instance to be used
109 * The mbufs to be distributed
111 * The number of mbufs in the mbufs array
113 * The number of mbufs processed.
116 rte_distributor_process(struct rte_distributor *d,
117 struct rte_mbuf **mbufs, unsigned int num_mbufs);
120 * Get a set of mbufs that have been returned to the distributor by workers
122 * This should only be called on the same lcore as rte_distributor_process()
125 * The distributor instance to be used
127 * The mbufs pointer array to be filled in
129 * The size of the mbufs array
131 * The number of mbufs returned in the mbufs array.
134 rte_distributor_returned_pkts(struct rte_distributor *d,
135 struct rte_mbuf **mbufs, unsigned int max_mbufs);
138 * Flush the distributor component, so that there are no in-flight or
139 * backlogged packets awaiting processing
141 * This should only be called on the same lcore as rte_distributor_process()
144 * The distributor instance to be used
146 * The number of queued/in-flight packets that were completed by this call.
149 rte_distributor_flush(struct rte_distributor *d);
152 * Clears the array of returned packets used as the source for the
153 * rte_distributor_returned_pkts() API call.
155 * This should only be called on the same lcore as rte_distributor_process()
158 * The distributor instance to be used
161 rte_distributor_clear_returns(struct rte_distributor *d);
163 /* *** APIS to be called on the worker lcores *** */
165 * The following APIs are the public APIs which are designed for use on
166 * multiple lcores which act as workers for a distributor. Each lcore should use
167 * a unique worker id when requesting packets.
169 * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
170 * for the same distributor instance, otherwise deadlock will result.
174 * API called by a worker to get new packets to process. Any previous packets
175 * given to the worker is assumed to have completed processing, and may be
176 * optionally returned to the distributor via the oldpkt parameter.
179 * The distributor instance to be used
181 * The worker instance number to use - must be less that num_workers passed
182 * at distributor creation time.
184 * The mbufs pointer array to be filled in (up to 8 packets)
186 * The previous packet, if any, being processed by the worker
188 * The number of packets being returned
191 * The number of packets in the pkts array
194 rte_distributor_get_pkt(struct rte_distributor *d,
195 unsigned int worker_id, struct rte_mbuf **pkts,
196 struct rte_mbuf **oldpkt, unsigned int retcount);
199 * API called by a worker to return a completed packet without requesting a
200 * new packet, for example, because a worker thread is shutting down
203 * The distributor instance to be used
205 * The worker instance number to use - must be less that num_workers passed
206 * at distributor creation time.
208 * The previous packets being processed by the worker
210 * The number of packets in the oldpkt array
213 rte_distributor_return_pkt(struct rte_distributor *d,
214 unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
217 * API called by a worker to request a new packet to process.
218 * Any previous packet given to the worker is assumed to have completed
219 * processing, and may be optionally returned to the distributor via
220 * the oldpkt parameter.
221 * Unlike rte_distributor_get_pkt_burst(), this function does not wait for a
222 * new packet to be provided by the distributor.
224 * NOTE: after calling this function, rte_distributor_poll_pkt_burst() should
225 * be used to poll for the packet requested. The rte_distributor_get_pkt_burst()
226 * API should *not* be used to try and retrieve the new packet.
229 * The distributor instance to be used
231 * The worker instance number to use - must be less that num_workers passed
232 * at distributor creation time.
234 * The returning packets, if any, processed by the worker
236 * The number of returning packets
239 rte_distributor_request_pkt(struct rte_distributor *d,
240 unsigned int worker_id, struct rte_mbuf **oldpkt,
244 * API called by a worker to check for a new packet that was previously
245 * requested by a call to rte_distributor_request_pkt(). It does not wait
246 * for the new packet to be available, but returns NULL if the request has
247 * not yet been fulfilled by the distributor.
250 * The distributor instance to be used
252 * The worker instance number to use - must be less that num_workers passed
253 * at distributor creation time.
255 * The array of mbufs being given to the worker
258 * The number of packets being given to the worker thread, zero if no
259 * packet is yet available.
262 rte_distributor_poll_pkt(struct rte_distributor *d,
263 unsigned int worker_id, struct rte_mbuf **mbufs);