aboutsummaryrefslogtreecommitdiffstats
path: root/lib/librte_distributor/rte_distributor.h
blob: 9b9efdbe0299babb1bde509f19a437fda904df12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*-
 *   BSD LICENSE
 *
 *   Copyright(c) 2017 Intel Corporation. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _RTE_DISTRIBUTOR_H_
#define _RTE_DISTRIBUTOR_H_

/**
 * @file
 * RTE distributor
 *
 * The distributor is a component which is designed to pass packets
 * one-at-a-time to workers, with dynamic load balancing.
 */

#ifdef __cplusplus
extern "C" {
#endif

/* Type of distribution (burst/single) */
enum rte_distributor_alg_type {
	RTE_DIST_ALG_BURST = 0,
	RTE_DIST_ALG_SINGLE,
	RTE_DIST_NUM_ALG_TYPES
};

struct rte_distributor;
struct rte_mbuf;

/**
 * Function to create a new distributor instance
 *
 * Reserves the memory needed for the distributor operation and
 * initializes the distributor to work with the configured number of workers.
 *
 * @param name
 *   The name to be given to the distributor instance.
 * @param socket_id
 *   The NUMA node on which the memory is to be allocated
 * @param num_workers
 *   The maximum number of workers that will request packets from this
 *   distributor
 * @param alg_type
 *   Call the legacy API, or use the new burst API. legacy uses 32-bit
 *   flow ID, and works on a single packet at a time. Latest uses 15-
 *   bit flow ID and works on up to 8 packets at a time to worers.
 * @return
 *   The newly created distributor instance
 */
struct rte_distributor *
rte_distributor_create(const char *name, unsigned int socket_id,
		unsigned int num_workers,
		unsigned int alg_type);

/*  *** APIS to be called on the distributor lcore ***  */
/*
 * The following APIs are the public APIs which are designed for use on a
 * single lcore which acts as the distributor lcore for a given distributor
 * instance. These functions cannot be called on multiple cores simultaneously
 * without using locking to protect access to the internals of the distributor.
 *
 * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
 * for the same distributor instance, otherwise deadlock will result.
 */

/**
 * Process a set of packets by distributing them among workers that request
 * packets. The distributor will ensure that no two packets that have the
 * same flow id, or tag, in the mbuf will be processed on different cores at
 * the same time.
 *
 * The user is advocated to set tag for each mbuf before calling this function.
 * If user doesn't set the tag, the tag value can be various values depending on
 * driver implementation and configuration.
 *
 * This is not multi-thread safe and should only be called on a single lcore.
 *
 * @param d
 *   The distributor instance to be used
 * @param mbufs
 *   The mbufs to be distributed
 * @param num_mbufs
 *   The number of mbufs in the mbufs array
 * @return
 *   The number of mbufs processed.
 */
int
rte_distributor_process(struct rte_distributor *d,
		struct rte_mbuf **mbufs, unsigned int num_mbufs);

/**
 * Get a set of mbufs that have been returned to the distributor by workers
 *
 * This should only be called on the same lcore as rte_distributor_process()
 *
 * @param d
 *   The distributor instance to be used
 * @param mbufs
 *   The mbufs pointer array to be filled in
 * @param max_mbufs
 *   The size of the mbufs array
 * @return
 *   The number of mbufs returned in the mbufs array.
 */
int
rte_distributor_returned_pkts(struct rte_distributor *d,
		struct rte_mbuf **mbufs, unsigned int max_mbufs);

/**
 * Flush the distributor component, so that there are no in-flight or
 * backlogged packets awaiting processing
 *
 * This should only be called on the same lcore as rte_distributor_process()
 *
 * @param d
 *   The distributor instance to be used
 * @return
 *   The number of queued/in-flight packets that were completed by this call.
 */
int
rte_distributor_flush(struct rte_distributor *d);

/**
 * Clears the array of returned packets used as the source for the
 * rte_distributor_returned_pkts() API call.
 *
 * This should only be called on the same lcore as rte_distributor_process()
 *
 * @param d
 *   The distributor instance to be used
 */
void
rte_distributor_clear_returns(struct rte_distributor *d);

/*  *** APIS to be called on the worker lcores ***  */
/*
 * The following APIs are the public APIs which are designed for use on
 * multiple lcores which act as workers for a distributor. Each lcore should use
 * a unique worker id when requesting packets.
 *
 * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
 * for the same distributor instance, otherwise deadlock will result.
 */

/**
 * API called by a worker to get new packets to process. Any previous packets
 * given to the worker is assumed to have completed processing, and may be
 * optionally returned to the distributor via the oldpkt parameter.
 *
 * @param d
 *   The distributor instance to be used
 * @param worker_id
 *   The worker instance number to use - must be less that num_workers passed
 *   at distributor creation time.
 * @param pkts
 *   The mbufs pointer array to be filled in (up to 8 packets)
 * @param oldpkt
 *   The previous packet, if any, being processed by the worker
 * @param retcount
 *   The number of packets being returned
 *
 * @return
 *   The number of packets in the pkts array
 */
int
rte_distributor_get_pkt(struct rte_distributor *d,
	unsigned int worker_id, struct rte_mbuf **pkts,
	struct rte_mbuf **oldpkt, unsigned int retcount);

/**
 * API called by a worker to return a completed packet without requesting a
 * new packet, for example, because a worker thread is shutting down
 *
 * @param d
 *   The distributor instance to be used
 * @param worker_id
 *   The worker instance number to use - must be less that num_workers passed
 *   at distributor creation time.
 * @param oldpkt
 *   The previous packets being processed by the worker
 * @param num
 *   The number of packets in the oldpkt array
 */
int
rte_distributor_return_pkt(struct rte_distributor *d,
	unsigned int worker_id, struct rte_mbuf **oldpkt, int num);

/**
 * API called by a worker to request a new packet to process.
 * Any previous packet given to the worker is assumed to have completed
 * processing, and may be optionally returned to the distributor via
 * the oldpkt parameter.
 * Unlike rte_distributor_get_pkt_burst(), this function does not wait for a
 * new packet to be provided by the distributor.
 *
 * NOTE: after calling this function, rte_distributor_poll_pkt_burst() should
 * be used to poll for the packet requested. The rte_distributor_get_pkt_burst()
 * API should *not* be used to try and retrieve the new packet.
 *
 * @param d
 *   The distributor instance to be used
 * @param worker_id
 *   The worker instance number to use - must be less that num_workers passed
 *   at distributor creation time.
 * @param oldpkt
 *   The returning packets, if any, processed by the worker
 * @param count
 *   The number of returning packets
 */
void
rte_distributor_request_pkt(struct rte_distributor *d,
		unsigned int worker_id, struct rte_mbuf **oldpkt,
		unsigned int count);

/**
 * API called by a worker to check for a new packet that was previously
 * requested by a call to rte_distributor_request_pkt(). It does not wait
 * for the new packet to be available, but returns NULL if the request has
 * not yet been fulfilled by the distributor.
 *
 * @param d
 *   The distributor instance to be used
 * @param worker_id
 *   The worker instance number to use - must be less that num_workers passed
 *   at distributor creation time.
 * @param mbufs
 *   The array of mbufs being given to the worker
 *
 * @return
 *   The number of packets being given to the worker thread, zero if no
 *   packet is yet available.
 */
int
rte_distributor_poll_pkt(struct rte_distributor *d,
		unsigned int worker_id, struct rte_mbuf **mbufs);

#ifdef __cplusplus
}
#endif

#endif