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