patches for DPDK stable branches
 help / color / mirror / Atom feed
From: Yongseok Koh <yskoh@mellanox.com>
To: yliu@fridaylinux.org
Cc: stable@dpdk.org, shahafs@mellanox.com,
	adrien.mazarguil@6wind.com, nelio.laranjeiro@6wind.com,
	Xueming Li <xuemingl@mellanox.com>
Subject: [dpdk-stable] [PATCH 10/67] net/mlx5: map UAR address around huge pages
Date: Mon,  4 Jun 2018 17:10:32 -0700	[thread overview]
Message-ID: <20180605001129.13184-11-yskoh@mellanox.com> (raw)
In-Reply-To: <20180605001129.13184-1-yskoh@mellanox.com>

From: Xueming Li <xuemingl@mellanox.com>

[ backported from upstream commit 4a984153430cbdafe2b971e999bba8d96610b299 ]

Reserving the memory space for the UAR near huge pages helps to
**reduce** the cases where the secondary process cannot start. Those
pages being physical pages they must be mapped at the same virtual
address as in the primary process to have a
working secondary process.

As this remap is almost the latest being done by the processes
(libraries, heaps, stacks are already loaded), similar to huge pages,
there is **no guarantee** this mechanism will always work.

Signed-off-by: Xueming Li <xuemingl@mellanox.com>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/mlx5.c         | 114 ++++++++++++++++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5.h         |   1 +
 drivers/net/mlx5/mlx5_defs.h    |  10 ++++
 drivers/net/mlx5/mlx5_rxtx.h    |   3 +-
 drivers/net/mlx5/mlx5_trigger.c |   7 ++-
 drivers/net/mlx5/mlx5_txq.c     |  51 +++++++++++++-----
 6 files changed, 167 insertions(+), 19 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 16ba5b724..7dc3dc399 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -39,6 +39,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <net/if.h>
+#include <sys/mman.h>
 
 /* Verbs header. */
 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
@@ -56,6 +57,7 @@
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
 #include <rte_common.h>
+#include <rte_eal_memconfig.h>
 #include <rte_kvargs.h>
 
 #include "mlx5.h"
@@ -496,6 +498,106 @@ mlx5_args(struct mlx5_args *args, struct rte_devargs *devargs)
 
 static struct rte_pci_driver mlx5_driver;
 
+/*
+ * Reserved UAR address space for TXQ UAR(hw doorbell) mapping, process
+ * local resource used by both primary and secondary to avoid duplicate
+ * reservation.
+ * The space has to be available on both primary and secondary process,
+ * TXQ UAR maps to this area using fixed mmap w/o double check.
+ */
+static void *uar_base;
+
+/**
+ * Reserve UAR address space for primary process.
+ *
+ * @param[in] priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   0 on success, errno value on failure.
+ */
+static int
+priv_uar_init_primary(struct priv *priv)
+{
+	void *addr = (void *)0;
+	int i;
+	const struct rte_mem_config *mcfg;
+	int ret;
+
+	if (uar_base) { /* UAR address space mapped. */
+		priv->uar_base = uar_base;
+		return 0;
+	}
+	/* find out lower bound of hugepage segments */
+	mcfg = rte_eal_get_configuration()->mem_config;
+	for (i = 0; i < RTE_MAX_MEMSEG && mcfg->memseg[i].addr; i++) {
+		if (addr)
+			addr = RTE_MIN(addr, mcfg->memseg[i].addr);
+		else
+			addr = mcfg->memseg[i].addr;
+	}
+	/* keep distance to hugepages to minimize potential conflicts. */
+	addr = RTE_PTR_SUB(addr, MLX5_UAR_OFFSET + MLX5_UAR_SIZE);
+	/* anonymous mmap, no real memory consumption. */
+	addr = mmap(addr, MLX5_UAR_SIZE,
+		    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if (addr == MAP_FAILED) {
+		ERROR("Failed to reserve UAR address space, please adjust "
+		      "MLX5_UAR_SIZE or try --base-virtaddr");
+		ret = ENOMEM;
+		return ret;
+	}
+	/* Accept either same addr or a new addr returned from mmap if target
+	 * range occupied.
+	 */
+	INFO("Reserved UAR address space: %p", addr);
+	priv->uar_base = addr; /* for primary and secondary UAR re-mmap. */
+	uar_base = addr; /* process local, don't reserve again. */
+	return 0;
+}
+
+/**
+ * Reserve UAR address space for secondary process, align with
+ * primary process.
+ *
+ * @param[in] priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   0 on success, errno value on failure.
+ */
+static int
+priv_uar_init_secondary(struct priv *priv)
+{
+	void *addr;
+	int ret;
+
+	assert(priv->uar_base);
+	if (uar_base) { /* already reserved. */
+		assert(uar_base == priv->uar_base);
+		return 0;
+	}
+	/* anonymous mmap, no real memory consumption. */
+	addr = mmap(priv->uar_base, MLX5_UAR_SIZE,
+		    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if (addr == MAP_FAILED) {
+		ERROR("UAR mmap failed: %p size: %llu",
+		      priv->uar_base, MLX5_UAR_SIZE);
+		ret = ENXIO;
+		return ret;
+	}
+	if (priv->uar_base != addr) {
+		ERROR("UAR address %p size %llu occupied, please adjust "
+		      "MLX5_UAR_OFFSET or try EAL parameter --base-virtaddr",
+		      priv->uar_base, MLX5_UAR_SIZE);
+		ret = ENXIO;
+		return ret;
+	}
+	uar_base = addr; /* process local, don't reserve again */
+	INFO("Reserved UAR address space: %p", addr);
+	return 0;
+}
+
 /**
  * Assign parameters from args into priv, only non default
  * values are considered.
@@ -710,6 +812,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			eth_dev->device = &pci_dev->device;
 			eth_dev->dev_ops = &mlx5_dev_sec_ops;
 			priv = eth_dev->data->dev_private;
+			err = priv_uar_init_secondary(priv);
+			if (err < 0) {
+				err = -err;
+				goto error;
+			}
 			/* Receive command fd from primary process */
 			err = priv_socket_connect(priv);
 			if (err < 0) {
@@ -718,10 +825,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			}
 			/* Remap UAR for Tx queues. */
 			err = priv_tx_uar_remap(priv, err);
-			if (err < 0) {
-				err = -err;
+			if (err)
 				goto error;
-			}
 			priv_dev_select_rx_function(priv, eth_dev);
 			priv_dev_select_tx_function(priv, eth_dev);
 			continue;
@@ -883,6 +988,9 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			WARN("Rx CQE compression isn't supported");
 			priv->cqe_comp = 0;
 		}
+		err = priv_uar_init_primary(priv);
+		if (err)
+			goto port_error;
 		/* Configure the first MAC address by default. */
 		if (priv_get_mac(priv, &mac.addr_bytes)) {
 			ERROR("cannot get MAC address, is mlx5_en loaded?"
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 004e83670..8f49cecc8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -166,6 +166,7 @@ struct priv {
 	struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
 	rte_spinlock_t lock; /* Lock for control functions. */
 	int primary_socket; /* Unix socket for primary process. */
+	void *uar_base; /* Reserved address space for UAR mapping */
 	struct rte_intr_handle intr_handle_socket; /* Interrupt handler. */
 	struct mlx5_verbs_alloc_ctx verbs_alloc_ctx;
 	/* Context for Verbs allocator. */
diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h
index 24caf7e79..9c740f5e1 100644
--- a/drivers/net/mlx5/mlx5_defs.h
+++ b/drivers/net/mlx5/mlx5_defs.h
@@ -113,4 +113,14 @@
 /* Maximum number of attempts to query link status before giving up. */
 #define MLX5_MAX_LINK_QUERY_ATTEMPTS 5
 
+/* Reserved address space for UAR mapping. */
+#define MLX5_UAR_SIZE (1ULL << 32)
+
+/* Offset of reserved UAR address space to hugepage memory. Offset is used here
+ * to minimize possibility of address next to hugepage being used by other code
+ * in either primary or secondary process, failing to map TX UAR would make TX
+ * packets invisible to HW.
+ */
+#define MLX5_UAR_OFFSET (1ULL << 32)
+
 #endif /* RTE_PMD_MLX5_DEFS_H_ */
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index e35a6ab34..28761c299 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -204,7 +204,7 @@ struct mlx5_txq_data {
 	volatile void *wqes; /* Work queue (use volatile to write into). */
 	volatile uint32_t *qp_db; /* Work queue doorbell. */
 	volatile uint32_t *cq_db; /* Completion queue doorbell. */
-	volatile void *bf_reg; /* Blueflame register. */
+	volatile void *bf_reg; /* Blueflame register remapped. */
 	struct mlx5_mr *mp2mr[MLX5_PMD_TX_MP_CACHE]; /* MR translation table. */
 	struct rte_mbuf *(*elts)[]; /* TX elements. */
 	struct mlx5_txq_stats stats; /* TX queue counters. */
@@ -229,6 +229,7 @@ struct mlx5_txq_ctrl {
 	struct mlx5_txq_ibv *ibv; /* Verbs queue object. */
 	struct mlx5_txq_data txq; /* Data path structure. */
 	off_t uar_mmap_offset; /* UAR mmap offset for non-primary process. */
+	volatile void *bf_reg_orig; /* Blueflame register from verbs. */
 };
 
 /* mlx5_rxq.c */
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index d682ea2c9..da9494eb8 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -76,10 +76,13 @@ priv_txq_start(struct priv *priv)
 			goto error;
 		}
 	}
-	return -ret;
+	ret = priv_tx_uar_remap(priv, priv->ctx->cmd_fd);
+	if (ret)
+		goto error;
+	return ret;
 error:
 	priv_txq_stop(priv);
-	return -ret;
+	return ret;
 }
 
 static void
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 12f258bbb..f39b98a9a 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -217,7 +217,9 @@ mlx5_tx_queue_release(void *dpdk_txq)
 
 
 /**
- * Map locally UAR used in Tx queues for BlueFlame doorbell.
+ * Mmap TX UAR(HW doorbell) pages into reserved UAR address space.
+ * Both primary and secondary process do mmap to make UAR address
+ * aligned.
  *
  * @param[in] priv
  *   Pointer to private structure.
@@ -234,11 +236,14 @@ priv_tx_uar_remap(struct priv *priv, int fd)
 	uintptr_t pages[priv->txqs_n];
 	unsigned int pages_n = 0;
 	uintptr_t uar_va;
+	uintptr_t off;
 	void *addr;
+	void *ret;
 	struct mlx5_txq_data *txq;
 	struct mlx5_txq_ctrl *txq_ctrl;
 	int already_mapped;
 	size_t page_size = sysconf(_SC_PAGESIZE);
+	int r;
 
 	memset(pages, 0, priv->txqs_n * sizeof(uintptr_t));
 	/*
@@ -251,8 +256,10 @@ priv_tx_uar_remap(struct priv *priv, int fd)
 			continue;
 		txq = (*priv->txqs)[i];
 		txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);
-		uar_va = (uintptr_t)txq_ctrl->txq.bf_reg;
-		uar_va = RTE_ALIGN_FLOOR(uar_va, page_size);
+		/* UAR addr form verbs used to find dup and offset in page. */
+		uar_va = (uintptr_t)txq_ctrl->bf_reg_orig;
+		off = uar_va & (page_size - 1); /* offset in page. */
+		uar_va = RTE_ALIGN_FLOOR(uar_va, page_size); /* page addr. */
 		already_mapped = 0;
 		for (j = 0; j != pages_n; ++j) {
 			if (pages[j] == uar_va) {
@@ -260,16 +267,30 @@ priv_tx_uar_remap(struct priv *priv, int fd)
 				break;
 			}
 		}
-		if (already_mapped)
-			continue;
-		pages[pages_n++] = uar_va;
-		addr = mmap((void *)uar_va, page_size,
-			    PROT_WRITE, MAP_FIXED | MAP_SHARED, fd,
-			    txq_ctrl->uar_mmap_offset);
-		if (addr != (void *)uar_va) {
-			ERROR("call to mmap failed on UAR for txq %d\n", i);
-			return -1;
+		/* new address in reserved UAR address space. */
+		addr = RTE_PTR_ADD(priv->uar_base,
+				   uar_va & (MLX5_UAR_SIZE - 1));
+		if (!already_mapped) {
+			pages[pages_n++] = uar_va;
+			/* fixed mmap to specified address in reserved
+			 * address space.
+			 */
+			ret = mmap(addr, page_size,
+				   PROT_WRITE, MAP_FIXED | MAP_SHARED, fd,
+				   txq_ctrl->uar_mmap_offset);
+			if (ret != addr) {
+				/* fixed mmap have to return same address */
+				ERROR("call to mmap failed on UAR for txq %d\n",
+				      i);
+				r = ENXIO;
+				return r;
+			}
 		}
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY) /* save once */
+			txq_ctrl->txq.bf_reg = RTE_PTR_ADD((void *)addr, off);
+		else
+			assert(txq_ctrl->txq.bf_reg ==
+			       RTE_PTR_ADD((void *)addr, off));
 	}
 	return 0;
 }
@@ -416,7 +437,7 @@ mlx5_priv_txq_ibv_new(struct priv *priv, uint16_t idx)
 	txq_data->wqes = qp.sq.buf;
 	txq_data->wqe_n = log2above(qp.sq.wqe_cnt);
 	txq_data->qp_db = &qp.dbrec[MLX5_SND_DBR];
-	txq_data->bf_reg = qp.bf.reg;
+	txq_ctrl->bf_reg_orig = qp.bf.reg;
 	txq_data->cq_db = cq_info.dbrec;
 	txq_data->cqes =
 		(volatile struct mlx5_cqe (*)[])
@@ -717,6 +738,7 @@ mlx5_priv_txq_release(struct priv *priv, uint16_t idx)
 {
 	unsigned int i;
 	struct mlx5_txq_ctrl *txq;
+	size_t page_size = sysconf(_SC_PAGESIZE);
 
 	if (!(*priv->txqs)[idx])
 		return 0;
@@ -736,6 +758,9 @@ mlx5_priv_txq_release(struct priv *priv, uint16_t idx)
 			txq->txq.mp2mr[i] = NULL;
 		}
 	}
+	if (priv->uar_base)
+		munmap((void *)RTE_ALIGN_FLOOR((uintptr_t)txq->txq.bf_reg,
+		       page_size), page_size);
 	if (rte_atomic32_dec_and_test(&txq->refcnt)) {
 		txq_free_elts(txq);
 		LIST_REMOVE(txq, next);
-- 
2.11.0

  parent reply	other threads:[~2018-06-05  0:12 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-05  0:10 [dpdk-stable] [PATCH 00/67] net/mlx5: backport patches for v17.11.3 LTS Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 01/67] net/mlx5: remove get priv internal function Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 02/67] net/mlx4: store RSS hash result in mbufs Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 03/67] net/mlx5: fix synchronization on polling Rx completions Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 04/67] net/mlx5: fix allocation when no memory on device NUMA node Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 05/67] net/mlx5: fix flow director conversion Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 06/67] net/mlx5: fix reception of multiple MAC addresses Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 07/67] net/mlx5: fix secondary process mempool registration Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 08/67] net/mlx5: remove assert un-accessible from secondary process Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 09/67] net/mlx5: warn for unsuccessful memory registration Yongseok Koh
2018-06-05  0:10 ` Yongseok Koh [this message]
2018-06-05  0:10 ` [dpdk-stable] [PATCH 11/67] net/mlx4: fix single port configuration Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 12/67] net/mlx4: fix broadcast Rx Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 13/67] net/mlx4: fix removal detection of stopped port Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 14/67] net/mlx5: fix CRC strip capability query Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 15/67] net/mlx5: fix close after start failure Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 16/67] net/mlx: control netdevices through ioctl only Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 17/67] net/mlx5: fix disabling Tx packet inlining Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 18/67] net/mlx5: fix sriov flag Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 19/67] net/mlx5: name parameters in function prototypes Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 20/67] net/mlx5: mark parameters with unused attribute Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 21/67] net/mlx5: normalize function prototypes Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 22/67] net/mlx5: add missing function documentation Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 23/67] net/mlx5: remove useless empty lines Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 24/67] net/mlx5: remove control path locks Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 25/67] net/mlx5: prefix all functions with mlx5 Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 26/67] net/mlx5: change non failing function return values Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 27/67] net/mlx5: standardize on negative errno values Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 28/67] net/mlx5: use port id in PMD log Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 29/67] net/mlx5: use dynamic logging Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 30/67] net/mlx5: remove kernel version check Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 31/67] net/mlx5: change pkt burst select function prototype Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 32/67] net/mlx5: fix link status behavior Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 33/67] net/mlx5: fix link status to use wait to complete Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 34/67] net/mlx5: change tunnel flow priority Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 35/67] net/mlx5: improve flow error explanation Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 36/67] net/mlx5: refuse empty VLAN flow specification Yongseok Koh
2018-06-05  0:10 ` [dpdk-stable] [PATCH 37/67] net/mlx5: fix icc build Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 38/67] net/mlx5: setup RSS regardless of queue count Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 39/67] net/mlx5: enforce RSS key length limitation Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 40/67] net/mlx5: fix RSS key length query Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 41/67] net/mlx4: fix a typo in header file Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 42/67] net/mlx5: remove 32-bit support Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 43/67] net/mlx5: remove excessive data prefetch Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 44/67] net/mlx5: fix link status initialization Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 45/67] net/mlx4: fix RSS resource leak in case of error Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 46/67] net/mlx5: fix RSS flow action bounds check Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 47/67] net/mlx5: fix invalid flow item check Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 48/67] net/mlx5: split L3/L4 in flow director Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 49/67] net/mlx5: fix flow director mask Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 50/67] net/mlx5: fix flow director rule deletion crash Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 51/67] net/mlx4: fix Rx resource leak in case of error Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 52/67] net/mlx5: fix ethtool link setting call order Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 53/67] net/mlx5: fix socket connection return value Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 54/67] net/mlx5: add data-plane debug message macro Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 55/67] net/mlx5: fix probe return value polarity Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 56/67] net/mlx5: fix flow validation Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 57/67] net/mlx4: fix UDP flow rule limitation enforcement Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 58/67] net/mlx5: fix double free on error handling Yongseok Koh
2018-06-05  0:11 ` [dpdk-stable] [PATCH 59/67] net/mlx5: fix resource leak in case of error Yongseok Koh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180605001129.13184-11-yskoh@mellanox.com \
    --to=yskoh@mellanox.com \
    --cc=adrien.mazarguil@6wind.com \
    --cc=nelio.laranjeiro@6wind.com \
    --cc=shahafs@mellanox.com \
    --cc=stable@dpdk.org \
    --cc=xuemingl@mellanox.com \
    --cc=yliu@fridaylinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).