From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail04.ics.ntt-tx.co.jp (mail05.ics.ntt-tx.co.jp [210.232.35.69]) by dpdk.org (Postfix) with ESMTP id ECFC85942 for ; Wed, 21 Nov 2018 02:41:07 +0100 (CET) Received: from gwchk03.silk.ntt-tx.co.jp (gwchk03.silk.ntt-tx.co.jp [10.107.0.111]) by mail04.ics.ntt-tx.co.jp (unknown) with ESMTP id wAL1f6dC002657; Wed, 21 Nov 2018 10:41:06 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id wAL1f5Is004440; Wed, 21 Nov 2018 10:41:05 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id LAA01760; Wed, 21 Nov 2018 10:36:00 +0900 Received: from imss03.silk.ntt-tx.co.jp (localhost [127.0.0.1]) by imss03.silk.ntt-tx.co.jp (unknown) with ESMTP id wAL1a0RZ009611; Wed, 21 Nov 2018 10:36:00 +0900 Received: from mgate02.silk.ntt-tx.co.jp (smtp02.silk.ntt-tx.co.jp [10.107.0.37]) by imss03.silk.ntt-tx.co.jp (unknown) with ESMTP id wAL1a0OB009608; Wed, 21 Nov 2018 10:36:00 +0900 Message-Id: <201811210136.wAL1a0OB009608@imss03.silk.ntt-tx.co.jp> Received: from localhost by mgate02.silk.ntt-tx.co.jp (unknown) id wAL1ZwWX008346 ; Wed, 21 Nov 2018 10:35:59 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp Cc: spp@dpdk.org Date: Wed, 21 Nov 2018 10:35:40 +0900 X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181121013558.8869-1-x-fn-spp@sl.ntt-tx.co.jp> References: <20181121013558.8869-1-x-fn-spp@sl.ntt-tx.co.jp> X-TM-AS-MML: No Subject: [spp] [PATCH 05/23] spp_vf: move functions to common directory X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Nov 2018 01:41:08 -0000 From: Hideyuki Yamashita Move common functions of spp_vf and spp_mirror to common directory. This patch also refactors code on following point. change of a function name and the return value. - from spp_check_core_index() to spp_check_core_update() - from get_del_core_element() to del_component_info() Signed-off-by: Hideyuki Yamashita Signed-off-by: Naoki Takada --- src/vf/classifier_mac.c | 2 +- src/vf/common/command_dec.c | 2 +- src/vf/common/spp_proc.c | 932 ++++++++++++++++++++++++++++++++++++ src/vf/common/spp_proc.h | 364 ++++++++++++++ src/vf/spp_vf.c | 916 +---------------------------------- src/vf/spp_vf.h | 100 ---- 6 files changed, 1300 insertions(+), 1016 deletions(-) create mode 100644 src/vf/common/spp_proc.c create mode 100644 src/vf/common/spp_proc.h diff --git a/src/vf/classifier_mac.c b/src/vf/classifier_mac.c index 2a01f0e..4016ab1 100644 --- a/src/vf/classifier_mac.c +++ b/src/vf/classifier_mac.c @@ -868,7 +868,7 @@ spp_classifier_mac_do(int id) } while (likely(spp_get_core_status(lcore_id) == SPP_CORE_FORWARD) && - likely(spp_check_core_index(lcore_id) == 0)) { + likely(spp_check_core_update(lcore_id) == SPP_RET_NG)) { /* change index of update side */ change_update_index(mng_info, id); diff --git a/src/vf/common/command_dec.c b/src/vf/common/command_dec.c index d16f358..5275f4f 100644 --- a/src/vf/common/command_dec.c +++ b/src/vf/common/command_dec.c @@ -273,7 +273,7 @@ decode_component_type_value(void *output, const char *arg_val) if (component->action != SPP_CMD_ACTION_START) return 0; - set_type = spp_change_component_type(arg_val); + set_type = spp_get_component_type(arg_val); if (unlikely(set_type <= 0)) { RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown component type. val=%s\n", diff --git a/src/vf/common/spp_proc.c b/src/vf/common/spp_proc.c new file mode 100644 index 0000000..7b92e38 --- /dev/null +++ b/src/vf/common/spp_proc.c @@ -0,0 +1,932 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "spp_proc.h" +#include "spp_port.h" + +#include "../vf/spp_forward.h" +#include "../vf/classifier_mac.h" + +/* Declare global variables */ + +/** + * Make a hexdump of an array data in every 4 byte. + * This function is used to dump core_info or component info. + */ +void +dump_buff(const char *name, const void *addr, const size_t size) +{ + size_t cnt = 0; + size_t max = (size / sizeof(unsigned int)) + + ((size % sizeof(unsigned int)) != 0); + const uint32_t *buff = addr; + + if ((name != NULL) && (name[0] != '\0')) + RTE_LOG(DEBUG, APP, "dump buff. (%s)\n", name); + + for (cnt = 0; cnt < max; cnt += 16) { + RTE_LOG(DEBUG, APP, "[%p]" + " %08x %08x %08x %08x %08x %08x %08x %08x" + " %08x %08x %08x %08x %08x %08x %08x %08x", + &buff[cnt], + buff[cnt+0], buff[cnt+1], + buff[cnt+2], buff[cnt+3], + buff[cnt+4], buff[cnt+5], + buff[cnt+6], buff[cnt+7], + buff[cnt+8], buff[cnt+9], + buff[cnt+10], buff[cnt+11], + buff[cnt+12], buff[cnt+13], + buff[cnt+14], buff[cnt+15]); + } +} + +int +add_ring_pmd(int ring_id) +{ + struct rte_ring *ring; + int ring_port_id; + + /* Lookup ring of given id */ + ring = rte_ring_lookup(get_rx_queue_name(ring_id)); + if (unlikely(ring == NULL)) { + RTE_LOG(ERR, APP, + "Cannot get RX ring - is server process running?\n"); + return -1; + } + + /* Create ring pmd */ + ring_port_id = rte_eth_from_ring(ring); + RTE_LOG(INFO, APP, "ring port add. (no = %d / port = %d)\n", + ring_id, ring_port_id); + return ring_port_id; +} + +int +add_vhost_pmd(int index, int client) +{ + struct rte_eth_conf port_conf = { + .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN } + }; + struct rte_mempool *mp; + uint16_t vhost_port_id; + int nr_queues = 1; + const char *name; + char devargs[64]; + char *iface; + uint16_t q; + int ret; +#define NR_DESCS 128 + + mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); + if (unlikely(mp == NULL)) { + RTE_LOG(ERR, APP, "Cannot get mempool for mbufs. " + "(name = %s)\n", PKTMBUF_POOL_NAME); + return -1; + } + + /* eth_vhost0 index 0 iface /tmp/sock0 on numa 0 */ + name = get_vhost_backend_name(index); + iface = get_vhost_iface_name(index); + + sprintf(devargs, "%s,iface=%s,queues=%d,client=%d", + name, iface, nr_queues, client); + ret = dev_attach_by_devargs(devargs, &vhost_port_id); + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, "spp_rte_eth_dev_attach error. " + "(ret = %d)\n", ret); + return ret; + } + + ret = rte_eth_dev_configure(vhost_port_id, nr_queues, nr_queues, + &port_conf); + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, "rte_eth_dev_configure error. " + "(ret = %d)\n", ret); + return ret; + } + + /* Allocate and set up 1 RX queue per Ethernet port. */ + for (q = 0; q < nr_queues; q++) { + ret = rte_eth_rx_queue_setup(vhost_port_id, q, NR_DESCS, + rte_eth_dev_socket_id(vhost_port_id), NULL, mp); + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, + "rte_eth_rx_queue_setup error. (ret = %d)\n", + ret); + return ret; + } + } + + /* Allocate and set up 1 TX queue per Ethernet port. */ + for (q = 0; q < nr_queues; q++) { + ret = rte_eth_tx_queue_setup(vhost_port_id, q, NR_DESCS, + rte_eth_dev_socket_id(vhost_port_id), NULL); + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, + "rte_eth_tx_queue_setup error. (ret = %d)\n", + ret); + return ret; + } + } + + /* Start the Ethernet port. */ + ret = rte_eth_dev_start(vhost_port_id); + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, "rte_eth_dev_start error. (ret = %d)\n", + ret); + return ret; + } + + RTE_LOG(INFO, APP, "vhost port add. (no = %d / port = %d)\n", + index, vhost_port_id); + return vhost_port_id; +} + +/* Get core status */ +enum spp_core_status +spp_get_core_status(unsigned int lcore_id) +{ + return g_core_info[lcore_id].status; +} + +/** + * Check status of all of cores is same as given + * + * It returns -1 as status mismatch if status is not same. + * If core is in use, status will be checked. + */ +static int +check_core_status(enum spp_core_status status) +{ + unsigned int lcore_id = 0; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (g_core_info[lcore_id].status != status) { + /* Status is mismatched */ + return -1; + } + } + return 0; +} + +int +check_core_status_wait(enum spp_core_status status) +{ + int cnt = 0; + for (cnt = 0; cnt < SPP_CORE_STATUS_CHECK_MAX; cnt++) { + sleep(1); + int ret = check_core_status(status); + if (ret == 0) + return 0; + } + + RTE_LOG(ERR, APP, "Status check time out. (status = %d)\n", status); + return -1; +} + +/* Set core status */ +void +set_core_status(unsigned int lcore_id, + enum spp_core_status status) +{ + g_core_info[lcore_id].status = status; +} + +/* Set all core to given status */ +void +set_all_core_status(enum spp_core_status status) +{ + unsigned int lcore_id = 0; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + g_core_info[lcore_id].status = status; + } +} + +/** + * Set all of component status to SPP_CORE_STOP_REQUEST if received signal + * is SIGTERM or SIGINT + */ +void +stop_process(int signal) +{ + if (unlikely(signal != SIGTERM) && + unlikely(signal != SIGINT)) { + return; + } + + g_core_info[g_main_lcore_id].status = SPP_CORE_STOP_REQUEST; + set_all_core_status(SPP_CORE_STOP_REQUEST); +} + +/** + * Return port info of given type and num of interface + * + * It returns NULL value if given type is invalid. + */ +struct spp_port_info * +get_iface_info(enum port_type iface_type, int iface_no) +{ + switch (iface_type) { + case PHY: + return &g_iface_info.nic[iface_no]; + case VHOST: + return &g_iface_info.vhost[iface_no]; + case RING: + return &g_iface_info.ring[iface_no]; + default: + return NULL; + } +} + +/* Dump of core information */ +void +dump_core_info(const struct core_mng_info *core_info) +{ + char str[SPP_NAME_STR_LEN]; + const struct core_mng_info *info = NULL; + unsigned int lcore_id = 0; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + info = &core_info[lcore_id]; + RTE_LOG(DEBUG, APP, "core[%d] status=%d, ref=%d, upd=%d\n", + lcore_id, info->status, + info->ref_index, info->upd_index); + + sprintf(str, "core[%d]-0 type=%d, num=%d", lcore_id, + info->core[0].type, info->core[0].num); + dump_buff(str, info->core[0].id, + sizeof(int)*info->core[0].num); + + sprintf(str, "core[%d]-1 type=%d, num=%d", lcore_id, + info->core[1].type, info->core[1].num); + dump_buff(str, info->core[1].id, + sizeof(int)*info->core[1].num); + } +} + +/* Dump of component information */ +void +dump_component_info(const struct spp_component_info *component_info) +{ + char str[SPP_NAME_STR_LEN]; + const struct spp_component_info *component = NULL; + int cnt = 0; + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + component = &component_info[cnt]; + if (component->type == SPP_COMPONENT_UNUSE) + continue; + + RTE_LOG(DEBUG, APP, "component[%d] name=%s, type=%d, " + "core=%u, index=%d\n", + cnt, component->name, component->type, + component->lcore_id, component->component_id); + + sprintf(str, "component[%d] rx=%d", cnt, + component->num_rx_port); + dump_buff(str, component->rx_ports, + sizeof(struct spp_port_info *)*component->num_rx_port); + + sprintf(str, "component[%d] tx=%d", cnt, + component->num_tx_port); + dump_buff(str, component->tx_ports, + sizeof(struct spp_port_info *)*component->num_tx_port); + } +} + +/* Dump of interface information */ +void +dump_interface_info(const struct iface_info *iface_info) +{ + const struct spp_port_info *port = NULL; + int cnt = 0; + RTE_LOG(DEBUG, APP, "interface phy=%d, vhost=%d, ring=%d\n", + iface_info->num_nic, + iface_info->num_vhost, + iface_info->num_ring); + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &iface_info->nic[cnt]; + if (port->iface_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "phy [%d] type=%d, no=%d, port=%d, " + "vid = %u, mac=%08lx(%s)\n", + cnt, port->iface_type, port->iface_no, + port->dpdk_port, + port->class_id.vlantag.vid, + port->class_id.mac_addr, + port->class_id.mac_addr_str); + } + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &iface_info->vhost[cnt]; + if (port->iface_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "vhost[%d] type=%d, no=%d, port=%d, " + "vid = %u, mac=%08lx(%s)\n", + cnt, port->iface_type, port->iface_no, + port->dpdk_port, + port->class_id.vlantag.vid, + port->class_id.mac_addr, + port->class_id.mac_addr_str); + } + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &iface_info->ring[cnt]; + if (port->iface_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "ring [%d] type=%d, no=%d, port=%d, " + "vid = %u, mac=%08lx(%s)\n", + cnt, port->iface_type, port->iface_no, + port->dpdk_port, + port->class_id.vlantag.vid, + port->class_id.mac_addr, + port->class_id.mac_addr_str); + } +} + +/* Dump of all management information */ +void +dump_all_mng_info( + const struct core_mng_info *core, + const struct spp_component_info *component, + const struct iface_info *interface) +{ + if (rte_log_get_global_level() < RTE_LOG_DEBUG) + return; + + dump_core_info(core); + dump_component_info(component); + dump_interface_info(interface); +} + +/* Copy management information */ +void +copy_mng_info( + struct core_mng_info *dst_core, + struct spp_component_info *dst_component, + struct iface_info *dst_interface, + const struct core_mng_info *src_core, + const struct spp_component_info *src_component, + const struct iface_info *src_interface, + enum copy_mng_flg flg) +{ + int upd_index = 0; + unsigned int lcore_id = 0; + + switch (flg) { + case COPY_MNG_FLG_UPDCOPY: + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + upd_index = src_core[lcore_id].upd_index; + memcpy(&dst_core[lcore_id].core[upd_index], + &src_core[lcore_id].core[upd_index], + sizeof(struct core_info)); + } + break; + default: + /* + * Even if the flag is set to None, + * copying of core is necessary, + * so we will treat all copies as default. + */ + memcpy(dst_core, src_core, + sizeof(struct core_mng_info)*RTE_MAX_LCORE); + break; + } + + memcpy(dst_component, src_component, + sizeof(struct spp_component_info)*RTE_MAX_LCORE); + memcpy(dst_interface, src_interface, + sizeof(struct iface_info)); +} + +/* Backup the management information */ +void +backup_mng_info(struct cancel_backup_info *backup) +{ + dump_all_mng_info(g_core_info, g_component_info, &g_iface_info); + copy_mng_info(backup->core, backup->component, &backup->interface, + g_core_info, g_component_info, &g_iface_info, + COPY_MNG_FLG_ALLCOPY); + dump_all_mng_info(backup->core, backup->component, &backup->interface); + memset(g_change_core, 0x00, sizeof(g_change_core)); + memset(g_change_component, 0x00, sizeof(g_change_component)); +} + +/** + * Initialize g_iface_info + * + * Clear g_iface_info and set initial value. + */ +static void +init_iface_info(void) +{ + int port_cnt; /* increment ether ports */ + memset(&g_iface_info, 0x00, sizeof(g_iface_info)); + for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) { + g_iface_info.nic[port_cnt].iface_type = UNDEF; + g_iface_info.nic[port_cnt].iface_no = port_cnt; + g_iface_info.nic[port_cnt].dpdk_port = -1; + g_iface_info.nic[port_cnt].class_id.vlantag.vid = + ETH_VLAN_ID_MAX; + g_iface_info.vhost[port_cnt].iface_type = UNDEF; + g_iface_info.vhost[port_cnt].iface_no = port_cnt; + g_iface_info.vhost[port_cnt].dpdk_port = -1; + g_iface_info.vhost[port_cnt].class_id.vlantag.vid = + ETH_VLAN_ID_MAX; + g_iface_info.ring[port_cnt].iface_type = UNDEF; + g_iface_info.ring[port_cnt].iface_no = port_cnt; + g_iface_info.ring[port_cnt].dpdk_port = -1; + g_iface_info.ring[port_cnt].class_id.vlantag.vid = + ETH_VLAN_ID_MAX; + } +} + +/** + * Initialize g_component_info + */ +static void +init_component_info(void) +{ + int cnt; + memset(&g_component_info, 0x00, sizeof(g_component_info)); + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) + g_component_info[cnt].component_id = cnt; + memset(g_change_component, 0x00, sizeof(g_change_component)); +} + +/** + * Initialize g_core_info + */ +static void +init_core_info(void) +{ + int cnt = 0; + memset(&g_core_info, 0x00, sizeof(g_core_info)); + set_all_core_status(SPP_CORE_STOP); + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + g_core_info[cnt].ref_index = 0; + g_core_info[cnt].upd_index = 1; + } + memset(g_change_core, 0x00, sizeof(g_change_core)); +} + +/** + * Setup port info of port on host + */ +static int +set_nic_interface(void) +{ + int nic_cnt = 0; + + /* NIC Setting */ + g_iface_info.num_nic = rte_eth_dev_count_avail(); + if (g_iface_info.num_nic > RTE_MAX_ETHPORTS) + g_iface_info.num_nic = RTE_MAX_ETHPORTS; + + for (nic_cnt = 0; nic_cnt < g_iface_info.num_nic; nic_cnt++) { + g_iface_info.nic[nic_cnt].iface_type = PHY; + g_iface_info.nic[nic_cnt].dpdk_port = nic_cnt; + } + + return 0; +} + +/** + * Setup management info for spp_vf + */ +int +init_mng_data(void) +{ + /* Initialize interface and core information */ + init_iface_info(); + init_core_info(); + init_component_info(); + + int ret_nic = set_nic_interface(); + if (unlikely(ret_nic != 0)) + return -1; + + return 0; +} + +#ifdef SPP_RINGLATENCYSTATS_ENABLE +/** + * Print statistics of time for packet processing in ring interface + */ +static void +print_ring_latency_stats(void) +{ + /* Clear screen and move cursor to top left */ + const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; + const char clr[] = { 27, '[', '2', 'J', '\0' }; + printf("%s%s", clr, topLeft); + + int ring_cnt, stats_cnt; + struct spp_ringlatencystats_ring_latency_stats stats[RTE_MAX_ETHPORTS]; + memset(&stats, 0x00, sizeof(stats)); + + printf("RING Latency\n"); + printf(" RING"); + for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) { + if (g_iface_info.ring[ring_cnt].iface_type == UNDEF) + continue; + + spp_ringlatencystats_get_stats(ring_cnt, &stats[ring_cnt]); + printf(", %-18d", ring_cnt); + } + printf("\n"); + + for (stats_cnt = 0; stats_cnt < SPP_RINGLATENCYSTATS_STATS_SLOT_COUNT; + stats_cnt++) { + printf("%3dns", stats_cnt); + for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) { + if (g_iface_info.ring[ring_cnt].iface_type == UNDEF) + continue; + + printf(", 0x%-16lx", stats[ring_cnt].slot[stats_cnt]); + } + printf("\n"); + } +} +#endif /* SPP_RINGLATENCYSTATS_ENABLE */ + +/* Remove sock file if spp is not running */ +void +del_vhost_sockfile(struct spp_port_info *vhost) +{ + int cnt; + + /* Do not remove for if it is running in vhost-client mode. */ + if (g_startup_param.vhost_client != 0) + return; + + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + if (likely(vhost[cnt].iface_type == UNDEF)) { + /* Skip removing if it is not using vhost */ + continue; + } + + remove(get_vhost_iface_name(cnt)); + } +} + +/* Get component type of target core */ +enum spp_component_type +spp_get_component_type(unsigned int lcore_id) +{ + struct core_mng_info *info = &g_core_info[lcore_id]; + return info->core[info->ref_index].type; +} + +/* Get core ID of target component */ +unsigned int +spp_get_component_core(int component_id) +{ + struct spp_component_info *info = &g_component_info[component_id]; + return info->lcore_id; +} + +/* Get core information which is in use */ +struct core_info * +get_core_info(unsigned int lcore_id) +{ + struct core_mng_info *info = &g_core_info[lcore_id]; + return &(info->core[info->ref_index]); +} + +/* Check core index change */ +int +spp_check_core_update(unsigned int lcore_id) +{ + struct core_mng_info *info = &g_core_info[lcore_id]; + if (info->ref_index == info->upd_index) + return SPP_RET_OK; + else + return SPP_RET_NG; +} + +int +spp_check_used_port( + enum port_type iface_type, + int iface_no, + enum spp_port_rxtx rxtx) +{ + int cnt, port_cnt, max = 0; + struct spp_component_info *component = NULL; + struct spp_port_info **port_array = NULL; + struct spp_port_info *port = get_iface_info(iface_type, iface_no); + + if (port == NULL) + return SPP_RET_NG; + + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + component = &g_component_info[cnt]; + if (component->type == SPP_COMPONENT_UNUSE) + continue; + + if (rxtx == SPP_PORT_RXTX_RX) { + max = component->num_rx_port; + port_array = component->rx_ports; + } else if (rxtx == SPP_PORT_RXTX_TX) { + max = component->num_tx_port; + port_array = component->tx_ports; + } + for (port_cnt = 0; port_cnt < max; port_cnt++) { + if (unlikely(port_array[port_cnt] == port)) + return cnt; + } + } + + return SPP_RET_NG; +} + +/* Set component update flag for given port */ +void +set_component_change_port(struct spp_port_info *port, enum spp_port_rxtx rxtx) +{ + int ret = 0; + if ((rxtx == SPP_PORT_RXTX_RX) || (rxtx == SPP_PORT_RXTX_ALL)) { + ret = spp_check_used_port(port->iface_type, port->iface_no, + SPP_PORT_RXTX_RX); + if (ret >= 0) + g_change_component[ret] = 1; + } + + if ((rxtx == SPP_PORT_RXTX_TX) || (rxtx == SPP_PORT_RXTX_ALL)) { + ret = spp_check_used_port(port->iface_type, port->iface_no, + SPP_PORT_RXTX_TX); + if (ret >= 0) + g_change_component[ret] = 1; + } +} + +/* Get unused component id */ +int +get_free_component(void) +{ + int cnt = 0; + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + if (g_component_info[cnt].type == SPP_COMPONENT_UNUSE) + return cnt; + } + return -1; +} + +/* Get component id for specified component name */ +int +spp_get_component_id(const char *name) +{ + int cnt = 0; + if (name[0] == '\0') + return SPP_RET_NG; + + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + if (strcmp(name, g_component_info[cnt].name) == 0) + return cnt; + } + return SPP_RET_NG; +} + +/* Delete component information */ +int +del_component_info(int component_id, int component_num, int *componet_array) +{ + int cnt; + int match = -1; + int max = component_num; + + for (cnt = 0; cnt < max; cnt++) { + if (component_id == componet_array[cnt]) + match = cnt; + } + + if (match < 0) + return -1; + + /* Last element is excluded from movement. */ + max--; + + for (cnt = match; cnt < max; cnt++) + componet_array[cnt] = componet_array[cnt+1]; + + /* Last element is cleared. */ + componet_array[cnt] = 0; + return 0; +} + +/* get port element which matches the condition */ +int +check_port_element( + struct spp_port_info *info, + int num, + struct spp_port_info *array[]) +{ + int cnt = 0; + int match = -1; + for (cnt = 0; cnt < num; cnt++) { + if (info == array[cnt]) + match = cnt; + } + return match; +} + +/* search matched port_info from array and delete it */ +int +get_del_port_element( + struct spp_port_info *info, + int num, + struct spp_port_info *array[]) +{ + int cnt = 0; + int match = -1; + int max = num; + + match = check_port_element(info, num, array); + if (match < 0) + return -1; + + /* Last element is excluded from movement. */ + max--; + + for (cnt = match; cnt < max; cnt++) + array[cnt] = array[cnt+1]; + + /* Last element is cleared. */ + array[cnt] = NULL; + return 0; +} + +/* Flush initial setting of each interface. */ +int +flush_port(void) +{ + int ret = 0; + int cnt = 0; + struct spp_port_info *port = NULL; + + /* Initialize added vhost. */ + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &g_iface_info.vhost[cnt]; + if ((port->iface_type != UNDEF) && (port->dpdk_port < 0)) { + ret = add_vhost_pmd(port->iface_no, + g_startup_param.vhost_client); + if (ret < 0) + return SPP_RET_NG; + port->dpdk_port = ret; + } + } + + /* Initialize added ring. */ + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &g_iface_info.ring[cnt]; + if ((port->iface_type != UNDEF) && (port->dpdk_port < 0)) { + ret = add_ring_pmd(port->iface_no); + if (ret < 0) + return SPP_RET_NG; + port->dpdk_port = ret; + } + } + return SPP_RET_OK; +} + +/* Flush changed core. */ +void +flush_core(void) +{ + int cnt = 0; + struct core_mng_info *info = NULL; + + /* Changed core has changed index. */ + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + if (g_change_core[cnt] != 0) { + info = &g_core_info[cnt]; + info->upd_index = info->ref_index; + } + } + + /* Waiting for changed core change. */ + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + if (g_change_core[cnt] != 0) { + info = &g_core_info[cnt]; + while (likely(info->ref_index == info->upd_index)) + rte_delay_us_block(SPP_CHANGE_UPDATE_INTERVAL); + + memcpy(&info->core[info->upd_index], + &info->core[info->ref_index], + sizeof(struct core_info)); + } + } +} + +/* Flush change for forwarder or classifier_mac */ +int +flush_component(void) +{ + int ret = 0; + int cnt = 0; + struct spp_component_info *component_info = NULL; + + for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { + if (g_change_component[cnt] == 0) + continue; + + component_info = &g_component_info[cnt]; + spp_port_ability_update(component_info); + + if (component_info->type == SPP_COMPONENT_CLASSIFIER_MAC) + ret = spp_classifier_mac_update(component_info); + else + ret = spp_forward_update(component_info); + + if (unlikely(ret < 0)) { + RTE_LOG(ERR, APP, "Flush error. " + "( component = %s, type = %d)\n", + component_info->name, + component_info->type); + return SPP_RET_NG; + } + } + return SPP_RET_OK; +} + +/** + * Generate a formatted string of combination from interface type and + * number and assign to given 'port' + */ +int spp_format_port_string(char *port, enum port_type iface_type, int iface_no) +{ + const char *iface_type_str; + + switch (iface_type) { + case PHY: + iface_type_str = SPP_IFTYPE_NIC_STR; + break; + case RING: + iface_type_str = SPP_IFTYPE_RING_STR; + break; + case VHOST: + iface_type_str = SPP_IFTYPE_VHOST_STR; + break; + default: + return -1; + } + + sprintf(port, "%s:%d", iface_type_str, iface_no); + + return 0; +} + +/** + * Change mac address of 'aa:bb:cc:dd:ee:ff' to int64 and return it + */ +int64_t +spp_change_mac_str_to_int64(const char *mac) +{ + int64_t ret_mac = 0; + int64_t token_val = 0; + int token_cnt = 0; + char tmp_mac[SPP_MIN_STR_LEN]; + char *str = tmp_mac; + char *saveptr = NULL; + char *endptr = NULL; + + RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s)\n", mac); + + strcpy(tmp_mac, mac); + while (1) { + /* Split by colon(':') */ + char *ret_tok = strtok_r(str, ":", &saveptr); + if (unlikely(ret_tok == NULL)) + break; + + /* Check for mal-formatted address */ + if (unlikely(token_cnt >= ETHER_ADDR_LEN)) { + RTE_LOG(ERR, APP, "MAC address format error. " + "(mac = %s)\n", mac); + return -1; + } + + /* Convert string to hex value */ + int ret_tol = strtol(ret_tok, &endptr, 16); + if (unlikely(ret_tok == endptr) || unlikely(*endptr != '\0')) + break; + + /* Append separated value to the result */ + token_val = (int64_t)ret_tol; + ret_mac |= token_val << (token_cnt * 8); + token_cnt++; + str = NULL; + } + + RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s => 0x%08lx)\n", + mac, ret_mac); + return ret_mac; +} diff --git a/src/vf/common/spp_proc.h b/src/vf/common/spp_proc.h new file mode 100644 index 0000000..125af52 --- /dev/null +++ b/src/vf/common/spp_proc.h @@ -0,0 +1,364 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _SPP_PROC_H_ +#define _SPP_PROC_H_ + +/** + * @file + * SPP process + * + * SPP component common function. + */ + +#include +#include "common.h" + +/** + * Make a hexdump of an array data in every 4 byte. + * This function is used to dump core_info or component info. + * + * @param name + * dump name. + * @param addr + * dump address. + * @param size + * dump byte size. + * + */ +void dump_buff(const char *name, const void *addr, const size_t size); + +/** + * added ring_pmd + * + * @param ring_id + * added ring id. + * + * @retval 0~ ring_port_id. + * @retval -1 failed. + */ +int add_ring_pmd(int ring_id); + +/** + * added vhost_pmd + * + * @param index + * add vohst id. + * @param client + * add client id. + * + * @retval 0~ vhost_port_id. + * @retval -1 failed. + */ +int add_vhost_pmd(int index, int client); + +/** + * Get core status + * + * @param lcore_id + * Logical core ID. + * + * @return + * Status of specified logical core. + */ +enum spp_core_status spp_get_core_status(unsigned int lcore_id); + +/** + * Get component type of target core + * + * @param lcore_id + * Logical core ID. + * + * @return + * Type of component executed on specified logical core + */ +enum spp_component_type spp_get_component_type(unsigned int lcore_id); + +/** + * Run check_core_status() for SPP_CORE_STATUS_CHECK_MAX times with + * interval time (1sec) + * + * @param status + * wait check status. + * + * @retval 0 succeeded. + * @retval -1 failed. + */ +int check_core_status_wait(enum spp_core_status status); + +/** + * Set core status + * + * @param lcore_id + * Logical core ID. + * @param status + * set status. + * + */ +void set_core_status(unsigned int lcore_id, enum spp_core_status status); + +/** + * Set all core status to given + * + * @param status + * set status. + * + */ +void set_all_core_status(enum spp_core_status status); + +/** + * Set all of component status to SPP_CORE_STOP_REQUEST if received signal + * is SIGTERM or SIGINT + * + * @param signl + * received signal. + * + */ +void stop_process(int signal); + +/** + * Return port info of given type and num of interface + * + * @param iface_type + * Interface type to be validated. + * @param iface_no + * Interface number to be validated. + * + * @retval !NULL spp_port_info. + * @retval NULL failed. + */ +struct spp_port_info * +get_iface_info(enum port_type iface_type, int iface_no); + +/* Dump of core information */ +void dump_core_info(const struct core_mng_info *core_info); + +/* Dump of component information */ +void dump_component_info(const struct spp_component_info *component_info); + +/* Dump of interface information */ +void dump_interface_info(const struct iface_info *iface_info); + +/* Dump of all management information */ +void dump_all_mng_info( + const struct core_mng_info *core, + const struct spp_component_info *component, + const struct iface_info *interface); + +/* Copy management information */ +void copy_mng_info( + struct core_mng_info *dst_core, + struct spp_component_info *dst_component, + struct iface_info *dst_interface, + const struct core_mng_info *src_core, + const struct spp_component_info *src_component, + const struct iface_info *src_interface, + enum copy_mng_flg flg); + +/* Backup the management information */ +void backup_mng_info(struct cancel_backup_info *backup); + +/** + * Setup management info for spp_vf + */ +int init_mng_data(void); + +#ifdef SPP_RINGLATENCYSTATS_ENABLE +/** + * Print statistics of time for packet processing in ring interface + */ +void print_ring_latency_stats(void); +#endif /* SPP_RINGLATENCYSTATS_ENABLE */ + +/* Remove sock file if spp is not running */ +void del_vhost_sockfile(struct spp_port_info *vhost); + +/** + * Get component type of target core + * + * @param lcore_id + * Logical core ID. + * + * @return + * Type of component executed on specified logical core + */ +enum spp_component_type +spp_get_component_type(unsigned int lcore_id); + +/** + * Get core ID of target component + * + * @param component_id + * unique component ID. + * + * @return + * Logical core id of specified component. + */ +unsigned int spp_get_component_core(int component_id); + +/* Get core information which is in use */ +struct core_info *get_core_info(unsigned int lcore_id); + +/** + * Check core index change + * + * @param lcore_id + * Logical core ID. + * + * True if index has changed. + * @retval SPP_RET_OK index has changed. + * @retval SPP_RET_NG index not changed. + */ +int spp_check_core_update(unsigned int lcore_id); + +/** + * Check if component is using port. + * + * @param iface_type + * Interface type to be validated. + * @param iface_no + * Interface number to be validated. + * @param rxtx + * tx/rx type to be validated. + * + * @retval 0~127 match component ID + * @retval SPP_RET_NG failed. + */ +int spp_check_used_port( + enum port_type iface_type, + int iface_no, + enum spp_port_rxtx rxtx); + +/** + * Set component update flag for given port. + * + * @param port + * spp_port_info address + * @param rxtx + * enum spp_port_rxtx + * + */ +void +set_component_change_port(struct spp_port_info *port, enum spp_port_rxtx rxtx); + +/** + * Get unused component id + * + * @retval 0~127 Component ID. + * @retval -1 failed. + */ +int get_free_component(void); + +/** + * Get component id for specified component name + * + * @param name + * Component name. + * + * @retval 0~127 Component ID. + * @retval SPP_RET_NG failed. + */ +int spp_get_component_id(const char *name); + +/** + * Delete component information. + * + * @param component_id + * check data + * @param component_num + * array check count + * @param componet_array + * check array address + * + * @retval 0 succeeded. + * @retval -1 failed. + */ +int +del_component_info(int component_id, int component_num, int *componet_array); + +/** + * get port element which matches the condition. + * + * @param info + * spp_port_info address + * @param num + * port count + * @param array[] + * spp_port_info array address + * + * @retval 0~ match index. + * @retval -1 failed. + */ +int check_port_element( + struct spp_port_info *info, + int num, + struct spp_port_info *array[]); + +/** + * search matched port_info from array and delete it. + * + * @param info + * spp_port_info address + * @param num + * port count + * @param array[] + * spp_port_info array address + * + * @retval 0 succeeded. + * @retval -1 failed. + */ +int get_del_port_element( + struct spp_port_info *info, + int num, + struct spp_port_info *array[]); + +/** + * Flush initial setting of each interface. + * + * @retval SPP_RET_OK succeeded. + * @retval SPP_RET_NG failed. + */ +int flush_port(void); + +/** + * Flush changed core. + */ +void flush_core(void); + +/** + * Flush change for forwarder or classifier_mac. + * + * @retval SPP_RET_OK succeeded. + * @retval SPP_RET_NG failed. + */ +int flush_component(void); + +/** + * Port type to string + * + * @param port + * Character string of Port type to be converted. + * @param iface_type + * port interface type + * @param iface_no + * interface no + * + * @retval 0 succeeded. + * @retval -1 failed. + */ +int +spp_format_port_string(char *port, enum port_type iface_type, int iface_no); + +/** + * Change mac address string to int64 + * + * @param mac + * Character string of MAC address to be converted. + * + * @retval 0< int64 that store mac address + * @retval -1 + */ +int64_t spp_change_mac_str_to_int64(const char *mac); + +#endif /* _SPP_PROC_H_ */ diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c index 96d331e..accef02 100644 --- a/src/vf/spp_vf.c +++ b/src/vf/spp_vf.c @@ -146,214 +146,6 @@ usage(const char *progname) , progname); } -/* Make a hexdump of an array data in every 4 byte */ -static void -dump_buff(const char *name, const void *addr, const size_t size) -{ - size_t cnt = 0; - size_t max = (size / sizeof(unsigned int)) + - ((size % sizeof(unsigned int)) != 0); - const uint32_t *buff = addr; - - if ((name != NULL) && (name[0] != '\0')) - RTE_LOG(DEBUG, APP, "dump buff. (%s)\n", name); - - for (cnt = 0; cnt < max; cnt += 16) { - RTE_LOG(DEBUG, APP, "[%p]" - " %08x %08x %08x %08x %08x %08x %08x %08x" - " %08x %08x %08x %08x %08x %08x %08x %08x", - &buff[cnt], - buff[cnt+0], buff[cnt+1], - buff[cnt+2], buff[cnt+3], - buff[cnt+4], buff[cnt+5], - buff[cnt+6], buff[cnt+7], - buff[cnt+8], buff[cnt+9], - buff[cnt+10], buff[cnt+11], - buff[cnt+12], buff[cnt+13], - buff[cnt+14], buff[cnt+15]); - } -} - -static int -add_ring_pmd(int ring_id) -{ - struct rte_ring *ring; - int ring_port_id; - - /* Lookup ring of given id */ - ring = rte_ring_lookup(get_rx_queue_name(ring_id)); - if (unlikely(ring == NULL)) { - RTE_LOG(ERR, APP, - "Cannot get RX ring - is server process running?\n"); - return -1; - } - - /* Create ring pmd */ - ring_port_id = rte_eth_from_ring(ring); - RTE_LOG(INFO, APP, "ring port add. (no = %d / port = %d)\n", - ring_id, ring_port_id); - return ring_port_id; -} - -static int -add_vhost_pmd(int index, int client) -{ - struct rte_eth_conf port_conf = { - .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN } - }; - struct rte_mempool *mp; - uint16_t vhost_port_id; - int nr_queues = 1; - const char *name; - char devargs[64]; - char *iface; - uint16_t q; - int ret; -#define NR_DESCS 128 - - mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); - if (unlikely(mp == NULL)) { - RTE_LOG(ERR, APP, "Cannot get mempool for mbufs. " - "(name = %s)\n", PKTMBUF_POOL_NAME); - return -1; - } - - /* eth_vhost0 index 0 iface /tmp/sock0 on numa 0 */ - name = get_vhost_backend_name(index); - iface = get_vhost_iface_name(index); - - sprintf(devargs, "%s,iface=%s,queues=%d,client=%d", - name, iface, nr_queues, client); - ret = dev_attach_by_devargs(devargs, &vhost_port_id); - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, "dev_attach_by_devargs error. (ret = %d)\n", - ret); - return ret; - } - - ret = rte_eth_dev_configure(vhost_port_id, nr_queues, nr_queues, - &port_conf); - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, "rte_eth_dev_configure error. " - "(ret = %d)\n", ret); - return ret; - } - - /* Allocate and set up 1 RX queue per Ethernet port. */ - for (q = 0; q < nr_queues; q++) { - ret = rte_eth_rx_queue_setup(vhost_port_id, q, NR_DESCS, - rte_eth_dev_socket_id(vhost_port_id), NULL, mp); - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, - "rte_eth_rx_queue_setup error. (ret = %d)\n", - ret); - return ret; - } - } - - /* Allocate and set up 1 TX queue per Ethernet port. */ - for (q = 0; q < nr_queues; q++) { - ret = rte_eth_tx_queue_setup(vhost_port_id, q, NR_DESCS, - rte_eth_dev_socket_id(vhost_port_id), NULL); - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, - "rte_eth_tx_queue_setup error. (ret = %d)\n", - ret); - return ret; - } - } - - /* Start the Ethernet port. */ - ret = rte_eth_dev_start(vhost_port_id); - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, "rte_eth_dev_start error. (ret = %d)\n", - ret); - return ret; - } - - RTE_LOG(INFO, APP, "vhost port add. (no = %d / port = %d)\n", - index, vhost_port_id); - return vhost_port_id; -} - -/* Get core status */ -enum spp_core_status -spp_get_core_status(unsigned int lcore_id) -{ - return g_core_info[lcore_id].status; -} - -/** - * Check status of all of cores is same as given - * - * It returns -1 as status mismatch if status is not same. - * If core is in use, status will be checked. - */ -static int -check_core_status(enum spp_core_status status) -{ - unsigned int lcore_id = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (g_core_info[lcore_id].status != status) { - /* Status is mismatched */ - return -1; - } - } - return 0; -} - -/** - * Run check_core_status() for SPP_CORE_STATUS_CHECK_MAX times with - * interval time (1sec) - */ -static int -check_core_status_wait(enum spp_core_status status) -{ - int cnt = 0; - for (cnt = 0; cnt < SPP_CORE_STATUS_CHECK_MAX; cnt++) { - sleep(1); - int ret = check_core_status(status); - if (ret == 0) - return 0; - } - - RTE_LOG(ERR, APP, "Status check time out. (status = %d)\n", status); - return -1; -} - -/* Set core status */ -static void -set_core_status(unsigned int lcore_id, - enum spp_core_status status) -{ - g_core_info[lcore_id].status = status; -} - -/* Set all core to given status */ -static void -set_all_core_status(enum spp_core_status status) -{ - unsigned int lcore_id = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - g_core_info[lcore_id].status = status; - } -} - -/** - * Set all of component status to SPP_CORE_STOP_REQUEST if received signal - * is SIGTERM or SIGINT - */ -static void -stop_process(int signal) { - if (unlikely(signal != SIGTERM) && - unlikely(signal != SIGINT)) { - return; - } - - g_core_info[g_main_lcore_id].status = SPP_CORE_STOP_REQUEST; - set_all_core_status(SPP_CORE_STOP_REQUEST); -} - /** * Convert string of given client id to integer * @@ -479,367 +271,6 @@ parse_app_args(int argc, char *argv[]) return 0; } -/** - * Return port info of given type and num of interface - * - * It returns NULL value if given type is invalid. - */ -static struct spp_port_info * -get_iface_info(enum port_type iface_type, int iface_no) -{ - switch (iface_type) { - case PHY: - return &g_iface_info.nic[iface_no]; - case VHOST: - return &g_iface_info.vhost[iface_no]; - case RING: - return &g_iface_info.ring[iface_no]; - default: - return NULL; - } -} - -/* Dump of core information */ -static void -dump_core_info(const struct core_mng_info *core_info) -{ - char str[SPP_NAME_STR_LEN]; - const struct core_mng_info *info = NULL; - unsigned int lcore_id = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - info = &core_info[lcore_id]; - RTE_LOG(DEBUG, APP, "core[%d] status=%d, ref=%d, upd=%d\n", - lcore_id, info->status, - info->ref_index, info->upd_index); - - sprintf(str, "core[%d]-0 type=%d, num=%d", lcore_id, - info->core[0].type, info->core[0].num); - dump_buff(str, info->core[0].id, - sizeof(int)*info->core[0].num); - - sprintf(str, "core[%d]-1 type=%d, num=%d", lcore_id, - info->core[1].type, info->core[1].num); - dump_buff(str, info->core[1].id, - sizeof(int)*info->core[1].num); - } -} - -/* Dump of component information */ -static void -dump_component_info(const struct spp_component_info *component_info) -{ - char str[SPP_NAME_STR_LEN]; - const struct spp_component_info *component = NULL; - int cnt = 0; - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - component = &component_info[cnt]; - if (component->type == SPP_COMPONENT_UNUSE) - continue; - - RTE_LOG(DEBUG, APP, "component[%d] name=%s, type=%d, " - "core=%u, index=%d\n", - cnt, component->name, component->type, - component->lcore_id, component->component_id); - - sprintf(str, "component[%d] rx=%d", cnt, - component->num_rx_port); - dump_buff(str, component->rx_ports, - sizeof(struct spp_port_info *)*component->num_rx_port); - - sprintf(str, "component[%d] tx=%d", cnt, - component->num_tx_port); - dump_buff(str, component->tx_ports, - sizeof(struct spp_port_info *)*component->num_tx_port); - } -} - -/* Dump of interface information */ -static void -dump_interface_info(const struct iface_info *iface_info) -{ - const struct spp_port_info *port = NULL; - int cnt = 0; - RTE_LOG(DEBUG, APP, "interface phy=%d, vhost=%d, ring=%d\n", - iface_info->num_nic, - iface_info->num_vhost, - iface_info->num_ring); - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - port = &iface_info->nic[cnt]; - if (port->iface_type == UNDEF) - continue; - - RTE_LOG(DEBUG, APP, "phy [%d] type=%d, no=%d, port=%d, " - "vid = %u, mac=%08lx(%s)\n", - cnt, port->iface_type, port->iface_no, - port->dpdk_port, - port->class_id.vlantag.vid, - port->class_id.mac_addr, - port->class_id.mac_addr_str); - } - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - port = &iface_info->vhost[cnt]; - if (port->iface_type == UNDEF) - continue; - - RTE_LOG(DEBUG, APP, "vhost[%d] type=%d, no=%d, port=%d, " - "vid = %u, mac=%08lx(%s)\n", - cnt, port->iface_type, port->iface_no, - port->dpdk_port, - port->class_id.vlantag.vid, - port->class_id.mac_addr, - port->class_id.mac_addr_str); - } - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - port = &iface_info->ring[cnt]; - if (port->iface_type == UNDEF) - continue; - - RTE_LOG(DEBUG, APP, "ring [%d] type=%d, no=%d, port=%d, " - "vid = %u, mac=%08lx(%s)\n", - cnt, port->iface_type, port->iface_no, - port->dpdk_port, - port->class_id.vlantag.vid, - port->class_id.mac_addr, - port->class_id.mac_addr_str); - } -} - -/* Dump of all management information */ -static void -dump_all_mng_info( - const struct core_mng_info *core, - const struct spp_component_info *component, - const struct iface_info *interface) -{ - if (rte_log_get_global_level() < RTE_LOG_DEBUG) - return; - - dump_core_info(core); - dump_component_info(component); - dump_interface_info(interface); -} - -/* Copy management information */ -static void -copy_mng_info( - struct core_mng_info *dst_core, - struct spp_component_info *dst_component, - struct iface_info *dst_interface, - const struct core_mng_info *src_core, - const struct spp_component_info *src_component, - const struct iface_info *src_interface, - enum copy_mng_flg flg) -{ - int upd_index = 0; - unsigned int lcore_id = 0; - - switch (flg) { - case COPY_MNG_FLG_UPDCOPY: - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - upd_index = src_core[lcore_id].upd_index; - memcpy(&dst_core[lcore_id].core[upd_index], - &src_core[lcore_id].core[upd_index], - sizeof(struct core_info)); - } - break; - default: - /* - * Even if the flag is set to None, - * copying of core is necessary, - * so we will treat all copies as default. - */ - memcpy(dst_core, src_core, - sizeof(struct core_mng_info)*RTE_MAX_LCORE); - break; - } - - memcpy(dst_component, src_component, - sizeof(struct spp_component_info)*RTE_MAX_LCORE); - memcpy(dst_interface, src_interface, - sizeof(struct iface_info)); -} - -/* Backup the management information */ -static void -backup_mng_info(struct cancel_backup_info *backup) -{ - dump_all_mng_info(g_core_info, g_component_info, &g_iface_info); - copy_mng_info(backup->core, backup->component, &backup->interface, - g_core_info, g_component_info, &g_iface_info, - COPY_MNG_FLG_ALLCOPY); - dump_all_mng_info(backup->core, backup->component, &backup->interface); - memset(g_change_core, 0x00, sizeof(g_change_core)); - memset(g_change_component, 0x00, sizeof(g_change_component)); -} - -/** - * Initialize g_iface_info - * - * Clear g_iface_info and set initial value. - */ -static void -init_iface_info(void) -{ - int port_cnt; /* increment ether ports */ - memset(&g_iface_info, 0x00, sizeof(g_iface_info)); - for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) { - g_iface_info.nic[port_cnt].iface_type = UNDEF; - g_iface_info.nic[port_cnt].iface_no = port_cnt; - g_iface_info.nic[port_cnt].dpdk_port = -1; - g_iface_info.nic[port_cnt].class_id.vlantag.vid = - ETH_VLAN_ID_MAX; - g_iface_info.vhost[port_cnt].iface_type = UNDEF; - g_iface_info.vhost[port_cnt].iface_no = port_cnt; - g_iface_info.vhost[port_cnt].dpdk_port = -1; - g_iface_info.vhost[port_cnt].class_id.vlantag.vid = - ETH_VLAN_ID_MAX; - g_iface_info.ring[port_cnt].iface_type = UNDEF; - g_iface_info.ring[port_cnt].iface_no = port_cnt; - g_iface_info.ring[port_cnt].dpdk_port = -1; - g_iface_info.ring[port_cnt].class_id.vlantag.vid = - ETH_VLAN_ID_MAX; - } -} - -/** - * Initialize g_component_info - */ -static void -init_component_info(void) -{ - int cnt; - memset(&g_component_info, 0x00, sizeof(g_component_info)); - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) - g_component_info[cnt].component_id = cnt; - memset(g_change_component, 0x00, sizeof(g_change_component)); -} - -/** - * Initialize g_core_info - */ -static void -init_core_info(void) -{ - int cnt = 0; - memset(&g_core_info, 0x00, sizeof(g_core_info)); - set_all_core_status(SPP_CORE_STOP); - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - g_core_info[cnt].ref_index = 0; - g_core_info[cnt].upd_index = 1; - } - memset(g_change_core, 0x00, sizeof(g_change_core)); -} - -/** - * Setup port info of port on host - */ -static int -set_nic_interface(void) -{ - int nic_cnt = 0; - - /* NIC Setting */ - g_iface_info.num_nic = rte_eth_dev_count_avail(); - if (g_iface_info.num_nic > RTE_MAX_ETHPORTS) - g_iface_info.num_nic = RTE_MAX_ETHPORTS; - - for (nic_cnt = 0; nic_cnt < g_iface_info.num_nic; nic_cnt++) { - g_iface_info.nic[nic_cnt].iface_type = PHY; - g_iface_info.nic[nic_cnt].dpdk_port = nic_cnt; - } - - return 0; -} - -/** - * Setup management info for spp_vf - */ -static int -init_mng_data(void) -{ - /* Initialize interface and core information */ - init_iface_info(); - init_core_info(); - init_component_info(); - - int ret_nic = set_nic_interface(); - if (unlikely(ret_nic != 0)) - return -1; - - return 0; -} - -#ifdef SPP_RINGLATENCYSTATS_ENABLE -/** - * Print statistics of time for packet processing in ring interface - */ -static void -print_ring_latency_stats(void) -{ - /* Clear screen and move cursor to top left */ - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; - const char clr[] = { 27, '[', '2', 'J', '\0' }; - printf("%s%s", clr, topLeft); - - int ring_cnt, stats_cnt; - struct spp_ringlatencystats_ring_latency_stats stats[RTE_MAX_ETHPORTS]; - memset(&stats, 0x00, sizeof(stats)); - - printf("RING Latency\n"); - printf(" RING"); - for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) { - if (g_iface_info.ring[ring_cnt].iface_type == UNDEF) - continue; - - spp_ringlatencystats_get_stats(ring_cnt, &stats[ring_cnt]); - printf(", %-18d", ring_cnt); - } - printf("\n"); - - for (stats_cnt = 0; stats_cnt < SPP_RINGLATENCYSTATS_STATS_SLOT_COUNT; - stats_cnt++) { - printf("%3dns", stats_cnt); - for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) { - if (g_iface_info.ring[ring_cnt].iface_type == UNDEF) - continue; - - printf(", 0x%-16lx", stats[ring_cnt].slot[stats_cnt]); - } - printf("\n"); - } -} -#endif /* SPP_RINGLATENCYSTATS_ENABLE */ - -/** - * Remove sock file - */ -static void -del_vhost_sockfile(struct spp_port_info *vhost) -{ - int cnt; - - /* Do not remove for if it is running in vhost-client mode. */ - if (g_startup_param.vhost_client != 0) - return; - - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - if (likely(vhost[cnt].iface_type == UNDEF)) { - /* Skip removing if it is not using vhost */ - continue; - } - - remove(get_vhost_iface_name(cnt)); - } -} - -/* Get component type of target core */ -enum spp_component_type -spp_get_component_type(unsigned int lcore_id) -{ - struct core_mng_info *info = &g_core_info[lcore_id]; - return info->core[info->ref_index].type; -} - /* Get component type being updated on target core */ enum spp_component_type spp_get_component_type_update(unsigned int lcore_id) @@ -848,29 +279,6 @@ spp_get_component_type_update(unsigned int lcore_id) return info->core[info->upd_index].type; } -/* Get core ID of target component */ -unsigned int -spp_get_component_core(int component_id) -{ - struct spp_component_info *info = &g_component_info[component_id]; - return info->lcore_id; -} - -/* Get usage area of target core */ -static struct core_info * -get_core_info(unsigned int lcore_id) -{ - struct core_mng_info *info = &g_core_info[lcore_id]; - return &(info->core[info->ref_index]); -} - -/* Check core index change */ -int -spp_check_core_index(unsigned int lcore_id) -{ - struct core_mng_info *info = &g_core_info[lcore_id]; - return info->ref_index == info->upd_index; -} /* Main process of slave core */ static int @@ -891,7 +299,7 @@ slave_main(void *arg __attribute__ ((unused))) if (status != SPP_CORE_FORWARD) continue; - if (spp_check_core_index(lcore_id)) { + if (spp_check_core_update(lcore_id) == SPP_RET_OK) { /* Setting with the flush command trigger. */ info->ref_index = (info->upd_index+1) % SPP_INFO_AREA_MAX; @@ -1102,66 +510,6 @@ spp_check_flush_port(enum port_type iface_type, int iface_no) return port->dpdk_port >= 0; } -/* - * Check if component is using port. - */ -int -spp_check_used_port( - enum port_type iface_type, - int iface_no, - enum spp_port_rxtx rxtx) -{ - int cnt, port_cnt, max = 0; - struct spp_component_info *component = NULL; - struct spp_port_info **port_array = NULL; - struct spp_port_info *port = get_iface_info(iface_type, iface_no); - - if (port == NULL) - return SPP_RET_NG; - - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - component = &g_component_info[cnt]; - if (component->type == SPP_COMPONENT_UNUSE) - continue; - - if (rxtx == SPP_PORT_RXTX_RX) { - max = component->num_rx_port; - port_array = component->rx_ports; - } else if (rxtx == SPP_PORT_RXTX_TX) { - max = component->num_tx_port; - port_array = component->tx_ports; - } - for (port_cnt = 0; port_cnt < max; port_cnt++) { - if (unlikely(port_array[port_cnt] == port)) - return cnt; - } - } - - return SPP_RET_NG; -} - -/* - * Set port change to component. - */ -static void -set_component_change_port(struct spp_port_info *port, enum spp_port_rxtx rxtx) -{ - int ret = 0; - if ((rxtx == SPP_PORT_RXTX_RX) || (rxtx == SPP_PORT_RXTX_ALL)) { - ret = spp_check_used_port(port->iface_type, port->iface_no, - SPP_PORT_RXTX_RX); - if (ret >= 0) - g_change_component[ret] = 1; - } - - if ((rxtx == SPP_PORT_RXTX_TX) || (rxtx == SPP_PORT_RXTX_ALL)) { - ret = spp_check_used_port(port->iface_type, port->iface_no, - SPP_PORT_RXTX_TX); - if (ret >= 0) - g_change_component[ret] = 1; - } -} - int spp_update_classifier_table( enum spp_command_action action, @@ -1247,59 +595,6 @@ spp_update_classifier_table( return SPP_RET_OK; } -/* Get free component */ -static int -get_free_component(void) -{ - int cnt = 0; - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - if (g_component_info[cnt].type == SPP_COMPONENT_UNUSE) - return cnt; - } - return -1; -} - -/* Get name matching component */ -int -spp_get_component_id(const char *name) -{ - int cnt = 0; - if (name[0] == '\0') - return SPP_RET_NG; - - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - if (strcmp(name, g_component_info[cnt].name) == 0) - return cnt; - } - return SPP_RET_NG; -} - -static int -get_del_core_element(int info, int num, int *array) -{ - int cnt; - int match = -1; - int max = num; - - for (cnt = 0; cnt < max; cnt++) { - if (info == array[cnt]) - match = cnt; - } - - if (match < 0) - return -1; - - /* Last element is excluded from movement. */ - max--; - - for (cnt = match; cnt < max; cnt++) - array[cnt] = array[cnt+1]; - - /* Last element is cleared. */ - array[cnt] = 0; - return 0; -} - /* Component command to execute it */ int spp_update_component( @@ -1369,7 +664,7 @@ spp_update_component( info = &g_core_info[tmp_lcore_id]; core = &info->core[info->upd_index]; - ret_del = get_del_core_element(component_id, + ret_del = del_component_info(component_id, core->num, core->id); if (ret_del >= 0) /* If deleted, decrement number. */ @@ -1390,46 +685,6 @@ spp_update_component( return ret; } -static int -check_port_element( - struct spp_port_info *info, - int num, - struct spp_port_info *array[]) -{ - int cnt = 0; - int match = -1; - for (cnt = 0; cnt < num; cnt++) { - if (info == array[cnt]) - match = cnt; - } - return match; -} - -static int -get_del_port_element( - struct spp_port_info *info, - int num, - struct spp_port_info *array[]) -{ - int cnt = 0; - int match = -1; - int max = num; - - match = check_port_element(info, num, array); - if (match < 0) - return -1; - - /* Last element is excluded from movement. */ - max--; - - for (cnt = match; cnt < max; cnt++) - array[cnt] = array[cnt+1]; - - /* Last element is cleared. */ - array[cnt] = NULL; - return 0; -} - /* Port add or del to execute it */ int spp_update_port(enum spp_command_action action, @@ -1523,99 +778,6 @@ spp_update_port(enum spp_command_action action, return ret; } -/* Flush initial setting of each interface. */ -static int -flush_port(void) -{ - int ret = 0; - int cnt = 0; - struct spp_port_info *port = NULL; - - /* Initialize added vhost. */ - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - port = &g_iface_info.vhost[cnt]; - if ((port->iface_type != UNDEF) && (port->dpdk_port < 0)) { - ret = add_vhost_pmd(port->iface_no, - g_startup_param.vhost_client); - if (ret < 0) - return SPP_RET_NG; - port->dpdk_port = ret; - } - } - - /* Initialize added ring. */ - for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { - port = &g_iface_info.ring[cnt]; - if ((port->iface_type != UNDEF) && (port->dpdk_port < 0)) { - ret = add_ring_pmd(port->iface_no); - if (ret < 0) - return SPP_RET_NG; - port->dpdk_port = ret; - } - } - return SPP_RET_OK; -} - -/* Flush changed core. */ -static void -flush_core(void) -{ - int cnt = 0; - struct core_mng_info *info = NULL; - - /* Changed core has changed index. */ - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - if (g_change_core[cnt] != 0) { - info = &g_core_info[cnt]; - info->upd_index = info->ref_index; - } - } - - /* Waiting for changed core change. */ - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - if (g_change_core[cnt] != 0) { - info = &g_core_info[cnt]; - while (likely(info->ref_index == info->upd_index)) - rte_delay_us_block(SPP_CHANGE_UPDATE_INTERVAL); - - memcpy(&info->core[info->upd_index], - &info->core[info->ref_index], - sizeof(struct core_info)); - } - } -} - -/* Flush changed component */ -static int -flush_component(void) -{ - int ret = 0; - int cnt = 0; - struct spp_component_info *component_info = NULL; - - for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) { - if (g_change_component[cnt] == 0) - continue; - - component_info = &g_component_info[cnt]; - spp_port_ability_update(component_info); - - if (component_info->type == SPP_COMPONENT_CLASSIFIER_MAC) - ret = spp_classifier_mac_update(component_info); - else - ret = spp_forward_update(component_info); - - if (unlikely(ret < 0)) { - RTE_LOG(ERR, APP, "Flush error. " - "( component = %s, type = %d)\n", - component_info->name, - component_info->type); - return SPP_RET_NG; - } - } - return SPP_RET_OK; -} - /* Flush command to execute it */ int spp_flush(void) @@ -1776,80 +938,6 @@ spp_get_iface_index(const char *port, return 0; } -/** - * Generate a formatted string of combination from interface type and - * number and assign to given 'port' - */ -int spp_format_port_string(char *port, enum port_type iface_type, int iface_no) -{ - const char *iface_type_str; - - switch (iface_type) { - case PHY: - iface_type_str = SPP_IFTYPE_NIC_STR; - break; - case RING: - iface_type_str = SPP_IFTYPE_RING_STR; - break; - case VHOST: - iface_type_str = SPP_IFTYPE_VHOST_STR; - break; - default: - return -1; - } - - sprintf(port, "%s:%d", iface_type_str, iface_no); - - return 0; -} - -/** - * Change mac address of 'aa:bb:cc:dd:ee:ff' to int64 and return it - */ -int64_t -spp_change_mac_str_to_int64(const char *mac) -{ - int64_t ret_mac = 0; - int64_t token_val = 0; - int token_cnt = 0; - char tmp_mac[SPP_MIN_STR_LEN]; - char *str = tmp_mac; - char *saveptr = NULL; - char *endptr = NULL; - - RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s)\n", mac); - - strcpy(tmp_mac, mac); - while (1) { - /* Split by colon(':') */ - char *ret_tok = strtok_r(str, ":", &saveptr); - if (unlikely(ret_tok == NULL)) - break; - - /* Check for mal-formatted address */ - if (unlikely(token_cnt >= ETHER_ADDR_LEN)) { - RTE_LOG(ERR, APP, "MAC address format error. " - "(mac = %s)\n", mac); - return -1; - } - - /* Convert string to hex value */ - int ret_tol = strtol(ret_tok, &endptr, 16); - if (unlikely(ret_tok == endptr) || unlikely(*endptr != '\0')) - break; - - /* Append separated value to the result */ - token_val = (int64_t)ret_tol; - ret_mac |= token_val << (token_cnt * 8); - token_cnt++; - str = NULL; - } - - RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s => 0x%08lx)\n", - mac, ret_mac); - return ret_mac; -} - /** * Return the type of forwarder as a member of enum of spp_component_type */ diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h index 8bc5961..5586207 100644 --- a/src/vf/spp_vf.h +++ b/src/vf/spp_vf.h @@ -327,28 +327,6 @@ struct spp_iterate_classifier_table_params { int spp_iterate_classifier_table( struct spp_iterate_classifier_table_params *params); -/** - * Get core status - * - * @param lcore_id - * Logical core ID. - * - * @return - * Status of specified logical core. - */ -enum spp_core_status spp_get_core_status(unsigned int lcore_id); - -/** - * Get component type of target core - * - * @param lcore_id - * Logical core ID. - * - * @return - * Type of component executed on specified logical core - */ -enum spp_component_type spp_get_component_type(unsigned int lcore_id); - /** * Get component type being updated on target core * @@ -361,39 +339,6 @@ enum spp_component_type spp_get_component_type(unsigned int lcore_id); */ enum spp_component_type spp_get_component_type_update(unsigned int lcore_id); -/** - * Get core ID of target component - * - * @param component_id - * unique component ID. - * - * @return - * Logical core id of specified component. - */ -unsigned int spp_get_component_core(int component_id); - -/** - * Check core index change - * - * @param lcore_id - * Logical core ID. - * - * @return - * True if index has changed. - */ -int spp_check_core_index(unsigned int lcore_id); - -/** - * Get name matching component ID - * - * @param name - * Component name. - * - * @retval 0~127 Component ID. - * @retval SPP_RET_NG failed. - */ -int spp_get_component_id(const char *name); - /** * Check mac address used on the port for registering or removing * @@ -440,35 +385,6 @@ int spp_check_added_port(enum port_type iface_type, int iface_no); */ int spp_check_flush_port(enum port_type iface_type, int iface_no); -/** - * Check if component is using port. - * - * @param iface_type - * Interface type to be validated. - * @param iface_no - * Interface number to be validated. - * @param rxtx - * tx/rx type to be validated. - * - * @retval 0~127 match component ID - * @retval SPP_RET_NG failed. - */ -int spp_check_used_port( - enum port_type iface_type, - int iface_no, - enum spp_port_rxtx rxtx); - -/** - * Change mac address string to int64 - * - * @param mac - * Character string of MAC address to be converted. - * - * @retval 0< int64 that store mac address - * @retval -1 - */ -int64_t spp_change_mac_str_to_int64(const char *mac); - /** * Get the port number of DPDK. * @@ -500,22 +416,6 @@ int spp_get_iface_index( enum port_type *iface_type, int *iface_no); -/** - * Format port string form if-type/if-number - * - * @param port - * Character string expressing the port, e.g. "phy:0","ring:1" - * @param iface_type - * Interface type. - * @param iface_no - * Interface number. - * - * @retval 0 succeeded. - * @retval -1 failed. - */ -int -spp_format_port_string(char *port, enum port_type iface_type, int iface_no); - /** * Change component type from string to type value. * -- 2.18.0