From e8591dc5c047fb89eca5ac7e5339eabd625fefe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fengbojiang=28=E5=A7=9C=E5=87=A4=E6=B3=A2=29?= Date: Thu, 14 Mar 2019 17:17:58 +0800 Subject: [PATCH] F-Stack's kni can work on DPDK 18.11 LTS now. --- example/main.c | 4 +- example/main_epoll.c | 4 +- lib/Makefile | 2 +- lib/ff_dpdk_if.c | 28 +++++++++---- lib/ff_dpdk_kni.c | 96 ++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 114 insertions(+), 20 deletions(-) diff --git a/example/main.c b/example/main.c index bebe3c62..73752bd9 100644 --- a/example/main.c +++ b/example/main.c @@ -27,7 +27,7 @@ char html[] = "Server: F-Stack\r\n" "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n" "Content-Type: text/html\r\n" -"Content-Length: 439\r\n" +"Content-Length: 438\r\n" "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n" "Connection: keep-alive\r\n" "Accept-Ranges: bytes\r\n" @@ -93,7 +93,7 @@ int loop(void *arg) char buf[256]; size_t readlen = ff_read(clientfd, buf, sizeof(buf)); - ff_write(clientfd, html, strlen(html)); + ff_write(clientfd, html, sizeof(html) - 1); } else { printf("unknown event: %8.8X\n", event.flags); } diff --git a/example/main_epoll.c b/example/main_epoll.c index fe280b4e..cde85831 100644 --- a/example/main_epoll.c +++ b/example/main_epoll.c @@ -28,7 +28,7 @@ char html[] = "Server: F-Stack\r\n" "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n" "Content-Type: text/html\r\n" -"Content-Length: 439\r\n" +"Content-Length: 438\r\n" "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n" "Connection: keep-alive\r\n" "Accept-Ranges: bytes\r\n" @@ -89,7 +89,7 @@ int loop(void *arg) char buf[256]; size_t readlen = ff_read( events[i].data.fd, buf, sizeof(buf)); if(readlen > 0) { - ff_write( events[i].data.fd, html, strlen(html)); + ff_write( events[i].data.fd, html, sizeof(html) - 1); } else { ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); ff_close( events[i].data.fd); diff --git a/lib/Makefile b/lib/Makefile index 03409983..76c50fb2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -41,7 +41,7 @@ else endif endif -DPDK_CFLAGS= -Wall -Werror -include ${FF_DPDK}/include/rte_config.h +DPDK_CFLAGS= -Wall -Wno-deprecated-declarations -Werror -include ${FF_DPDK}/include/rte_config.h DPDK_CFLAGS+= -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 DPDK_CFLAGS+= -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 DPDK_CFLAGS+= -DRTE_COMPILE_TIME_CPUFLAGS=RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2 diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 8cb096d6..91b364b0 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -572,6 +572,10 @@ init_port_start(void) uint16_t nb_queues = pconf->nb_lcores; struct rte_eth_dev_info dev_info; + struct rte_eth_conf port_conf = {0}; + struct rte_eth_rxconf rxq_conf; + struct rte_eth_txconf txq_conf; + rte_eth_dev_info_get(port_id, &dev_info); if (nb_queues > dev_info.max_rx_queues) { @@ -598,8 +602,6 @@ init_port_start(void) rte_memcpy(pconf->mac, addr.addr_bytes, ETHER_ADDR_LEN); - struct rte_eth_conf port_conf = {0}; - /* Set RSS mode */ uint64_t default_rss_hf = ETH_RSS_PROTO_MASK; port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; @@ -689,6 +691,14 @@ init_port_start(void) if (ret != 0) { return ret; } + + static uint16_t nb_rxd = RX_QUEUE_SIZE; + static uint16_t nb_txd = TX_QUEUE_SIZE; + ret = rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd, &nb_txd); + if (ret < 0) + printf("Could not adjust number of descriptors " + "for port%u (%d)\n", (unsigned)port_id, ret); + uint16_t q; for (q = 0; q < nb_queues; q++) { if (numa_on) { @@ -697,14 +707,18 @@ init_port_start(void) } mbuf_pool = pktmbuf_pool[socketid]; - ret = rte_eth_tx_queue_setup(port_id, q, TX_QUEUE_SIZE, - socketid, &dev_info.default_txconf); + txq_conf = dev_info.default_txconf; + txq_conf.offloads = port_conf.txmode.offloads; + ret = rte_eth_tx_queue_setup(port_id, q, nb_txd, + socketid, &txq_conf); if (ret < 0) { return ret; } - - ret = rte_eth_rx_queue_setup(port_id, q, RX_QUEUE_SIZE, - socketid, &dev_info.default_rxconf, mbuf_pool); + + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = port_conf.rxmode.offloads; + ret = rte_eth_rx_queue_setup(port_id, q, nb_rxd, + socketid, &rxq_conf, mbuf_pool); if (ret < 0) { return ret; } diff --git a/lib/ff_dpdk_kni.c b/lib/ff_dpdk_kni.c index cbd1499c..c634d5ab 100644 --- a/lib/ff_dpdk_kni.c +++ b/lib/ff_dpdk_kni.c @@ -79,6 +79,7 @@ struct kni_interface_stats { struct rte_ring **kni_rp; struct kni_interface_stats **kni_stat; +int kni_link = ETH_LINK_DOWN; static void set_bitmap(uint16_t port, unsigned char *bitmap) @@ -129,12 +130,51 @@ kni_change_mtu(uint16_t port_id, unsigned new_mtu) return 0; } +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) { + kni_link = ETH_LINK_UP; + printf("%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) { + kni_link = ETH_LINK_DOWN; + printf("%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(uint16_t port_id) +{ + struct rte_eth_link link; + unsigned int i; + int prev; + + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(port_id, &link); + prev = rte_kni_update_link(kni_stat[port_id]->kni, link.link_status); + log_link_state(kni_stat[port_id]->kni, prev, &link); + + return NULL; +} + static int kni_config_network_interface(uint16_t port_id, uint8_t if_up) { int ret = 0; - if (port_id >= rte_eth_dev_count_avail() || port_id >= RTE_MAX_ETHPORTS) { + if (!rte_eth_dev_is_valid_port(port_id)) { printf("Invalid port id %d\n", port_id); return -EINVAL; } @@ -158,6 +198,9 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up) } } + if (!if_up) + kni_link = ETH_LINK_DOWN; + if (ret < 0) printf("Failed to Configure network interface of %d %s\n", port_id, if_up ? "up" : "down"); @@ -165,6 +208,36 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up) return ret; } +static void +print_ethaddr(const char *name, struct ether_addr *mac_addr) +{ + char buf[ETHER_ADDR_FMT_SIZE]; + ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr); + printf("\t%s%s\n", name, buf); +} + + +/* Callback for request of configuring mac address */ +static int +kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]) +{ + int ret = 0; + + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("Invalid port id %d\n", port_id); + return -EINVAL; + } + + print_ethaddr("Address:", (struct ether_addr *)mac_addr); + + ret = rte_eth_dev_default_mac_addr_set(port_id, + (struct ether_addr *)mac_addr); + if (ret < 0) + printf("Failed to config mac_addr for port %d\n", port_id); + + return ret; +} + static int kni_process_tx(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **pkts_burst, unsigned count) @@ -363,17 +436,22 @@ ff_kni_alloc(uint16_t port_id, unsigned socket_id, memset(&dev_info, 0, sizeof(dev_info)); rte_eth_dev_info_get(port_id, &dev_info); if (dev_info.device) - bus = rte_bus_find_by_device(dev_info.device); - if (bus && !strcmp(bus->name, "pci")) { - pci_dev = RTE_DEV_TO_PCI(dev_info.device); - conf.addr = pci_dev->addr; - conf.id = pci_dev->id; - } + bus = rte_bus_find_by_device(dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(dev_info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } + + /* Get the interface default mac address */ + rte_eth_macaddr_get(port_id, + (struct ether_addr *)&conf.mac_addr); memset(&ops, 0, sizeof(ops)); ops.port_id = port_id; ops.change_mtu = kni_change_mtu; ops.config_network_if = kni_config_network_interface; + ops.config_mac_address = kni_config_mac_address; kni_stat[port_id]->kni = rte_kni_alloc(mbuf_pool, &conf, &ops); if (kni_stat[port_id]->kni == NULL) @@ -407,11 +485,13 @@ ff_kni_alloc(uint16_t port_id, unsigned socket_id, rte_ring_free_count(kni_rp[port_id])); } - void ff_kni_process(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **pkts_burst, unsigned count) { + if (unlikely(kni_link == ETH_LINK_DOWN)) { + monitor_all_ports_link_status(port_id); + } kni_process_tx(port_id, queue_id, pkts_burst, count); kni_process_rx(port_id, queue_id, pkts_burst, count); }