mempool: fix non-IO flag inference
authorDmitry Kozlyuk <dkozlyuk@nvidia.com>
Fri, 22 Oct 2021 21:09:19 +0000 (00:09 +0300)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 25 Oct 2021 14:52:56 +0000 (16:52 +0200)
When mempool had been created with RTE_MEMPOOL_F_NO_IOVA_CONTIG flag
but later populated with valid IOVA, RTE_MEMPOOL_F_NON_IO was unset,
while it should be kept. The unit test did not catch this
because rte_mempool_populate_default() it used was populating
with RTE_BAD_IOVA.

Keep setting RTE_MEMPOOL_NON_IO at an empty mempool creation
and add an assert for it in the unit test (remove the separate case).
Do not reset the flag if RTE_MEMPOOL_F_ON_IOVA_CONTIG is set.

Fixes: 11541c5c81dd ("mempool: add non-IO flag")

Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
app/test/test_mempool.c
lib/mempool/rte_mempool.c

index 4f399b4..4b0f6b0 100644 (file)
@@ -740,16 +740,31 @@ exit:
 static int
 test_mempool_flag_non_io_set_when_no_iova_contig_set(void)
 {
+       void *virt = NULL;
+       rte_iova_t iova;
+       size_t size = MEMPOOL_ELT_SIZE * 16;
        struct rte_mempool *mp = NULL;
        int ret;
 
+       virt = rte_malloc("test_mempool", size, rte_mem_page_size());
+       RTE_TEST_ASSERT_NOT_NULL(virt, "Cannot allocate memory");
+       iova = rte_mem_virt2iova(virt);
+       RTE_TEST_ASSERT_NOT_EQUAL(iova,  RTE_BAD_IOVA, "Cannot get IOVA");
        mp = rte_mempool_create_empty("empty", MEMPOOL_SIZE,
                                      MEMPOOL_ELT_SIZE, 0, 0,
                                      SOCKET_ID_ANY, RTE_MEMPOOL_F_NO_IOVA_CONTIG);
        RTE_TEST_ASSERT_NOT_NULL(mp, "Cannot create mempool: %s",
                                 rte_strerror(rte_errno));
        rte_mempool_set_ops_byname(mp, rte_mbuf_best_mempool_ops(), NULL);
-       ret = rte_mempool_populate_default(mp);
+
+       RTE_TEST_ASSERT(mp->flags & RTE_MEMPOOL_F_NON_IO,
+                       "NON_IO flag is not set on an empty mempool");
+
+       /*
+        * Always use valid IOVA so that populate() has no other reason
+        * to infer that the mempool cannot be used for IO.
+        */
+       ret = rte_mempool_populate_iova(mp, virt, iova, size, NULL, NULL);
        RTE_TEST_ASSERT(ret > 0, "Failed to populate mempool: %s",
                        rte_strerror(-ret));
        RTE_TEST_ASSERT(mp->flags & RTE_MEMPOOL_F_NON_IO,
@@ -757,6 +772,7 @@ test_mempool_flag_non_io_set_when_no_iova_contig_set(void)
        ret = TEST_SUCCESS;
 exit:
        rte_mempool_free(mp);
+       rte_free(virt);
        return ret;
 }
 
@@ -785,6 +801,9 @@ test_mempool_flag_non_io_unset_when_populated_with_valid_iova(void)
        RTE_TEST_ASSERT_NOT_NULL(mp, "Cannot create mempool: %s",
                                 rte_strerror(rte_errno));
 
+       RTE_TEST_ASSERT(mp->flags & RTE_MEMPOOL_F_NON_IO,
+                       "NON_IO flag is not set on an empty mempool");
+
        ret = rte_mempool_populate_iova(mp, RTE_PTR_ADD(virt, 1 * block_size),
                                        RTE_BAD_IOVA, block_size, NULL, NULL);
        RTE_TEST_ASSERT(ret > 0, "Failed to populate mempool: %s",
@@ -812,28 +831,6 @@ exit:
        return ret;
 }
 
-static int
-test_mempool_flag_non_io_unset_by_default(void)
-{
-       struct rte_mempool *mp;
-       int ret;
-
-       mp = rte_mempool_create_empty("empty", MEMPOOL_SIZE,
-                                     MEMPOOL_ELT_SIZE, 0, 0,
-                                     SOCKET_ID_ANY, 0);
-       RTE_TEST_ASSERT_NOT_NULL(mp, "Cannot create mempool: %s",
-                                rte_strerror(rte_errno));
-       ret = rte_mempool_populate_default(mp);
-       RTE_TEST_ASSERT_EQUAL(ret, (int)mp->size, "Failed to populate mempool: %s",
-                             rte_strerror(-ret));
-       RTE_TEST_ASSERT(!(mp->flags & RTE_MEMPOOL_F_NON_IO),
-                       "NON_IO flag is set by default");
-       ret = TEST_SUCCESS;
-exit:
-       rte_mempool_free(mp);
-       return ret;
-}
-
 #pragma pop_macro("RTE_TEST_TRACE_FAILURE")
 
 static int
@@ -1022,8 +1019,6 @@ test_mempool(void)
                GOTO_ERR(ret, err);
 
        /* test NON_IO flag inference */
-       if (test_mempool_flag_non_io_unset_by_default() < 0)
-               GOTO_ERR(ret, err);
        if (test_mempool_flag_non_io_set_when_no_iova_contig_set() < 0)
                GOTO_ERR(ret, err);
        if (test_mempool_flag_non_io_unset_when_populated_with_valid_iova() < 0)
index 2d915e5..c5a699b 100644 (file)
@@ -373,8 +373,8 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
        STAILQ_INSERT_TAIL(&mp->mem_list, memhdr, next);
        mp->nb_mem_chunks++;
 
-       /* At least some objects in the pool can now be used for IO. */
-       if (iova != RTE_BAD_IOVA)
+       /* Check if at least some objects in the pool are now usable for IO. */
+       if (!(mp->flags & RTE_MEMPOOL_F_NO_IOVA_CONTIG) && iova != RTE_BAD_IOVA)
                mp->flags &= ~RTE_MEMPOOL_F_NON_IO;
 
        /* Report the mempool as ready only when fully populated. */