From patchwork Wed Feb 25 19:32:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tetsuya Mukawa X-Patchwork-Id: 3725 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 70D367F1C; Wed, 25 Feb 2015 20:33:56 +0100 (CET) Received: from mail-pd0-f173.google.com (mail-pd0-f173.google.com [209.85.192.173]) by dpdk.org (Postfix) with ESMTP id 091E45A9C for ; Wed, 25 Feb 2015 20:33:10 +0100 (CET) Received: by pdbfl12 with SMTP id fl12so7102399pdb.2 for ; Wed, 25 Feb 2015 11:33:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RqSITtOtkNJLTeMIiTq7/npqIjLSvhZs6Ym/e06QWN4=; b=NT3VLJBxUnHrwmNuLstA9pj814v9btC0c9Nrdn7u4+GzYmGDTO/KBs1F/eCD9ANE+q ks7ttHkO823PUgXGeCfFeZLHMqNBSagrv8pWhn5fVKPRihewkm2Km53c1tve3we2KVAi mifa/Ubl6R95HRjkwj93F8n1SNmL+90bTEndIowB1VOt0JA70p+Q/eciIfzJYjJIXKt8 Y3DzDm44nkItjnbHxaI2MWqnM3BZvSqUytiSTSoYx0G1uBS6jwxu9/f7qDS75+Jcx0oo A+Z5dGvh3FRLfKfbtNSSXnuNGDx1qSwxYDmB7uWEtOJFTtTKqBr7IbrSa8gYysBsX0yY /efw== X-Gm-Message-State: ALoCoQltCtUs7QXCDO0TWi0clZT38Nd1AF+39SsUybInILB7cUzdYbTizpPpI080WEShVuIdhWvM X-Received: by 10.68.217.103 with SMTP id ox7mr8463808pbc.56.1424892789466; Wed, 25 Feb 2015 11:33:09 -0800 (PST) Received: from localhost.localdomain (napt.igel.co.jp. [219.106.231.132]) by mx.google.com with ESMTPSA id ux7sm39997444pab.19.2015.02.25.11.33.07 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 25 Feb 2015 11:33:08 -0800 (PST) From: Tetsuya Mukawa To: dev@dpdk.org Date: Thu, 26 Feb 2015 04:32:25 +0900 Message-Id: <1424892749-31862-12-git-send-email-mukawa@igel.co.jp> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1424892749-31862-1-git-send-email-mukawa@igel.co.jp> References: <1424837093-5661-13-git-send-email-mukawa@igel.co.jp> <1424892749-31862-1-git-send-email-mukawa@igel.co.jp> Subject: [dpdk-dev] [PATCH v15 11/13] eal/pci: Add vdev driver initialization and uninitialization functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The patch adds following functions. - rte_eal_vdev_init(); - rte_eal_vdev_uninit(); - rte_eal_parse_devargs_str(). These functions are used for driver initialization and finalization. v15: - Add this patch to hotplug series. Signed-off-by: Tetsuya Mukawa --- lib/librte_eal/common/eal_common_dev.c | 77 ++++++++++++++++++++----- lib/librte_eal/common/eal_common_devargs.c | 54 +++++++++++------ lib/librte_eal/common/include/rte_dev.h | 28 +++++++++ lib/librte_eal/common/include/rte_devargs.h | 28 +++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + 5 files changed, 155 insertions(+), 35 deletions(-) diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c index eae5656..92a5a94 100644 --- a/lib/librte_eal/common/eal_common_dev.c +++ b/lib/librte_eal/common/eal_common_dev.c @@ -32,6 +32,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include "eal_private.h" @@ -62,6 +64,32 @@ rte_eal_driver_unregister(struct rte_driver *driver) } int +rte_eal_vdev_init(const char *name, const char *args) +{ + struct rte_driver *driver; + + if (name == NULL) + return -EINVAL; + + TAILQ_FOREACH(driver, &dev_driver_list, next) { + if (driver->type != PMD_VDEV) + continue; + + /* + * search a driver prefix in virtual device name. + * For example, if the driver is pcap PMD, driver->name + * will be "eth_pcap", but "name" will be "eth_pcapN". + * So use strncmp to compare. + */ + if (!strncmp(driver->name, name, strlen(driver->name))) + return driver->init(name, args); + } + + RTE_LOG(ERR, EAL, "no driver found for %s\n", name); + return -EINVAL; +} + +int rte_eal_dev_init(void) { struct rte_devargs *devargs; @@ -79,22 +107,11 @@ rte_eal_dev_init(void) if (devargs->type != RTE_DEVTYPE_VIRTUAL) continue; - TAILQ_FOREACH(driver, &dev_driver_list, next) { - if (driver->type != PMD_VDEV) - continue; - - /* search a driver prefix in virtual device name */ - if (!strncmp(driver->name, devargs->virtual.drv_name, - strlen(driver->name))) { - driver->init(devargs->virtual.drv_name, - devargs->args); - break; - } - } - - if (driver == NULL) { - rte_panic("no driver found for %s\n", - devargs->virtual.drv_name); + if (rte_eal_vdev_init(devargs->virtual.drv_name, + devargs->args)) { + RTE_LOG(ERR, EAL, "failed to initialize %s device\n", + devargs->virtual.drv_name); + return -1; } } @@ -107,3 +124,31 @@ rte_eal_dev_init(void) } return 0; } + +#ifdef RTE_LIBRTE_EAL_HOTPLUG +int +rte_eal_vdev_uninit(const char *name) +{ + struct rte_driver *driver; + + if (name == NULL) + return -EINVAL; + + TAILQ_FOREACH(driver, &dev_driver_list, next) { + if (driver->type != PMD_VDEV) + continue; + + /* + * search a driver prefix in virtual device name. + * For example, if the driver is pcap PMD, driver->name + * will be "eth_pcap", but "name" will be "eth_pcapN". + * So use strncmp to compare. + */ + if (!strncmp(driver->name, name, strlen(driver->name))) + return driver->uninit(name); + } + + RTE_LOG(ERR, EAL, "no driver found for %s\n", name); + return -EINVAL; +} +#endif /* RTE_LIBRTE_EAL_HOTPLUG */ diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c index eadd719..9b110f7 100644 --- a/lib/librte_eal/common/eal_common_devargs.c +++ b/lib/librte_eal/common/eal_common_devargs.c @@ -44,13 +44,46 @@ struct rte_devargs_list devargs_list = TAILQ_HEAD_INITIALIZER(devargs_list); +int +rte_eal_parse_devargs_str(const char *devargs_str, + char **drvname, char **drvargs) +{ + char *sep; + + if ((devargs_str) == NULL || (drvname) == NULL || (drvargs == NULL)) + return -1; + + *drvname = strdup(devargs_str); + if (drvname == NULL) { + RTE_LOG(ERR, EAL, + "cannot allocate temp memory for driver name\n"); + return -1; + } + + /* set the first ',' to '\0' to split name and arguments */ + sep = strchr(*drvname, ','); + if (sep != NULL) { + sep[0] = '\0'; + *drvargs = strdup(sep + 1); + } else { + *drvargs = strdup(""); + } + + if (*drvargs == NULL) { + RTE_LOG(ERR, EAL, + "cannot allocate temp memory for driver arguments\n"); + free(*drvname); + return -1; + } + return 0; +} + /* store a whitelist parameter for later parsing */ int rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str) { struct rte_devargs *devargs = NULL; char *buf = NULL; - char *sep; int ret; /* use malloc instead of rte_malloc as it's called early at init */ @@ -62,25 +95,8 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str) memset(devargs, 0, sizeof(*devargs)); devargs->type = devtype; - buf = strdup(devargs_str); - if (buf == NULL) { - RTE_LOG(ERR, EAL, "cannot allocate temp memory for devargs\n"); - goto fail; - } - - /* set the first ',' to '\0' to split name and arguments */ - sep = strchr(buf, ','); - if (sep != NULL) { - sep[0] = '\0'; - devargs->args = strdup(sep + 1); - } else { - devargs->args = strdup(""); - } - - if (devargs->args == NULL) { - RTE_LOG(ERR, EAL, "cannot allocate for devargs args\n"); + if (rte_eal_parse_devargs_str(devargs_str, &buf, &devargs->args)) goto fail; - } switch (devargs->type) { case RTE_DEVTYPE_WHITELISTED_PCI: diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index f7e3a10..f601d21 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -57,6 +57,11 @@ TAILQ_HEAD(rte_driver_list, rte_driver); typedef int (rte_dev_init_t)(const char *name, const char *args); /** + * Uninitilization function called for each device driver once. + */ +typedef int (rte_dev_uninit_t)(const char *name); + +/** * Driver type enumeration */ enum pmd_type { @@ -72,6 +77,7 @@ struct rte_driver { enum pmd_type type; /**< PMD Driver type */ const char *name; /**< Driver name. */ rte_dev_init_t *init; /**< Device init. function. */ + rte_dev_uninit_t *uninit; /**< Device uninit. function. */ }; /** @@ -97,6 +103,28 @@ void rte_eal_driver_unregister(struct rte_driver *driver); */ int rte_eal_dev_init(void); +/** + * Initialize a driver specified by name. + * + * @param name + * The pointer to a driver name to be initialized. + * @param args + * The pointer to arguments used by driver initialization. + * @return + * 0 on success, negative on error + */ +int rte_eal_vdev_init(const char *name, const char *args); + +/** + * Uninitalize a driver specified by name. + * + * @param name + * The pointer to a driver name to be initialized. + * @return + * 0 on success, negative on error + */ +int rte_eal_vdev_uninit(const char *name); + #define PMD_REGISTER_DRIVER(d)\ void devinitfn_ ##d(void);\ void __attribute__((constructor, used)) devinitfn_ ##d(void)\ diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h index 6834333..039f728 100644 --- a/lib/librte_eal/common/include/rte_devargs.h +++ b/lib/librte_eal/common/include/rte_devargs.h @@ -99,6 +99,34 @@ TAILQ_HEAD(rte_devargs_list, rte_devargs); extern struct rte_devargs_list devargs_list; /** + * Parse a devargs string. + * + * For PCI devices, the format of arguments string is "PCI_ADDR" or + * "PCI_ADDR,key=val,key2=val2,...". Examples: "08:00.1", "0000:5:00.0", + * "04:00.0,arg=val". + * + * For virtual devices, the format of arguments string is "DRIVER_NAME*" + * or "DRIVER_NAME*,key=val,key2=val2,...". Examples: "eth_ring", + * "eth_ring0", "eth_pmdAnything,arg=0:arg2=1". + * + * The function parses the arguments string to get driver name and driver + * arguments. + * + * @param devargs_str + * The arguments as given by the user. + * @param drvname + * The pointer to the string to store parsed driver name. + * @param drvargs + * The pointer to the string to store parsed driver arguments. + * + * @return + * - 0 on success + * - A negative value on error + */ +int rte_eal_parse_devargs_str(const char *devargs_str, + char **drvname, char **drvargs); + +/** * Add a device to the user device list * * For PCI devices, the format of arguments string is "PCI_ADDR" or diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index 5478492..214643d 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -38,6 +38,7 @@ DPDK_2.0 { rte_eal_lcore_role; rte_eal_mp_remote_launch; rte_eal_mp_wait_lcore; + rte_eal_parse_devargs_str; rte_eal_pci_close_one; rte_eal_pci_dump; rte_eal_pci_probe; @@ -50,6 +51,8 @@ DPDK_2.0 { rte_eal_tailq_lookup_by_idx; rte_eal_tailq_reserve; rte_eal_tailq_reserve_by_idx; + rte_eal_vdev_init; + rte_eal_vdev_uninit; rte_eal_wait_lcore; rte_exit; rte_get_hpet_cycles;