[spp] [PATCH 2/4] spp_vf: support cancel command

x-fn-spp at sl.ntt-tx.co.jp x-fn-spp at sl.ntt-tx.co.jp
Wed Jan 10 03:47:59 CET 2018


From: Hiroyuki Nakamura <nakamura.hioryuki at po.ntt-tx.co.jp>

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 <watanabe.kentaro.z01 at as.ntt-tx.co.jp>
Signed-off-by: Yasufum Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
---
 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



More information about the spp mailing list