[4/4] mempool: use lcore API to check if lcore ID is valid
Checks
Commit Message
Use lcore API to check if the lcore ID is valid. The runtime
check does not add much value. Hence use assert to validate
the lcore ID.
Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Reviewed-by: Wathsala Vithanage <wathsala.vithanage@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
lib/mempool/rte_mempool.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
Comments
>
> Use lcore API to check if the lcore ID is valid. The runtime
> check does not add much value.
From my perspective it adds a perfect value:
Only threads with valid lcore id have their own default mempool cache.
> Hence use assert to validate
> the lcore ID.
Wonder why?
What's wrong for the thread to try to get default mempool cache?
That would change existing behavior and in general seems wrong to me.
So I am strongly opposed.
> Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Reviewed-by: Wathsala Vithanage <wathsala.vithanage@arm.com>
> Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> ---
> lib/mempool/rte_mempool.h | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
> index 009bd10215..00c5aa961b 100644
> --- a/lib/mempool/rte_mempool.h
> +++ b/lib/mempool/rte_mempool.h
> @@ -1314,10 +1314,9 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache);
> static __rte_always_inline struct rte_mempool_cache *
> rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
> {
> - if (mp->cache_size == 0)
> - return NULL;
> + RTE_ASSERT(rte_lcore_id_is_valid(lcore_id));
>
> - if (lcore_id >= RTE_MAX_LCORE)
> + if (mp->cache_size == 0)
> return NULL;
>
> rte_mempool_trace_default_cache(mp, lcore_id,
> --
> 2.25.1
>
<snip>
>
>
>
> >
> > Use lcore API to check if the lcore ID is valid. The runtime check
> > does not add much value.
>
> From my perspective it adds a perfect value:
> Only threads with valid lcore id have their own default mempool cache.
The threads would call 'rte_lcore_id()' to return their lcore_id. This ensures the lcore_id is valid already. Why do we need to check it again in rte_mempool_default_cache? Why would a thread use an incorrect lcore_id?
>
> > Hence use assert to validate
> > the lcore ID.
>
> Wonder why?
> What's wrong for the thread to try to get default mempool cache?
What are the cases where a thread does not know that it is not an EAL thread and call rte_mempool_default_cache with a random lcore_id?
Since, this API is called in the data plane, it makes sense to remove any additional validations.
> That would change existing behavior and in general seems wrong to me.
Agree on the change in existing behavior. We can discuss this once we agree/disagree on the above.
> So I am strongly opposed.
>
> > Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > Reviewed-by: Wathsala Vithanage <wathsala.vithanage@arm.com>
> > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > ---
> > lib/mempool/rte_mempool.h | 5 ++---
> > 1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
> > index 009bd10215..00c5aa961b 100644
> > --- a/lib/mempool/rte_mempool.h
> > +++ b/lib/mempool/rte_mempool.h
> > @@ -1314,10 +1314,9 @@ rte_mempool_cache_free(struct
> rte_mempool_cache
> > *cache); static __rte_always_inline struct rte_mempool_cache *
> > rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
> > {
> > - if (mp->cache_size == 0)
> > - return NULL;
> > + RTE_ASSERT(rte_lcore_id_is_valid(lcore_id));
> >
> > - if (lcore_id >= RTE_MAX_LCORE)
> > + if (mp->cache_size == 0)
> > return NULL;
> >
> > rte_mempool_trace_default_cache(mp, lcore_id,
> > --
> > 2.25.1
> >
>
> <snip>
> >
> >
> >
> > >
> > > Use lcore API to check if the lcore ID is valid. The runtime check
> > > does not add much value.
> >
> > From my perspective it adds a perfect value:
> > Only threads with valid lcore id have their own default mempool cache.
> The threads would call 'rte_lcore_id()' to return their lcore_id. This ensures the lcore_id is valid already.
> Why do we need to check it
> again in rte_mempool_default_cache? Why would a thread use an incorrect lcore_id?
rte_lcore_id() will just return you value of per-thread variable: RTE_PER_LCORE(_lcore_id).
Without any checking. For non-eal tthreads this value would be UINT32_MAX.
> >
> > > Hence use assert to validate
> > > the lcore ID.
> >
> > Wonder why?
> > What's wrong for the thread to try to get default mempool cache?
> What are the cases where a thread does not know that it is not an EAL thread and call rte_mempool_default_cache with a random
> lcore_id?
> Since, this API is called in the data plane, it makes sense to remove any additional validations.
Why is that?
I believe this API have to be generic and safe to call from any thread.
Let's look for example at:
*/
static __rte_always_inline void
rte_mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
unsigned int n)
{
struct rte_mempool_cache *cache;
cache = rte_mempool_default_cache(mp, rte_lcore_id());
rte_mempool_trace_put_bulk(mp, obj_table, n, cache);
rte_mempool_generic_put(mp, obj_table, n, cache);
}
Right now it is perfectly valid to invoke it from any thread.
With the change you propose invoking mempool_put() from non-EAL thread
will cause either a crash or silent memory corruption.
> > That would change existing behavior and in general seems wrong to me.
> Agree on the change in existing behavior. We can discuss this once we agree/disagree on the above.
>
> > So I am strongly opposed.
> >
> > > Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > Reviewed-by: Wathsala Vithanage <wathsala.vithanage@arm.com>
> > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > ---
> > > lib/mempool/rte_mempool.h | 5 ++---
> > > 1 file changed, 2 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
> > > index 009bd10215..00c5aa961b 100644
> > > --- a/lib/mempool/rte_mempool.h
> > > +++ b/lib/mempool/rte_mempool.h
> > > @@ -1314,10 +1314,9 @@ rte_mempool_cache_free(struct
> > rte_mempool_cache
> > > *cache); static __rte_always_inline struct rte_mempool_cache *
> > > rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
> > > {
> > > - if (mp->cache_size == 0)
> > > - return NULL;
> > > + RTE_ASSERT(rte_lcore_id_is_valid(lcore_id));
> > >
> > > - if (lcore_id >= RTE_MAX_LCORE)
> > > + if (mp->cache_size == 0)
> > > return NULL;
> > >
> > > rte_mempool_trace_default_cache(mp, lcore_id,
> > > --
> > > 2.25.1
> > >
@@ -1314,10 +1314,9 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache);
static __rte_always_inline struct rte_mempool_cache *
rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
{
- if (mp->cache_size == 0)
- return NULL;
+ RTE_ASSERT(rte_lcore_id_is_valid(lcore_id));
- if (lcore_id >= RTE_MAX_LCORE)
+ if (mp->cache_size == 0)
return NULL;
rte_mempool_trace_default_cache(mp, lcore_id,