Re: [dpdk-dev] [PATCH] kni: fix wrong mbuf alloc count in kni_allocate_mbufs
From: Ferruh Yigit <hidden>
Date: 2021-06-22 07:44:10
On 6/22/2021 8:32 AM, wangyunjian wrote:
quoted
-----Original Message----- From: Ferruh Yigit [mailto:ferruh.yigit@intel.com] Sent: Monday, June 21, 2021 7:26 PM To: wangyunjian <redacted>; dev@dpdk.org Cc: liucheng (J) <redacted>; dingxiaoxiong [off-list ref] Subject: Re: [dpdk-dev] [PATCH] kni: fix wrong mbuf alloc count in kni_allocate_mbufs On 6/21/2021 4:27 AM, wangyunjian wrote:quoted
quoted
-----Original Message----- From: Ferruh Yigit [mailto:ferruh.yigit@intel.com] Sent: Friday, June 18, 2021 9:37 PM To: wangyunjian <redacted>; dev@dpdk.org Cc: liucheng (J) <redacted>; dingxiaoxiong [off-list ref] Subject: Re: [dpdk-dev] [PATCH] kni: fix wrong mbuf alloc count in kni_allocate_mbufs On 5/31/2021 1:09 PM, wangyunjian wrote:quoted
From: Yunjian Wang <redacted> In kni_allocate_mbufs(), we alloc mbuf for alloc_q as this code. allocq_free = (kni->alloc_q->read - kni->alloc_q->write - 1) \ & (MAX_MBUF_BURST_NUM - 1); The value of allocq_free maybe zero (e.g 32 & (32 - 1) = 0), and it will not fill the alloc_q. When the alloc_q's free count is zero, it will drop the packet in kernel kni.nack Both 'read' & 'write' pointers can be max 'len-1', so 'read - write - 1' can't be 'len'. For above example first part can't be '32'. But if you are observing a problem, can you please describe it a little more, it may be because of something else.The ring size is 1024. After init, write = read = 0. Then we fill kni->alloc_q tofull. At this time, write = 1023, read = 0.quoted
Then the kernel send 32 packets to userspace. At this time, write = 1023,read = 32.quoted
And then the userspace recieve this 32 packets. Then fill the kni->alloc_q, (32- 1023 - 1)&31 = 0, fill nothing.quoted
... Then the kernel send 32 packets to userspace. At this time, write = 1023,read = 992.quoted
And then the userspace recieve this 32 packets. Then fill the kni->alloc_q,(992 - 1023 - 1)&31 = 0, fill nothing.quoted
Then the kernel send 32 packets to userspace. The kni->alloc_q only has 31mbufs and will drop one packet.quoted
Absolutely, this is a special scene. Normally, it will fill some mbufs everytime,but may not enough for the kernel to use.quoted
In this patch, we always keep the kni->alloc_q to full for the kernel to use.I see now, yes it is technically possible to have above scenario and it can cause glitch in the datapath. Below fix looks good, +1 to use 'kni_fifo_free_count()' instead of calculation within the function which may be wrong for the 'RTE_USE_C11_MEM_MODEL' case.I compiled them on the ARM and x86 platforms with the 'RTE_USE_C11_MEM_MODEL' case, and no error is reported.
May not be build error, but in 'RTE_USE_C11_MEM_MODEL' case 'read'/'write' are not volatile and need to read them via C11 atomic instructions. 'allocq_free' calculation in the 'kni_allocate_mbufs()' doesn't do that, that is why better to replace calculation with 'kni_fifo_free_count()'.
quoted
Can you please add fixes line too?OK, will include it in next version.
Thanks.
Thanksquoted
quoted
Thanksquoted
quoted
In this patch, we set the allocq_free as the min between MAX_MBUF_BURST_NUM and the free count of the alloc_q. Signed-off-by: Cheng Liu <redacted> Signed-off-by: Yunjian Wang <redacted> --- lib/kni/rte_kni.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)diff --git a/lib/kni/rte_kni.c b/lib/kni/rte_kni.c index9dae6a8d7c..20d8f20cef 100644--- a/lib/kni/rte_kni.c +++ b/lib/kni/rte_kni.c@@ -677,8 +677,9 @@ kni_allocate_mbufs(struct rte_kni *kni) return; } - allocq_free = (kni->alloc_q->read - kni->alloc_q->write - 1) - & (MAX_MBUF_BURST_NUM - 1); + allocq_free = kni_fifo_free_count(kni->alloc_q); + allocq_free = (allocq_free > MAX_MBUF_BURST_NUM) ? + MAX_MBUF_BURST_NUM : allocq_free; for (i = 0; i < allocq_free; i++) { pkts[i] = rte_pktmbuf_alloc(kni->pktmbuf_pool); if (unlikely(pkts[i] == NULL)) {