From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f193.google.com (mail-wr0-f193.google.com [209.85.128.193]) by dpdk.org (Postfix) with ESMTP id 7A39EAAD0 for ; Thu, 15 Mar 2018 18:50:23 +0100 (CET) Received: by mail-wr0-f193.google.com with SMTP id f14so9154872wre.8 for ; Thu, 15 Mar 2018 10:50:23 -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=CVd424fW09tgOA1A0AS0Lj1DgvTc033PVXdjaErDW/4=; b=GVAh9o/yQ7VercqqkiKe5/CHgbCdTS4kfmzBAqH3V2P8eDl7PjwQ5rUZzubGkx1EFU GvW59A+EvgA+ciehV74cTFpFkYBirCc+0E8DdXw3lIziQ5hBNLBWny9akTTLvBkgvT3E R56hVRcX+xjnhJUDYPYOnjpSxpCo1ygBKsM5xKe9fh9fRTZLI7VRrV+U+9i8bUzCE4vx GRrZ+ZZjlqabx71XuGGX6UEw/Y93x/zlQUW1xzgdxYtNP59l+f85uXw3h34uy/4vM27S ZrPMybc0yAPhUvDy1T3J073gCpEJNCW0GwbzeQoQn7z+0rnw/4oLCpiOi81Y6uUdmKyC TbiQ== 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=CVd424fW09tgOA1A0AS0Lj1DgvTc033PVXdjaErDW/4=; b=G9KYqn6Hm4xmVzfSw0kDRqh+De8cdBI1j7uEDC3GLrjYYbs72gubslCaTeIA/zKH/W P7q4CxGofoOAdOjKXdEBqJbeaOawcbi9ICa1AJZLbZsKd75m8v2wI1zBYEvXAmTx7EY5 E+ywFtB61wGou3UJwtQ1kEpt0rE5OnJn5WRV2+lwul2TJpPxzlUjbNhFfYmyWYv4Nfdb EHpSPbZuvIsy8z2G/5/MVXtTsF/Z+JymMKBh0ffd8PqFLocqhON/yJQAR1YEMtcC8Sko ETFL1GRRY4iPcDlVDeDYS+Hcm+g+QSgoJG1RzT+TpI0EfL4iJS9kP33tcdRMeURnBcxD 0fyg== X-Gm-Message-State: AElRT7Fuhu1TYn6xNZLM19E6uoB9OlrH2ztbc5c7I5MWcUGiUDIP3naO Th3eNk51/QUN15YpHfVonF+6O+In X-Google-Smtp-Source: AG47ELv4dhY/ug9eXiFdbTZ59FiVhFBhsmQXP0/rl0N7DVnfYl9nQLOvtZWtJuwZQf2ZpQymrkzpbQ== X-Received: by 10.223.226.14 with SMTP id j14mr7791147wri.17.1521136221879; Thu, 15 Mar 2018 10:50:21 -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 69sm4756596wmp.36.2018.03.15.10.50.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Mar 2018 10:50:20 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Thu, 15 Mar 2018 18:49:39 +0100 Message-Id: <76d4a4ed4a4dd480f41f005620202709253396a3.1521124599.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 v1 09/18] eal/dev: implement device iteration 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: Thu, 15 Mar 2018 17:50:24 -0000 Use the iteration hooks in the abstraction layers to perform the requested filtering on the internal device lists. Signed-off-by: Gaetan Rivet --- lib/librte_eal/common/eal_common_dev.c | 81 +++++++++++++++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 25 ++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 3 files changed, 107 insertions(+) diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c index bdab1423a..159fdcf73 100644 --- a/lib/librte_eal/common/eal_common_dev.c +++ b/lib/librte_eal/common/eal_common_dev.c @@ -303,3 +303,84 @@ rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str) it->cls = cls; return 0; } + +static int +class_next_dev_cmp(const struct rte_class *cls, + const void *_it) +{ + const struct rte_dev_iterator *cit = _it; + struct rte_dev_iterator *it; + + if (cls->dev_iterate == NULL) + return 1; + /* We need a mutable iterator. */ + it = (void *)(intptr_t)cit; + /* it->clsstr != NULL means a class + * was specified in the devstr. + */ + if (it->clsstr != NULL && cls != it->cls) + return 1; + return cls->dev_iterate(it) == NULL; +} + +static int +bus_next_dev_cmp(const struct rte_bus *bus, + const void *_it) +{ + const struct rte_dev_iterator *cit = _it; + struct rte_class *cls = NULL; + struct rte_dev_iterator *it; + + if (bus->dev_iterate == NULL) + return 1; + /* We need a mutable iterator. */ + it = (void *)(intptr_t)cit; + /* it->busstr != NULL means a bus + * was specified in the devstr. + */ + if (it->busstr != NULL && bus != it->bus) + return 1; + if (it->clsstr == NULL) + return bus->dev_iterate(it) == NULL; + /* clsstr != NULL */ + if (it->device == NULL) +next_dev_on_bus: + bus->dev_iterate(it); + if (it->device == NULL) + return 1; + if (it->cls != NULL) + cls = TAILQ_PREV(it->cls, rte_class_list, next); + cls = rte_class_find(cls, class_next_dev_cmp, it); + if (cls != NULL) { + it->cls = cls; + return 0; + } + goto next_dev_on_bus; +} +__rte_experimental struct rte_device * +rte_dev_iterator_next(struct rte_dev_iterator *it) +{ + struct rte_bus *bus = NULL; + int old_errno = rte_errno; + + rte_errno = 0; + if (it->busstr == NULL && it->clsstr == NULL) { + /* Invalid iterator. */ + rte_errno = EINVAL; + return NULL; + } + if (it->bus != NULL) + bus = TAILQ_PREV(it->bus, rte_bus_list, next); + while ((bus = rte_bus_find(bus, bus_next_dev_cmp, it))) { + if (it->device != NULL) { + it->bus = bus; + return it->device; + } + if (it->busstr != NULL || + rte_errno != 0) + break; + } + if (rte_errno == 0) + rte_errno = old_errno; + return NULL; +} diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index 9b53f0ad3..11a6d786c 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -322,6 +322,31 @@ typedef struct rte_device *(*rte_dev_iterate_t)(struct rte_dev_iterator *it); int __rte_experimental rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str); +/** + * Iterates on a device iterator. + * + * Generates a new rte_device handle corresponding to the next element + * in the list described in comprehension by the iterator. + * + * The next object is returned, and the iterator is updated. + * + * @param it + * Device iterator handle. + * + * @return + * An rte_device handle if found. + * NULL if an error occurred (rte_errno is set). + * NULL if no device could be found (rte_errno is not set). + */ +struct rte_device * __rte_experimental +rte_dev_iterator_next(struct rte_dev_iterator *it); + +#define RTE_DEV_FOREACH(dev, devstr, it) \ + for (rte_dev_iterator_init(it, devstr), \ + dev = rte_dev_iterator_next(it); \ + dev != NULL; \ + dev = rte_dev_iterator_next(it)) + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 921da3075..925efcb6d 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -229,6 +229,7 @@ EXPERIMENTAL { rte_mp_request; rte_mp_reply; rte_dev_iterator_init; + rte_dev_iterator_next; rte_service_attr_get; rte_service_attr_reset_all; rte_service_component_register; -- 2.11.0