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
