static void app_init_mbuf_pools(void) { /* Init the buffer pool */ RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n"); app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size, app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id()); if (app.pool == NULL) rte_panic("Cannot create mbuf pool\n"); /* Init the indirect buffer pool */ RTE_LOG(INFO, USER1, "Creating the indirect mbuf pool ...\n"); app.indirect_pool = rte_pktmbuf_pool_create("indirect mempool", app.pool_size, app.pool_cache_size, sizeof(struct app_pkt_metadata), 0, rte_socket_id()); if (app.indirect_pool == NULL) rte_panic("Cannot create mbuf pool\n"); /* Init the message buffer pool */ RTE_LOG(INFO, USER1, "Creating the message pool ...\n"); app.msg_pool = rte_mempool_create( "mempool msg", app.msg_pool_size, app.msg_pool_buffer_size, app.msg_pool_cache_size, 0, NULL, NULL, rte_ctrlmbuf_init, NULL, rte_socket_id(), 0); if (app.msg_pool == NULL) rte_panic("Cannot create message pool\n"); }
static void app_init_mbuf_pools(void) { unsigned socket, lcore; /* Init the buffer pools */ for (socket = 0; socket < APP_MAX_SOCKETS; socket ++) { char name[32]; if (app_is_socket_used(socket) == 0) { continue; } snprintf(name, sizeof(name), "mbuf_pool_%u", socket); printf("Creating the mbuf pool for socket %u ...\n", socket); app.pools[socket] = rte_pktmbuf_pool_create( name, APP_DEFAULT_MEMPOOL_BUFFERS, APP_DEFAULT_MEMPOOL_CACHE_SIZE, 0, APP_DEFAULT_MBUF_DATA_SIZE, socket); if (app.pools[socket] == NULL) { rte_panic("Cannot create mbuf pool on socket %u\n", socket); } } for (lcore = 0; lcore < APP_MAX_LCORES; lcore ++) { if (app.lcore_params[lcore].type == e_APP_LCORE_DISABLED) { continue; } socket = rte_lcore_to_socket_id(lcore); app.lcore_params[lcore].pool = app.pools[socket]; } }
static int init_mbufpool(unsigned nb_mbuf) { int socketid; unsigned lcore_id; char s[64]; for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { if (rte_lcore_is_enabled(lcore_id) == 0) continue; socketid = rte_lcore_to_socket_id(lcore_id); if (socketid >= NB_SOCKETS) { rte_exit(EXIT_FAILURE, "Socket %d of lcore %u is out of range %d\n", socketid, lcore_id, NB_SOCKETS); } if (mbufpool[socketid] == NULL) { snprintf(s, sizeof(s), "mbuf_pool_%d", socketid); mbufpool[socketid] = rte_pktmbuf_pool_create(s, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socketid); if (mbufpool[socketid] == NULL) rte_exit(EXIT_FAILURE, "Cannot init mbuf pool on socket %d\n", socketid); else printf("Allocated mbuf pool on socket %d\n", socketid); } } return 0; }
/* * The main function, which does initialization and calls the per-lcore * functions. */ int main(int argc, char *argv[]) { unsigned nb_ports; uint8_t portid; /* Initialize the Environment Abstraction Layer (EAL). */ int ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); argc -= ret; argv += ret; /* Check that there is an even number of ports to send/receive on. */ nb_ports = rte_eth_dev_count(); if (nb_ports < 2 || (nb_ports & 1)) rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n"); /* Creates a new mempool in memory to hold the mbufs. */ mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); /* Creates a new mempool in memory to hold the headers for cloned ports. */ header_pool = rte_pktmbuf_pool_create("header_pool", NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, RTE_PKTMBUF_HEADROOM * 2, rte_socket_id()); if (header_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot init header mbuf pool\n"); /* Initialize all ports. */ for (portid = 0; portid < nb_ports; portid++) if (port_init(portid, mbuf_pool) != 0) rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", portid); if (rte_lcore_count() > 1) printf("\nWARNING: Too many lcores enabled. Only 1 used.\n"); /* Call lcore_main on the master core only. */ lcore_main(); return 0; }
static void app_init_mbuf_pools(void) { /* Init the buffer pool */ RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n"); app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size, app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id()); if (app.pool == NULL) rte_panic("Cannot create mbuf pool\n"); }
static int init_mempool_socket(int coreid, int sid) { char name[256]; sprintf(name, "pframe%d", coreid); #if PER_CORE pframe_pool[coreid] = rte_pktmbuf_pool_create(name, NUM_PFRAMES, NUM_MEMPOOL_CACHE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, sid); return pframe_pool[coreid] != NULL; #else pframe_pool[sid] = rte_pktmbuf_pool_create(name, NUM_PFRAMES, NUM_MEMPOOL_CACHE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, sid); return pframe_pool[sid] != NULL; #endif }
/** * 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("Creating mbuf pool '%s' [%u mbufs] ...\n", PKTMBUF_POOL_NAME, num_mbufs); pktmbuf_pool = rte_pktmbuf_pool_create(PKTMBUF_POOL_NAME, num_mbufs, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); return (pktmbuf_pool == NULL); /* 0 on success */ }
int main(int argc, char* argv[]) { int ret; struct rte_mempool *mbuf_pool; /* Initialize the Environment Abstraction Layer (EAL). */ ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); /* Creates a new mempool in memory to hold the msend_bufs. */ mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); // Create Signal Action for interrupts struct sigaction newSigAction; memset((void *)&newSigAction, 0, sizeof(struct sigaction)); newSigAction.sa_handler = &signal_handler; newSigAction.sa_flags = SA_NODEFER; // Attach signal handlers if (sigaction(SIGINT, &newSigAction, NULL) < 0) { fprintf(stderr, "Error attaching signal handler.\n"); exit(0); } if (sigaction(SIGALRM, &newSigAction, NULL) < 0) { fprintf(stderr, "Error attaching signal handler.\n"); exit(0); } if (sigaction(SIGRTMIN, &newSigAction, NULL) < 0) { fprintf(stderr, "Error attaching signal handler.\n"); exit(0); } sleep(1); setup_sender(mbuf_pool); rte_eal_mp_wait_lcore(); return 0; }
int kni_init(void) { int i; char poolname[32]; for (i = 0; i < get_numa_nodes(); i++) { memset(poolname, 0, sizeof(poolname)); snprintf(poolname, sizeof(poolname) - 1, "kni_mbuf_pool_%d", i); kni_mbuf_pool[i] = rte_pktmbuf_pool_create(poolname, KNI_MBUFPOOL_ELEMS, KNI_MBUFPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, i); if (!kni_mbuf_pool[i]) rte_exit(EXIT_FAILURE, "Fail to create pktmbuf_pool for kni."); } return EDPVS_OK; }
/* Main function, does initialisation and calls the per-lcore functions */ int main(int argc, char *argv[]) { struct rte_mempool *mbuf_pool; uint8_t portid = 0; /* init EAL */ int ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); argc -= ret; argv += ret; mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); /* initialize all ports */ if (port_init(portid, mbuf_pool) != 0) rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8"\n", portid); stats_mapping_setup(portid); fdir_filter_add(portid, FDIR_DROP_ADDR, RTE_ETH_FDIR_REJECT, 0); fdir_filter_add(portid, FDIR_ACCEPT_ADDR, RTE_ETH_FDIR_ACCEPT, 1); ntuple_filter_add(portid, NTUPLE_DROP_ADDR, PKT_DROP_QUEUE); ntuple_filter_add(portid, NTUPLE_ACCEPT_ADDR, PKT_ACCEPT_QUEUE); fdir_get_infos(portid); if (rte_lcore_count() > 1) printf("\nWARNING: Too much enabled lcores - " "App uses only 1 lcore\n"); lcore_stats(); /* call lcore_main on master core only */ //lcore_main(); return 0; }
struct rte_mempool* init_mem(uint32_t nb_mbuf, uint32_t socket, uint32_t mbuf_size) { static volatile uint32_t mbuf_cnt = 0; char pool_name[32]; sprintf(pool_name, "mbuf_pool%d", __sync_fetch_and_add(&mbuf_cnt, 1)); // rte_mempool_create is apparently not thread-safe :( static rte_spinlock_t lock = RTE_SPINLOCK_INITIALIZER; rte_spinlock_lock(&lock); struct rte_mempool* pool = rte_pktmbuf_pool_create(pool_name, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, mbuf_size + RTE_PKTMBUF_HEADROOM, socket ); rte_spinlock_unlock(&lock); if (!pool) { printf("Memory allocation failed: %s (%d)\n", rte_strerror(-rte_errno), rte_errno); return 0; } return pool; }
static struct rte_mempool * pktgen_mbuf_pool_create(const char *type, uint8_t pid, uint8_t queue_id, uint32_t nb_mbufs, int socket_id, int cache_size){ struct rte_mempool *mp; char name[RTE_MEMZONE_NAMESIZE]; snprintf(name, sizeof(name), "%-12s%u:%u", type, pid, queue_id); pktgen_log_info(" Create: %-*s - Memory used (MBUFs %4u x (size %u + Hdr %lu)) + %lu = %6lu KB", 16, name, nb_mbufs, MBUF_SIZE, sizeof(struct rte_mbuf), sizeof(struct rte_mempool), (((nb_mbufs * (MBUF_SIZE + sizeof(struct rte_mbuf)) + sizeof(struct rte_mempool))) + 1023) / 1024); pktgen.mem_used += ((nb_mbufs * (MBUF_SIZE + sizeof(struct rte_mbuf)) + sizeof(struct rte_mempool))); pktgen.total_mem_used += ((nb_mbufs * (MBUF_SIZE + sizeof(struct rte_mbuf)) + sizeof(struct rte_mempool))); /* create the mbuf pool */ mp = rte_pktmbuf_pool_create(name, nb_mbufs, cache_size, DEFAULT_PRIV_SIZE, MBUF_SIZE, socket_id); if (mp == NULL) pktgen_log_panic("Cannot create mbuf pool (%s) port %d, queue %d, nb_mbufs %d, socket_id %d: %s", name, pid, queue_id, nb_mbufs, socket_id, rte_strerror(errno)); return mp; }
static void app_init_mempool(struct app_params *app) { uint32_t i; for (i = 0; i < app->n_mempools; i++) { struct app_mempool_params *p = &app->mempool_params[i]; APP_LOG(app, HIGH, "Initializing %s ...", p->name); app->mempool[i] = rte_pktmbuf_pool_create( p->name, p->pool_size, p->cache_size, 0, /* priv_size */ p->buffer_size - sizeof(struct rte_mbuf), /* mbuf data size */ p->cpu_socket_id); if (app->mempool[i] == NULL) rte_panic("%s init error\n", p->name); } }
int dpdk_init(void) { int ret; /* -m stands for memory in MBs that DPDK will allocate. Must be enough * to accommodate the pool_size defined below. */ char *argv[] = { "./ix", "-m", "148" }; const int pool_buffer_size = 0; const int pool_cache_size = 0; /* pool_size sets an implicit limit on cores * NICs that DPDK allows */ const int pool_size = 32768; optind = 0; internal_config.no_hugetlbfs = 1; ret = rte_eal_init(sizeof(argv) / sizeof(argv[0]), argv); if (ret < 0) return ret; dpdk_pool = rte_pktmbuf_pool_create("mempool", pool_size, pool_cache_size, 0, pool_buffer_size, rte_socket_id()); if (dpdk_pool == NULL) panic("Cannot create DPDK pool\n"); return 0; }
static int init_mem(unsigned nb_mbuf) { int socketid; unsigned lcore_id; char s[64]; for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { if (rte_lcore_is_enabled(lcore_id) == 0) continue; if (sk.numa_on) socketid = rte_lcore_to_socket_id(lcore_id); else socketid = 0; if (socketid >= NB_SOCKETS) { rte_exit(EXIT_FAILURE, "Socket %d of lcore %u is out of range %d\n", socketid, lcore_id, NB_SOCKETS); } if (pktmbuf_pool[socketid] == NULL) { snprintf(s, sizeof(s), "mbuf_pool_%d", socketid); pktmbuf_pool[socketid] = rte_pktmbuf_pool_create(s, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socketid); if (pktmbuf_pool[socketid] == NULL) rte_exit(EXIT_FAILURE, "Cannot init mbuf pool on socket %d\n", socketid); else LOG_INFO("Allocated mbuf pool on socket %d.", socketid); } #ifdef IP_FRAG struct rte_mempool *mp; if (socket_direct_pool[socketid] == NULL) { LOG_INFO("Creating direct mempool on socket %i\n", socketid); snprintf(s, sizeof(s), "pool_direct_%i", socketid); mp = rte_pktmbuf_pool_create(s, IP_FRAG_NB_MBUF, 32, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socketid); if (mp == NULL) { LOG_ERR("Cannot create direct mempool\n"); return -1; } socket_direct_pool[socketid] = mp; } if (socket_indirect_pool[socketid] == NULL) { LOG_INFO("Creating indirect mempool on socket %i\n", socketid); snprintf(s, sizeof(s), "pool_indirect_%i", socketid); mp = rte_pktmbuf_pool_create(s, IP_FRAG_NB_MBUF, 32, 0, 0, socketid); if (mp == NULL) { LOG_ERR("Cannot create indirect mempool\n"); return -1; } socket_indirect_pool[socketid] = mp; } #endif } return 0; }
int main(int argc, char **argv) { int ret; unsigned nb_ports; unsigned int lcore_id, last_lcore_id, master_lcore_id; uint8_t port_id; uint8_t nb_ports_available; struct worker_thread_args worker_args = {NULL, NULL}; struct send_thread_args send_args = {NULL, NULL}; struct rte_ring *rx_to_workers; struct rte_ring *workers_to_tx; /* catch ctrl-c so we can print on exit */ signal(SIGINT, int_handler); /* Initialize EAL */ ret = rte_eal_init(argc, argv); if (ret < 0) return -1; argc -= ret; argv += ret; /* Parse the application specific arguments */ ret = parse_args(argc, argv); if (ret < 0) return -1; /* Check if we have enought cores */ if (rte_lcore_count() < 3) rte_exit(EXIT_FAILURE, "Error, This application needs at " "least 3 logical cores to run:\n" "1 lcore for packet RX\n" "1 lcore for packet TX\n" "and at least 1 lcore for worker threads\n"); nb_ports = rte_eth_dev_count(); if (nb_ports == 0) rte_exit(EXIT_FAILURE, "Error: no ethernet ports detected\n"); if (nb_ports != 1 && (nb_ports & 1)) rte_exit(EXIT_FAILURE, "Error: number of ports must be even, except " "when using a single port\n"); mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, MBUF_POOL_CACHE_SIZE, 0, MBUF_DATA_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); nb_ports_available = nb_ports; /* initialize all ports */ for (port_id = 0; port_id < nb_ports; port_id++) { /* skip ports that are not enabled */ if ((portmask & (1 << port_id)) == 0) { printf("\nSkipping disabled port %d\n", port_id); nb_ports_available--; continue; } /* init port */ printf("Initializing port %u... done\n", (unsigned) port_id); if (configure_eth_port(port_id) != 0) rte_exit(EXIT_FAILURE, "Cannot initialize port %"PRIu8"\n", port_id); } if (!nb_ports_available) { rte_exit(EXIT_FAILURE, "All available ports are disabled. Please set portmask.\n"); } /* Create rings for inter core communication */ rx_to_workers = rte_ring_create("rx_to_workers", RING_SIZE, rte_socket_id(), RING_F_SP_ENQ); if (rx_to_workers == NULL) rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); workers_to_tx = rte_ring_create("workers_to_tx", RING_SIZE, rte_socket_id(), RING_F_SC_DEQ); if (workers_to_tx == NULL) rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); if (!disable_reorder) { send_args.buffer = rte_reorder_create("PKT_RO", rte_socket_id(), REORDER_BUFFER_SIZE); if (send_args.buffer == NULL) rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); } last_lcore_id = get_last_lcore_id(); master_lcore_id = rte_get_master_lcore(); worker_args.ring_in = rx_to_workers; worker_args.ring_out = workers_to_tx; /* Start worker_thread() on all the available slave cores but the last 1 */ for (lcore_id = 0; lcore_id <= get_previous_lcore_id(last_lcore_id); lcore_id++) if (rte_lcore_is_enabled(lcore_id) && lcore_id != master_lcore_id) rte_eal_remote_launch(worker_thread, (void *)&worker_args, lcore_id); if (disable_reorder) { /* Start tx_thread() on the last slave core */ rte_eal_remote_launch((lcore_function_t *)tx_thread, workers_to_tx, last_lcore_id); } else { send_args.ring_in = workers_to_tx; /* Start send_thread() on the last slave core */ rte_eal_remote_launch((lcore_function_t *)send_thread, (void *)&send_args, last_lcore_id); } /* Start rx_thread() on the master core */ rx_thread(rx_to_workers); RTE_LCORE_FOREACH_SLAVE(lcore_id) { if (rte_eal_wait_lcore(lcore_id) < 0) return -1; } print_stats(); return 0; }
static int test_distributor_perf(void) { static struct rte_distributor *ds; static struct rte_distributor *db; static struct rte_mempool *p; if (rte_lcore_count() < 2) { printf("ERROR: not enough cores to test distributor\n"); return -1; } /* first time how long it takes to round-trip a cache line */ time_cache_line_switch(); if (ds == NULL) { ds = rte_distributor_create("Test_perf", rte_socket_id(), rte_lcore_count() - 1, RTE_DIST_ALG_SINGLE); if (ds == NULL) { printf("Error creating distributor\n"); return -1; } } else { rte_distributor_clear_returns(ds); } if (db == NULL) { db = rte_distributor_create("Test_burst", rte_socket_id(), rte_lcore_count() - 1, RTE_DIST_ALG_BURST); if (db == NULL) { printf("Error creating burst distributor\n"); return -1; } } else { rte_distributor_clear_returns(db); } const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); if (p == NULL) { p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (p == NULL) { printf("Error creating mempool\n"); return -1; } } printf("=== Performance test of distributor (single mode) ===\n"); rte_eal_mp_remote_launch(handle_work, ds, SKIP_MASTER); if (perf_test(ds, p) < 0) return -1; quit_workers(ds, p); printf("=== Performance test of distributor (burst mode) ===\n"); rte_eal_mp_remote_launch(handle_work, db, SKIP_MASTER); if (perf_test(db, p) < 0) return -1; quit_workers(db, p); return 0; }
int main(int argc, char *argv[]) { int err, ret; uint32_t i, pmsk; struct nmreq req; struct pollfd pollfd[MAX_PORT_NUM]; struct rte_mempool *pool; struct netmap_ring *rx_ring, *tx_ring; ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Cannot initialize EAL\n"); argc -= ret; argv += ret; parse_args(argc, argv); if (ports.num == 0) rte_exit(EXIT_FAILURE, "no ports specified\n"); if (rte_eth_dev_count() < 1) rte_exit(EXIT_FAILURE, "Not enough ethernet ports available\n"); pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0, MBUF_DATA_SIZE, rte_socket_id()); if (pool == NULL) rte_exit(EXIT_FAILURE, "Couldn't create mempool\n"); netmap_conf.socket_id = rte_socket_id(); err = rte_netmap_init(&netmap_conf); if (err < 0) rte_exit(EXIT_FAILURE, "Couldn't initialize librte_compat_netmap\n"); else printf("librte_compat_netmap initialized\n"); port_conf.pool = pool; port_conf.socket_id = rte_socket_id(); for (i = 0; i != ports.num; i++) { err = rte_netmap_init_port(ports.p[i].id, &port_conf); if (err < 0) rte_exit(EXIT_FAILURE, "Couldn't setup port %hhu\n", ports.p[i].id); rte_eth_promiscuous_enable(ports.p[i].id); } for (i = 0; i != ports.num; i++) { err = netmap_port_open(i); if (err) { rte_exit(EXIT_FAILURE, "Couldn't set port %hhu " "under NETMAP control\n", ports.p[i].id); } else printf("Port %hhu now in Netmap mode\n", ports.p[i].id); } memset(pollfd, 0, sizeof(pollfd)); for (i = 0; i != ports.num; i++) { pollfd[i].fd = ports.p[i].fd; pollfd[i].events = POLLIN | POLLOUT; } signal(SIGINT, sigint_handler); pmsk = ports.num - 1; printf("Bridge up and running!\n"); while (!stop) { uint32_t n_pkts; pollfd[0].revents = 0; pollfd[1].revents = 0; ret = rte_netmap_poll(pollfd, ports.num, 0); if (ret < 0) { stop = 1; printf("[E] poll returned with error %d\n", ret); } if (((pollfd[0].revents | pollfd[1].revents) & POLLERR) != 0) { printf("POLLERR!\n"); } if ((pollfd[0].revents & POLLIN) != 0 && (pollfd[pmsk].revents & POLLOUT) != 0) { rx_ring = ports.p[0].rx_ring; tx_ring = ports.p[pmsk].tx_ring; n_pkts = RTE_MIN(rx_ring->avail, tx_ring->avail); move(n_pkts, rx_ring, tx_ring); } if (pmsk != 0 && (pollfd[pmsk].revents & POLLIN) != 0 && (pollfd[0].revents & POLLOUT) != 0) { rx_ring = ports.p[pmsk].rx_ring; tx_ring = ports.p[0].tx_ring; n_pkts = RTE_MIN(rx_ring->avail, tx_ring->avail); move(n_pkts, rx_ring, tx_ring); } } printf("Bridge stopped!\n"); for (i = 0; i != ports.num; i++) { err = rte_netmap_ioctl(ports.p[i].fd, NIOCUNREGIF, &req); if (err) { printf("[E] NIOCUNREGIF ioctl failed (error %d)\n", err); } else printf("Port %hhu unregistered from Netmap mode\n", ports.p[i].id); rte_netmap_close(ports.p[i].fd); } return 0; }
static int test_distributor(void) { static struct rte_distributor *ds; static struct rte_distributor *db; static struct rte_distributor *dist[2]; static struct rte_mempool *p; int i; if (rte_lcore_count() < 2) { printf("ERROR: not enough cores to test distributor\n"); return -1; } if (db == NULL) { db = rte_distributor_create("Test_dist_burst", rte_socket_id(), rte_lcore_count() - 1, RTE_DIST_ALG_BURST); if (db == NULL) { printf("Error creating burst distributor\n"); return -1; } } else { rte_distributor_flush(db); rte_distributor_clear_returns(db); } if (ds == NULL) { ds = rte_distributor_create("Test_dist_single", rte_socket_id(), rte_lcore_count() - 1, RTE_DIST_ALG_SINGLE); if (ds == NULL) { printf("Error creating single distributor\n"); return -1; } } else { rte_distributor_flush(ds); rte_distributor_clear_returns(ds); } const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); if (p == NULL) { p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (p == NULL) { printf("Error creating mempool\n"); return -1; } } dist[0] = ds; dist[1] = db; for (i = 0; i < 2; i++) { worker_params.dist = dist[i]; if (i) sprintf(worker_params.name, "burst"); else sprintf(worker_params.name, "single"); rte_eal_mp_remote_launch(handle_work, &worker_params, SKIP_MASTER); if (sanity_test(&worker_params, p) < 0) goto err; quit_workers(&worker_params, p); rte_eal_mp_remote_launch(handle_work_with_free_mbufs, &worker_params, SKIP_MASTER); if (sanity_test_with_mbuf_alloc(&worker_params, p) < 0) goto err; quit_workers(&worker_params, p); if (rte_lcore_count() > 2) { rte_eal_mp_remote_launch(handle_work_for_shutdown_test, &worker_params, SKIP_MASTER); if (sanity_test_with_worker_shutdown(&worker_params, p) < 0) goto err; quit_workers(&worker_params, p); rte_eal_mp_remote_launch(handle_work_for_shutdown_test, &worker_params, SKIP_MASTER); if (test_flush_with_worker_shutdown(&worker_params, p) < 0) goto err; quit_workers(&worker_params, p); } else { printf("Too few cores to run worker shutdown test\n"); } } if (test_error_distributor_create_numworkers() == -1 || test_error_distributor_create_name() == -1) { printf("rte_distributor_create parameter check tests failed"); return -1; } return 0; err: quit_workers(&worker_params, p); return -1; }
/* Main function, does initialisation and calls the per-lcore functions */ int main(int argc, char *argv[]) { unsigned cores; struct rte_mempool *mbuf_pool; unsigned lcore_id; uintptr_t i; int ret; unsigned nb_ports, valid_num_ports; uint16_t portid; signal(SIGHUP, sighup_handler); /* init EAL */ ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); argc -= ret; argv += ret; /* parse app arguments */ ret = vmdq_parse_args(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Invalid VMDQ argument\n"); cores = rte_lcore_count(); if ((cores & (cores - 1)) != 0 || cores > RTE_MAX_LCORE) { rte_exit(EXIT_FAILURE,"This program can only run on an even" " number of cores(1-%d)\n\n", RTE_MAX_LCORE); } nb_ports = rte_eth_dev_count(); /* * Update the global var NUM_PORTS and global array PORTS * and get value of var VALID_NUM_PORTS according to system ports number */ valid_num_ports = check_ports_num(nb_ports); if (valid_num_ports < 2 || valid_num_ports % 2) { printf("Current valid ports number is %u\n", valid_num_ports); rte_exit(EXIT_FAILURE, "Error with valid ports number is not even or less than 2\n"); } mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS_PER_PORT * nb_ports, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); /* initialize all ports */ for (portid = 0; portid < nb_ports; portid++) { /* skip ports that are not enabled */ if ((enabled_port_mask & (1 << portid)) == 0) { printf("\nSkipping disabled port %d\n", portid); continue; } if (port_init(portid, mbuf_pool) != 0) rte_exit(EXIT_FAILURE, "Cannot initialize network ports\n"); } /* call lcore_main() on every slave lcore */ i = 0; RTE_LCORE_FOREACH_SLAVE(lcore_id) { rte_eal_remote_launch(lcore_main, (void*)i++, lcore_id); } /* call on master too */ (void) lcore_main((void*)i); return 0; }
/* Main function */ int main(int argc, char **argv) { int ret; int i; /* Create handler for SIGINT for CTRL + C closing and SIGALRM to print stats*/ signal(SIGINT, sig_handler); signal(SIGALRM, alarm_routine); /* Initialize DPDK enviroment with args, then shift argc and argv to get application parameters */ ret = rte_eal_init(argc, argv); if (ret < 0) FATAL_ERROR("Cannot init EAL\n"); argc -= ret; argv += ret; /* Check if this application can use two cores*/ ret = rte_lcore_count (); if (ret != 2) PRINT_INFO("This application needs exactly two (2) cores."); /* Parse arguments */ parse_args(argc, argv); if (ret < 0) FATAL_ERROR("Wrong arguments\n"); /* Probe PCI bus for ethernet devices, mandatory only in DPDK < 1.8.0 */ #if RTE_VER_MAJOR == 1 && RTE_VER_MINOR < 8 ret = rte_eal_pci_probe(); if (ret < 0) FATAL_ERROR("Cannot probe PCI\n"); #endif /* Get number of ethernet devices */ nb_sys_ports = rte_eth_dev_count(); //if (nb_sys_ports <= 0) FATAL_ERROR("Cannot find ETH devices\n"); /* Create a mempool with per-core cache, initializing every element for be used as mbuf, and allocating on the current NUMA node */ // pktmbuf_pool = rte_mempool_create(MEMPOOL_NAME, buffer_size-1, MEMPOOL_ELEM_SZ, MEMPOOL_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,rte_socket_id(), 0); pktmbuf_pool = rte_pktmbuf_pool_create(MEMPOOL_NAME,buffer_size-1, MEMPOOL_CACHE_SZ, 0, snaplen + RTE_PKTMBUF_HEADROOM, rte_socket_id()); if (pktmbuf_pool == NULL) FATAL_ERROR("Cannot create cluster_mem_pool. Errno: %d [ENOMEM: %d, ENOSPC: %d, E_RTE_NO_TAILQ: %d, E_RTE_NO_CONFIG: %d, E_RTE_SECONDARY: %d, EINVAL: %d, EEXIST: %d]\n", rte_errno, ENOMEM, ENOSPC, RTE_MAX_TAILQ/*E_RTE_NO_TAILQ*/, E_RTE_NO_CONFIG, E_RTE_SECONDARY, EINVAL, EEXIST ); /* Init intermediate queue data structures: the ring. */ intermediate_ring = rte_ring_create (INTERMEDIATERING_NAME, buffer_size, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ ); if (intermediate_ring == NULL ) FATAL_ERROR("Cannot create ring"); /* Operations needed for each ethernet device */ for(i=0; i < nb_sys_ports; i++) init_port(i); /* Start Pcap */ //PcapStartUp(); /* Start consumer and producer routine on 2 different cores: consumer launched first... */ ret = rte_eal_mp_remote_launch (main_loop_producer, NULL, SKIP_MASTER); if (ret != 0) FATAL_ERROR("Cannot start consumer thread\n"); /*RTE_LCORE_FOREACH_SLAVE(i) { if (rte_eal_wait_lcore(i) < 0) return -1; }*/ /* ... and then loop in consumer */ //main_loop_producer ( NULL ); main_loop_consumer(NULL); return 0; }
/* * Initialize a given port using default settings and with the RX buffers * coming from the mbuf_pool passed as a parameter. * FIXME: Starting with assumption of one thread/core per port */ static inline int uhd_dpdk_port_init(struct uhd_dpdk_port *port, struct rte_mempool *rx_mbuf_pool, unsigned int mtu) { int retval; /* Check for a valid port */ if (port->id >= rte_eth_dev_count()) return -ENODEV; /* Set up Ethernet device with defaults (1 RX ring, 1 TX ring) */ /* FIXME: Check if hw_ip_checksum is possible */ struct rte_eth_conf port_conf = { .rxmode = { .max_rx_pkt_len = mtu, .jumbo_frame = 1, .hw_ip_checksum = 1, } }; retval = rte_eth_dev_configure(port->id, 1, 1, &port_conf); if (retval != 0) return retval; retval = rte_eth_rx_queue_setup(port->id, 0, DEFAULT_RING_SIZE, rte_eth_dev_socket_id(port->id), NULL, rx_mbuf_pool); if (retval < 0) return retval; retval = rte_eth_tx_queue_setup(port->id, 0, DEFAULT_RING_SIZE, rte_eth_dev_socket_id(port->id), NULL); if (retval < 0) goto port_init_fail; /* Create the hash table for the RX sockets */ char name[32]; snprintf(name, sizeof(name), "rx_table_%u", port->id); struct rte_hash_parameters hash_params = { .name = name, .entries = UHD_DPDK_MAX_SOCKET_CNT, .key_len = sizeof(struct uhd_dpdk_ipv4_5tuple), .hash_func = NULL, .hash_func_init_val = 0, }; port->rx_table = rte_hash_create(&hash_params); if (port->rx_table == NULL) { retval = rte_errno; goto port_init_fail; } /* Create ARP table */ snprintf(name, sizeof(name), "arp_table_%u", port->id); hash_params.name = name; hash_params.entries = UHD_DPDK_MAX_SOCKET_CNT; hash_params.key_len = sizeof(uint32_t); hash_params.hash_func = NULL; hash_params.hash_func_init_val = 0; port->arp_table = rte_hash_create(&hash_params); if (port->arp_table == NULL) { retval = rte_errno; goto free_rx_table; } /* Set up list for TX queues */ LIST_INIT(&port->txq_list); /* Start the Ethernet port. */ retval = rte_eth_dev_start(port->id); if (retval < 0) { goto free_arp_table; } /* Display the port MAC address. */ rte_eth_macaddr_get(port->id, &port->mac_addr); RTE_LOG(INFO, EAL, "Port %u MAC: %02x %02x %02x %02x %02x %02x\n", (unsigned)port->id, port->mac_addr.addr_bytes[0], port->mac_addr.addr_bytes[1], port->mac_addr.addr_bytes[2], port->mac_addr.addr_bytes[3], port->mac_addr.addr_bytes[4], port->mac_addr.addr_bytes[5]); struct rte_eth_link link; rte_eth_link_get(port->id, &link); RTE_LOG(INFO, EAL, "Port %u UP: %d\n", port->id, link.link_status); return 0; free_arp_table: rte_hash_free(port->arp_table); free_rx_table: rte_hash_free(port->rx_table); port_init_fail: return rte_errno; } static int uhd_dpdk_thread_init(struct uhd_dpdk_thread *thread, unsigned int id) { if (!ctx || !thread) return -EINVAL; unsigned int socket_id = rte_lcore_to_socket_id(id); thread->id = id; thread->rx_pktbuf_pool = ctx->rx_pktbuf_pools[socket_id]; thread->tx_pktbuf_pool = ctx->tx_pktbuf_pools[socket_id]; LIST_INIT(&thread->port_list); char name[32]; snprintf(name, sizeof(name), "sockreq_ring_%u", id); thread->sock_req_ring = rte_ring_create( name, UHD_DPDK_MAX_PENDING_SOCK_REQS, socket_id, RING_F_SC_DEQ ); if (!thread->sock_req_ring) return -ENOMEM; return 0; } int uhd_dpdk_init(int argc, char **argv, unsigned int num_ports, int *port_thread_mapping, int num_mbufs, int mbuf_cache_size, int mtu) { /* Init context only once */ if (ctx) return 1; if ((num_ports == 0) || (port_thread_mapping == NULL)) { return -EINVAL; } /* Grabs arguments intended for DPDK's EAL */ int ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); ctx = (struct uhd_dpdk_ctx *) rte_zmalloc("uhd_dpdk_ctx", sizeof(*ctx), rte_socket_id()); if (!ctx) return -ENOMEM; ctx->num_threads = rte_lcore_count(); if (ctx->num_threads <= 1) rte_exit(EXIT_FAILURE, "Error: No worker threads enabled\n"); /* Check that we have ports to send/receive on */ ctx->num_ports = rte_eth_dev_count(); if (ctx->num_ports < 1) rte_exit(EXIT_FAILURE, "Error: Found no ports\n"); if (ctx->num_ports < num_ports) rte_exit(EXIT_FAILURE, "Error: User requested more ports than available\n"); /* Get memory for thread and port data structures */ ctx->threads = rte_zmalloc("uhd_dpdk_thread", RTE_MAX_LCORE*sizeof(struct uhd_dpdk_thread), 0); if (!ctx->threads) rte_exit(EXIT_FAILURE, "Error: Could not allocate memory for thread data\n"); ctx->ports = rte_zmalloc("uhd_dpdk_port", ctx->num_ports*sizeof(struct uhd_dpdk_port), 0); if (!ctx->ports) rte_exit(EXIT_FAILURE, "Error: Could not allocate memory for port data\n"); /* Initialize the thread data structures */ for (int i = rte_get_next_lcore(-1, 1, 0); (i < RTE_MAX_LCORE); i = rte_get_next_lcore(i, 1, 0)) { /* Do one mempool of RX/TX per socket */ unsigned int socket_id = rte_lcore_to_socket_id(i); /* FIXME Probably want to take into account actual number of ports per socket */ if (ctx->tx_pktbuf_pools[socket_id] == NULL) { /* Creates a new mempool in memory to hold the mbufs. * This is done for each CPU socket */ const int mbuf_size = mtu + 2048 + RTE_PKTMBUF_HEADROOM; char name[32]; snprintf(name, sizeof(name), "rx_mbuf_pool_%u", socket_id); ctx->rx_pktbuf_pools[socket_id] = rte_pktmbuf_pool_create( name, ctx->num_ports*num_mbufs, mbuf_cache_size, 0, mbuf_size, socket_id ); snprintf(name, sizeof(name), "tx_mbuf_pool_%u", socket_id); ctx->tx_pktbuf_pools[socket_id] = rte_pktmbuf_pool_create( name, ctx->num_ports*num_mbufs, mbuf_cache_size, 0, mbuf_size, socket_id ); if ((ctx->rx_pktbuf_pools[socket_id]== NULL) || (ctx->tx_pktbuf_pools[socket_id]== NULL)) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); } if (uhd_dpdk_thread_init(&ctx->threads[i], i) < 0) rte_exit(EXIT_FAILURE, "Error initializing thread %i\n", i); } unsigned master_lcore = rte_get_master_lcore(); /* Assign ports to threads and initialize the port data structures */ for (unsigned int i = 0; i < num_ports; i++) { int thread_id = port_thread_mapping[i]; if (thread_id < 0) continue; if (((unsigned int) thread_id) == master_lcore) RTE_LOG(WARNING, EAL, "User requested master lcore for port %u\n", i); if (ctx->threads[thread_id].id != (unsigned int) thread_id) rte_exit(EXIT_FAILURE, "Requested inactive lcore %u for port %u\n", (unsigned int) thread_id, i); struct uhd_dpdk_port *port = &ctx->ports[i]; port->id = i; port->parent = &ctx->threads[thread_id]; ctx->threads[thread_id].num_ports++; LIST_INSERT_HEAD(&ctx->threads[thread_id].port_list, port, port_entry); /* Initialize port. */ if (uhd_dpdk_port_init(port, port->parent->rx_pktbuf_pool, mtu) != 0) rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", i); } RTE_LOG(INFO, EAL, "Init DONE!\n"); /* FIXME: Create functions to do this */ RTE_LOG(INFO, EAL, "Starting I/O threads!\n"); for (int i = rte_get_next_lcore(-1, 1, 0); (i < RTE_MAX_LCORE); i = rte_get_next_lcore(i, 1, 0)) { struct uhd_dpdk_thread *t = &ctx->threads[i]; if (!LIST_EMPTY(&t->port_list)) { rte_eal_remote_launch(_uhd_dpdk_driver_main, NULL, ctx->threads[i].id); } } return 0; } /* FIXME: This will be changed once we have functions to handle the threads */ int uhd_dpdk_destroy(void) { if (!ctx) return -ENODEV; struct uhd_dpdk_config_req *req = (struct uhd_dpdk_config_req *) rte_zmalloc(NULL, sizeof(*req), 0); if (!req) return -ENOMEM; req->req_type = UHD_DPDK_LCORE_TERM; for (int i = rte_get_next_lcore(-1, 1, 0); (i < RTE_MAX_LCORE); i = rte_get_next_lcore(i, 1, 0)) { struct uhd_dpdk_thread *t = &ctx->threads[i]; if (LIST_EMPTY(&t->port_list)) continue; if (rte_eal_get_lcore_state(t->id) == FINISHED) continue; pthread_mutex_init(&req->mutex, NULL); pthread_cond_init(&req->cond, NULL); pthread_mutex_lock(&req->mutex); if (rte_ring_enqueue(t->sock_req_ring, req)) { pthread_mutex_unlock(&req->mutex); RTE_LOG(ERR, USER2, "Failed to terminate thread %d\n", i); rte_free(req); return -ENOSPC; } struct timespec timeout = { .tv_sec = 1, .tv_nsec = 0 }; pthread_cond_timedwait(&req->cond, &req->mutex, &timeout); pthread_mutex_unlock(&req->mutex); } rte_free(req); return 0; }
static int paxos_rx_process(struct rte_mbuf *pkt, struct proposer* proposer) { int ret = 0; uint8_t l4_proto = 0; uint16_t outer_header_len; union tunnel_offload_info info = { .data = 0 }; struct udp_hdr *udp_hdr; struct paxos_hdr *paxos_hdr; struct ether_hdr *phdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); parse_ethernet(phdr, &info, &l4_proto); if (l4_proto != IPPROTO_UDP) return -1; udp_hdr = (struct udp_hdr *)((char *)phdr + info.outer_l2_len + info.outer_l3_len); /* if UDP dst port is not either PROPOSER or LEARNER port */ if (!(udp_hdr->dst_port == rte_cpu_to_be_16(PROPOSER_PORT) || udp_hdr->dst_port == rte_cpu_to_be_16(LEARNER_PORT)) && (pkt->packet_type & RTE_PTYPE_TUNNEL_MASK) == 0) return -1; paxos_hdr = (struct paxos_hdr *)((char *)udp_hdr + sizeof(struct udp_hdr)); if (rte_get_log_level() == RTE_LOG_DEBUG) { //rte_hexdump(stdout, "udp", udp_hdr, sizeof(struct udp_hdr)); //rte_hexdump(stdout, "paxos", paxos_hdr, sizeof(struct paxos_hdr)); print_paxos_hdr(paxos_hdr); } int value_len = rte_be_to_cpu_16(paxos_hdr->value_len); struct paxos_value *v = paxos_value_new((char *)paxos_hdr->paxosval, value_len); switch(rte_be_to_cpu_16(paxos_hdr->msgtype)) { case PAXOS_PROMISE: { struct paxos_promise promise = { .iid = rte_be_to_cpu_32(paxos_hdr->inst), .ballot = rte_be_to_cpu_16(paxos_hdr->rnd), .value_ballot = rte_be_to_cpu_16(paxos_hdr->vrnd), .aid = rte_be_to_cpu_16(paxos_hdr->acptid), .value = *v }; proposer_handle_promise(proposer, &promise); break; } case PAXOS_ACCEPT: { if (first_time) { proposer_preexecute(proposer); first_time = false; } struct paxos_accept acpt = { .iid = rte_be_to_cpu_32(paxos_hdr->inst), .ballot = rte_be_to_cpu_16(paxos_hdr->rnd), .value_ballot = rte_be_to_cpu_16(paxos_hdr->vrnd), .aid = rte_be_to_cpu_16(paxos_hdr->acptid), .value = *v }; proposer_handle_accept(proposer, &acpt); break; } case PAXOS_ACCEPTED: { struct paxos_accepted ack = { .iid = rte_be_to_cpu_32(paxos_hdr->inst), .ballot = rte_be_to_cpu_16(paxos_hdr->rnd), .value_ballot = rte_be_to_cpu_16(paxos_hdr->vrnd), .aid = rte_be_to_cpu_16(paxos_hdr->acptid), .value = *v }; proposer_handle_accepted(proposer, &ack); break; } default: break; } outer_header_len = info.outer_l2_len + info.outer_l3_len + sizeof(struct udp_hdr) + sizeof(struct paxos_hdr); rte_pktmbuf_adj(pkt, outer_header_len); return ret; } static uint16_t add_timestamps(uint8_t port __rte_unused, uint16_t qidx __rte_unused, struct rte_mbuf **pkts, uint16_t nb_pkts, uint16_t max_pkts __rte_unused, void *user_param) { struct proposer* proposer = (struct proposer *)user_param; unsigned i; uint64_t now = rte_rdtsc(); for (i = 0; i < nb_pkts; i++) { pkts[i]->udata64 = now; paxos_rx_process(pkts[i], proposer); } return nb_pkts; } static inline int port_init(uint8_t port, struct rte_mempool *mbuf_pool, struct proposer* proposer) { struct rte_eth_dev_info dev_info; struct rte_eth_txconf *txconf; struct rte_eth_rxconf *rxconf; struct rte_eth_conf port_conf = port_conf_default; const uint16_t rx_rings = 1, tx_rings = 1; int retval; uint16_t q; rte_eth_dev_info_get(port, &dev_info); rxconf = &dev_info.default_rxconf; txconf = &dev_info.default_txconf; txconf->txq_flags &= PKT_TX_IPV4; txconf->txq_flags &= PKT_TX_UDP_CKSUM; if (port >= rte_eth_dev_count()) return -1; retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); if (retval != 0) return retval; for (q = 0; q < rx_rings; q++) { retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, rte_eth_dev_socket_id(port), rxconf, mbuf_pool); if (retval < 0) return retval; } for (q = 0; q < tx_rings; q++) { retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, rte_eth_dev_socket_id(port), txconf); if (retval < 0) return retval; } retval = rte_eth_dev_start(port); if (retval < 0) return retval; struct ether_addr addr; rte_eth_macaddr_get(port, &addr); rte_eth_promiscuous_enable(port); rte_eth_add_rx_callback(port, 0, add_timestamps, proposer); rte_eth_add_tx_callback(port, 0, calc_latency, NULL); return 0; } static void lcore_main(uint8_t port, __rte_unused struct proposer *p) { proposer_preexecute(p); for (;;) { // Check if signal is received if (force_quit) break; struct rte_mbuf *bufs[BURST_SIZE]; const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE); if (unlikely(nb_rx == 0)) continue; uint16_t buf; for (buf = 0; buf < nb_rx; buf++) rte_pktmbuf_free(bufs[buf]); } } static __attribute__((noreturn)) int lcore_mainloop(__attribute__((unused)) void *arg) { uint64_t prev_tsc = 0, cur_tsc, diff_tsc; unsigned lcore_id; lcore_id = rte_lcore_id(); rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_TIMER, "Starting mainloop on core %u\n", lcore_id); while(1) { cur_tsc = rte_rdtsc(); diff_tsc = cur_tsc - prev_tsc; if (diff_tsc > TIMER_RESOLUTION_CYCLES) { rte_timer_manage(); prev_tsc = cur_tsc; } } } static void report_stat(struct rte_timer *tim, __attribute((unused)) void *arg) { /* print stat */ uint32_t count = rte_atomic32_read(&stat); rte_log(RTE_LOG_INFO, RTE_LOGTYPE_USER8, "Throughput = %8u msg/s\n", count); /* reset stat */ rte_atomic32_set(&stat, 0); /* this timer is automatically reloaded until we decide to stop it */ if (force_quit) rte_timer_stop(tim); } static void check_timeout(struct rte_timer *tim, void *arg) { struct proposer* p = (struct proposer *) arg; unsigned lcore_id = rte_lcore_id(); rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER8, "%s() on lcore_id %i\n", __func__, lcore_id); struct paxos_message out; out.type = PAXOS_PREPARE; struct timeout_iterator* iter = proposer_timeout_iterator(p); while(timeout_iterator_prepare(iter, &out.u.prepare)) { rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER8, "%s Send PREPARE inst %d ballot %d\n", __func__, out.u.prepare.iid, out.u.prepare.ballot); send_paxos_message(&out); } out.type = PAXOS_ACCEPT; while(timeout_iterator_accept(iter, &out.u.accept)) { rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER8, "%s: Send ACCEPT inst %d ballot %d\n", __func__, out.u.prepare.iid, out.u.prepare.ballot); send_paxos_message(&out); } timeout_iterator_free(iter); /* this timer is automatically reloaded until we decide to stop it */ if (force_quit) rte_timer_stop(tim); } int main(int argc, char *argv[]) { uint8_t portid = 0; unsigned master_core, lcore_id; signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); force_quit = false; int proposer_id = 0; if (rte_get_log_level() == RTE_LOG_DEBUG) { paxos_config.verbosity = PAXOS_LOG_DEBUG; } struct proposer *proposer = proposer_new(proposer_id, NUM_ACCEPTORS); first_time = true; /* init EAL */ int ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); /* init timer structure */ rte_timer_init(&timer); rte_timer_init(&stat_timer); /* load deliver_timer, every 1 s, on a slave lcore, reloaded automatically */ uint64_t hz = rte_get_timer_hz(); /* Call rte_timer_manage every 10ms */ TIMER_RESOLUTION_CYCLES = hz / 100; rte_log(RTE_LOG_INFO, RTE_LOGTYPE_USER1, "Clock: %"PRIu64"\n", hz); /* master core */ master_core = rte_lcore_id(); /* slave core */ lcore_id = rte_get_next_lcore(master_core, 0, 1); rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER1, "lcore_id: %d\n", lcore_id); rte_timer_reset(&timer, hz, PERIODICAL, lcore_id, check_timeout, proposer); /* reset timer */ rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id); /* stat core */ lcore_id = rte_get_next_lcore(lcore_id , 0, 1); rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER1, "lcore_id: %d\n", lcore_id); rte_timer_reset(&stat_timer, hz, PERIODICAL, lcore_id, report_stat, NULL); /* init RTE timer library */ rte_timer_subsystem_init(); mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf_pool\n"); /* reset timer */ rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id); if (port_init(portid, mbuf_pool, proposer) != 0) rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8"\n", portid); lcore_main(portid, proposer); rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_USER8, "Free proposer\n"); proposer_free(proposer); return 0; }
int main(int argc, char ** argv) { int ret, socket; unsigned pid, nb_ports, lcore_id, rx_lcore_id; struct sock_parameter sk_param; struct sock *sk; struct txrx_queue *rxq; struct port_queue_conf *port_q; struct lcore_queue_conf *lcore_q; ret = rte_eal_init(argc, argv); if (ret < 0) return -1; argc -= ret; argv += ret; /*parse gw ip and mac from cmdline*/ if (argc > 1) { default_host_addr = argv[1]; if (argc == 3) default_gw_addr = argv[2]; else if (argc == 4) default_gw_mac = argv[3]; else rte_exit(EXIT_FAILURE, "invalid arguments\n"); } /*config nic*/ nb_ports = rte_eth_dev_count(); if (nb_ports == 0) rte_exit(EXIT_FAILURE, "No available NIC\n"); for (pid = 0; pid < nb_ports; pid++) { ret = net_device_init(pid); if (ret) { RTE_LOG(WARNING, LDNS, "fail to initialize port %u\n", pid); goto release_net_device; } } pkt_rx_pool = rte_pktmbuf_pool_create("ldns rx pkt pool", PKT_RX_NB, 32, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (pkt_rx_pool == NULL) rte_exit(EXIT_FAILURE, "cannot alloc rx_mbuf_pool"); /*sock create*/ sk_param.mode = SOCK_MODE_COMPLETE; sk_param.func = dns_process; sk = create_sock(0, SOCK_PTOTO_IPPROTO_UDP, &sk_param); if (sk == NULL) rte_exit(EXIT_FAILURE, "cannot create sock\n"); if (sock_bind(sk, inet_network(default_host_addr), DNS_PORT)) rte_exit(EXIT_FAILURE, "cannot bind addr:%s port:%u", default_host_addr, DNS_PORT); /*init ethdev*/ lcore_id = 0; lcore_q = lcore_q_conf_get(lcore_id); for (pid = 0; pid < nb_ports; pid++) { port_q = port_q_conf_get(pid); ret = rte_eth_dev_configure(pid, rx_rings, tx_rings, &default_rte_eth_conf); if (ret != 0) rte_exit(EXIT_FAILURE, "port %u configure error\n", pid); while (rx_lcore_id == rte_get_master_lcore() || !rte_lcore_is_enabled(rx_lcore_id) || lcore_q->nb_rxq == nb_rx_queue_per_core) { rx_lcore_id++; if (rx_lcore_id == RTE_MAX_LCORE) rte_exit(EXIT_FAILURE, "not enough core for port %u\n", pid); lcore_q = lcore_q_conf_get(lcore_id); } rxq = &lcore_q->rxq[lcore_q->nb_rxq]; rxq->port = pid; rxq->lcore = rx_lcore_id; rxq->qid = port_q->nb_rxq; lcore_q->nb_rxq++; port_q->nb_rxq++; socket = rte_lcore_to_socket_id(rx_lcore_id); if (socket == SOCKET_ID_ANY) socket = 0; ret = rte_eth_tx_queue_setup(pid, rxq->qid, nb_txd, socket, NULL); if (ret < 0) rte_exit(EXIT_FAILURE, "fail to setup txq %u on port %u", rxq->qid, pid); ret = rte_eth_rx_queue_setup(pid, rxq->qid, nb_rxd, socket, NULL, pkt_rx_pool); if (ret < 0) rte_exit(EXIT_FAILURE, "failt to setup rxq %u on port %u", rxq->qid, pid); ret = rte_eth_dev_start(pid); if (ret < 0) rte_exit(EXIT_FAILURE, "fail to start port %u\n", pid); } if (dns_set_cfg(&default_dns_cfg)) rte_exit(EXIT_FAILURE, "fail to set dns configuration%u\n", pid); rte_eal_mp_remote_launch(packet_launch_one_lcore, NULL, SKIP_MASTER); RTE_LCORE_FOREACH_SLAVE(lcore_id) { if (rte_eal_wait_lcore(lcore_id) < 0) return -1; } return 0; release_net_device: for (pid; pid != 0; pid--) { net_device_release(pid - 1); } return -1; }