/** * @brief Initialize MBuf pool for device * * @param name const char*, name of MemPool object * * @return true if success and false otherwice */ bool DPDKAdapter::initDevMBufPool(const char* name) { if(!name) return false; // Don't create MemPool if it already exists MemPool_t* pool = rte_mempool_lookup(name); if(pool) return pool; pool = rte_mempool_create(name, DPDK_MEMPOOL_SIZE, MBUF_SIZE, DPDK_MEMPOOL_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, SOCKET_ID_ANY, MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET); if(pool == NULL) { qCritical("Can not init memory pool"); return false; } if(rte_mempool_lookup(name) != pool) { qCritical("Can not lookup memory pool by its name"); return false; } return true; }
void * intel_pool_lookup(const char *name) { struct rte_mempool *mempool = rte_mempool_lookup(name); return mempool; }
int netdpcmd_ring_init(void) { netdpcmd_ring_rx = rte_ring_lookup(NETDP_PRI_2_SEC); if(NULL == netdpcmd_ring_rx) { printf("Lookup ring(%s) failed \n", NETDP_PRI_2_SEC); return NETDP_ECTRLRING; } netdpcmd_ring_tx = rte_ring_lookup(NETDP_SEC_2_PRI); if(NULL == netdpcmd_ring_tx) { printf("Lookup ring(%s) failed \n", NETDP_SEC_2_PRI); return NETDP_ECTRLRING; } netdpcmd_message_pool = rte_mempool_lookup(NETDP_MSG_POOL_NAME); if(NULL == netdpcmd_message_pool) { printf("Lookup message pool(%s) failed \n", NETDP_MSG_POOL_NAME); return NETDP_EMSGPOOL; } return 0; }
/** * Initialise the mbuf pool for packet reception for the NIC, and any other * buffer pools needed by the app - currently none. */ static int init_mbuf_pools(void) { const unsigned num_mbufs = (num_rings * MBUFS_PER_RING); /* don't pass single-producer/single-consumer flags to mbuf create as it * seems faster to use a cache instead */ printf("Creating mbuf pool '%s' [%u mbufs] ...\n", HSM_POOL_NAME, num_mbufs); if (rte_eal_process_type() == RTE_PROC_SECONDARY) { pktmbuf_pool = rte_mempool_lookup(HSM_POOL_NAME); if (pktmbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n"); } else { pktmbuf_pool = rte_mempool_create(HSM_POOL_NAME, num_mbufs, MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS ); } return (pktmbuf_pool == NULL); /* 0 on success */ }
/* Initialize DPDK link layer. * * No need to free any memory on shutdown as memory is owned by datapath. */ int dpdk_link_init(void) { DPDK_DEBUG() reply_ring = rte_ring_lookup(VSWITCHD_REPLY_RING_NAME); if (reply_ring == NULL) { rte_exit(EXIT_FAILURE, "Cannot get reply ring - is datapath running?\n"); } message_ring = rte_ring_lookup(VSWITCHD_MESSAGE_RING_NAME); if (message_ring == NULL) { rte_exit(EXIT_FAILURE, "Cannot get message ring - is datapath running?\n"); } packet_ring = rte_ring_lookup(VSWITCHD_PACKET_RING_NAME); if (packet_ring == NULL) { rte_exit(EXIT_FAILURE, "Cannot get packet packet ring - is datapath running?\n"); } mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); if (mp == NULL) { rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs - is datapath running?\n"); } return 0; }
int anscli_ring_init(void) { anscli_ring_rx = rte_ring_lookup(ANS_PRI_2_SEC); if(NULL == anscli_ring_rx) { printf("Lookup ring(%s) failed \n", ANS_PRI_2_SEC); return ANS_ECTRLRING; } anscli_ring_tx = rte_ring_lookup(ANS_SEC_2_PRI); if(NULL == anscli_ring_tx) { printf("Lookup ring(%s) failed \n", ANS_SEC_2_PRI); return ANS_ECTRLRING; } anscli_message_pool = rte_mempool_lookup(ANS_MSG_POOL_NAME); if(NULL == anscli_message_pool) { printf("Lookup message pool(%s) failed \n", ANS_MSG_POOL_NAME); return ANS_EMSGPOOL; } return 0; }
/** * @brief Lookup for MBuf assigned to socket * * @param devId uint8_t, device identifier * @param prefix const char*, prefix for MemPool name * * @return MBuf_t*, pointer to MBuf that was found */ MemPool_t* DPDKAdapter::findMPool(uint8_t devId, const char* prefix) { char name[RTE_MEMPOOL_NAMESIZE]; mbufPoolNameBuilder(devId, name, sizeof(name), prefix); return (rte_mempool_lookup((const char*)name)); }
int init_secondary_mempool(const char* mempool_name) { struct rte_mempool *mempool = rte_mempool_lookup(mempool_name); if (mempool == NULL) { return -EINVAL; } set_mempool(mempool); return 0; }
struct rte_mempool * __rte_experimental rte_comp_op_pool_create(const char *name, unsigned int nb_elts, unsigned int cache_size, uint16_t user_size, int socket_id) { struct rte_comp_op_pool_private *priv; unsigned int elt_size = sizeof(struct rte_comp_op) + user_size; /* lookup mempool in case already allocated */ struct rte_mempool *mp = rte_mempool_lookup(name); if (mp != NULL) { priv = (struct rte_comp_op_pool_private *) rte_mempool_get_priv(mp); if (mp->elt_size != elt_size || mp->cache_size < cache_size || mp->size < nb_elts || priv->user_size < user_size) { mp = NULL; COMPRESSDEV_LOG(ERR, "Mempool %s already exists but with incompatible parameters", name); return NULL; } return mp; } mp = rte_mempool_create( name, nb_elts, elt_size, cache_size, sizeof(struct rte_comp_op_pool_private), NULL, NULL, rte_comp_op_init, NULL, socket_id, 0); if (mp == NULL) { COMPRESSDEV_LOG(ERR, "Failed to create mempool %s", name); return NULL; } priv = (struct rte_comp_op_pool_private *) rte_mempool_get_priv(mp); priv->user_size = user_size; return mp; }
void InitSocketInterface(void) { // socket_tcb_ring_recv = rte_ring_lookup(TCB_TO_SOCKET); buffer_message_pool = rte_mempool_lookup(_MSG_POOL); if(buffer_message_pool == NULL) { printf("ERROR **** socket tcb Message pool failed\n"); } else { printf("socket tcb recv side OK.\n"); } }
inline static int onvm_nf_stop(struct onvm_nf_info *nf_info) { uint16_t nf_id; uint16_t service_id; int mapIndex; struct rte_mempool *nf_info_mp; if(nf_info == NULL || nf_info->status != NF_RUNNING) return 1; nf_info->status = NF_STOPPED; nf_id = nf_info->instance_id; service_id = nf_info->service_id; cores[nf_info->core].nf_count--; cores[nf_info->core].is_dedicated_core = 0; /* Clean up dangling pointers to info struct */ nfs[nf_id].info = NULL; /* Reset stats */ onvm_stats_clear_nf(nf_id); /* Remove this NF from the service map. * Need to shift all elements past it in the array left to avoid gaps */ nf_per_service_count[service_id]--; for (mapIndex = 0; mapIndex < MAX_NFS_PER_SERVICE; mapIndex++) { if (services[service_id][mapIndex] == nf_id) { break; } } if (mapIndex < MAX_NFS_PER_SERVICE) { // sanity error check services[service_id][mapIndex] = 0; for (; mapIndex < MAX_NFS_PER_SERVICE - 1; mapIndex++) { // Shift the NULL to the end of the array if (services[service_id][mapIndex + 1] == 0) { // Short circuit when we reach the end of this service's list break; } services[service_id][mapIndex] = services[service_id][mapIndex + 1]; services[service_id][mapIndex + 1] = 0; } } /* Free info struct */ /* Lookup mempool for nf_info struct */ nf_info_mp = rte_mempool_lookup(_NF_MEMPOOL_NAME); if (nf_info_mp == NULL) return 1; rte_mempool_put(nf_info_mp, (void*)nf_info); return 0; }
static struct rte_mempool * create_mempool(void) { struct rte_mempool * mp; mp = rte_mempool_lookup("test_sched"); if (!mp) mp = rte_mempool_create("test_sched", NB_MBUF, MBUF_SZ, MEMPOOL_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, SOCKET, 0); return mp; }
int main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; if ((arg_offset = onvm_nf_init(argc, argv, NF_TAG)) < 0) return -1; argc -= arg_offset; argv += arg_offset; if (parse_app_args(argc, argv, progname) < 0) rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); struct rte_mempool *pktmbuf_pool; struct rte_mbuf* pkts[NUM_PKTS]; int i; pktmbuf_pool = rte_mempool_lookup(PKTMBUF_POOL_NAME); if(pktmbuf_pool == NULL) { rte_exit(EXIT_FAILURE, "Cannot find mbuf pool!\n"); } printf("Creating %d packets to send to %d\n", NUM_PKTS, destination); for (i=0; i < NUM_PKTS; i++) { struct onvm_pkt_meta* pmeta; pkts[i] = rte_pktmbuf_alloc(pktmbuf_pool); pmeta = onvm_get_pkt_meta(pkts[i]); pmeta->destination = destination; pmeta->action = ONVM_NF_ACTION_TONF; pkts[i]->port = 3; pkts[i]->hash.rss = i; onvm_nf_return_pkt(pkts[i]); } onvm_nf_run(nf_info, &packet_handler); printf("If we reach here, program is ending"); return 0; }
/** * Initialise the mbuf pool for packet reception for the NIC, and any other * buffer pools needed by the app - currently none. */ static int init_mbuf_pools(void) { const unsigned num_mbufs = (num_clients * MBUFS_PER_CLIENT) \ + (ports->num_ports * MBUFS_PER_PORT); /* don't pass single-producer/single-consumer flags to mbuf create as it * seems faster to use a cache instead */ printf("Lookup mbuf pool '%s' [%u mbufs] ...\n", VM_PKTMBUF_POOL_NAME, num_mbufs); pktmbuf_pool = rte_mempool_lookup(VM_PKTMBUF_POOL_NAME); if (pktmbuf_pool == NULL) { printf("Creating mbuf pool '%s' [%u mbufs] ...\n", VM_PKTMBUF_POOL_NAME, num_mbufs); pktmbuf_pool = rte_mempool_create(VM_PKTMBUF_POOL_NAME, num_mbufs, MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS ); } if (pktmbuf_pool == NULL) { printf("Creating mbuf pool '%s' [%u mbufs] ...\n", VM_PKTMBUF_POOL_NAME, num_mbufs); pktmbuf_pool = rte_mempool_create(VM_PKTMBUF_POOL_NAME, num_mbufs, MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS ); } return (pktmbuf_pool == NULL); /* 0 on success */ }
void send_loop(void) { RTE_LOG(INFO, APP, "send_loop()\n"); char pkt[PKT_SIZE] = {0}; int nreceived; int retval = 0; (void) retval; #ifdef CALC_CHECKSUM unsigned int kk = 0; #endif srand(time(NULL)); //Initializate packet contents int i; for(i = 0; i < PKT_SIZE; i++) pkt[i] = rand()%256; #if ALLOC_METHOD == ALLOC_APP struct rte_mempool * packets_pool = rte_mempool_lookup("ovs_mp_1500_0_262144"); //struct rte_mempool * packets_pool = rte_mempool_lookup("packets"); //Create mempool //struct rte_mempool * packets_pool = rte_mempool_create( // "packets", // NUM_PKTS, // MBUF_SIZE, // CACHE_SIZE, //This is the size of the mempool cache // sizeof(struct rte_pktmbuf_pool_private), // rte_pktmbuf_pool_init, // NULL, // rte_pktmbuf_init, // NULL, // rte_socket_id(), // 0 /*NO_FLAGS*/); if(packets_pool == NULL) { RTE_LOG(INFO, APP, "rte_errno: %s\n", rte_strerror(rte_errno)); rte_exit(EXIT_FAILURE, "Cannot find memory pool\n"); } RTE_LOG(INFO, APP, "There are %d free packets in the pool\n", rte_mempool_count(packets_pool)); #endif #ifdef USE_BURST struct rte_mbuf * packets_array[BURST_SIZE] = {0}; struct rte_mbuf * packets_array_rx[BURST_SIZE] = {0}; int ntosend; int n; (void) n; /* prealloc packets */ do { n = rte_mempool_get_bulk(packets_pool, (void **) packets_array, BURST_SIZE); } while(n != 0 && !stop); ntosend = BURST_SIZE; #else struct rte_mbuf * mbuf; /* prealloc packet */ do { mbuf = rte_pktmbuf_alloc(packets_pool); } while(mbuf == NULL); #endif RTE_LOG(INFO, APP, "Starting sender loop\n"); signal (SIGINT, crtl_c_handler); stop = 0; while(likely(!stop)) { while(pause_); #ifdef USE_BURST #if ALLOC_METHOD == ALLOC_OVS //Try to get BURS_SIZE free slots ntosend = rte_ring_dequeue_burst(alloc_q, (void **) packets_array, BURST_SIZE); #elif ALLOC_METHOD == ALLOC_APP //do //{ // n = rte_mempool_get_bulk(packets_pool, (void **) packets_array, BURST_SIZE); //} while(n != 0 && !stop); //ntosend = BURST_SIZE; #else #error "No implemented" #endif //Copy data to the buffers for(i = 0; i < ntosend; i++) { rte_memcpy(packets_array[i]->buf_addr, pkt, PKT_SIZE); //fill_packet(packets_array[i]->pkt.data); packets_array[i]->next = NULL; packets_array[i]->pkt_len = PKT_SIZE; packets_array[i]->data_len = PKT_SIZE; #ifdef CALC_CHECKSUM for(i = 0; i < ntosend; i++) for(kk = 0; kk < 8; kk++) checksum += ((uint64_t *)packets_array[i]->buf_addr)[kk]; #endif } //Enqueue data (try until all the allocated packets are enqueue) i = 0; while(i < ntosend && !stop) { i += rte_ring_enqueue_burst(tx_ring, (void **) &packets_array[i], ntosend - i); /* also dequeue some packets */ nreceived= rte_ring_dequeue_burst(rx_ring, (void **) packets_array_rx, BURST_SIZE); rx += nreceived; /* update statistics */ } #else // [NO] USE_BURST #if ALLOC_METHOD == ALLOC_OVS //Method 1 //Read a buffer to be used as a buffer for a packet retval = rte_ring_dequeue(alloc_q, (void **)&mbuf); if(retval != 0) { #ifdef CALC_ALLOC_STATS //stats.alloc_fails++; #endif continue; } #elif ALLOC_METHOD == ALLOC_APP //Method 2 //mbuf = rte_pktmbuf_alloc(packets_pool); //if(mbuf == NULL) //{ //#ifdef CALC_ALLOC_STATS // stats.alloc_fails++; //#endif // continue; //} #else #error "ALLOC_METHOD has a non valid value" #endif #if DELAY_CYCLES > 0 //This loop increases mumber of packets per second (don't ask me why) unsigned long long j = 0; for(j = 0; j < DELAY_CYCLES; j++) asm(""); #endif //Copy packet to the correct buffer rte_memcpy(mbuf->buf_addr, pkt, PKT_SIZE); //fill_packet(mbuf->pkt.data); //mbuf->pkt.next = NULL; //mbuf->pkt.pkt_len = PKT_SIZE; //mbuf->pkt.data_len = PKT_SIZE; (void) pkt; mbuf->next = NULL; mbuf->pkt_len = PKT_SIZE; mbuf->data_len = PKT_SIZE; #ifdef CALC_CHECKSUM for(kk = 0; kk < 8; kk++) checksum += ((uint64_t *)mbuf->buf_addr)[kk]; #endif //this method avoids dropping packets: //Simple tries until the packet is inserted in the queue tryagain: retval = rte_ring_enqueue(tx_ring, (void *) mbuf); if(retval == -ENOBUFS && !stop) { #ifdef CALC_TX_TRIES //stats.tx_retries++; #endif goto tryagain; } #ifdef CALC_TX_STATS //stats.tx++; #endif #endif //USE_BURST } #ifdef CALC_CHECKSUM printf("Checksum was %" PRIu64 "\n", checksum); #endif }
static struct vr_usocket * usock_alloc(unsigned short proto, unsigned short type) { int sock_fd = -1, domain, ret; /* socket TX buffer size = (hold flow table entries * size of jumbo frame) */ int setsocksndbuff = vr_flow_hold_limit * VR_DPDK_MAX_PACKET_SZ; int getsocksndbuff; socklen_t getsocksndbufflen = sizeof(getsocksndbuff); int error = 0, flags; unsigned int buf_len; struct vr_usocket *usockp = NULL, *child; bool is_socket = true; unsigned short sock_type; RTE_SET_USED(child); RTE_LOG(DEBUG, USOCK, "%s[%lx]: proto %u type %u\n", __func__, pthread_self(), proto, type); switch (type) { case TCP: domain = AF_INET; sock_type = SOCK_STREAM; break; case UNIX: case RAW: domain = AF_UNIX; sock_type = SOCK_DGRAM; break; default: return NULL; } if (proto == EVENT) { is_socket = false; sock_fd = eventfd(0, 0); RTE_LOG(DEBUG, USOCK, "%s[%lx]: new event FD %d\n", __func__, pthread_self(), sock_fd); if (sock_fd < 0) return NULL; } if (is_socket) { sock_fd = socket(domain, sock_type, 0); RTE_LOG(INFO, USOCK, "%s[%lx]: new socket FD %d\n", __func__, pthread_self(), sock_fd); if (sock_fd < 0) return NULL; /* set socket send buffer size */ ret = setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &setsocksndbuff, sizeof(setsocksndbuff)); if (ret == 0) { /* check if setting buffer succeeded */ ret = getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &getsocksndbuff, &getsocksndbufflen); if (ret == 0) { if (getsocksndbuff >= setsocksndbuff) { RTE_LOG(INFO, USOCK, "%s[%lx]: setting socket FD %d send buff size.\n" "Buffer size set to %d (requested %d)\n", __func__, pthread_self(), sock_fd, getsocksndbuff, setsocksndbuff); } else { /* set other than requested */ RTE_LOG(ERR, USOCK, "%s[%lx]: setting socket FD %d send buff size failed.\n" "Buffer size set to %d (requested %d)\n", __func__, pthread_self(), sock_fd, getsocksndbuff, setsocksndbuff); } } else { /* requesting buffer size failed */ RTE_LOG(ERR, USOCK, "%s[%lx]: getting socket FD %d send buff size failed (%d)\n", __func__, pthread_self(), sock_fd, errno); } } else { /* setting buffer size failed */ RTE_LOG(ERR, USOCK, "%s[%lx]: setting socket FD %d send buff size %d failed (%d)\n", __func__, pthread_self(), sock_fd, setsocksndbuff, errno); } } usockp = vr_zalloc(sizeof(*usockp), VR_USOCK_OBJECT); if (!usockp) goto error_exit; usockp->usock_type = type; usockp->usock_proto = proto; usockp->usock_fd = sock_fd; usockp->usock_state = INITED; if (is_socket) { error = vr_usocket_bind(usockp); if (error < 0) goto error_exit; if (usockp->usock_proto == PACKET) { error = vr_usocket_connect(usockp); if (error < 0) goto error_exit; } } switch (proto) { case NETLINK: usockp->usock_max_cfds = USOCK_MAX_CHILD_FDS; buf_len = 0; break; case PACKET: usockp->usock_max_cfds = USOCK_MAX_CHILD_FDS; buf_len = 0; break; case EVENT: /* TODO: we don't need the buf since we use stack to send an event */ buf_len = USOCK_EVENT_BUF_LEN; break; default: buf_len = 0; break; } if (buf_len) { usockp->usock_rx_buf = vr_zalloc(buf_len, VR_USOCK_BUF_OBJECT); if (!usockp->usock_rx_buf) goto error_exit; usockp->usock_buf_len = buf_len; usock_read_init(usockp); } if (proto == PACKET) { usockp->usock_mbuf_pool = rte_mempool_lookup("packet_mbuf_pool"); if (!usockp->usock_mbuf_pool) { usockp->usock_mbuf_pool = rte_mempool_create("packet_mbuf_pool", PKT0_MBUF_POOL_SIZE, PKT0_MBUF_PACKET_SIZE, PKT0_MBUF_POOL_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private), vr_dpdk_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL, rte_socket_id(), 0); if (!usockp->usock_mbuf_pool) goto error_exit; } usockp->usock_iovec = vr_zalloc(sizeof(struct iovec) * PKT0_MAX_IOV_LEN, VR_USOCK_IOVEC_OBJECT); if (!usockp->usock_iovec) goto error_exit; usock_read_init(usockp); } RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d F_GETFL\n", __func__, pthread_self(), usockp->usock_fd); flags = fcntl(usockp->usock_fd, F_GETFL); if (flags == -1) goto error_exit; RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d F_SETFL\n", __func__, pthread_self(), usockp->usock_fd); error = fcntl(usockp->usock_fd, F_SETFL, flags | O_NONBLOCK); if (error == -1) goto error_exit; usockp->usock_poll_block = 1; return usockp; error_exit: error = errno; if (sock_fd >= 0) { close(sock_fd); sock_fd = -1; } usock_close(usockp); usockp = NULL; errno = error; return usockp; }
/** * CALLED BY NF: * Initialises everything we need * * Returns the number of arguments parsed by both rte_eal_init and * parse_nflib_args offset by 1. This is used by getopt in the NF's * code. The offsetting by one accounts for getopt parsing "--" which * increments optind by 1 each time. */ int onvm_nf_init(int argc, char *argv[], const char *nf_tag) { const struct rte_memzone *mz; const struct rte_memzone *mz_scp; struct rte_mempool *mp; struct onvm_service_chain **scp; int retval_eal, retval_parse, retval_final; if ((retval_eal = rte_eal_init(argc, argv)) < 0) return -1; /* Modify argc and argv to conform to getopt rules for parse_nflib_args */ argc -= retval_eal; argv += retval_eal; /* Reset getopt global variables opterr and optind to their default values */ opterr = 0; optind = 1; if ((retval_parse = parse_nflib_args(argc, argv)) < 0) rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); /* * Calculate the offset that the nf will use to modify argc and argv for its * getopt call. This is the sum of the number of arguments parsed by * rte_eal_init and parse_nflib_args. This will be decremented by 1 to assure * getopt is looking at the correct index since optind is incremented by 1 each * time "--" is parsed. * This is the value that will be returned if initialization succeeds. */ retval_final = (retval_eal + retval_parse) - 1; /* Reset getopt global variables opterr and optind to their default values */ opterr = 0; optind = 1; /* Lookup mempool for nf_info struct */ nf_info_mp = rte_mempool_lookup(_NF_MEMPOOL_NAME); if (nf_info_mp == NULL) rte_exit(EXIT_FAILURE, "No Client Info mempool - bye\n"); /* Initialize the info struct */ nf_info = ovnm_nf_info_init(nf_tag); mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); if (mp == NULL) rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n"); mz = rte_memzone_lookup(MZ_CLIENT_INFO); if (mz == NULL) rte_exit(EXIT_FAILURE, "Cannot get tx info structure\n"); tx_stats = mz->addr; mz_scp = rte_memzone_lookup(MZ_SCP_INFO); if (mz_scp == NULL) rte_exit(EXIT_FAILURE, "Cannot get service chain info structre\n"); scp = mz_scp->addr; default_chain = *scp; onvm_sc_print(default_chain); nf_info_ring = rte_ring_lookup(_NF_QUEUE_NAME); if (nf_info_ring == NULL) rte_exit(EXIT_FAILURE, "Cannot get nf_info ring"); /* Put this NF's info struct onto queue for manager to process startup */ if (rte_ring_enqueue(nf_info_ring, nf_info) < 0) { rte_mempool_put(nf_info_mp, nf_info); // give back mermory rte_exit(EXIT_FAILURE, "Cannot send nf_info to manager"); } /* Wait for a client id to be assigned by the manager */ RTE_LOG(INFO, APP, "Waiting for manager to assign an ID...\n"); for (; nf_info->status == (uint16_t)NF_WAITING_FOR_ID ;) { sleep(1); } /* This NF is trying to declare an ID already in use. */ if (nf_info->status == NF_ID_CONFLICT) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_ID_CONFLICT, "Selected ID already in use. Exiting...\n"); } else if(nf_info->status == NF_NO_IDS) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_NO_IDS, "There are no ids available for this NF\n"); } else if(nf_info->status != NF_STARTING) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(EXIT_FAILURE, "Error occurred during manager initialization\n"); } RTE_LOG(INFO, APP, "Using Instance ID %d\n", nf_info->instance_id); RTE_LOG(INFO, APP, "Using Service ID %d\n", nf_info->service_id); /* Now, map rx and tx rings into client space */ rx_ring = rte_ring_lookup(get_rx_queue_name(nf_info->instance_id)); if (rx_ring == NULL) rte_exit(EXIT_FAILURE, "Cannot get RX ring - is server process running?\n"); tx_ring = rte_ring_lookup(get_tx_queue_name(nf_info->instance_id)); if (tx_ring == NULL) rte_exit(EXIT_FAILURE, "Cannot get TX ring - is server process running?\n"); /* Tell the manager we're ready to recieve packets */ nf_info->status = NF_RUNNING; RTE_LOG(INFO, APP, "Finished Process Init.\n"); return retval_final; }
/* * This function is run in the secondary instance to test that creation of * objects fails in a secondary */ static int run_object_creation_tests(void) { const unsigned flags = 0; const unsigned size = 1024; const unsigned elt_size = 64; const unsigned cache_size = 64; const unsigned priv_data_size = 32; printf("### Testing object creation - expect lots of mz reserve errors!\n"); rte_errno = 0; if ((rte_memzone_reserve("test_mz", size, rte_socket_id(), flags) == NULL) && (rte_memzone_lookup("test_mz") == NULL)) { printf("Error: unexpected return value from rte_memzone_reserve\n"); return -1; } printf("# Checked rte_memzone_reserve() OK\n"); rte_errno = 0; if ((rte_ring_create( "test_ring", size, rte_socket_id(), flags) == NULL) && (rte_ring_lookup("test_ring") == NULL)){ printf("Error: unexpected return value from rte_ring_create()\n"); return -1; } printf("# Checked rte_ring_create() OK\n"); rte_errno = 0; if ((rte_mempool_create("test_mp", size, elt_size, cache_size, priv_data_size, NULL, NULL, NULL, NULL, rte_socket_id(), flags) == NULL) && (rte_mempool_lookup("test_mp") == NULL)){ printf("Error: unexpected return value from rte_mempool_create()\n"); return -1; } printf("# Checked rte_mempool_create() OK\n"); #ifdef RTE_LIBRTE_HASH const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" }; rte_errno=0; if ((rte_hash_create(&hash_params) != NULL) && (rte_hash_find_existing(hash_params.name) == NULL)){ printf("Error: unexpected return value from rte_hash_create()\n"); return -1; } printf("# Checked rte_hash_create() OK\n"); const struct rte_fbk_hash_params fbk_params = { .name = "test_fbk_mp_hash" }; rte_errno=0; if ((rte_fbk_hash_create(&fbk_params) != NULL) && (rte_fbk_hash_find_existing(fbk_params.name) == NULL)){ printf("Error: unexpected return value from rte_fbk_hash_create()\n"); return -1; } printf("# Checked rte_fbk_hash_create() OK\n"); #endif #ifdef RTE_LIBRTE_LPM rte_errno=0; struct rte_lpm_config config; config.max_rules = rte_socket_id(); config.number_tbl8s = 256; config.flags = 0; if ((rte_lpm_create("test_lpm", size, &config) != NULL) && (rte_lpm_find_existing("test_lpm") == NULL)){ printf("Error: unexpected return value from rte_lpm_create()\n"); return -1; } printf("# Checked rte_lpm_create() OK\n"); #endif /* Run a test_pci call */ if (test_pci() != 0) { printf("PCI scan failed in secondary\n"); if (getuid() == 0) /* pci scans can fail as non-root */ return -1; } else printf("PCI scan succeeded in secondary\n"); return 0; } /* if called in a primary process, just spawns off a secondary process to * run validation tests - which brings us right back here again... * if called in a secondary process, this runs a series of API tests to check * how things run in a secondary instance. */ int test_mp_secondary(void) { if (rte_eal_process_type() == RTE_PROC_PRIMARY) { if (!test_pci_run) { printf("=== Running pre-requisite test of test_pci\n"); test_pci(); printf("=== Requisite test done\n"); } return run_secondary_instances(); } printf("IN SECONDARY PROCESS\n"); return run_object_creation_tests(); } static struct test_command multiprocess_cmd = { .command = "multiprocess_autotest", .callback = test_mp_secondary, }; REGISTER_TEST_COMMAND(multiprocess_cmd);
/* must be called per process */ int ipaugenblick_app_init(int argc,char **argv,char *app_unique_id) { int i; char ringname[1024]; openlog(NULL, 0, LOG_USER); if(rte_eal_init(argc, argv) < 0) { syslog(LOG_ERR,"cannot initialize rte_eal"); return -1; } syslog(LOG_INFO,"EAL initialized\n"); free_clients_ring = rte_ring_lookup(FREE_CLIENTS_RING); if(!free_clients_ring) { syslog(LOG_ERR,"cannot find ring %s %d\n",__FILE__,__LINE__); exit(0); } free_connections_ring = rte_ring_lookup(FREE_CONNECTIONS_RING); if(!free_connections_ring) { syslog(LOG_ERR,"cannot find free connections ring\n"); return -1; } free_connections_pool = rte_mempool_lookup(FREE_CONNECTIONS_POOL_NAME); if(!free_connections_pool) { syslog(LOG_ERR,"cannot find free connections pool\n"); return -1; } memset(local_socket_descriptors,0,sizeof(local_socket_descriptors)); for(i = 0;i < IPAUGENBLICK_CONNECTION_POOL_SIZE;i++) { sprintf(ringname,RX_RING_NAME_BASE"%d",i); local_socket_descriptors[i].rx_ring = rte_ring_lookup(ringname); if(!local_socket_descriptors[i].rx_ring) { syslog(LOG_ERR,"%s %d\n",__FILE__,__LINE__); exit(0); } sprintf(ringname,TX_RING_NAME_BASE"%d",i); local_socket_descriptors[i].tx_ring = rte_ring_lookup(ringname); if(!local_socket_descriptors[i].tx_ring) { syslog(LOG_ERR,"%s %d\n",__FILE__,__LINE__); exit(0); } local_socket_descriptors[i].select = -1; local_socket_descriptors[i].socket = NULL; sprintf(ringname,"lrxcache%s_%d",app_unique_id,i); syslog(LOG_DEBUG,"local cache name %s\n",ringname); local_socket_descriptors[i].local_cache = rte_ring_create(ringname, 16384,rte_socket_id(), RING_F_SC_DEQ|RING_F_SP_ENQ); if(!local_socket_descriptors[i].local_cache) { syslog(LOG_WARNING,"cannot create local cache\n"); local_socket_descriptors[i].local_cache = rte_ring_lookup(ringname); if(!local_socket_descriptors[i].local_cache) { syslog(LOG_ERR,"and cannot find\n"); exit(0); } } local_socket_descriptors[i].any_event_received = 0; } tx_bufs_pool = rte_mempool_lookup("mbufs_mempool"); if(!tx_bufs_pool) { syslog(LOG_ERR,"cannot find tx bufs pool\n"); return -1; } free_command_pool = rte_mempool_lookup(FREE_COMMAND_POOL_NAME); if(!free_command_pool) { syslog(LOG_ERR,"cannot find free command pool\n"); return -1; } command_ring = rte_ring_lookup(COMMAND_RING_NAME); if(!command_ring) { syslog(LOG_ERR,"cannot find command ring\n"); return -1; } rx_bufs_ring = rte_ring_lookup("rx_mbufs_ring"); if(!rx_bufs_ring) { syslog(LOG_ERR,"cannot find rx bufs ring\n"); return -1; } selectors_ring = rte_ring_lookup(SELECTOR_RING_NAME); for(i = 0;i < IPAUGENBLICK_SELECTOR_POOL_SIZE;i++) { sprintf(ringname,"SELECTOR_RING_NAME%d",i); selectors[i].ready_connections = rte_ring_lookup(ringname); if(!selectors[i].ready_connections) { syslog(LOG_ERR,"cannot find ring %s %d\n",__FILE__,__LINE__); exit(0); } } signal(SIGHUP, sig_handler); signal(SIGINT, sig_handler); signal(SIGILL, sig_handler); signal(SIGABRT, sig_handler); signal(SIGFPE, sig_handler); signal(SIGFPE, sig_handler); signal(SIGSEGV, sig_handler); signal(SIGTERM, sig_handler); signal(SIGUSR1, sig_handler); // pthread_create(&stats_thread,NULL,print_stats,NULL); return ((tx_bufs_pool == NULL)||(command_ring == NULL)||(free_command_pool == NULL)); }
/* * Application main function - loops through * receiving and processing packets. Never returns */ int main(int argc, char *argv[]) { const struct rte_memzone *mz; struct rte_ring *rx_ring; struct rte_mempool *mp; struct port_info *ports; int need_flush = 0; /* indicates whether we have unsent packets */ int retval; void *pkts[PKT_READ_SIZE]; uint16_t sent; if ((retval = rte_eal_init(argc, argv)) < 0) return -1; argc -= retval; argv += retval; if (parse_app_args(argc, argv) < 0) rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); if (rte_eth_dev_count() == 0) rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); rx_ring = rte_ring_lookup(get_rx_queue_name(client_id)); if (rx_ring == NULL) rte_exit(EXIT_FAILURE, "Cannot get RX ring - is server process running?\n"); mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); if (mp == NULL) rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n"); mz = rte_memzone_lookup(MZ_PORT_INFO); if (mz == NULL) rte_exit(EXIT_FAILURE, "Cannot get port info structure\n"); ports = mz->addr; tx_stats = &(ports->tx_stats[client_id]); configure_output_ports(ports); RTE_LOG(INFO, APP, "Finished Process Init.\n"); printf("\nClient process %d handling packets\n", client_id); printf("[Press Ctrl-C to quit ...]\n"); for (;;) { uint16_t i, rx_pkts = PKT_READ_SIZE; uint8_t port; /* try dequeuing max possible packets first, if that fails, get the * most we can. Loop body should only execute once, maximum */ while (rx_pkts > 0 && unlikely(rte_ring_dequeue_bulk(rx_ring, pkts, rx_pkts) != 0)) rx_pkts = (uint16_t)RTE_MIN(rte_ring_count(rx_ring), PKT_READ_SIZE); if (unlikely(rx_pkts == 0)) { if (need_flush) for (port = 0; port < ports->num_ports; port++) { sent = rte_eth_tx_buffer_flush(ports->id[port], client_id, tx_buffer[port]); if (unlikely(sent)) tx_stats->tx[port] += sent; } need_flush = 0; continue; } for (i = 0; i < rx_pkts; i++) handle_packet(pkts[i]); need_flush = 1; } }