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