From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f66.google.com (mail-wm0-f66.google.com [74.125.82.66]) by dpdk.org (Postfix) with ESMTP id 1B3891BE06 for ; Tue, 26 Jun 2018 18:56:57 +0200 (CEST) Received: by mail-wm0-f66.google.com with SMTP id e16-v6so2752065wmd.0 for ; Tue, 26 Jun 2018 09:56:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=JiGoqkJjNRKoNIo30pwQ3qEnkhOjDh/K3fTAwhD+xtQ=; b=DwGYK9Rng9uj/QPObjvpp8kt86m2lrUkaFB96bCH1r/yv+/S1pshJSDOHBavTFWiJC xaMewRsWTwcHENmXALs2wEa2L117tx2cruL55jZ9gvPXEqa6AwAXvtEfOsUK9fJpQrTv Wojcoh9Jx/XKAJDN1zawYdsD+OujcXaCb8hi9M49If3SUg/T/rJo7ex/DAiwe2tbM898 8ZxxvlaXPqjgBZ58aKj9bvcWQCBGMb+DRDCQBFcaEXMAYvODthAU4cTe5pmgEfeAWehR a22/AXb5AF9i4+hs8pdfN5Hkoy3oxF1tDRKN8ei+I2yxFgnFYQTRaJL50gkEy3zUfzu2 1lVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=JiGoqkJjNRKoNIo30pwQ3qEnkhOjDh/K3fTAwhD+xtQ=; b=m9mjNQ8qJ/cicGljgBzFZHcB5Vvbm52JF3TJGnvx+10V8XGQEPG2mOrWqNlXG5Y+s2 9sOST3qXFod604VnpC5pV4BpOhxpvH6jHhAUEPBjGArXR0fSbnzldkhW2o2GJ45B5QEp EXDkJjoILnm4D/MLLRUrE7XmOXMaaHIooEybel0Tht7j2P+HivaF5P2SUpfszvXMsUZC vz4UYckuDGJQW7Xcitd4AgZE+JSRRmPUJCafzSkNa3JjjgFwOWElUCWj44vbkgbvb98Z qkFLKlretiBeZvUkFs4bg7C2MaxCfOwJDd4mp5MGnToGIpgEH2r1hbAB2rhv/gJiQaqx Tj0Q== X-Gm-Message-State: APt69E12DpXhNTrz2ZfCd37CU08FKrgJEK4EQjkRI08WxoPvpKPUNhm6 TgxO8v0Jg8LtOmO9/RUl7NVCIw2e X-Google-Smtp-Source: AAOMgpd7pqogDp+2R6NlKKQhrYrvjkoZNBDTYCoMLQK7T/gWmqYWvYUO7shWrLKDpTbXdyWXiXLbJw== X-Received: by 2002:a1c:2489:: with SMTP id k131-v6mr2396501wmk.114.1530032216215; Tue, 26 Jun 2018 09:56:56 -0700 (PDT) Received: from bidouze.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id p5-v6sm2680880wre.83.2018.06.26.09.56.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Jun 2018 09:56:55 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Tue, 26 Jun 2018 18:56:10 +0200 Message-Id: <0ce131421cf2386dec4393d848a15a365c9698d4.1530031921.git.gaetan.rivet@6wind.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v8 07/21] devargs: add function to parse device layers 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: , X-List-Received-Date: Tue, 26 Jun 2018 16:56:57 -0000 This function is private to the EAL. It is used to parse each layers in a device description string, and store the result in an rte_devargs structure. Signed-off-by: Gaetan Rivet --- lib/librte_eal/common/eal_common_devargs.c | 144 ++++++++++++++++++++++++++++ lib/librte_eal/common/eal_private.h | 27 ++++++ lib/librte_eal/common/include/rte_devargs.h | 13 ++- 3 files changed, 181 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c index 0a83beb94..9fee2153f 100644 --- a/lib/librte_eal/common/eal_common_devargs.c +++ b/lib/librte_eal/common/eal_common_devargs.c @@ -13,9 +13,13 @@ #include #include +#include +#include #include #include #include +#include +#include #include #include "eal_private.h" @@ -56,6 +60,146 @@ rte_eal_parse_devargs_str(const char *devargs_str, return 0; } +static size_t +devargs_layer_count(const char *s) +{ + size_t i = s ? 1 : 0; + + while (s != NULL && s[0] != '\0') { + i += s[0] == '/'; + s++; + } + return i; +} + +int +rte_devargs_layers_parse(struct rte_devargs *da, + const char *devstr) +{ + struct { + const char *key; + const char *str; + struct rte_kvargs *kvlist; + } layers[] = { + { "bus=", NULL, NULL, }, + { "class=", NULL, NULL, }, + { "driver=", NULL, NULL, }, + }; + struct rte_kvargs_pair *kv = NULL; + struct rte_class *cls = NULL; + struct rte_bus *bus = NULL; + const char *s = devstr; + size_t nblayer; + size_t i = 0; + int ret = 0; + + /* Split each sub-lists. */ + nblayer = devargs_layer_count(devstr); + if (nblayer > RTE_DIM(layers)) { + RTE_LOG(ERR, EAL, "Invalid format: too many layers (%zu)\n", + nblayer); + ret = -E2BIG; + goto get_out; + } + + /* If the devargs points the devstr + * as source data, then it should not allocate + * anything and keep referring only to it. + */ + if (da->data != devstr) { + da->data = strdup(devstr); + if (da->data == NULL) { + RTE_LOG(ERR, EAL, "OOM\n"); + ret = -ENOMEM; + goto get_out; + } + s = da->data; + } + + while (s != NULL) { + if (strncmp(layers[i].key, s, + strlen(layers[i].key)) && + /* The last layer is free-form. + * The "driver" key is not required (but accepted). + */ + i != RTE_DIM(layers) - 1) + goto next_layer; + layers[i].str = s; + layers[i].kvlist = rte_kvargs_parse2(s, NULL, "/"); + if (layers[i].kvlist == NULL) { + RTE_LOG(ERR, EAL, "Could not parse %s\n", s); + ret = -EINVAL; + goto get_out; + } + s = strchr(s, '/'); + if (s != NULL) + s++; +next_layer: + if (i >= RTE_DIM(layers)) { + RTE_LOG(ERR, EAL, "Unrecognized layer %s\n", s); + ret = -EINVAL; + goto get_out; + } + i++; + } + + /* Parse each sub-list. */ + for (i = 0; i < RTE_DIM(layers); i++) { + if (layers[i].kvlist == NULL) + continue; + kv = &layers[i].kvlist->pairs[0]; + if (strcmp(kv->key, "bus") == 0) { + bus = rte_bus_find_by_name(kv->value); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Could not find bus \"%s\"\n", + kv->value); + ret = -EFAULT; + goto get_out; + } + } else if (strcmp(kv->key, "class") == 0) { + cls = rte_class_find_by_name(kv->value); + if (cls == NULL) { + RTE_LOG(ERR, EAL, "Could not find class \"%s\"\n", + kv->value); + ret = -EFAULT; + goto get_out; + } + } else if (strcmp(kv->key, "driver") == 0) { + /* Ignore */ + continue; + } + } + + /* Fill devargs fields. */ + da->busstr = layers[0].str; + da->clsstr = layers[1].str; + da->drvstr = layers[2].str; + da->bus = bus; + da->cls = cls; + + /* If we own the data, clean up a bit + * the several layers string, to ease + * their parsing afterward. + */ + if (da->data != devstr) { + char *s = (void*)(intptr_t)(da->data); + + while ((s = strchr(s, '/'))) { + *s = '\0'; + s++; + } + } + +get_out: + for (i = 0; i < RTE_DIM(layers); i++) { + if (layers[i].kvlist) + rte_kvargs_free(layers[i].kvlist); + } + if (ret != 0) + rte_errno = -ret; + return ret; +} + static int bus_name_cmp(const struct rte_bus *bus, const void *name) { diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index bdadc4d50..c4c9283c8 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -258,4 +258,31 @@ int rte_mp_channel_init(void); */ void dev_callback_process(char *device_name, enum rte_dev_event_type event); +/** + * @internal + * Parse a device string and store its information in an + * rte_devargs structure. + * + * Note: if the "data" field of da points to devstr, + * then no dynamic allocation is performed and the rte_devargs + * can be safely discarded. + * + * Otherwise ``data`` will hold a workable copy of devstr, that will be + * used by layers descriptors within rte_devargs. In this case, + * any rte_devargs should be cleaned-up before being freed. + * + * @param da + * rte_devargs structure to fill. + * + * @param devstr + * Device string. + * + * @return + * 0 on success. + * Negative errno values on error (rte_errno is set). + */ +int +rte_devargs_layers_parse(struct rte_devargs *da, + const char *devstr); + #endif /* _EAL_PRIVATE_H_ */ diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h index 6c3b6326b..148600258 100644 --- a/lib/librte_eal/common/include/rte_devargs.h +++ b/lib/librte_eal/common/include/rte_devargs.h @@ -51,12 +51,19 @@ struct rte_devargs { enum rte_devtype type; /** Device policy. */ enum rte_dev_policy policy; - /** Bus handle for the device. */ - struct rte_bus *bus; /** Name of the device. */ char name[RTE_DEV_NAME_MAX_LEN]; + RTE_STD_C11 + union { /** Arguments string as given by user or "" for no argument. */ - char *args; + char *args; + const char *drvstr; + }; + struct rte_bus *bus; /**< bus handle. */ + struct rte_class *cls; /**< class handle. */ + const char *busstr; /**< bus-related part of device string. */ + const char *clsstr; /**< bus-related part of device string. */ + const char *data; /**< Device string storage. */ }; /** -- 2.11.0