From patchwork Thu Jul 12 01:15:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 42936 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7670C1B802; Thu, 12 Jul 2018 03:15:55 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id A2EE31B52A for ; Thu, 12 Jul 2018 03:15:09 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Jul 2018 18:15:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,339,1526367600"; d="scan'208";a="244990548" Received: from dpdk51.sh.intel.com ([10.67.110.190]) by fmsmga006.fm.intel.com with ESMTP; 11 Jul 2018 18:15:07 -0700 From: Qi Zhang To: thomas@monjalon.net, anatoly.burakov@intel.com Cc: konstantin.ananyev@intel.com, dev@dpdk.org, bruce.richardson@intel.com, ferruh.yigit@intel.com, benjamin.h.shelton@intel.com, narender.vangati@intel.com, Qi Zhang Date: Thu, 12 Jul 2018 09:15:13 +0800 Message-Id: <20180712011514.45006-19-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180712011514.45006-1-qi.z.zhang@intel.com> References: <20180607123849.14439-1-qi.z.zhang@intel.com> <20180712011514.45006-1-qi.z.zhang@intel.com> Subject: [dpdk-dev] [PATCH v13 18/19] examples/multi_process: add hotplug sample X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The sample code demonstrates device (ethdev only) management at a multi-process environment. The user can attach/detach a device on primary process and see it is synced on secondary process automatically. How to start? ./hotplug_mp --proc-type=auto Command Line Example: >help >list /* attach a pci device */ > attach 0000:81:00.0 /* detach a pci device */ > detach 0000:81:00.0 /* attach a vdev af_packet device */ >attach net_af_packet,iface=eth0 /* detach the vdev af_packet device */ >detach net_af_packet Signed-off-by: Qi Zhang --- examples/multi_process/Makefile | 1 + examples/multi_process/hotplug_mp/Makefile | 23 +++ examples/multi_process/hotplug_mp/commands.c | 214 +++++++++++++++++++++++++++ examples/multi_process/hotplug_mp/commands.h | 10 ++ examples/multi_process/hotplug_mp/main.c | 41 +++++ 5 files changed, 289 insertions(+) create mode 100644 examples/multi_process/hotplug_mp/Makefile create mode 100644 examples/multi_process/hotplug_mp/commands.c create mode 100644 examples/multi_process/hotplug_mp/commands.h create mode 100644 examples/multi_process/hotplug_mp/main.c diff --git a/examples/multi_process/Makefile b/examples/multi_process/Makefile index a6708b7e4..b76b02fcb 100644 --- a/examples/multi_process/Makefile +++ b/examples/multi_process/Makefile @@ -13,5 +13,6 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += client_server_mp DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += simple_mp DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += symmetric_mp +DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += hotplug_mp include $(RTE_SDK)/mk/rte.extsubdir.mk diff --git a/examples/multi_process/hotplug_mp/Makefile b/examples/multi_process/hotplug_mp/Makefile new file mode 100644 index 000000000..bc36aeaed --- /dev/null +++ b/examples/multi_process/hotplug_mp/Makefile @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Intel Corporation + +ifeq ($(RTE_SDK),) +$(error "Please define RTE_SDK environment variable") +endif + +# Default target, can be overridden by command line or environment +RTE_TARGET ?= x86_64-native-linuxapp-gcc + +include $(RTE_SDK)/mk/rte.vars.mk + +# binary name +APP = hotplug_mp + +# all source are stored in SRCS-y +SRCS-y := main.c commands.c + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) +CFLAGS += -DALLOW_EXPERIMENTAL_API + +include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/multi_process/hotplug_mp/commands.c b/examples/multi_process/hotplug_mp/commands.c new file mode 100644 index 000000000..62f328261 --- /dev/null +++ b/examples/multi_process/hotplug_mp/commands.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include + +/**********************************************************/ + +struct cmd_help_result { + cmdline_fixed_string_t help; +}; + +static void cmd_help_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, + "commands:\n" + "- attach \n" + "- detach \n" + "- list\n\n"); +} + +cmdline_parse_token_string_t cmd_help_help = + TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help"); + +cmdline_parse_inst_t cmd_help = { + .f = cmd_help_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "show help", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_help_help, + NULL, + }, +}; + +/**********************************************************/ + +struct cmd_quit_result { + cmdline_fixed_string_t quit; +}; + +static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_quit(cl); +} + +cmdline_parse_token_string_t cmd_quit_quit = + TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); + +cmdline_parse_inst_t cmd_quit = { + .f = cmd_quit_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "quit", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_quit_quit, + NULL, + }, +}; + +/**********************************************************/ + +struct cmd_list_result { + cmdline_fixed_string_t list; +}; + +static void cmd_list_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + uint16_t port_id; + char dev_name[RTE_DEV_NAME_MAX_LEN]; + + cmdline_printf(cl, "list all etherdev\n"); + + RTE_ETH_FOREACH_DEV(port_id) { + rte_eth_dev_get_name_by_port(port_id, dev_name); + if (strlen(dev_name) > 0) + cmdline_printf(cl, "%d\t%s\n", port_id, dev_name); + else + printf("empty dev_name is not expected!\n"); + } +} + +cmdline_parse_token_string_t cmd_list_list = + TOKEN_STRING_INITIALIZER(struct cmd_list_result, list, "list"); + +cmdline_parse_inst_t cmd_list = { + .f = cmd_list_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "list all devices", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_list_list, + NULL, + }, +}; + +/**********************************************************/ + +struct cmd_dev_attach_result { + cmdline_fixed_string_t attach; + cmdline_fixed_string_t devargs; +}; + +static void cmd_dev_attach_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_dev_attach_result *res = parsed_result; + struct rte_devargs da; + + memset(&da, 0, sizeof(da)); + + if (rte_devargs_parse(&da, "%s", res->devargs)) { + cmdline_printf(cl, "cannot parse devargs\n"); + if (da.args) + free(da.args); + return; + } + + if (!rte_eal_hotplug_add(da.bus->name, da.name, da.args)) + cmdline_printf(cl, "attached device %s\n", da.name); + else + cmdline_printf(cl, "failed to attached device %s\n", + da.name); +} + +cmdline_parse_token_string_t cmd_dev_attach_attach = + TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, attach, + "attach"); +cmdline_parse_token_string_t cmd_dev_attach_devargs = + TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, devargs, NULL); + +cmdline_parse_inst_t cmd_attach_device = { + .f = cmd_dev_attach_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "attach a device", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_dev_attach_attach, + (void *)&cmd_dev_attach_devargs, + NULL, + }, +}; + +/**********************************************************/ + +struct cmd_dev_detach_result { + cmdline_fixed_string_t detach; + cmdline_fixed_string_t devargs; +}; + +static void cmd_dev_detach_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_dev_detach_result *res = parsed_result; + struct rte_devargs da; + + memset(&da, 0, sizeof(da)); + + if (rte_devargs_parse(&da, "%s", res->devargs)) { + cmdline_printf(cl, "cannot parse devargs\n"); + if (da.args) + free(da.args); + return; + } + + printf("detaching...\n"); + if (!rte_eal_hotplug_remove(da.bus->name, da.name)) + cmdline_printf(cl, "detached device %s\n", + da.name); + else + cmdline_printf(cl, "failed to dettach device %s\n", + da.name); +} + +cmdline_parse_token_string_t cmd_dev_detach_detach = + TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, detach, + "detach"); + +cmdline_parse_token_string_t cmd_dev_detach_devargs = + TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, devargs, NULL); + +cmdline_parse_inst_t cmd_detach_device = { + .f = cmd_dev_detach_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "detach a device", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_dev_detach_detach, + (void *)&cmd_dev_detach_devargs, + NULL, + }, +}; + +/**********************************************************/ +/**********************************************************/ +/****** CONTEXT (list of instruction) */ + +cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_help, + (cmdline_parse_inst_t *)&cmd_quit, + (cmdline_parse_inst_t *)&cmd_list, + (cmdline_parse_inst_t *)&cmd_attach_device, + (cmdline_parse_inst_t *)&cmd_detach_device, + NULL, +}; diff --git a/examples/multi_process/hotplug_mp/commands.h b/examples/multi_process/hotplug_mp/commands.h new file mode 100644 index 000000000..afcf177db --- /dev/null +++ b/examples/multi_process/hotplug_mp/commands.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#ifndef _COMMANDS_H_ +#define _COMMANDS_H_ + +extern cmdline_parse_ctx_t main_ctx[]; + +#endif /* _COMMANDS_H_ */ diff --git a/examples/multi_process/hotplug_mp/main.c b/examples/multi_process/hotplug_mp/main.c new file mode 100644 index 000000000..d66858078 --- /dev/null +++ b/examples/multi_process/hotplug_mp/main.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "commands.h" + +int main(int argc, char **argv) +{ + int ret; + struct cmdline *cl; + + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_panic("Cannot init EAL\n"); + + cl = cmdline_stdin_new(main_ctx, "example> "); + if (cl == NULL) + rte_panic("Cannot create cmdline instance\n"); + cmdline_interact(cl); + cmdline_stdin_exit(cl); + + rte_eal_cleanup(); + + return 0; +}