Hi Bruce, Konstantin,
>-----Original Message----- >From: Bruce Richardson <bruce.richard...@intel.com> >Sent: Thursday 8 October 2020 15:18 >To: Ananyev, Konstantin <konstantin.anan...@intel.com> >Cc: Power, Ciara <ciara.po...@intel.com>; dev@dpdk.org; Ray Kinsella ><m...@ashroe.eu>; Neil Horman <nhor...@tuxdriver.com> >Subject: Re: [dpdk-dev] [PATCH v3 01/18] eal: add max SIMD bitwidth > >On Thu, Oct 08, 2020 at 03:07:54PM +0100, Ananyev, Konstantin wrote: >> >> > On Thu, Oct 08, 2020 at 01:07:26PM +0000, Ananyev, Konstantin wrote: >> > > >> > > > This patch adds a max SIMD bitwidth EAL configuration. The API >> > > > allows for an app to set this value. It can also be set using >> > > > EAL argument --force-max-simd-bitwidth, which will lock the >> > > > value and override any modifications made by the app. >> > > > >> > > > Signed-off-by: Ciara Power <ciara.po...@intel.com> >> > > > >> > > > --- >> > > > v3: >> > > > - Added enum value to essentially disable using max SIMD to choose >> > > > paths, intended for use by ARM SVE. >> > > > - Fixed parsing bitwidth argument to return an error for values >> > > > greater than uint16_t. >> > > > v2: Added to Doxygen comment for API. >> > > > --- >> > > > lib/librte_eal/common/eal_common_options.c | 64 >++++++++++++++++++++++ >> > > > lib/librte_eal/common/eal_internal_cfg.h | 8 +++ >> > > > lib/librte_eal/common/eal_options.h | 2 + >> > > > lib/librte_eal/include/rte_eal.h | 33 +++++++++++ >> > > > lib/librte_eal/rte_eal_version.map | 4 ++ >> > > > 5 files changed, 111 insertions(+) >> > > > >> > > > diff --git a/lib/librte_eal/common/eal_common_options.c >> > > > b/lib/librte_eal/common/eal_common_options.c >> > > > index a5426e1234..e9117a96af 100644 >> > > > --- a/lib/librte_eal/common/eal_common_options.c >> > > > +++ b/lib/librte_eal/common/eal_common_options.c >> > > > @@ -102,6 +102,7 @@ eal_long_options[] = { >> > > > {OPT_MATCH_ALLOCATIONS, 0, NULL, >OPT_MATCH_ALLOCATIONS_NUM}, >> > > > {OPT_TELEMETRY, 0, NULL, OPT_TELEMETRY_NUM }, >> > > > {OPT_NO_TELEMETRY, 0, NULL, OPT_NO_TELEMETRY_NUM }, >> > > > +{OPT_FORCE_MAX_SIMD_BITWIDTH, 1, NULL, >> > > > +OPT_FORCE_MAX_SIMD_BITWIDTH_NUM}, >> > > > {0, 0, NULL, 0 } >> > > > }; >> > > > >> > > > @@ -1309,6 +1310,34 @@ eal_parse_iova_mode(const char *name) >> > > > return 0; } >> > > > >> > > > +static int >> > > > +eal_parse_simd_bitwidth(const char *arg, bool locked) { char >> > > > +*end; unsigned long bitwidth; int ret; struct internal_config >> > > > +*internal_conf = eal_get_internal_configuration(); >> > > > + >> > > > +if (arg == NULL || arg[0] == '\0') return -1; >> > > > + >> > > > +errno = 0; >> > > > +bitwidth = strtoul(arg, &end, 0); >> > > > + >> > > > +/* check for errors */ >> > > > +if (bitwidth > UINT16_MAX || errno != 0 || end == NULL || *end >> > > > +!= '\0') return -1; >> > > > + >> > > > +if (bitwidth == 0) >> > > > +bitwidth = UINT16_MAX; >> > > > +ret = rte_set_max_simd_bitwidth(bitwidth); >> > > > +if (ret < 0) >> > > > +return -1; >> > > > +internal_conf->max_simd_bitwidth.locked = locked; return 0; } >> > > > + >> > > > static int >> > > > eal_parse_base_virtaddr(const char *arg) { @@ -1707,6 +1736,13 >> > > > @@ eal_parse_common_option(int opt, const char *optarg, case >> > > > OPT_NO_TELEMETRY_NUM: >> > > > conf->no_telemetry = 1; >> > > > break; >> > > > +case OPT_FORCE_MAX_SIMD_BITWIDTH_NUM: >> > > > +if (eal_parse_simd_bitwidth(optarg, 1) < 0) { RTE_LOG(ERR, EAL, >> > > > +"invalid parameter for --" >> > > > +OPT_FORCE_MAX_SIMD_BITWIDTH "\n"); return -1; } break; >> > > > >> > > > /* don't know what to do, leave this to caller */ >> > > > default: >> > > > @@ -1903,6 +1939,33 @@ eal_check_common_options(struct >> > > > internal_config *internal_cfg) return 0; } >> > > > >> > > > +uint16_t >> > > > +rte_get_max_simd_bitwidth(void) { const struct internal_config >> > > > +*internal_conf = eal_get_internal_configuration(); return >> > > > +internal_conf->max_simd_bitwidth.bitwidth; >> > > > +} >> > > > + >> > > > +int >> > > > +rte_set_max_simd_bitwidth(uint16_t bitwidth) { struct >> > > > +internal_config *internal_conf = >> > > > +eal_get_internal_configuration(); >> > > > +if (internal_conf->max_simd_bitwidth.locked) { RTE_LOG(NOTICE, >> > > > +EAL, "Cannot set max SIMD bitwidth - user runtime override >> > > > +enabled"); return -EPERM; } >> > > > + >> > > > +if (bitwidth != RTE_MAX_SIMD_DISABLE && (bitwidth < >RTE_NO_SIMD >> > > > +|| >> > > > +!rte_is_power_of_2(bitwidth))) { RTE_LOG(ERR, EAL, "Invalid >> > > > +bitwidth value!\n"); return -EINVAL; } >> > > > +internal_conf->max_simd_bitwidth.bitwidth = bitwidth; return 0; >> > > > +} >> > > > + >> > > > void >> > > > eal_common_usage(void) >> > > > { >> > > > @@ -1981,6 +2044,7 @@ eal_common_usage(void) >> > > > " --"OPT_BASE_VIRTADDR" Base virtual address\n" >> > > > " --"OPT_TELEMETRY" Enable telemetry support (on by >default)\n" >> > > > " --"OPT_NO_TELEMETRY" Disable telemetry support\n" >> > > > + " --"OPT_FORCE_MAX_SIMD_BITWIDTH" Force the max SIMD >bitwidth\n" >> > > > "\nEAL options for DEBUG use only:\n" >> > > > " --"OPT_HUGE_UNLINK" Unlink hugepage files after >> > > > init\n" >> > > > " --"OPT_NO_HUGE" Use malloc instead of hugetlbfs\n" >> > > > diff --git a/lib/librte_eal/common/eal_internal_cfg.h >b/lib/librte_eal/common/eal_internal_cfg.h >> > > > index 13f93388a7..367e0cc19e 100644 >> > > > --- a/lib/librte_eal/common/eal_internal_cfg.h >> > > > +++ b/lib/librte_eal/common/eal_internal_cfg.h >> > > > @@ -33,6 +33,12 @@ struct hugepage_info { >> > > > int lock_descriptor; /**< file descriptor for hugepage dir */ >> > > > }; >> > > > >> > > > +struct simd_bitwidth { >> > > > +/**< flag indicating if bitwidth is locked from further modification >> > > > */ >> > > > +bool locked; >> > > > +uint16_t bitwidth; /**< bitwidth value */ >> > > > +}; >> > > > + >> > > > /** >> > > > * internal configuration >> > > > */ >> > > > @@ -85,6 +91,8 @@ struct internal_config { >> > > > volatile unsigned int init_complete; >> > > > /**< indicates whether EAL has completed initialization */ >> > > > unsigned int no_telemetry; /**< true to disable Telemetry */ >> > > > +/** max simd bitwidth path to use */ >> > > > +struct simd_bitwidth max_simd_bitwidth; >> > > > }; >> > > > >> > > > void eal_reset_internal_config(struct internal_config *internal_cfg); >> > > > diff --git a/lib/librte_eal/common/eal_options.h >b/lib/librte_eal/common/eal_options.h >> > > > index 89769d48b4..ef33979664 100644 >> > > > --- a/lib/librte_eal/common/eal_options.h >> > > > +++ b/lib/librte_eal/common/eal_options.h >> > > > @@ -85,6 +85,8 @@ enum { >> > > > OPT_TELEMETRY_NUM, >> > > > #define OPT_NO_TELEMETRY "no-telemetry" >> > > > OPT_NO_TELEMETRY_NUM, >> > > > +#define OPT_FORCE_MAX_SIMD_BITWIDTH "force-max-simd- >bitwidth" >> > > > +OPT_FORCE_MAX_SIMD_BITWIDTH_NUM, >> > > > OPT_LONG_MAX_NUM >> > > > }; >> > > > >> > > > diff --git a/lib/librte_eal/include/rte_eal.h >b/lib/librte_eal/include/rte_eal.h >> > > > index ddcf6a2e7a..fb739f3474 100644 >> > > > --- a/lib/librte_eal/include/rte_eal.h >> > > > +++ b/lib/librte_eal/include/rte_eal.h >> > > > @@ -43,6 +43,14 @@ enum rte_proc_type_t { >> > > > RTE_PROC_INVALID >> > > > }; >> > > > >> > > > +enum rte_max_simd_t { >> > > > +RTE_NO_SIMD = 64, >> > > >> > > While I do understand the idea of having that value from consistency >point of view, >> > > I wonder do we really need to allow user to specify values smaller then >128. >> > > At least on x86 we always have 128 bit SIMD enabled, even for - >Dmachine=default. >> > > So seems no much point to forbid libraries using SSE code-path when >compiler >> > > is free to insert SSE instructions on its own will. >> > > >> > >> > The reason to support this is for testing purposes, as it allows an easy >> > way for a tester to check out any scalar code paths - which are often >> > common across architectures. >> >> If it is just for testing things in a consistent way, then it is probably >> ok. >> The thing that worries me - later in this series there are patches >> that insert extra checks into inline functions that use SSE instincts: >> https://patches.dpdk.org/patch/79355/ (lpm: choose vector path at >runtime). >> Which seems like a total overkill for me. >> >> > >> > > > +RTE_MAX_128_SIMD = 128, >> > > > +RTE_MAX_256_SIMD = 256, >> > > > +RTE_MAX_512_SIMD = 512, >> > > > +RTE_MAX_SIMD_DISABLE = UINT16_MAX, >> > > >> > > As a nit, I think it is safe enough to have this last value >> > > (RTE_MAX_SIMD_DISABLE or RTE_MAX_SIMD_MAX) equal to >(INT16_MAX + 1). >> > > That would be big enough to probably never hit actual HW limit, >> > > while it still remains power of two, as other values. >> > > >> > >> > I actually think it's probably clearer as-is, because the fact of the rest >> > being powers of 2 is irrelevant since we just check greater than or less >> > than. >> >> Well, rte_set_max_simd_bitwidth() does accept only power of two values >> _AND_ this special one (UINT16_MAX). >> By changing it to 2^15, we can remove that special value test. >> >> > If we did change it, then we need to put in a comment explaining why >> > the plus-one, >> >> I don't think it is that big deal to put a comment, >> plus for UINT16_MAX we do need some explanation too, right? >> >I'm ok either way. Ciara, what do you think? Either is fine with me, I can change it to (INT16_MAX + 1) if that is preferred, and remove the extra special case check in the rte_set_max_simd_bitwidth() Thanks, Ciara