From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from zyc-PC.local (unknown [119.61.11.228]) by dpdk.org (Postfix) with SMTP id 9A1421BC44; Wed, 11 Apr 2018 14:34:49 +0200 (CEST) Date: Wen, 11 Apr 2018 20:34:41 +0800 From: Yangchao Zhou CC: ferruh.yigit@intel.com;stable@dpdk.org Sender: Yangchao Zhou To: dev@dpdk.org; Message-ID: <2191a738-7443-464e-8600-eedcaf160593@zyc-PC.local> X-Mailer: TortoiseGit MIME-Version: 1.0 Content-Type: text/plain; Subject: [dpdk-dev] [PATCH v2] kni: fix possible rx_q mbuf leak and speed up alloc_q release X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Apr 2018 12:34:51 -0000 >>From 3293d014123150bcd0650ce1d09b19bbb9eae9c4 Mon Sep 17 00:00:00 2001 From: zhouyangchao Date: Tue, 10 Apr 2018 18:26:35 +0800 Subject: [PATCH] kni: fix possible rx_q mbuf leak and speed up alloc_q release 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. Signed-off-by: Yangchao Zhou Suggested-by: Ferruh Yigit --- 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(+) 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 @@ kni_dev_remove(struct kni_dev *dev) 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..1d64d78 100644 --- a/kernel/linux/kni/kni_net.c +++ b/kernel/linux/kni/kni_net.c @@ -163,6 +163,46 @@ kni_net_release(struct net_device *dev) 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_fq, num_rx; + void *kva; + do { + num_fq = kni_fifo_free_count(kni->free_q); + if (num_fq == 0) + return; + + num_rx = min_t(uint32_t, num_fq, 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) */ -- 2.9.0.windows.1