X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl3fwd%2Fl3fwd_event.c;h=4d31593a0af4017f428964ea2493d54299e5dbe2;hb=ad976bd40d28;hp=1040da4ea355ca61464acac6d46f70a68270413c;hpb=e2de1f7bb9668415c8fdfce6b736112bfb24f377;p=dpdk.git diff --git a/examples/l3fwd/l3fwd_event.c b/examples/l3fwd/l3fwd_event.c index 1040da4ea3..4d31593a0a 100644 --- a/examples/l3fwd/l3fwd_event.c +++ b/examples/l3fwd/l3fwd_event.c @@ -10,6 +10,14 @@ #include "l3fwd.h" #include "l3fwd_event.h" +static void +print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr) +{ + char buf[RTE_ETHER_ADDR_FMT_SIZE]; + rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); + printf("%s%s", name, buf); +} + struct l3fwd_event_resources * l3fwd_get_eventdev_rsrc(void) { @@ -30,11 +38,230 @@ l3fwd_get_eventdev_rsrc(void) return NULL; } +static void +l3fwd_eth_dev_port_setup(struct rte_eth_conf *port_conf) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + uint16_t nb_ports = rte_eth_dev_count_avail(); + uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; + uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + unsigned int nb_lcores = rte_lcore_count(); + struct rte_eth_conf local_port_conf; + struct rte_eth_dev_info dev_info; + struct rte_eth_txconf txconf; + struct rte_eth_rxconf rxconf; + unsigned int nb_mbuf; + uint16_t port_id; + uint8_t eth_qid; + int32_t ret; + + /* initialize all ports */ + RTE_ETH_FOREACH_DEV(port_id) { + local_port_conf = *port_conf; + /* skip ports that are not enabled */ + if ((evt_rsrc->port_mask & (1 << port_id)) == 0) { + printf("\nSkipping disabled port %d\n", port_id); + continue; + } + + /* init port */ + printf("Initializing port %d ... ", port_id); + fflush(stdout); + printf("Creating queues: nb_rxq=%d nb_txq=1...\n", + evt_rsrc->eth_rx_queues); + + ret = rte_eth_dev_info_get(port_id, &dev_info); + if (ret != 0) + rte_panic("Error during getting device (port %u) info:" + "%s\n", port_id, strerror(-ret)); + + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + local_port_conf.txmode.offloads |= + DEV_TX_OFFLOAD_MBUF_FAST_FREE; + + local_port_conf.rx_adv_conf.rss_conf.rss_hf &= + dev_info.flow_type_rss_offloads; + if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != + port_conf->rx_adv_conf.rss_conf.rss_hf) { + printf("Port %u modified RSS hash function " + "based on hardware support," + "requested:%#"PRIx64" configured:%#"PRIx64"\n", + port_id, + port_conf->rx_adv_conf.rss_conf.rss_hf, + local_port_conf.rx_adv_conf.rss_conf.rss_hf); + } + + ret = rte_eth_dev_configure(port_id, evt_rsrc->eth_rx_queues, + 1, &local_port_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot configure device: err=%d, port=%d\n", + ret, port_id); + + ret = rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd, + &nb_txd); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot adjust number of descriptors: err=%d, " + "port=%d\n", ret, port_id); + + rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]); + print_ethaddr(" Address:", &ports_eth_addr[port_id]); + printf(", "); + print_ethaddr("Destination:", + (const struct rte_ether_addr *)&dest_eth_addr[port_id]); + printf(", "); + + /* prepare source MAC for each port. */ + rte_ether_addr_copy(&ports_eth_addr[port_id], + (struct rte_ether_addr *)(val_eth + port_id) + 1); + + /* init memory */ + if (!evt_rsrc->per_port_pool) { + /* port_id = 0; this is *not* signifying the first port, + * rather, it signifies that port_id is ignored. + */ + nb_mbuf = RTE_MAX(nb_ports * nb_rxd + + nb_ports * nb_txd + + nb_ports * nb_lcores * + MAX_PKT_BURST + + nb_lcores * MEMPOOL_CACHE_SIZE, + 8192u); + ret = init_mem(0, nb_mbuf); + } else { + nb_mbuf = RTE_MAX(nb_rxd + nb_rxd + + nb_lcores * MAX_PKT_BURST + + nb_lcores * MEMPOOL_CACHE_SIZE, + 8192u); + ret = init_mem(port_id, nb_mbuf); + } + /* init Rx queues per port */ + rxconf = dev_info.default_rxconf; + rxconf.offloads = local_port_conf.rxmode.offloads; + + for (eth_qid = 0; eth_qid < evt_rsrc->eth_rx_queues; + eth_qid++) { + if (!evt_rsrc->per_port_pool) + ret = rte_eth_rx_queue_setup(port_id, eth_qid, + nb_rxd, 0, &rxconf, + evt_rsrc->pkt_pool[0][0]); + else + ret = rte_eth_rx_queue_setup(port_id, eth_qid, + nb_rxd, 0, &rxconf, + evt_rsrc->pkt_pool[port_id][0]); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "rte_eth_rx_queue_setup: err=%d, " + "port=%d, eth_qid: %d\n", + ret, port_id, eth_qid); + } + + /* init one Tx queue per port */ + txconf = dev_info.default_txconf; + txconf.offloads = local_port_conf.txmode.offloads; + ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 0, &txconf); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "rte_eth_tx_queue_setup: err=%d, " + "port=%d\n", ret, port_id); + } +} + +static void +l3fwd_event_capability_setup(void) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + uint32_t caps = 0; + uint16_t i; + int ret; + + RTE_ETH_FOREACH_DEV(i) { + ret = rte_event_eth_tx_adapter_caps_get(0, i, &caps); + if (ret) + rte_exit(EXIT_FAILURE, + "Invalid capability for Tx adptr port %d\n", + i); + + evt_rsrc->tx_mode_q |= !(caps & + RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT); + } + + if (evt_rsrc->tx_mode_q) + l3fwd_event_set_generic_ops(&evt_rsrc->ops); + else + l3fwd_event_set_internal_port_ops(&evt_rsrc->ops); +} + +int +l3fwd_get_free_event_port(struct l3fwd_event_resources *evt_rsrc) +{ + static int index; + int port_id; + + rte_spinlock_lock(&evt_rsrc->evp.lock); + if (index >= evt_rsrc->evp.nb_ports) { + printf("No free event port is available\n"); + return -1; + } + + port_id = evt_rsrc->evp.event_p_id[index]; + index++; + rte_spinlock_unlock(&evt_rsrc->evp.lock); + + return port_id; +} + void -l3fwd_event_resource_setup(void) +l3fwd_event_resource_setup(struct rte_eth_conf *port_conf) { struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + const event_loop_cb lpm_event_loop[2][2] = { + [0][0] = lpm_event_main_loop_tx_d, + [0][1] = lpm_event_main_loop_tx_d_burst, + [1][0] = lpm_event_main_loop_tx_q, + [1][1] = lpm_event_main_loop_tx_q_burst, + }; + const event_loop_cb em_event_loop[2][2] = { + [0][0] = em_event_main_loop_tx_d, + [0][1] = em_event_main_loop_tx_d_burst, + [1][0] = em_event_main_loop_tx_q, + [1][1] = em_event_main_loop_tx_q_burst, + }; + uint32_t event_queue_cfg; + int ret; if (!evt_rsrc->enabled) return; + + if (!rte_event_dev_count()) + rte_exit(EXIT_FAILURE, "No Eventdev found"); + + /* Setup eventdev capability callbacks */ + l3fwd_event_capability_setup(); + + /* Ethernet device configuration */ + l3fwd_eth_dev_port_setup(port_conf); + + /* Event device configuration */ + event_queue_cfg = evt_rsrc->ops.event_device_setup(); + + /* Event queue configuration */ + evt_rsrc->ops.event_queue_setup(event_queue_cfg); + + /* Event port configuration */ + evt_rsrc->ops.event_port_setup(); + + /* Rx/Tx adapters configuration */ + evt_rsrc->ops.adapter_setup(); + + /* Start event device */ + ret = rte_event_dev_start(evt_rsrc->event_d_id); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Error in starting eventdev"); + + evt_rsrc->ops.lpm_event_loop = lpm_event_loop[evt_rsrc->tx_mode_q] + [evt_rsrc->has_burst]; + + evt_rsrc->ops.em_event_loop = em_event_loop[evt_rsrc->tx_mode_q] + [evt_rsrc->has_burst]; }