From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yangchao Zhou Subject: [PATCH v4] kni: fix possible rx_q mbuf leaks and speed up alloc_q release Date: Thu, 19 Apr 2018 11:12:20 +0800 Message-ID: <1524107540-11544-1-git-send-email-zhouyates@gmail.com> References: <9a57896f-a2db-7f4b-f5c4-cf04970f1636@intel.com> Cc: stable@dpdk.org, ferruh.yigit@intel.com, thomas@monjalon.net To: dev@dpdk.org Return-path: In-Reply-To: <9a57896f-a2db-7f4b-f5c4-cf04970f1636@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" rx_q fifo can only be released by kernel thread. There may be mbuf leaks in rx_q because kernel threads are randomly stopped. When the kni is released and netdev is unregisterd, convert the physical address mbufs in rx_q to the virtual address in free_q. By the way, alloc_q can be processed together to speed up the release rate in userspace. In my test, it is improved from 300-500ms with a mempool that has 131072 mbufs to 10ms(regardless of the specifications). Signed-off-by: Yangchao Zhou Suggested-by: Ferruh Yigit --- v4: * Add improve performance description. --- kernel/linux/kni/kni_dev.h | 1 + kernel/linux/kni/kni_misc.c | 2 ++ kernel/linux/kni/kni_net.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 0 deletions(-) diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h index c9393d8..6275ef2 100644 --- a/kernel/linux/kni/kni_dev.h +++ b/kernel/linux/kni/kni_dev.h @@ -92,6 +92,7 @@ struct kni_dev { void *alloc_va[MBUF_BURST_SZ]; }; +void kni_net_release_fifo_phy(struct kni_dev *kni); void kni_net_rx(struct kni_dev *kni); void kni_net_init(struct net_device *dev); void kni_net_config_lo_mode(char *lo_str); diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c index 01574ec..fa69f8e 100644 --- a/kernel/linux/kni/kni_misc.c +++ b/kernel/linux/kni/kni_misc.c @@ -192,6 +192,8 @@ struct kni_net { free_netdev(dev->net_dev); } + kni_net_release_fifo_phy(dev); + return 0; } diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c index 9f9b798..7fcfa10 100644 --- a/kernel/linux/kni/kni_net.c +++ b/kernel/linux/kni/kni_net.c @@ -163,6 +163,46 @@ return (ret == 0) ? req.result : ret; } +static void +kni_fifo_trans_pa2va(struct kni_dev *kni, + struct rte_kni_fifo *src_pa, struct rte_kni_fifo *dst_va) +{ + uint32_t ret, i, num_dst, num_rx; + void *kva; + do { + num_dst = kni_fifo_free_count(dst_va); + if (num_dst == 0) + return; + + num_rx = min_t(uint32_t, num_dst, MBUF_BURST_SZ); + + num_rx = kni_fifo_get(src_pa, kni->pa, num_rx); + if (num_rx == 0) + return; + + for (i = 0; i < num_rx; i++) { + kva = pa2kva(kni->pa[i]); + kni->va[i] = pa2va(kni->pa[i], kva); + } + + ret = kni_fifo_put(dst_va, kni->va, num_rx); + if (ret != num_rx) { + /* Failing should not happen */ + pr_err("Fail to enqueue entries into dst_va\n"); + return; + } + } while (1); +} + +/* Try to release mbufs when kni release */ +void kni_net_release_fifo_phy(struct kni_dev *kni) +{ + /* release rx_q first, because it can't release in userspace */ + kni_fifo_trans_pa2va(kni, kni->rx_q, kni->free_q); + /* release alloc_q for speeding up kni release in userspace */ + kni_fifo_trans_pa2va(kni, kni->alloc_q, kni->free_q); +} + /* * Configuration changes (passed on by ifconfig) */ -- 1.7.1