> 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?

>while as it is now it's clearly a placeholder $BIGNUM.
> 
> /Bruce

Reply via email to