X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Flink_status_interrupt%2Fmain.c;h=ce8ae059d789419d5d9fe6ef16ecfb2737be8951;hb=69a3c6319140b34fb714fa5bd6990cceb2ea2997;hp=9cd4dc7a69e629b7c7c3d33a40c7462e1f927239;hpb=538da7a1cad25fbdffe298c8ca76fc4dbd262d1b;p=dpdk.git diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c index 9cd4dc7a69..ce8ae059d7 100644 --- a/examples/link_status_interrupt/main.c +++ b/examples/link_status_interrupt/main.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -67,15 +65,18 @@ static unsigned lsi_dst_ports[RTE_MAX_ETHPORTS] = {0}; #define MAX_RX_QUEUE_PER_LCORE 16 #define MAX_TX_QUEUE_PER_PORT 16 +/* List of queues must be polled for a give lcore. 8< */ struct lcore_queue_conf { unsigned n_rx_port; unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; unsigned tx_queue_id; } __rte_cache_aligned; struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; +/* >8 End of list of queues to be polled. */ struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; +/* Global configuration stored in a static structure. 8< */ static struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, @@ -87,6 +88,7 @@ static struct rte_eth_conf port_conf = { .lsc = 1, /**< lsc interrupt feature enabled */ }, }; +/* >8 End of global configuration stored in a static structure. */ struct rte_mempool * lsi_pktmbuf_pool = NULL; @@ -117,6 +119,7 @@ print_stats(void) const char clr[] = { 27, '[', '2', 'J', '\0' }; const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; + int link_get_err; /* Clear screen and move to top left */ printf("%s%s", clr, topLeft); @@ -129,17 +132,20 @@ print_stats(void) continue; memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); + link_get_err = rte_eth_link_get_nowait(portid, &link); printf("\nStatistics for port %u ------------------------------" "\nLink status: %25s" - "\nLink speed: %26u" + "\nLink speed: %26s" "\nLink duplex: %25s" "\nPackets sent: %24"PRIu64 "\nPackets received: %20"PRIu64 "\nPackets dropped: %21"PRIu64, portid, + link_get_err < 0 ? "Link get failed" : (link.link_status ? "Link up" : "Link down"), - (unsigned)link.link_speed, + link_get_err < 0 ? "0" : + rte_eth_link_speed_to_str(link.link_speed), + link_get_err < 0 ? "Link get failed" : (link.link_duplex == ETH_LINK_FULL_DUPLEX ? \ "full-duplex" : "half-duplex"), port_statistics[portid].tx, @@ -158,8 +164,11 @@ print_stats(void) total_packets_rx, total_packets_dropped); printf("\n====================================================\n"); + + fflush(stdout); } +/* Replacing the source and destination MAC addresses. 8< */ static void lsi_simple_forward(struct rte_mbuf *m, unsigned portid) { @@ -172,17 +181,18 @@ lsi_simple_forward(struct rte_mbuf *m, unsigned portid) eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); /* 02:00:00:00:00:xx */ - tmp = ð->d_addr.addr_bytes[0]; + tmp = ð->dst_addr.addr_bytes[0]; *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40); /* src addr */ - rte_ether_addr_copy(&lsi_ports_eth_addr[dst_port], ð->s_addr); + rte_ether_addr_copy(&lsi_ports_eth_addr[dst_port], ð->src_addr); buffer = tx_buffer[dst_port]; sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); if (sent) port_statistics[dst_port].tx += sent; } +/* >8 End of replacing the source and destination MAC addresses. */ /* main processing loop */ static void @@ -221,6 +231,7 @@ lsi_main_loop(void) while (1) { + /* Draining TX queue in its main loop. 8< */ cur_tsc = rte_rdtsc(); /* @@ -249,8 +260,8 @@ lsi_main_loop(void) /* if timer has reached its timeout */ if (unlikely(timer_tsc >= (uint64_t) timer_period)) { - /* do this only on master core */ - if (lcore_id == rte_get_master_lcore()) { + /* do this only on main core */ + if (lcore_id == rte_get_main_lcore()) { print_stats(); /* reset the timer */ timer_tsc = 0; @@ -260,10 +271,9 @@ lsi_main_loop(void) prev_tsc = cur_tsc; } + /* >8 End of draining TX queue in its main loop. */ - /* - * Read packet from RX queues - */ + /* Read packet from RX queues. 8< */ for (i = 0; i < qconf->n_rx_port; i++) { portid = qconf->rx_port_list[i]; @@ -278,11 +288,12 @@ lsi_main_loop(void) lsi_simple_forward(m, portid); } } + /* >8 End of reading packet from RX queues. */ } } static int -lsi_launch_one_lcore(__attribute__((unused)) void *dummy) +lsi_launch_one_lcore(__rte_unused void *dummy) { lsi_main_loop(); return 0; @@ -308,10 +319,7 @@ lsi_parse_portmask(const char *portmask) /* parse hexadecimal string */ pm = strtoul(portmask, &end, 16); if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - - if (pm == 0) - return -1; + return 0; return pm; } @@ -433,28 +441,33 @@ lsi_parse_args(int argc, char **argv) * @return * int. */ + +/* lsi_event_callback 8< */ static int lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param, void *ret_param) { struct rte_eth_link link; + int ret; + char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; RTE_SET_USED(param); RTE_SET_USED(ret_param); printf("\n\nIn registered callback...\n"); printf("Event type: %s\n", type == RTE_ETH_EVENT_INTR_LSC ? "LSC interrupt" : "unknown event"); - rte_eth_link_get_nowait(port_id, &link); - if (link.link_status) { - printf("Port %d Link Up - speed %u Mbps - %s\n\n", - port_id, (unsigned)link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex")); - } else - printf("Port %d Link Down\n\n", port_id); + ret = rte_eth_link_get_nowait(port_id, &link); + if (ret < 0) { + printf("Failed link get on port %d: %s\n", + port_id, rte_strerror(-ret)); + return ret; + } + rte_eth_link_to_str(link_status_text, sizeof(link_status_text), &link); + printf("Port %d %s\n\n", port_id, link_status_text); return 0; } +/* >8 End of registering one or more callbacks. */ /* Check the link status of all ports in up to 9s, and print them finally */ static void @@ -465,6 +478,8 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) uint8_t count, all_ports_up, print_flag = 0; uint16_t portid; struct rte_eth_link link; + int ret; + char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; printf("\nChecking link status"); fflush(stdout); @@ -474,17 +489,20 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) if ((port_mask & (1 << portid)) == 0) continue; memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); + ret = rte_eth_link_get_nowait(portid, &link); + if (ret < 0) { + all_ports_up = 0; + if (print_flag == 1) + printf("Port %u link get failed: %s\n", + portid, rte_strerror(-ret)); + continue; + } /* print link status if flag set */ if (print_flag == 1) { - if (link.link_status) - printf( - "Port%d Link Up. Speed %u Mbps - %s\n", - portid, link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - else - printf("Port %d Link Down\n", portid); + rte_eth_link_to_str(link_status_text, + sizeof(link_status_text), &link); + printf("Port %d %s", portid, + link_status_text); continue; } /* clear all_ports_up flag if any link down */ @@ -544,9 +562,7 @@ main(int argc, char **argv) if (nb_ports == 0) rte_panic("No Ethernet port - bye\n"); - /* - * Each logical core is assigned a dedicated TX queue on each port. - */ + /* Each logical core is assigned a dedicated TX queue on each port. 8< */ for (portid = 0; portid < nb_ports; portid++) { /* skip ports that are not enabled */ if ((lsi_enabled_port_mask & (1 << portid)) == 0) @@ -562,6 +578,7 @@ main(int argc, char **argv) nb_ports_in_mask++; } + /* >8 End of assigning logical core. */ if (nb_ports_in_mask < 2 || nb_ports_in_mask % 2) rte_exit(EXIT_FAILURE, "Current enabled port number is %u, " "but it should be even and at least 2\n", @@ -609,14 +626,22 @@ main(int argc, char **argv) /* init port */ printf("Initializing port %u... ", (unsigned) portid); fflush(stdout); - rte_eth_dev_info_get(portid, &dev_info); + + ret = rte_eth_dev_info_get(portid, &dev_info); + if (ret != 0) + rte_exit(EXIT_FAILURE, + "Error during getting device (port %u) info: %s\n", + portid, 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; + /* Configure RX and TX queues. 8< */ ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); if (ret < 0) rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", ret, (unsigned) portid); + /* >8 End of configure RX and TX queues. */ ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, &nb_txd); @@ -630,16 +655,24 @@ main(int argc, char **argv) * lsc interrupt will be present, and below callback to * be registered will never be called. */ + + /* RTE callback register. 8< */ rte_eth_dev_callback_register(portid, RTE_ETH_EVENT_INTR_LSC, lsi_event_callback, NULL); + /* >8 End of registering lsi interrupt callback. */ - rte_eth_macaddr_get(portid, + ret = rte_eth_macaddr_get(portid, &lsi_ports_eth_addr[portid]); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "rte_eth_macaddr_get: err=%d, port=%u\n", + ret, (unsigned int)portid); /* init one RX queue */ fflush(stdout); rxq_conf = dev_info.default_rxconf; rxq_conf.offloads = local_port_conf.rxmode.offloads; + /* RX queue initialization. 8< */ ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, rte_eth_dev_socket_id(portid), &rxq_conf, @@ -647,8 +680,9 @@ main(int argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d, port=%u\n", ret, (unsigned) portid); + /* >8 End of RX queue initialization. */ - /* init one TX queue logical core on each port */ + /* init one TX queue logical core on each port. 8< */ fflush(stdout); txq_conf = dev_info.default_txconf; txq_conf.offloads = local_port_conf.txmode.offloads; @@ -658,6 +692,7 @@ main(int argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d,port=%u\n", ret, (unsigned) portid); + /* >8 End of init one TX queue. */ /* Initialize TX buffers */ tx_buffer[portid] = rte_zmalloc_socket("tx_buffer", @@ -683,16 +718,15 @@ main(int argc, char **argv) ret, (unsigned) portid); printf("done:\n"); - rte_eth_promiscuous_enable(portid); + ret = rte_eth_promiscuous_enable(portid); + if (ret != 0) + rte_exit(EXIT_FAILURE, + "rte_eth_promiscuous_enable: err=%s, port=%u\n", + rte_strerror(-ret), portid); - printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", + printf("Port %u, MAC address: " RTE_ETHER_ADDR_PRT_FMT "\n\n", (unsigned) portid, - lsi_ports_eth_addr[portid].addr_bytes[0], - lsi_ports_eth_addr[portid].addr_bytes[1], - lsi_ports_eth_addr[portid].addr_bytes[2], - lsi_ports_eth_addr[portid].addr_bytes[3], - lsi_ports_eth_addr[portid].addr_bytes[4], - lsi_ports_eth_addr[portid].addr_bytes[5]); + RTE_ETHER_ADDR_BYTES(&lsi_ports_eth_addr[portid])); /* initialize port stats */ memset(&port_statistics, 0, sizeof(port_statistics)); @@ -701,11 +735,14 @@ main(int argc, char **argv) check_all_ports_link_status(nb_ports, lsi_enabled_port_mask); /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(lsi_launch_one_lcore, NULL, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + rte_eal_mp_remote_launch(lsi_launch_one_lcore, NULL, CALL_MAIN); + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (rte_eal_wait_lcore(lcore_id) < 0) return -1; } + /* clean up the EAL */ + rte_eal_cleanup(); + return 0; }