On 5/16/2023 11:48 AM, Yasin CANER wrote: > Coverity issue: > Bugzilla ID: 1227 > Fixes: > Cc: sta...@dpdk.org > Cc: step...@networkplumber.org > > Adding new condition to check buffer is removed or not. > it prevent allocation each time when rte_kni_rx_burst function called > that cause memory-leak. > > Signed-off-by: Yasin CANER <yasinnca...@gmail.com> > --- > lib/kni/rte_kni.c | 25 +++++++++++++++++++++---- > 1 file changed, 21 insertions(+), 4 deletions(-) > > diff --git a/lib/kni/rte_kni.c b/lib/kni/rte_kni.c > index bfa6a001ff..2244892aae 100644 > --- a/lib/kni/rte_kni.c > +++ b/lib/kni/rte_kni.c > @@ -660,7 +660,8 @@ kni_allocate_mbufs(struct rte_kni *kni) > int i, ret; > struct rte_mbuf *pkts[MAX_MBUF_BURST_NUM]; > void *phys[MAX_MBUF_BURST_NUM]; > - int allocq_free; > + int allocq_free, allocq_count; > + uint32_t allocq; > > RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pool) != > offsetof(struct rte_kni_mbuf, pool)); > @@ -682,10 +683,26 @@ kni_allocate_mbufs(struct rte_kni *kni) > RTE_LOG(ERR, KNI, "No valid mempool for allocating mbufs\n"); > return; > } > - > + /* First, getting allocation count from alloc_q. alloc_q is allocated > in this function > + * and/or kni_alloc function from mempool. > + * If alloc_q is completely removed, it shall be allocated again. > + * */ > + allocq = kni_fifo_count(kni->alloc_q); > + /* How many free allocation is possible from mempool. */ > allocq_free = kni_fifo_free_count(kni->alloc_q); > - allocq_free = (allocq_free > MAX_MBUF_BURST_NUM) ? > - MAX_MBUF_BURST_NUM : allocq_free; > + /* Allocated alloc_q count shall be max MAX_MBUF_BURST_NUM. */ > + allocq_count = MAX_MBUF_BURST_NUM - (int)allocq; > + /* Try to figure out how many allocation is possible. allocq_free is > max possible.*/ > + allocq_free = (allocq_free > MAX_MBUF_BURST_NUM )? MAX_MBUF_BURST_NUM : > allocq_free; > + /* Buffer is not removed so no need re-allocate*/ > + > + if(!allocq_count) { > + /* Buffer is not removed so no need re-allocation*/ > + return; > + } else if (allocq_free > allocq_count) { > + allocq_free = allocq_count; > + } > + > for (i = 0; i < allocq_free; i++) { > pkts[i] = rte_pktmbuf_alloc(kni->pktmbuf_pool); > if (unlikely(pkts[i] == NULL)) {
Nack, Above logic caps number of mbufs can be stored in 'kni->alloc_q' to MAX_MBUF_BURST_NUM. I can see from Bugzilla this is done based on a memory leak concern but that concern is not valid. Original logic is to keep 'kni->alloc_q' as full as possible to prevent buffer underflow for kernel side. And 'kni->alloc_q' freed when kni released, so there shouldn't be any memory leak. But some mbufs can stay in the 'kni->alloc_q' for a longer period, this needs to taken into account. I believe it is known, but let me briefly describe mbuf flow in KNI, there are four fifos shared between userspace and kernel: alloc_q, free_q, rx_q & tx_q. Userspace manages (allocs and frees) buffers, but kernel needs to able to access them that is why: Rx path: 1- userspace allocates mbufs and stores in 'alloc_q' 2- kernel gets mbuf from 'alloc_q', stores packet to mbuf and stores mbuf to 'tx_q' 3- userspace consumes mbuf from 'tx_q' Tx path: 1- userspace stores mbuf to 'rx_q' 2- kernel consumes mbuf form 'rx_q' and stores empty mbuf to 'free_q' 3- userspace gets mbuf from 'free_q' and frees it That is why userspace target is to keep 'alloc_q' fifo full and 'free_q' fifo empty to not block the kernel side. If above explanation makes sense, can you also close the Bugzilla defect please? Thanks, ferruh