mempool: enforce valid flags at creation
Checks
Commit Message
If we do not enforce valid flags are passed by an application, this
application might face issues in the future when we add more flags.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
app/test/test_mempool.c | 21 +++++++++++++++++++++
lib/mempool/rte_mempool.c | 13 +++++++++++++
lib/mempool/rte_mempool.h | 2 +-
3 files changed, 35 insertions(+), 1 deletion(-)
Comments
On 10/12/21 10:28 AM, David Marchand wrote:
> If we do not enforce valid flags are passed by an application, this
> application might face issues in the future when we add more flags.
Thanks. I'd even consider it as a bug and the fix to be
backported.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
A nit below, other than that:
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
[snip]
> diff --git a/lib/mempool/rte_mempool.c b/lib/mempool/rte_mempool.c
> index c5f859ae71..a2a78125f4 100644
> --- a/lib/mempool/rte_mempool.c
> +++ b/lib/mempool/rte_mempool.c
> @@ -777,6 +777,13 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache)
> rte_free(cache);
> }
>
> +#define MEMPOOL_KNOWN_FLAGS ( MEMPOOL_F_NO_SPREAD \
> + | MEMPOOL_F_NO_CACHE_ALIGN \
> + | MEMPOOL_F_SP_PUT \
> + | MEMPOOL_F_SC_GET \
> + | MEMPOOL_F_POOL_CREATED \
> + | MEMPOOL_F_NO_IOVA_CONTIG \
> + )
> /* create an empty mempool */
> struct rte_mempool *
> rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
> @@ -806,6 +813,12 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
> RTE_CACHE_LINE_MASK) != 0);
> #endif
>
> + /* enforce no unknown flag is passed by the application */
> + if ((flags & ~MEMPOOL_KNOWN_FLAGS) != 0) {
> + rte_errno = EINVAL;
> + return NULL;
> + }
> +
I think it is better to check arguments in parameters order.
So, it is a bit better to move the check to happen after
cache_size validation below.
> mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
>
> /* asked for zero items */
[snip]
On Tue, Oct 12, 2021 at 9:49 AM Andrew Rybchenko
<andrew.rybchenko@oktetlabs.ru> wrote:
>
> On 10/12/21 10:28 AM, David Marchand wrote:
> > If we do not enforce valid flags are passed by an application, this
> > application might face issues in the future when we add more flags.
>
> Thanks. I'd even consider it as a bug and the fix to be
> backported.
I wondered too when writing the patch.
I'd like to hear from others.
>
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
>
> A nit below, other than that:
>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>
> [snip]
>
> > diff --git a/lib/mempool/rte_mempool.c b/lib/mempool/rte_mempool.c
> > index c5f859ae71..a2a78125f4 100644
> > --- a/lib/mempool/rte_mempool.c
> > +++ b/lib/mempool/rte_mempool.c
> > @@ -777,6 +777,13 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache)
> > rte_free(cache);
> > }
> >
> > +#define MEMPOOL_KNOWN_FLAGS ( MEMPOOL_F_NO_SPREAD \
> > + | MEMPOOL_F_NO_CACHE_ALIGN \
> > + | MEMPOOL_F_SP_PUT \
> > + | MEMPOOL_F_SC_GET \
> > + | MEMPOOL_F_POOL_CREATED \
> > + | MEMPOOL_F_NO_IOVA_CONTIG \
> > + )
> > /* create an empty mempool */
> > struct rte_mempool *
> > rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
> > @@ -806,6 +813,12 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
> > RTE_CACHE_LINE_MASK) != 0);
> > #endif
> >
> > + /* enforce no unknown flag is passed by the application */
> > + if ((flags & ~MEMPOOL_KNOWN_FLAGS) != 0) {
> > + rte_errno = EINVAL;
> > + return NULL;
> > + }
> > +
>
> I think it is better to check arguments in parameters order.
> So, it is a bit better to move the check to happen after
> cache_size validation below.
Sounds reasonable, for v2.
On 12/10/2021 08:28, David Marchand wrote:
> If we do not enforce valid flags are passed by an application, this
> application might face issues in the future when we add more flags.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Ray Kinsella <mdr@ashroe.eu>
On Tue, Oct 12, 2021 at 9:57 AM David Marchand
<david.marchand@redhat.com> wrote:
>
> On Tue, Oct 12, 2021 at 9:49 AM Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru> wrote:
> >
> > On 10/12/21 10:28 AM, David Marchand wrote:
> > > If we do not enforce valid flags are passed by an application, this
> > > application might face issues in the future when we add more flags.
> >
> > Thanks. I'd even consider it as a bug and the fix to be
> > backported.
>
> I wondered too when writing the patch.
> I'd like to hear from others.
Backporting risks breaking existing applications which were validated
with potentially invalid flags.
So I won't mark it for backport.
I'll send v2 wrt to your other comment.
Thanks Andrew.
@@ -205,6 +205,24 @@ static int test_mempool_creation_with_exceeded_cache_size(void)
return 0;
}
+static int test_mempool_creation_with_unknown_flag(void)
+{
+ struct rte_mempool *mp_cov;
+
+ mp_cov = rte_mempool_create("test_mempool_unknown_flag", MEMPOOL_SIZE,
+ MEMPOOL_ELT_SIZE, 0, 0,
+ NULL, NULL,
+ NULL, NULL,
+ SOCKET_ID_ANY, MEMPOOL_F_NO_IOVA_CONTIG << 1);
+
+ if (mp_cov != NULL) {
+ rte_mempool_free(mp_cov);
+ RET_ERR();
+ }
+
+ return 0;
+}
+
static struct rte_mempool *mp_spsc;
static rte_spinlock_t scsp_spinlock;
static void *scsp_obj_table[MAX_KEEP];
@@ -635,6 +653,9 @@ test_mempool(void)
if (test_mempool_creation_with_exceeded_cache_size() < 0)
GOTO_ERR(ret, err);
+ if (test_mempool_creation_with_unknown_flag() < 0)
+ GOTO_ERR(ret, err);
+
if (test_mempool_same_name_twice_creation() < 0)
GOTO_ERR(ret, err);
@@ -777,6 +777,13 @@ rte_mempool_cache_free(struct rte_mempool_cache *cache)
rte_free(cache);
}
+#define MEMPOOL_KNOWN_FLAGS ( MEMPOOL_F_NO_SPREAD \
+ | MEMPOOL_F_NO_CACHE_ALIGN \
+ | MEMPOOL_F_SP_PUT \
+ | MEMPOOL_F_SC_GET \
+ | MEMPOOL_F_POOL_CREATED \
+ | MEMPOOL_F_NO_IOVA_CONTIG \
+ )
/* create an empty mempool */
struct rte_mempool *
rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
@@ -806,6 +813,12 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
RTE_CACHE_LINE_MASK) != 0);
#endif
+ /* enforce no unknown flag is passed by the application */
+ if ((flags & ~MEMPOOL_KNOWN_FLAGS) != 0) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
+
mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
/* asked for zero items */
@@ -996,7 +996,7 @@ typedef void (rte_mempool_ctor_t)(struct rte_mempool *, void *);
* with rte_errno set appropriately. Possible rte_errno values include:
* - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
* - E_RTE_SECONDARY - function was called from a secondary process instance
- * - EINVAL - cache size provided is too large
+ * - EINVAL - cache size provided is too large or an unknown flag was passed
* - ENOSPC - the maximum number of memzones has already been allocated
* - EEXIST - a memzone with the same name already exists
* - ENOMEM - no appropriate memory area found in which to create memzone