diff mbox series

[ovs-dev,v15,01/15] netdev-dpdk: Serialise non-pmds mbufs' alloc/free.

Message ID 20190911080828.2087-2-michalx.obrembski@intel.com
State Superseded
Headers show
Series Support multi-segment mbufs | expand

Commit Message

Michal Obrembski Sept. 11, 2019, 8:08 a.m. UTC
From: Tiago Lam <tiago.lam@intel.com>

A new mutex, 'nonpmd_mp_mutex', has been introduced to serialise
allocation and free operations by non-pmd threads on a given mempool.

free_dpdk_buf() has been modified to make use of the introduced mutex.

Signed-off-by: Tiago Lam <tiago.lam@intel.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Flavio Leitner <fbl@sysclose.org>
Signed-off-by: Michal Obrembski <michalx.obrembski@intel.com>
---
 lib/netdev-dpdk.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

Comments

0-day Robot Sept. 11, 2019, 9:02 a.m. UTC | #1
Bleep bloop.  Greetings Obrembski, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Unexpected sign-offs from developers who are not authors or co-authors or committers: Michal Obrembski <michalx.obrembski@intel.com>
Lines checked: 85, Warnings: 1, Errors: 0


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
diff mbox series

Patch

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index bc20d68..09fd72d 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -289,6 +289,16 @@  static struct ovs_mutex dpdk_mp_mutex OVS_ACQ_AFTER(dpdk_mutex)
 static struct ovs_list dpdk_mp_list OVS_GUARDED_BY(dpdk_mp_mutex)
     = OVS_LIST_INITIALIZER(&dpdk_mp_list);
 
+/* This mutex must be used by non pmd threads when allocating or freeing
+ * mbufs through mempools, when outside of the `non_pmd_mutex` mutex, in struct
+ * dp_netdev.
+ * The reason, as pointed out in the "Known Issues" section in DPDK's EAL docs,
+ * is that the implementation on which mempool is based off is non-preemptable.
+ * Since non-pmds may end up not being pinned this could lead to the preemption
+ * between non-pmds performing operations on the same mempool, which could lead
+ * to memory corruption. */
+static struct ovs_mutex nonpmd_mp_mutex = OVS_MUTEX_INITIALIZER;
+
 struct dpdk_mp {
      struct rte_mempool *mp;
      int mtu;
@@ -468,6 +478,8 @@  struct netdev_rxq_dpdk {
     dpdk_port_t port_id;
 };
 
+static bool dpdk_thread_is_pmd(void);
+
 static void netdev_dpdk_destruct(struct netdev *netdev);
 static void netdev_dpdk_vhost_destruct(struct netdev *netdev);
 
@@ -501,6 +513,12 @@  dpdk_buf_size(int mtu)
             + RTE_PKTMBUF_HEADROOM;
 }
 
+static bool
+dpdk_thread_is_pmd(void)
+{
+     return rte_lcore_id() != NON_PMD_CORE_ID;
+}
+
 /* Allocates an area of 'sz' bytes from DPDK.  The memory is zero'ed.
  *
  * Unlike xmalloc(), this function can return NULL on failure. */
@@ -513,9 +531,18 @@  dpdk_rte_mzalloc(size_t sz)
 void
 free_dpdk_buf(struct dp_packet *p)
 {
-    struct rte_mbuf *pkt = (struct rte_mbuf *) p;
+    /* If non-pmd we need to lock on nonpmd_mp_mutex mutex */
+    if (!dpdk_thread_is_pmd()) {
+        ovs_mutex_lock(&nonpmd_mp_mutex);
+
+        rte_pktmbuf_free(&p->mbuf);
+
+        ovs_mutex_unlock(&nonpmd_mp_mutex);
+
+        return;
+    }
 
-    rte_pktmbuf_free(pkt);
+    rte_pktmbuf_free(&p->mbuf);
 }
 
 static void