The packet pool may run out of blocks before reaching the low buffer
watermark. A block low watermark is added to fix it.

Signed-off-by: Oriol Arcas <[email protected]>
---
 platform/linux-generic/include/odp_pool_internal.h | 21 +++++++++++++++++++--
 platform/linux-generic/odp_pool.c                  |  9 +++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/platform/linux-generic/include/odp_pool_internal.h 
b/platform/linux-generic/include/odp_pool_internal.h
index 6832b31..0940c87 100644
--- a/platform/linux-generic/include/odp_pool_internal.h
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -121,6 +121,7 @@ struct pool_entry_s {
        } flags;
        uint32_t                quiesced;
        uint32_t                low_wm_assert;
+       uint32_t                blk_low_wm_assert;
        uint8_t                *pool_base_addr;
        uint8_t                *pool_mdata_addr;
        size_t                  pool_size;
@@ -136,6 +137,8 @@ struct pool_entry_s {
        uint32_t                blk_size;
        uint32_t                high_wm;
        uint32_t                low_wm;
+       uint32_t                blk_high_wm;
+       uint32_t                blk_low_wm;
        uint32_t                headroom;
        uint32_t                tailroom;
 
@@ -171,7 +174,14 @@ static inline void *get_blk(struct pool_entry_s *pool)
        } else {
                pool->blk_freelist = ((odp_buf_blk_t *)myhead)->next;
                POOL_UNLOCK(&pool->blk_lock);
-               odp_atomic_dec_u32(&pool->blkcount);
+               uint64_t blkcount = odp_atomic_fetch_sub_u32(&pool->blkcount, 
1) - 1;
+
+               /* Check for low watermark condition */
+               if (blkcount == pool->blk_low_wm && !pool->blk_low_wm_assert) {
+                       pool->blk_low_wm_assert = 1;
+                       /* stats here? */
+               }
+
                odp_atomic_inc_u64(&pool->poolstats.blkallocs);
        }
 
@@ -187,7 +197,14 @@ static inline void ret_blk(struct pool_entry_s *pool, void 
*block)
 
        POOL_UNLOCK(&pool->blk_lock);
 
-       odp_atomic_inc_u32(&pool->blkcount);
+       uint64_t blkcount = odp_atomic_fetch_add_u32(&pool->blkcount, 1);
+
+       /* Check if low watermark condition should be deasserted */
+       if (blkcount == pool->blk_high_wm && pool->blk_low_wm_assert) {
+               pool->blk_low_wm_assert = 0;
+               /* stats here? */
+       }
+
        odp_atomic_inc_u64(&pool->poolstats.blkfrees);
 }
 
diff --git a/platform/linux-generic/odp_pool.c 
b/platform/linux-generic/odp_pool.c
index eb545b2..ac29121 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/odp_pool.c
@@ -176,7 +176,7 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
        /* Restriction for v1.0: No zeroization support */
        const int zeroized = 0;
 
-       uint32_t blk_size, buf_stride, buf_num, seg_len = 0;
+       uint32_t blk_size, buf_stride, buf_num, blk_num, seg_len = 0;
        uint32_t buf_align =
                params->type == ODP_POOL_BUFFER ? params->buf.align : 0;
 
@@ -382,6 +382,8 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
                                blk -= pool->s.seg_size;
                        } while (blk >= block_base_addr);
 
+               blk_num = odp_atomic_load_u32(&pool->s.blkcount);
+
                /* Initialize pool statistics counters */
                odp_atomic_store_u64(&pool->s.poolstats.bufallocs, 0);
                odp_atomic_store_u64(&pool->s.poolstats.buffrees, 0);
@@ -394,6 +396,7 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
 
                /* Reset other pool globals to initial state */
                pool->s.low_wm_assert = 0;
+               pool->s.blk_low_wm_assert = 0;
                pool->s.quiesced = 0;
                pool->s.headroom = headroom;
                pool->s.tailroom = tailroom;
@@ -401,6 +404,8 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
                /* Watermarks are hard-coded for now to control caching */
                pool->s.high_wm = buf_num / 2;
                pool->s.low_wm  = buf_num / 4;
+               pool->s.blk_high_wm = blk_num / 2;
+               pool->s.blk_low_wm = blk_num / 4;
 
                pool_hdl = pool->s.pool_hdl;
                break;
@@ -568,7 +573,7 @@ void odp_buffer_free(odp_buffer_t buf)
 
        ODP_ASSERT(buf_hdr->allocator != ODP_FREEBUF);
 
-       if (odp_unlikely(pool->s.low_wm_assert))
+       if (odp_unlikely(pool->s.low_wm_assert || pool->s.blk_low_wm_assert))
                ret_buf(&pool->s, buf_hdr);
        else
                ret_local_buf(&pool->s.local_cache[local_id], buf_hdr);
-- 
1.9.1

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to