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