X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fkni%2Fmain.c;h=8bea07182f7f05d689ad347d1b62c36bcebbf3ca;hb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;hp=80c401c511c59adae0a766afce34cd331a381e69;hpb=323e7b667f18376c60351282950b28d4d0cc6165;p=dpdk.git diff --git a/examples/kni/main.c b/examples/kni/main.c index 80c401c511..8bea07182f 100644 --- a/examples/kni/main.c +++ b/examples/kni/main.c @@ -106,6 +106,8 @@ static struct rte_mempool * pktmbuf_pool = NULL; static uint32_t ports_mask = 0; /* Ports set in promiscuous mode off by default. */ static int promiscuous_on = 0; +/* Monitor link status continually. off by default. */ +static int monitor_links; /* Structure type for recording kni interface specific stats */ struct kni_interface_stats { @@ -130,6 +132,7 @@ static int kni_config_network_interface(uint16_t port_id, uint8_t if_up); static int kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]); static rte_atomic32_t kni_stop = RTE_ATOMIC32_INIT(0); +static rte_atomic32_t kni_pause = RTE_ATOMIC32_INIT(0); /* Print out statistics on packets handled */ static void @@ -169,14 +172,13 @@ signal_handler(int signum) /* When we receive a USR2 signal, reset stats */ if (signum == SIGUSR2) { memset(&kni_stats, 0, sizeof(kni_stats)); - printf("\n**Statistics have been reset**\n"); + printf("\n** Statistics have been reset **\n"); return; } /* When we receive a RTMIN or SIGINT signal, stop kni processing */ if (signum == SIGRTMIN || signum == SIGINT){ - printf("SIGRTMIN is received, and the KNI processing is " - "going to stop\n"); + printf("\nSIGRTMIN/SIGINT received. KNI processing stopping.\n"); rte_atomic32_inc(&kni_stop); return; } @@ -222,7 +224,8 @@ kni_ingress(struct kni_port_params *p) } /* Burst tx to kni */ num = rte_kni_tx_burst(p->kni[i], pkts_burst, nb_rx); - kni_stats[port_id].rx_packets += num; + if (num) + kni_stats[port_id].rx_packets += num; rte_kni_handle_request(p->kni[i]); if (unlikely(num < nb_rx)) { @@ -259,7 +262,8 @@ kni_egress(struct kni_port_params *p) } /* Burst tx to eth */ nb_tx = rte_eth_tx_burst(port_id, 0, pkts_burst, (uint16_t)num); - kni_stats[port_id].tx_packets += nb_tx; + if (nb_tx) + kni_stats[port_id].tx_packets += nb_tx; if (unlikely(nb_tx < num)) { /* Free mbufs not tx to NIC */ kni_burst_free_mbufs(&pkts_burst[nb_tx], num - nb_tx); @@ -273,6 +277,7 @@ main_loop(__rte_unused void *arg) { uint16_t i; int32_t f_stop; + int32_t f_pause; const unsigned lcore_id = rte_lcore_id(); enum lcore_rxtx { LCORE_NONE, @@ -301,8 +306,11 @@ main_loop(__rte_unused void *arg) kni_port_params_array[i]->port_id); while (1) { f_stop = rte_atomic32_read(&kni_stop); + f_pause = rte_atomic32_read(&kni_pause); if (f_stop) break; + if (f_pause) + continue; kni_ingress(kni_port_params_array[i]); } } else if (flag == LCORE_TX) { @@ -311,8 +319,11 @@ main_loop(__rte_unused void *arg) kni_port_params_array[i]->port_id); while (1) { f_stop = rte_atomic32_read(&kni_stop); + f_pause = rte_atomic32_read(&kni_pause); if (f_stop) break; + if (f_pause) + continue; kni_egress(kni_port_params_array[i]); } } else @@ -325,11 +336,12 @@ main_loop(__rte_unused void *arg) static void print_usage(const char *prgname) { - RTE_LOG(INFO, APP, "\nUsage: %s [EAL options] -- -p PORTMASK -P " + RTE_LOG(INFO, APP, "\nUsage: %s [EAL options] -- -p PORTMASK -P -m " "[--config (port,lcore_rx,lcore_tx,lcore_kthread...)" "[,(port,lcore_rx,lcore_tx,lcore_kthread...)]]\n" " -p PORTMASK: hex bitmask of ports to use\n" " -P : enable promiscuous mode\n" + " -m : enable monitoring of port carrier state\n" " --config (port,lcore_rx,lcore_tx,lcore_kthread...): " "port and lcore configurations\n", prgname); @@ -510,7 +522,7 @@ parse_args(int argc, char **argv) opterr = 0; /* Parse command line */ - while ((opt = getopt_long(argc, argv, "p:P", longopts, + while ((opt = getopt_long(argc, argv, "p:Pm", longopts, &longindex)) != EOF) { switch (opt) { case 'p': @@ -519,6 +531,9 @@ parse_args(int argc, char **argv) case 'P': promiscuous_on = 1; break; + case 'm': + monitor_links = 1; + break; case 0: if (!strncmp(longopts[longindex].name, CMDLINE_OPT_CONFIG, @@ -674,6 +689,55 @@ check_all_ports_link_status(uint32_t port_mask) } } +static void +log_link_state(struct rte_kni *kni, int prev, struct rte_eth_link *link) +{ + if (kni == NULL || link == NULL) + return; + + if (prev == ETH_LINK_DOWN && link->link_status == ETH_LINK_UP) { + RTE_LOG(INFO, APP, "%s NIC Link is Up %d Mbps %s %s.\n", + rte_kni_get_name(kni), + link->link_speed, + link->link_autoneg ? "(AutoNeg)" : "(Fixed)", + link->link_duplex ? "Full Duplex" : "Half Duplex"); + } else if (prev == ETH_LINK_UP && link->link_status == ETH_LINK_DOWN) { + RTE_LOG(INFO, APP, "%s NIC Link is Down.\n", + rte_kni_get_name(kni)); + } +} + +/* + * Monitor the link status of all ports and update the + * corresponding KNI interface(s) + */ +static void * +monitor_all_ports_link_status(void *arg) +{ + uint16_t portid; + struct rte_eth_link link; + unsigned int i; + struct kni_port_params **p = kni_port_params_array; + int prev; + (void) arg; + + while (monitor_links) { + rte_delay_ms(500); + RTE_ETH_FOREACH_DEV(portid) { + if ((ports_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + for (i = 0; i < p[portid]->nb_kni; i++) { + prev = rte_kni_update_link(p[portid]->kni[i], + link.link_status); + log_link_state(p[portid]->kni[i], prev, &link); + } + } + } + return NULL; +} + /* Callback for request of changing MTU */ static int kni_change_mtu(uint16_t port_id, unsigned int new_mtu) @@ -751,12 +815,16 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up) RTE_LOG(INFO, APP, "Configure network interface of %d %s\n", port_id, if_up ? "up" : "down"); + rte_atomic32_inc(&kni_pause); + if (if_up != 0) { /* Configure network interface up */ rte_eth_dev_stop(port_id); ret = rte_eth_dev_start(port_id); } else /* Configure network interface down */ rte_eth_dev_stop(port_id); + rte_atomic32_dec(&kni_pause); + if (ret < 0) RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id); @@ -764,7 +832,7 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up) } static void -print_ethaddr(const char *name, struct ether_addr *mac_addr) +print_ethaddr(const char *name, struct rte_ether_addr *mac_addr) { char buf[ETHER_ADDR_FMT_SIZE]; ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr); @@ -783,10 +851,10 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]) } RTE_LOG(INFO, APP, "Configure mac address of %d\n", port_id); - print_ethaddr("Address:", (struct ether_addr *)mac_addr); + print_ethaddr("Address:", (struct rte_ether_addr *)mac_addr); ret = rte_eth_dev_default_mac_addr_set(port_id, - (struct ether_addr *)mac_addr); + (struct rte_ether_addr *)mac_addr); if (ret < 0) RTE_LOG(ERR, APP, "Failed to config mac_addr for port %d\n", port_id); @@ -844,7 +912,7 @@ kni_alloc(uint16_t port_id) } /* Get the interface default mac address */ rte_eth_macaddr_get(port_id, - (struct ether_addr *)&conf.mac_addr); + (struct rte_ether_addr *)&conf.mac_addr); rte_eth_dev_get_mtu(port_id, &conf.mtu); @@ -893,6 +961,9 @@ main(int argc, char** argv) int ret; uint16_t nb_sys_ports, port; unsigned i; + void *retval; + pthread_t kni_link_tid; + int pid; /* Associate signal_hanlder function with USR signals */ signal(SIGUSR1, signal_handler); @@ -949,12 +1020,31 @@ main(int argc, char** argv) } check_all_ports_link_status(ports_mask); + pid = getpid(); + RTE_LOG(INFO, APP, "========================\n"); + RTE_LOG(INFO, APP, "KNI Running\n"); + RTE_LOG(INFO, APP, "kill -SIGUSR1 %d\n", pid); + RTE_LOG(INFO, APP, " Show KNI Statistics.\n"); + RTE_LOG(INFO, APP, "kill -SIGUSR2 %d\n", pid); + RTE_LOG(INFO, APP, " Zero KNI Statistics.\n"); + RTE_LOG(INFO, APP, "========================\n"); + fflush(stdout); + + ret = rte_ctrl_thread_create(&kni_link_tid, + "KNI link status check", NULL, + monitor_all_ports_link_status, NULL); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Could not create link status thread!\n"); + /* Launch per-lcore function on every lcore */ rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER); RTE_LCORE_FOREACH_SLAVE(i) { if (rte_eal_wait_lcore(i) < 0) return -1; } + monitor_links = 0; + pthread_join(kni_link_tid, &retval); /* Release resources */ RTE_ETH_FOREACH_DEV(port) {