From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4C0B1A04C7; Tue, 15 Sep 2020 18:51:27 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 18DD91C13B; Tue, 15 Sep 2020 18:51:06 +0200 (CEST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 5C9D51C139 for ; Tue, 15 Sep 2020 18:51:04 +0200 (CEST) IronPort-SDR: Re/oGYddhX7LuxksHNWSRqWloaNV/kMrRcwbm44p9ylT4Xqmf8Cbl3XI8Uk2cfFdl1w65AH321 EjqMHO0rd4oA== X-IronPort-AV: E=McAfee;i="6000,8403,9745"; a="139310971" X-IronPort-AV: E=Sophos;i="5.76,430,1592895600"; d="scan'208";a="139310971" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Sep 2020 09:51:03 -0700 IronPort-SDR: RJ1mEritolBoRhwtp+uV59Y97onnukwLKKJnPZgOIWX8M3QpX9xfKf94Prm03OGdae5e3vW+oM mqU4hOp8EsNQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,430,1592895600"; d="scan'208";a="306709376" Received: from sivswdev08.ir.intel.com ([10.237.217.47]) by orsmga006.jf.intel.com with ESMTP; 15 Sep 2020 09:51:02 -0700 From: Konstantin Ananyev To: dev@dpdk.org Cc: jerinj@marvell.com, ruifeng.wang@arm.com, vladimir.medvedkin@intel.com, Konstantin Ananyev Date: Tue, 15 Sep 2020 17:50:17 +0100 Message-Id: <20200915165025.543-5-konstantin.ananyev@intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200915165025.543-1-konstantin.ananyev@intel.com> References: <20200807162829.11690-1-konstantin.ananyev@intel.com> <20200915165025.543-1-konstantin.ananyev@intel.com> Subject: [dpdk-dev] [PATCH v2 04/12] acl: remove library constructor 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" Right now ACL library determines best possible (default) classify method on a given platform with specilal constructor function rte_acl_init(). This patch makes the following changes: - Move selection of default classify method into a separate private function and call it for each ACL context creation (rte_acl_create()). - Remove library constructor function - Make rte_acl_set_ctx_classify() to check that requested algorithm is supported on given platform. The purpose of these changes to improve and simplify algorithm selection process and prepare ACL library to be integrated with: add max SIMD bitwidth to EAL (https://patches.dpdk.org/project/dpdk/list/?series=11831) patch-set Signed-off-by: Konstantin Ananyev --- lib/librte_acl/rte_acl.c | 166 ++++++++++++++++++++++++++++++--------- lib/librte_acl/rte_acl.h | 1 + 2 files changed, 132 insertions(+), 35 deletions(-) diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c index 715b02359..fbcf45fdc 100644 --- a/lib/librte_acl/rte_acl.c +++ b/lib/librte_acl/rte_acl.c @@ -79,57 +79,153 @@ static const rte_acl_classify_t classify_fns[] = { [RTE_ACL_CLASSIFY_ALTIVEC] = rte_acl_classify_altivec, }; -/* by default, use always available scalar code path. */ -static enum rte_acl_classify_alg rte_acl_default_classify = - RTE_ACL_CLASSIFY_SCALAR; +/* + * Helper function for acl_check_alg. + * Check support for ARM specific classify methods. + */ +static int +acl_check_alg_arm(enum rte_acl_classify_alg alg) +{ + if (alg == RTE_ACL_CLASSIFY_NEON) { +#if defined(RTE_ARCH_ARM64) + return 0; +#elif defined(RTE_ARCH_ARM) + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) + return 0; + return -ENOTSUP; +#else + return -ENOTSUP; +#endif + } + + return -EINVAL; +} -static void -rte_acl_set_default_classify(enum rte_acl_classify_alg alg) +/* + * Helper function for acl_check_alg. + * Check support for PPC specific classify methods. + */ +static int +acl_check_alg_ppc(enum rte_acl_classify_alg alg) { - rte_acl_default_classify = alg; + if (alg == RTE_ACL_CLASSIFY_ALTIVEC) { +#if defined(RTE_ARCH_PPC_64) + return 0; +#else + return -ENOTSUP; +#endif + } + + return -EINVAL; } -extern int -rte_acl_set_ctx_classify(struct rte_acl_ctx *ctx, enum rte_acl_classify_alg alg) +/* + * Helper function for acl_check_alg. + * Check support for x86 specific classify methods. + */ +static int +acl_check_alg_x86(enum rte_acl_classify_alg alg) { - if (ctx == NULL || (uint32_t)alg >= RTE_DIM(classify_fns)) - return -EINVAL; + if (alg == RTE_ACL_CLASSIFY_AVX2) { +#ifdef CC_AVX2_SUPPORT + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2)) + return 0; +#endif + return -ENOTSUP; + } - ctx->alg = alg; - return 0; + if (alg == RTE_ACL_CLASSIFY_SSE) { +#ifdef RTE_ARCH_X86 + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1)) + return 0; +#endif + return -ENOTSUP; + } + + return -EINVAL; } /* - * Select highest available classify method as default one. - * Note that CLASSIFY_AVX2 should be set as a default only - * if both conditions are met: - * at build time compiler supports AVX2 and target cpu supports AVX2. + * Check if input alg is supported by given platform/binary. + * Note that both conditions should be met: + * - at build time compiler supports ISA used by given methos + * at run time target cpu supports necessary ISA. */ -RTE_INIT(rte_acl_init) +static int +acl_check_alg(enum rte_acl_classify_alg alg) { - enum rte_acl_classify_alg alg = RTE_ACL_CLASSIFY_DEFAULT; + switch (alg) { + case RTE_ACL_CLASSIFY_NEON: + return acl_check_alg_arm(alg); + case RTE_ACL_CLASSIFY_ALTIVEC: + return acl_check_alg_ppc(alg); + case RTE_ACL_CLASSIFY_AVX2: + case RTE_ACL_CLASSIFY_SSE: + return acl_check_alg_x86(alg); + /* scalar method is supported on all platforms */ + case RTE_ACL_CLASSIFY_SCALAR: + return 0; + default: + return -EINVAL; + } +} -#if defined(RTE_ARCH_ARM64) - alg = RTE_ACL_CLASSIFY_NEON; -#elif defined(RTE_ARCH_ARM) - if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) - alg = RTE_ACL_CLASSIFY_NEON; +/* + * Get preferred alg for given platform. + */ +static enum rte_acl_classify_alg +acl_get_best_alg(void) +{ + /* + * array of supported methods for each platform. + * Note that order is important - from most to less preferable. + */ + static const enum rte_acl_classify_alg alg[] = { +#if defined(RTE_ARCH_ARM) + RTE_ACL_CLASSIFY_NEON, #elif defined(RTE_ARCH_PPC_64) - alg = RTE_ACL_CLASSIFY_ALTIVEC; -#else -#ifdef CC_AVX2_SUPPORT - if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2)) - alg = RTE_ACL_CLASSIFY_AVX2; - else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1)) -#else - if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1)) + RTE_ACL_CLASSIFY_ALTIVEC, +#elif defined(RTE_ARCH_X86) + RTE_ACL_CLASSIFY_AVX2, + RTE_ACL_CLASSIFY_SSE, #endif - alg = RTE_ACL_CLASSIFY_SSE; + RTE_ACL_CLASSIFY_SCALAR, + }; -#endif - rte_acl_set_default_classify(alg); + uint32_t i; + + /* find best possible alg */ + for (i = 0; i != RTE_DIM(alg) && acl_check_alg(alg[i]) != 0; i++) + ; + + /* we always have to find something suitable */ + RTE_VERIFY(i != RTE_DIM(alg)); + return alg[i]; +} + +extern int +rte_acl_set_ctx_classify(struct rte_acl_ctx *ctx, enum rte_acl_classify_alg alg) +{ + int32_t rc; + + /* formal parameters check */ + if (ctx == NULL || (uint32_t)alg >= RTE_DIM(classify_fns)) + return -EINVAL; + + /* user asked us to select the *best* one */ + if (alg == RTE_ACL_CLASSIFY_DEFAULT) + alg = acl_get_best_alg(); + + /* check that given alg is supported */ + rc = acl_check_alg(alg); + if (rc != 0) + return rc; + + ctx->alg = alg; + return 0; } + int rte_acl_classify_alg(const struct rte_acl_ctx *ctx, const uint8_t **data, uint32_t *results, uint32_t num, uint32_t categories, @@ -262,7 +358,7 @@ rte_acl_create(const struct rte_acl_param *param) ctx->max_rules = param->max_rule_num; ctx->rule_sz = param->rule_size; ctx->socket_id = param->socket_id; - ctx->alg = rte_acl_default_classify; + ctx->alg = acl_get_best_alg(); strlcpy(ctx->name, param->name, sizeof(ctx->name)); te->data = (void *) ctx; diff --git a/lib/librte_acl/rte_acl.h b/lib/librte_acl/rte_acl.h index b814423a6..3999f15de 100644 --- a/lib/librte_acl/rte_acl.h +++ b/lib/librte_acl/rte_acl.h @@ -329,6 +329,7 @@ rte_acl_classify_alg(const struct rte_acl_ctx *ctx, * existing algorithm, and that it could be run on the given CPU. * @return * - -EINVAL if the parameters are invalid. + * - -ENOTSUP requested algorithm is not supported by given platform. * - Zero if operation completed successfully. */ extern int -- 2.17.1