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 494B61B00F for ; Wed, 10 Jan 2018 03:48:03 +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 w0A2m2bt010097 for unknown; Wed, 10 Jan 2018 11:48:02 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id w0A2m2wO023023 for unknown; Wed, 10 Jan 2018 11:48:02 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id MAA23020; Wed, 10 Jan 2018 11:48:02 +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 w0A2m1a9006357 for unknown; Wed, 10 Jan 2018 11:48:01 +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 w0A2m1QV006354 for unknown; Wed, 10 Jan 2018 11:48:01 +0900 Message-Id: <201801100248.w0A2m1QV006354@imss03.silk.ntt-tx.co.jp> Received: from localhost by mgate02.silk.ntt-tx.co.jp (unknown) id w0A2m1wB005491 ; Wed, 10 Jan 2018 11:48:01 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: spp@dpdk.org Date: Wed, 10 Jan 2018 11:47:59 +0900 X-Mailer: git-send-email 1.9.1 In-Reply-To: <201801100246.w0A2kio5005692@imss03.silk.ntt-tx.co.jp> References: <201801100246.w0A2kio5005692@imss03.silk.ntt-tx.co.jp> X-TM-AS-MML: No Subject: [spp] [PATCH 2/4] spp_vf: support cancel command 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, 10 Jan 2018 02:48:03 -0000 From: Hiroyuki Nakamura Newly support 'cancel' command. * 'cancel' command provides the cancel function for the unflushed 'component', 'port' and 'classifier_table' commands. * Also add a debug log functions for the data being canceled by the command. Signed-off-by: Kentaro Watanabe Signed-off-by: Yasufum Ogawa --- src/vf/command_dec.c | 12 +-- src/vf/command_dec.h | 1 + src/vf/command_proc.c | 5 ++ src/vf/spp_vf.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/vf/spp_vf.h | 5 ++ 5 files changed, 251 insertions(+), 11 deletions(-) diff --git a/src/vf/command_dec.c b/src/vf/command_dec.c index 56360e9..9576c6f 100644 --- a/src/vf/command_dec.c +++ b/src/vf/command_dec.c @@ -524,6 +524,7 @@ static struct decode_parameter_list parameter_list[][SPP_CMD_MAX_PARAMETERS] = { }, DECODE_PARAMETER_LIST_EMPTY, }, + { DECODE_PARAMETER_LIST_EMPTY }, /* cancel */ { DECODE_PARAMETER_LIST_EMPTY }, /* termination */ }; @@ -562,13 +563,14 @@ struct decode_command_list { /* command list */ static struct decode_command_list command_list[] = { { "classifier_table", 5, 5, decode_comand_parameter_in_list }, /* classifier_table */ - { "flush", 1, 1, NULL }, /* flush */ - { "_get_client_id", 1, 1, NULL }, /* _get_client_id */ - { "status", 1, 1, NULL }, /* status */ - { "exit", 1, 1, NULL }, /* exit */ + { "flush", 1, 1, NULL }, /* flush */ + { "_get_client_id", 1, 1, NULL }, /* _get_client_id */ + { "status", 1, 1, NULL }, /* status */ + { "exit", 1, 1, NULL }, /* exit */ { "component", 3, 5, decode_comand_parameter_in_list }, /* component */ { "port", 5, 5, decode_comand_parameter_in_list }, /* port */ - { "", 0, 0, NULL } /* termination */ + { "cancel", 1, 1, NULL }, /* cancel */ + { "", 0, 0, NULL } /* termination */ }; /* Decode command line parameters */ diff --git a/src/vf/command_dec.h b/src/vf/command_dec.h index 359f5e5..1ab2e43 100644 --- a/src/vf/command_dec.h +++ b/src/vf/command_dec.h @@ -38,6 +38,7 @@ enum spp_command_type { SPP_CMDTYPE_EXIT, SPP_CMDTYPE_COMPONENT, SPP_CMDTYPE_PORT, + SPP_CMDTYPE_CANCEL, }; /* "classifier_table" command specific parameters */ diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c index 214cb2e..d7fbded 100644 --- a/src/vf/command_proc.c +++ b/src/vf/command_proc.c @@ -204,6 +204,11 @@ execute_command(const struct spp_command *command) command->spec.port.name); break; + case SPP_CMDTYPE_CANCEL: + RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute cancel command.\n"); + spp_cancel(); + break; + default: RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute other command. type=%d\n", command->type); /* nothing to do here */ diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c index b809807..feb7f4d 100644 --- a/src/vf/spp_vf.c +++ b/src/vf/spp_vf.c @@ -31,6 +31,13 @@ enum SPP_LONGOPT_RETVAL { SPP_LONGOPT_RETVAL_VHOST_CLIENT }; +/* Flag of processing type to copy management information */ +enum copy_mng_flg { + COPY_MNG_FLG_NONE, + COPY_MNG_FLG_UPDCOPY, + COPY_MNG_FLG_ALLCOPY, +}; + /* Manage given options as global variable */ struct startup_param { int client_id; @@ -65,6 +72,13 @@ struct core_mng_info { struct core_info core[SPP_INFO_AREA_MAX]; }; +/* Manage data to be backup */ +struct cancel_backup_info { + struct core_mng_info core[RTE_MAX_LCORE]; + struct spp_component_info component[RTE_MAX_LCORE]; + struct if_info interface; +}; + /* Declare global variables */ static unsigned int g_main_lcore_id = 0xffffffff; static struct startup_param g_startup_param; @@ -75,6 +89,8 @@ static struct core_mng_info g_core_info[RTE_MAX_LCORE]; static int g_change_core[RTE_MAX_LCORE]; /* TODO(yasufum) add desc how it is used and why changed component is kept */ static int g_change_component[RTE_MAX_LCORE]; +static struct cancel_backup_info g_backup_info; + /* Print help message */ static void usage(const char *progname) @@ -89,6 +105,34 @@ 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) { @@ -417,6 +461,183 @@ get_if_area(enum port_type if_type, int if_no) } } +/* 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 if_info *if_info) +{ + const struct spp_port_info *port = NULL; + int cnt = 0; + RTE_LOG(DEBUG, APP, "interface phy=%d, vhost=%d, ring=%d\n", + if_info->num_nic, + if_info->num_vhost, + if_info->num_ring); + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &if_info->nic[cnt]; + if (port->if_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "phy [%d] type=%d, no=%d, port=%d, " + "mac=%08lx(%s)\n", + cnt, port->if_type, port->if_no, + port->dpdk_port, + port->mac_addr, port->mac_addr_str); + } + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &if_info->vhost[cnt]; + if (port->if_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "vhost[%d] type=%d, no=%d, port=%d, " + "mac=%08lx(%s)\n", + cnt, port->if_type, port->if_no, + port->dpdk_port, + port->mac_addr, port->mac_addr_str); + } + for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) { + port = &if_info->ring[cnt]; + if (port->if_type == UNDEF) + continue; + + RTE_LOG(DEBUG, APP, "ring [%d] type=%d, no=%d, port=%d, " + "mac=%08lx(%s)\n", + cnt, port->if_type, port->if_no, + port->dpdk_port, + port->mac_addr, port->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 if_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 if_info *dst_interface, + const struct core_mng_info *src_core, + const struct spp_component_info *src_component, + const struct if_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 if_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_if_info); + copy_mng_info(backup->core, backup->component, &backup->interface, + g_core_info, g_component_info, &g_if_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)); +} + +/* Cancel update of management information */ +static void +cancel_mng_info(struct cancel_backup_info *backup) +{ + dump_all_mng_info(backup->core, backup->component, &backup->interface); + copy_mng_info(g_core_info, g_component_info, &g_if_info, + backup->core, backup->component, &backup->interface, + COPY_MNG_FLG_ALLCOPY); + dump_all_mng_info(g_core_info, g_component_info, &g_if_info); + memset(g_change_core, 0x00, sizeof(g_change_core)); + memset(g_change_component, 0x00, sizeof(g_change_component)); +} + /** * Initialize g_if_info * @@ -764,6 +985,9 @@ ut_main(int argc, char *argv[]) RTE_LOG(INFO, APP, "My ID %d start handling message\n", 0); RTE_LOG(INFO, APP, "[Press Ctrl-C to quit ...]\n"); + /* Backup the management information after initialization */ + backup_mng_info(&g_backup_info); + /* Enter loop for accepting commands */ int ret_do = 0; #ifndef USE_UT_SPP_VF @@ -1321,16 +1545,19 @@ spp_flush(void) /* Flush of core index. */ flush_core(); - memset(g_change_core, 0x00, sizeof(g_change_core)); /* Flush of component */ ret = flush_component(); - if (ret < 0) - return ret; - /* Finally, zero-clear g_change_core */ - memset(g_change_component, 0x00, sizeof(g_change_component)); - return SPP_RET_OK; + backup_mng_info(&g_backup_info); + return ret; +} + +/* Cancel data that is not flushing */ +void +spp_cancel(void) +{ + cancel_mng_info(&g_backup_info); } /* Iterate core infomartion */ diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h index 442fb0e..3c1f586 100644 --- a/src/vf/spp_vf.h +++ b/src/vf/spp_vf.h @@ -167,6 +167,11 @@ int spp_update_port( */ int spp_flush(void); +/* + * Cancel data that is not flushing + */ +void spp_cancel(void); + /* definition of iterated core element procedure function */ struct spp_iterate_core_params; typedef int (*spp_iterate_core_element_proc)( -- 1.9.1