On Wed, Jul 15, 2026 at 11:12:59AM -0400, Kishore Padmanabha wrote:
>    On Wed, Jul 15, 2026 at 5:02 AM Morten Brørup
>    <[1][email protected]> wrote:
> 
>      > From: fengchengwen [mailto:[2][email protected]]
>      > Sent: Wednesday, 15 July 2026 10.12
>      >
>      > On 7/15/2026 4:08 AM, Morten Brørup wrote:
>      > > Hi Kishore,
>      > >
>      > > For your testing purposes, please follow the guidance provided
>      to
>      > Wisam Jaddo:
>      > >
>      >
>      [3]https://inbox.dpdk.org/dev/98CBD80474FA8B44BF855DF32C47DC35F65964
>      @smart
>      > [4]server.smartshare.dk/
>      >
>      > We need to recompile in this case. We should try to avoid
>      > recompilation.
>      > I think it is necessary to adjust RTE_MEMPOOL_CACHE_MAX_SIZE to
>      768 as
>      > a default configuration.
>      Changing RTE_MEMPOOL_CACHE_MAX_SIZE breaks both the API and the ABI;
>      so it has to be done when building locally, where API/ABI breakage
>      is acceptable.
>      For DPDK 26.11, where API/ABI breakage is acceptable, we can discuss
>      increasing the default from 512 to a higher value. I do have some
>      input to that discussion, but let's postpone it until after DPDK
>      26.07 has been released.
> 
>    We should increase this value to avoid performance degradation, as
>    users may not realize they need to change it.  We do not have do it
>    right away for 26.07 release but we should it right after the
>    release.
> 

Out of interest, does adjusting the 50% fill/flush threshold to be a 75%
one, i.e. fill to 75% rather than 50%, flush to 25% rather than 50%, help at
all? Draft patch below, can you test it quickly, perhaps?

/Bruce

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 50d958c7c6..2526a23903 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -1417,6 +1417,7 @@ rte_mempool_do_generic_put(struct rte_mempool *mp, void * 
const *obj_table,
                           unsigned int n, struct rte_mempool_cache *cache)
 {
        void **cache_objs;
+       uint32_t quarter, flush;
 
        /* No cache provided? */
        if (unlikely(cache == NULL))
@@ -1426,30 +1427,39 @@ rte_mempool_do_generic_put(struct rte_mempool *mp, void 
* const *obj_table,
        RTE_MEMPOOL_CACHE_STAT_ADD(cache, put_bulk, 1);
        RTE_MEMPOOL_CACHE_STAT_ADD(cache, put_objs, n);
 
+       /* A quarter (25%) of the cache size, computed with a shift to avoid
+        * a divide. Draining the cache down to this level on overflow leaves
+        * room for a burst of up to (size - quarter), i.e. three quarters
+        * (75%), of the cache size.
+        */
+       quarter = cache->size >> 2;
+
        __rte_assume(cache->size <= RTE_MEMPOOL_CACHE_MAX_SIZE);
-       __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
+       __rte_assume(quarter <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
        __rte_assume(cache->len <= RTE_MEMPOOL_CACHE_MAX_SIZE);
        __rte_assume(cache->len <= cache->size);
        if (likely(cache->len + n <= cache->size)) {
                /* Sufficient room in the cache for the objects. */
                cache_objs = &cache->objs[cache->len];
                cache->len += n;
-       } else if (n <= cache->size / 2) {
+       } else if (n <= cache->size - quarter) {
                /*
                 * The number of objects is within the cache bounce buffer 
limit,
                 * but - as detected by the comparison above - the cache has
                 * insufficient room for them.
                 * Flush the cache to the backend to make room for the objects;
-                * flush (size / 2) objects from the bottom of the cache, where
-                * objects are less hot, and move down the remaining objects, 
which
-                * are more hot, from the upper half of the cache.
+                * flush objects from the bottom of the cache, where objects are
+                * less hot, draining it down to a quarter (25%) of its size, 
and
+                * move down the remaining quarter of objects, which are more 
hot,
+                * from the upper part of the cache.
                 */
-               __rte_assume(cache->len > cache->size / 2);
-               rte_mempool_ops_enqueue_bulk(mp, &cache->objs[0], cache->size / 
2);
-               rte_memcpy(&cache->objs[0], &cache->objs[cache->size / 2],
-                               sizeof(void *) * (cache->len - cache->size / 
2));
-               cache_objs = &cache->objs[cache->len - cache->size / 2];
-               cache->len = cache->len - cache->size / 2 + n;
+               __rte_assume(cache->len > quarter);
+               flush = cache->len - quarter;
+               rte_mempool_ops_enqueue_bulk(mp, &cache->objs[0], flush);
+               rte_memcpy(&cache->objs[0], &cache->objs[flush],
+                               sizeof(void *) * quarter);
+               cache_objs = &cache->objs[quarter];
+               cache->len = quarter + n;
        } else {
                /* The request itself is too big for the cache. */
                goto driver_enqueue_stats_incremented;
@@ -1557,6 +1567,7 @@ rte_mempool_do_generic_get(struct rte_mempool *mp, void 
**obj_table,
        int ret;
        unsigned int remaining;
        uint32_t index, len;
+       uint32_t quarter, fill;
        void **cache_objs;
 
        /* No cache provided? */
@@ -1592,13 +1603,23 @@ rte_mempool_do_generic_get(struct rte_mempool *mp, void 
**obj_table,
        for (index = 0; index < len; index++)
                *obj_table++ = *--cache_objs;
 
+       /* A quarter (25%) of the cache size, computed with a shift to avoid
+        * a divide; 'fill' is the complementary three quarters (75%), which
+        * is the amount fetched from the backend to fill the cache up to 75%,
+        * and also the burst limit for this bounce buffer (since the cache
+        * was just fully drained above, up to 'fill' objects can be filled
+        * and handed back to the caller in one go).
+        */
+       quarter = cache->size >> 2;
+       fill = cache->size - quarter;
+
        /* Dequeue below would exceed the cache bounce buffer limit? */
-       __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
-       if (unlikely(remaining > cache->size / 2))
+       __rte_assume(fill <= RTE_MEMPOOL_CACHE_MAX_SIZE);
+       if (unlikely(remaining > fill))
                goto driver_dequeue;
 
-       /* Fill the cache from the backend; fetch (size / 2) objects. */
-       ret = rte_mempool_ops_dequeue_bulk(mp, cache->objs, cache->size / 2);
+       /* Fill the cache from the backend, up to 75% of its size. */
+       ret = rte_mempool_ops_dequeue_bulk(mp, cache->objs, fill);
        if (unlikely(ret < 0)) {
                /*
                 * We are buffer constrained, and not able to fetch all that.
@@ -1612,11 +1633,10 @@ rte_mempool_do_generic_get(struct rte_mempool *mp, void 
**obj_table,
        RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_bulk, 1);
        RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_objs, n);
 
-       __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
-       __rte_assume(remaining <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
-       __rte_assume(remaining <= cache->size / 2);
-       cache_objs = &cache->objs[cache->size / 2];
-       cache->len = cache->size / 2 - remaining;
+       __rte_assume(fill <= RTE_MEMPOOL_CACHE_MAX_SIZE);
+       __rte_assume(remaining <= fill);
+       cache_objs = &cache->objs[fill];
+       cache->len = fill - remaining;
        for (index = 0; index < remaining; index++)
                *obj_table++ = *--cache_objs;

Reply via email to