From patchwork Wed May 29 15:41:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruce Richardson X-Patchwork-Id: 53825 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 81CE21B9BC; Wed, 29 May 2019 17:41:50 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 9EA991B9B1 for ; Wed, 29 May 2019 17:41:48 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 May 2019 08:41:47 -0700 X-ExtLoop1: 1 Received: from silpixa00399126.ir.intel.com (HELO silpixa00399126.ger.corp.intel.com) ([10.237.223.2]) by FMSMGA003.fm.intel.com with ESMTP; 29 May 2019 08:41:47 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: Bruce Richardson Date: Wed, 29 May 2019 16:41:31 +0100 Message-Id: <20190529154132.49955-4-bruce.richardson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190529154132.49955-1-bruce.richardson@intel.com> References: <20190529154132.49955-1-bruce.richardson@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 3/4] eal: allow checking CPU flags by name 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" Rather than using enum values for CPU flags, which means the symbols don't exist on other architectures, provide a flag lookup by name, allowing us to unconditionally check for a CPU flag. Signed-off-by: Bruce Richardson --- lib/librte_eal/common/eal_common_cpuflags.c | 41 +++++++++++++++++ .../common/include/generic/rte_cpuflags.h | 44 ++++++++++++++++++- lib/librte_eal/rte_eal_version.map | 3 ++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c index 3a055f7c7..5084a3e7a 100644 --- a/lib/librte_eal/common/eal_common_cpuflags.c +++ b/lib/librte_eal/common/eal_common_cpuflags.c @@ -3,6 +3,7 @@ */ #include +#include #include #include @@ -48,3 +49,43 @@ rte_cpu_is_supported(void) return 1; } + +static enum rte_cpu_flag_t +rte_cpu_get_flag(const char *flagname) +{ + int i; + + if (flagname == NULL) + return RTE_CPUFLAG_NUMFLAGS; + + for (i = 0; i < RTE_CPUFLAG_NUMFLAGS; i++) + if (strcmp(flagname, rte_cpu_get_flag_name(i)) == 0) + break; + return i; +} + +static int +rte_cpu_is_architecture(enum rte_cpu_arch arch) +{ + switch (arch) { + case rte_cpu_arch_arm: + return strcmp(RTE_ARCH, "arm") == 0 || + strcmp(RTE_ARCH, "arm64") == 0; + case rte_cpu_arch_ppc: + return strcmp(RTE_ARCH, "ppc_64") == 0; + case rte_cpu_arch_x86: + return strcmp(RTE_ARCH, "x86_64") == 0 || + strcmp(RTE_ARCH, "i686") == 0; + default: + return -EINVAL; + } +} + +int +rte_cpu_get_flagname_enabled(enum rte_cpu_arch arch, const char *flagname) +{ + if (!rte_cpu_is_architecture(arch)) + return 0; + + return rte_cpu_get_flag_enabled(rte_cpu_get_flag(flagname)) == 1; +} diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h index 156ea0029..a53551eba 100644 --- a/lib/librte_eal/common/include/generic/rte_cpuflags.h +++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h @@ -10,7 +10,8 @@ * Architecture specific API to determine available CPU features at runtime. */ -#include "rte_common.h" +#include +#include #include /** @@ -46,6 +47,47 @@ __extension__ int rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature); +/** + * Enumeration of the various CPU architectures supported by DPDK. + * + * When checking for CPU flags by name, it's possible that multiple + * architectures have flags with the same name e.g. AES is defined in + * both arm and x86 feature lists. Therefore we need to pass in at runtime + * the architecture we are checking for as well as the CPU flag. This enum + * defines the various supported architectures to be used for that checking. + */ +enum rte_cpu_arch { + rte_cpu_arch_arm = 0, + rte_cpu_arch_ppc, + rte_cpu_arch_x86, + + rte_cpu_num_arch /* must always be the last */ +}; + +/** + * Function for checking if a named CPU flag is enabled + * + * Wrapper around the rte_cpu_get_flag() and rte_cpu_get_flag_enabled() + * calls, which is safe to use even if the flag doesn't exist on target + * architecture. The function also verifies the target architecture so that + * we can distinguish e.g. AES support for arm vs x86 platforms. + * + * Note: This function uses multiple string compares in its operation and + * so is not recommended for data-path use. It should be called once, and + * the return value cached for later use. + * + * @param arch + * The architecture on which we need to check the flag, since multiple + * architectures could have flags with the same name. + * @param flagname + * The name of the flag to query + * @return + * 1 if flag is available + * 0 if flag is not unavailable or invalid + */ +__rte_experimental int +rte_cpu_get_flagname_enabled(enum rte_cpu_arch arch, const char *flagname); + /** * This function checks that the currently used CPU supports the CPU features * that were specified at compile time. It is called automatically within the diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 245493461..5ca5584a5 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -378,4 +378,7 @@ EXPERIMENTAL { rte_service_lcore_attr_get; rte_service_lcore_attr_reset_all; rte_service_may_be_active; + + # added in 19.08 + rte_cpu_get_flagname_enabled; };