Skip to contentSkip to conversation

vmxnet3: upgrade to version 3

PATCH In review Shrikrishna Khare 2 participants 9 messages Mar 6, 2017 – Mar 7, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v3 cover vmxnet3: upgrade to version 3

vmxnet3 emulation has recently added several new features which includes support for new commands the driver can issue to emulation, change in descriptor fields etc. This patch series extends the vmxnet3 driver to leverage these new features.

Compatibility is maintained using existing vmxnet3 versioning mechanism as follows:
- new features added to vmxnet3 emulation are associated with new vmxnet3 version viz. vmxnet3 version 3.
- emulation advertises all the versions it supports to the driver.
- during initialization, vmxnet3 driver picks the highest version number supported by both the emulation and the driver and configures emulation to run at that version.

In particular, following changes are introduced:

Patch 1:
Trivial cleanup in preparation of version 3 changes.

Patch 2:
This patch introduces generalized command interface which allows for easily adding new commands that vmxnet3 driver can issue to the emulation. Further patches in this series make use of this facility.

Patch 3:
Transmit data ring buffer is used to copy packet headers or small packets. It is a fixed size buffer. This patch extends the driver to allow variable sized transmit data ring buffer.

Patch 4:
This patch introduces receive data ring buffer - a set of small sized buffers that are always mapped by the emulation. This avoids memory mapping/unmapping overhead for small packets.

Patch 5:
This patch adds reserved commands.

Patch 6:
In vmxnet3 version 3, the emulation added support for the vmxnet3 driver to communicate information about the memory regions the driver will use for rx/tx buffers. This patch exposes related commands to the driver. The driver is also extended to make use of this feaeture.

Patch 7:
With all vmxnet3 version 3 changes incorporated in the vmxnet3 driver, with this patch, the driver can configure emulation to run at vmxnet3 version 3.

---

Changes in v2:
- updated release notes to document vmxnet3 version 3 support.
- fixed coding style issues identified by checkpatches.sh.
- fixed patch title style issued identified by check-git-log.sh.
- fixed compilation issues hit when debug logging is turned on.

Change in v3:
- fix a typo in commit message for add receive data ring change

Shrikrishna Khare (7):
net/vmxnet3: prepare for version 3 changes net/vmxnet3: introduce generalized cmd interface net/vmxnet3: variable length transmit data ring net/vmxnet3: add receive data ring support net/vmxnet3: add reserved version 3 command net/vmxnet3: add cmd to register memory region net/vmxnet3: update to version 3

 doc/guides/rel_notes/release_17_05.rst  |   6 ++
 drivers/net/vmxnet3/base/vmxnet3_defs.h |  85 ++++++++++++++++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c    | 154 +++++++++++++++++++++++++++++++-
 drivers/net/vmxnet3/vmxnet3_ethdev.h    |  28 ++++++
 drivers/net/vmxnet3/vmxnet3_ring.h      |  14 +++
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |  55 +++++++++---
 6 files changed, 323 insertions(+), 19 deletions(-)
Signature · 1 line
2.6.2
#1 lore raw

PATCH v3 1/7 net/vmxnet3: prepare for version 3 changes

Cleanup some code in preparation of vmxnet3 version 3 changes.

---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 17 +++++++++++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.h |  9 +++++++++
 2 files changed, 22 insertions(+), 4 deletions(-)
drivers/net/vmxnet3/vmxnet3_ethdev.c +13 -4
index b7b5377..09f2085 100644
@@ -265,13 +265,22 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	/* Check h/w version compatibility with driver. */
 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_VRRS);
 	PMD_INIT_LOG(DEBUG, "Hardware version : %d", ver);
-	if (ver & 0x1)
-		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS, 1);
-	else {
-		PMD_INIT_LOG(ERR, "Incompatible h/w version, should be 0x1");
+
+	if (ver & (1 << VMXNET3_REV_2)) {
+		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
+				       1 << VMXNET3_REV_2);
+		hw->version = VMXNET3_REV_2 + 1;
+	} else if (ver & (1 << VMXNET3_REV_1)) {
+		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
+				       1 << VMXNET3_REV_1);
+		hw->version = VMXNET3_REV_1 + 1;
+	} else {
+		PMD_INIT_LOG(ERR, "Incompatible hardware version: %d", ver);
 		return -EIO;
 	}
 
+	PMD_INIT_LOG(DEBUG, "Using device version %d\n", hw->version);
+
 	/* Check UPT version compatibility with driver. */
 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_UVRS);
 	PMD_INIT_LOG(DEBUG, "UPT hardware version : %d", ver);
drivers/net/vmxnet3/vmxnet3_ethdev.h +9 -0
index 348c840..3cc8979 100644
@@ -101,6 +101,8 @@ struct vmxnet3_hw {
 	uint8_t num_rx_queues;
 	uint8_t bufs_per_pkt;
 
+	uint8_t	version;
+
 	Vmxnet3_TxQueueDesc   *tqd_start;	/* start address of all tx queue desc */
 	Vmxnet3_RxQueueDesc   *rqd_start;	/* start address of all rx queue desc */
 
@@ -117,6 +119,13 @@ struct vmxnet3_hw {
 #define VMXNET3_VFT_TABLE_SIZE     (VMXNET3_VFT_SIZE * sizeof(uint32_t))
 };
 
+#define VMXNET3_REV_3		2		/* Vmxnet3 Rev. 3 */
+#define VMXNET3_REV_2		1		/* Vmxnet3 Rev. 2 */
+#define VMXNET3_REV_1		0		/* Vmxnet3 Rev. 1 */
+
+#define VMXNET3_VERSION_GE_3(hw) ((hw)->version >= VMXNET3_REV_3 + 1)
+#define VMXNET3_VERSION_GE_2(hw) ((hw)->version >= VMXNET3_REV_2 + 1)
+
 #define VMXNET3_GET_ADDR_LO(reg)   ((uint32_t)(reg))
 #define VMXNET3_GET_ADDR_HI(reg)   ((uint32_t)(((uint64_t)(reg)) >> 32))
 
Signature · 1 line
2.6.2
#2 lore raw

PATCH v3 2/7 net/vmxnet3: introduce generalized cmd interface

In reply to Shrikrishna Khare

Shared memory is used to exchange information between the vmxnet3 driver and the emulation. In order to request emulation to perform a task, the driver first populates specific fields in this shared memory and then issues corresponding command by writing to the command register(CMD). The layout of the shared memory was defined by vmxnet3 version 1 and cannot be extended for every new command without breaking backward compatibility.

To address this problem, in vmxnet3 version 3, the emulation repurposed a reserved field in the shared memory to represent command information instead. For new commands, the driver first populates the command information field in the shared memory and then issues the command. The emulation interprets the data written to the command information depending on the type of the command. This patch exposes this capability to the driver.

---
 drivers/net/vmxnet3/base/vmxnet3_defs.h | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
drivers/net/vmxnet3/base/vmxnet3_defs.h +31 -1
index 68ae8b6..7484b84 100644
@@ -109,6 +109,7 @@ typedef enum {
    VMXNET3_CMD_STOP_EMULATION,
    VMXNET3_CMD_LOAD_PLUGIN,
    VMXNET3_CMD_ACTIVATE_VF,
+   VMXNET3_CMD_RESERVED3,
 
    VMXNET3_CMD_FIRST_GET = 0xF00D0000,
    VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -695,12 +696,41 @@ Vmxnet3_RxQueueDesc;
 
 typedef
 #include "vmware_pack_begin.h"
+struct Vmxnet3_SetPolling {
+   uint8 enablePolling;
+}
+#include "vmware_pack_end.h"
+Vmxnet3_SetPolling;
+
+/*
+ * If the command data <= 16 bytes, use the shared memory direcly.
+ * Otherwise, use the variable length configuration descriptor.
+ */
+typedef
+#include "vmware_pack_begin.h"
+union Vmxnet3_CmdInfo {
+   Vmxnet3_VariableLenConfDesc varConf;
+   Vmxnet3_SetPolling          setPolling;
+   __le64                      data[2];
+}
+#include "vmware_pack_end.h"
+Vmxnet3_CmdInfo;
+
+typedef
+#include "vmware_pack_begin.h"
 struct Vmxnet3_DriverShared {
    __le32               magic;
    __le32               pad; /* make devRead start at 64-bit boundaries */
    Vmxnet3_DSDevRead    devRead;
    __le32               ecr;
-   __le32               reserved[5];
+   __le32               reserved;
+
+   union {
+      __le32            reserved1[4];
+      Vmxnet3_CmdInfo   cmdInfo; /* only valid in the context of executing the
+				  * relevant command
+				  */
+   } cu;
 }
 #include "vmware_pack_end.h"
 Vmxnet3_DriverShared;
Signature · 1 line
2.6.2
#3 lore raw

PATCH v3 3/7 net/vmxnet3: variable length transmit data ring

In reply to Shrikrishna Khare

vmxnet3 driver supports transmit data ring viz. a set of fixed size buffers used by the driver to copy packet headers. Small packets that fit these buffers are copied into these buffers entirely.

Currently this buffer size of fixed at 128 bytes. This patch extends transmit data ring implementation to allow variable length transmit data ring buffers. The length of the buffer is read from the emulation during initialization.

---
 drivers/net/vmxnet3/base/vmxnet3_defs.h | 14 ++++++++++++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c    | 22 ++++++++++++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.h    |  2 ++
 drivers/net/vmxnet3/vmxnet3_ring.h      |  1 +
 drivers/net/vmxnet3/vmxnet3_rxtx.c      | 25 ++++++++++++++++---------
 5 files changed, 53 insertions(+), 11 deletions(-)
drivers/net/vmxnet3/base/vmxnet3_defs.h +12 -2
index 7484b84..e201808 100644
@@ -121,7 +121,8 @@ typedef enum {
    VMXNET3_CMD_GET_DID_HI,
    VMXNET3_CMD_GET_DEV_EXTRA_INFO,
    VMXNET3_CMD_GET_CONF_INTR,
-   VMXNET3_CMD_GET_ADAPTIVE_RING_INFO
+   VMXNET3_CMD_GET_ADAPTIVE_RING_INFO,
+   VMXNET3_CMD_GET_TXDATA_DESC_SIZE
 } Vmxnet3_Cmd;
 
 /* Adaptive Ring Info Flags */
@@ -403,12 +404,19 @@ typedef union Vmxnet3_GenericDesc {
 #define VMXNET3_RING_SIZE_ALIGN 32
 #define VMXNET3_RING_SIZE_MASK  (VMXNET3_RING_SIZE_ALIGN - 1)
 
+/* Tx Data Ring buffer size must be a multiple of 64 */
+#define VMXNET3_TXDATA_DESC_SIZE_ALIGN 64
+#define VMXNET3_TXDATA_DESC_SIZE_MASK  (VMXNET3_TXDATA_DESC_SIZE_ALIGN - 1)
+
 /* Max ring size */
 #define VMXNET3_TX_RING_MAX_SIZE   4096
 #define VMXNET3_TC_RING_MAX_SIZE   4096
 #define VMXNET3_RX_RING_MAX_SIZE   4096
 #define VMXNET3_RC_RING_MAX_SIZE   8192
 
+#define VMXNET3_TXDATA_DESC_MIN_SIZE 128
+#define VMXNET3_TXDATA_DESC_MAX_SIZE 2048
+
 /* a list of reasons for queue stop */
 
 #define VMXNET3_ERR_NOEOP        0x80000000  /* cannot find the EOP desc of a pkt */
@@ -508,7 +516,9 @@ struct Vmxnet3_TxQueueConf {
    __le32    compRingSize; /* # of comp desc */
    __le32    ddLen;        /* size of driver data */
    uint8     intrIdx;
-   uint8     _pad[7];
+   uint8     _pad[1];
+   __le16    txDataRingDescSize;
+   uint8     _pad2[4];
 }
 #include "vmware_pack_end.h"
 Vmxnet3_TxQueueConf;
drivers/net/vmxnet3/vmxnet3_ethdev.c +22 -0
index 09f2085..05b0864 100644
@@ -225,6 +225,24 @@ vmxnet3_disable_intr(struct vmxnet3_hw *hw)
 }
 
 /*
+ * Gets tx data ring descriptor size.
+ */
+static uint16_t
+eth_vmxnet3_txdata_get(struct vmxnet3_hw *hw)
+{
+	uint16 txdata_desc_size;
+
+	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+			       VMXNET3_CMD_GET_TXDATA_DESC_SIZE);
+	txdata_desc_size = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
+
+	return (txdata_desc_size < VMXNET3_TXDATA_DESC_MIN_SIZE ||
+		txdata_desc_size > VMXNET3_TXDATA_DESC_MAX_SIZE ||
+		txdata_desc_size & VMXNET3_TXDATA_DESC_SIZE_MASK) ?
+		sizeof(struct Vmxnet3_TxDataDesc) : txdata_desc_size;
+}
+
+/*
  * It returns 0 on success.
  */
 static int
@@ -320,6 +338,9 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	/* allow untagged pkts */
 	VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
 
+	hw->txdata_desc_size = VMXNET3_VERSION_GE_3(hw) ?
+		eth_vmxnet3_txdata_get(hw) : sizeof(struct Vmxnet3_TxDataDesc);
+
 	return 0;
 }
 
@@ -511,6 +532,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
 		tqd->conf.txRingSize   = txq->cmd_ring.size;
 		tqd->conf.compRingSize = txq->comp_ring.size;
 		tqd->conf.dataRingSize = txq->data_ring.size;
+		tqd->conf.txDataRingDescSize = txq->txdata_desc_size;
 		tqd->conf.intrIdx      = txq->comp_ring.intr_idx;
 		tqd->status.stopped    = TRUE;
 		tqd->status.error      = 0;
drivers/net/vmxnet3/vmxnet3_ethdev.h +2 -0
index 3cc8979..f1c8bc1 100644
@@ -103,6 +103,8 @@ struct vmxnet3_hw {
 
 	uint8_t	version;
 
+	uint16_t txdata_desc_size; /* tx data ring buffer size */
+
 	Vmxnet3_TxQueueDesc   *tqd_start;	/* start address of all tx queue desc */
 	Vmxnet3_RxQueueDesc   *rqd_start;	/* start address of all rx queue desc */
 
drivers/net/vmxnet3/vmxnet3_ring.h +1 -0
index b50d2b0..b27290f 100644
@@ -141,6 +141,7 @@ typedef struct vmxnet3_tx_queue {
 	bool                         stopped;
 	uint16_t                     queue_id;      /**< Device TX queue index. */
 	uint8_t                      port_id;       /**< Device port identifier. */
+	uint16_t		     txdata_desc_size;
 } vmxnet3_tx_queue_t;
 
 struct vmxnet3_rxq_stats {
drivers/net/vmxnet3/vmxnet3_rxtx.c +16 -9
index b246884..705b601 100644
@@ -244,7 +244,7 @@ vmxnet3_dev_tx_queue_reset(void *txq)
 
 	size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
 	size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
-	size += sizeof(struct Vmxnet3_TxDataDesc) * data_ring->size;
+	size += tq->txdata_desc_size * data_ring->size;
 
 	memset(ring->base, 0, size);
 }
@@ -471,10 +471,13 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 		}
 
 		if (txm->nb_segs == 1 &&
-		    rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
+		    rte_pktmbuf_pkt_len(txm) <= txq->txdata_desc_size) {
 			struct Vmxnet3_TxDataDesc *tdd;
 
-			tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
+			tdd = (struct Vmxnet3_TxDataDesc *)
+				((uint8 *)txq->data_ring.base +
+				 txq->cmd_ring.next2fill *
+				 txq->txdata_desc_size);
 			copy_size = rte_pktmbuf_pkt_len(txm);
 			rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
 		}
@@ -491,12 +494,15 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			 * maximum size of mbuf segment size.
 			 */
 			gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
-			if (copy_size)
-				gdesc->txd.addr = rte_cpu_to_le_64(txq->data_ring.basePA +
-								   txq->cmd_ring.next2fill *
-								   sizeof(struct Vmxnet3_TxDataDesc));
-			else
+			if (copy_size) {
+				uint64 offset = txq->cmd_ring.next2fill *
+						txq->txdata_desc_size;
+				gdesc->txd.addr =
+					rte_cpu_to_le_64(txq->data_ring.basePA +
+							 offset);
+			} else {
 				gdesc->txd.addr = rte_mbuf_data_dma_addr(m_seg);
+			}
 
 			gdesc->dword[2] = dw2 | m_seg->data_len;
 			gdesc->dword[3] = 0;
@@ -932,6 +938,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->hw = hw;
 	txq->qid = queue_idx;
 	txq->stopped = TRUE;
+	txq->txdata_desc_size = hw->txdata_desc_size;
 
 	ring = &txq->cmd_ring;
 	comp_ring = &txq->comp_ring;
@@ -961,7 +968,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
 	size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
-	size += sizeof(struct Vmxnet3_TxDataDesc) * data_ring->size;
+	size += txq->txdata_desc_size * data_ring->size;
 
 	mz = ring_dma_zone_reserve(dev, "txdesc", queue_idx, size, socket_id);
 	if (mz == NULL) {
Signature · 1 line
2.6.2
#4 lore raw

PATCH v3 4/7 net/vmxnet3: add receive data ring support

In reply to Shrikrishna Khare

vmxnet3 driver preallocates buffers for receiving packets and posts the buffers to the emulation. In order to deliver a received packet to the guest, the emulation must map buffer(s) and copy the packet into it.

To avoid this memory mapping overhead, this patch introduces the receive data ring - a set of small sized buffers that are always mapped by the emulation. If a packet fits into the receive data ring buffer, the emulation delivers the packet via the receive data ring (which must be copied by the guest driver), or else the usual receive path is used.

---
 drivers/net/vmxnet3/base/vmxnet3_defs.h | 12 ++++++++++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  9 +++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.h    | 15 +++++++++++++++
 drivers/net/vmxnet3/vmxnet3_ring.h      | 13 +++++++++++++
 drivers/net/vmxnet3/vmxnet3_rxtx.c      | 30 +++++++++++++++++++++++++++++-
 5 files changed, 76 insertions(+), 3 deletions(-)
drivers/net/vmxnet3/base/vmxnet3_defs.h +10 -2
index e201808..746d709 100644
@@ -408,6 +408,10 @@ typedef union Vmxnet3_GenericDesc {
 #define VMXNET3_TXDATA_DESC_SIZE_ALIGN 64
 #define VMXNET3_TXDATA_DESC_SIZE_MASK  (VMXNET3_TXDATA_DESC_SIZE_ALIGN - 1)
 
+/* Rx Data Ring buffer size must be a multiple of 64 */
+#define VMXNET3_RXDATA_DESC_SIZE_ALIGN 64
+#define VMXNET3_RXDATA_DESC_SIZE_MASK  (VMXNET3_RXDATA_DESC_SIZE_ALIGN - 1)
+
 /* Max ring size */
 #define VMXNET3_TX_RING_MAX_SIZE   4096
 #define VMXNET3_TC_RING_MAX_SIZE   4096
@@ -417,6 +421,8 @@ typedef union Vmxnet3_GenericDesc {
 #define VMXNET3_TXDATA_DESC_MIN_SIZE 128
 #define VMXNET3_TXDATA_DESC_MAX_SIZE 2048
 
+#define VMXNET3_RXDATA_DESC_MAX_SIZE 2048
+
 /* a list of reasons for queue stop */
 
 #define VMXNET3_ERR_NOEOP        0x80000000  /* cannot find the EOP desc of a pkt */
@@ -529,12 +535,14 @@ struct Vmxnet3_RxQueueConf {
    __le64    rxRingBasePA[2];
    __le64    compRingBasePA;
    __le64    ddPA;            /* driver data */
-   __le64    reserved;
+   __le64    rxDataRingBasePA;
    __le32    rxRingSize[2];   /* # of rx desc */
    __le32    compRingSize;    /* # of rx comp desc */
    __le32    ddLen;           /* size of driver data */
    uint8     intrIdx;
-   uint8     _pad[7];
+   uint8     _pad1[1];
+   __le16    rxDataRingDescSize;  /* size of rx data ring buffer */
+   uint8     _pad2[4];
 }
 #include "vmware_pack_end.h"
 Vmxnet3_RxQueueConf;
drivers/net/vmxnet3/vmxnet3_ethdev.c +9 -0
index 05b0864..8591ce1 100644
@@ -341,6 +341,11 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	hw->txdata_desc_size = VMXNET3_VERSION_GE_3(hw) ?
 		eth_vmxnet3_txdata_get(hw) : sizeof(struct Vmxnet3_TxDataDesc);
 
+	hw->rxdata_desc_size = VMXNET3_VERSION_GE_3(hw) ?
+		VMXNET3_DEF_RXDATA_DESC_SIZE : 0;
+	RTE_ASSERT((hw->rx_data_desc_size & ~VMXNET3_RXDATA_DESC_SIZE_MASK) ==
+		   hw->rx_data_desc_size);
+
 	return 0;
 }
 
@@ -551,6 +556,10 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
 		rqd->conf.rxRingSize[1]   = rxq->cmd_ring[1].size;
 		rqd->conf.compRingSize    = rxq->comp_ring.size;
 		rqd->conf.intrIdx         = rxq->comp_ring.intr_idx;
+		if (VMXNET3_VERSION_GE_3(hw)) {
+			rqd->conf.rxDataRingBasePA = rxq->data_ring.basePA;
+			rqd->conf.rxDataRingDescSize = rxq->data_desc_size;
+		}
 		rqd->status.stopped       = TRUE;
 		rqd->status.error         = 0;
 		memset(&rqd->stats, 0, sizeof(rqd->stats));
drivers/net/vmxnet3/vmxnet3_ethdev.h +15 -0
index f1c8bc1..9d00cd1 100644
@@ -104,6 +104,7 @@ struct vmxnet3_hw {
 	uint8_t	version;
 
 	uint16_t txdata_desc_size; /* tx data ring buffer size */
+	uint16_t rxdata_desc_size; /* rx data ring buffer size */
 
 	Vmxnet3_TxQueueDesc   *tqd_start;	/* start address of all tx queue desc */
 	Vmxnet3_RxQueueDesc   *rqd_start;	/* start address of all rx queue desc */
@@ -157,6 +158,20 @@ vmxnet3_read_addr(volatile void *addr)
 #define VMXNET3_WRITE_BAR1_REG(hw, reg, value) \
 	VMXNET3_PCI_REG_WRITE(VMXNET3_PCI_BAR1_REG_ADDR((hw), (reg)), (value))
 
+static inline uint8_t
+vmxnet3_get_ring_idx(struct vmxnet3_hw *hw, uint32 rqID)
+{
+	return (rqID >= hw->num_rx_queues &&
+		rqID < 2 * hw->num_rx_queues) ? 1 : 0;
+}
+
+static inline bool
+vmxnet3_rx_data_ring(struct vmxnet3_hw *hw, uint32 rqID)
+{
+	return (rqID >= 2 * hw->num_rx_queues &&
+		rqID < 3 * hw->num_rx_queues);
+}
+
 /*
  * RX/TX function prototypes
  */
drivers/net/vmxnet3/vmxnet3_ring.h +13 -0
index b27290f..0ce46c5 100644
@@ -42,6 +42,9 @@
 #define VMXNET3_DEF_TX_RING_SIZE 512
 #define VMXNET3_DEF_RX_RING_SIZE 128
 
+/* Default rx data ring desc size */
+#define VMXNET3_DEF_RXDATA_DESC_SIZE 128
+
 #define VMXNET3_SUCCESS 0
 #define VMXNET3_FAIL   -1
 
@@ -151,13 +154,23 @@ struct vmxnet3_rxq_stats {
 	uint64_t                     rx_buf_alloc_failure;
 };
 
+struct vmxnet3_rx_data_ring {
+	uint8_t  *base;
+	uint64_t basePA;
+	uint32_t size;
+};
+
 typedef struct vmxnet3_rx_queue {
 	struct rte_mempool          *mp;
 	struct vmxnet3_hw           *hw;
 	struct vmxnet3_cmd_ring     cmd_ring[VMXNET3_RX_CMDRING_SIZE];
 	struct vmxnet3_comp_ring    comp_ring;
+	struct vmxnet3_rx_data_ring data_ring;
+	uint16_t                    data_desc_size;
 	uint32_t                    qid1;
 	uint32_t                    qid2;
+	/* rqID in RCD for buffer from data ring */
+	uint32_t                    data_ring_qid;
 	Vmxnet3_RxQueueDesc         *shared;
 	struct rte_mbuf             *start_seg;
 	struct rte_mbuf             *last_seg;
drivers/net/vmxnet3/vmxnet3_rxtx.c +29 -1
index 705b601..6649c3f 100644
@@ -254,8 +254,10 @@ vmxnet3_dev_rx_queue_reset(void *rxq)
 {
 	int i;
 	vmxnet3_rx_queue_t *rq = rxq;
+	struct vmxnet3_hw *hw = rq->hw;
 	struct vmxnet3_cmd_ring *ring0, *ring1;
 	struct vmxnet3_comp_ring *comp_ring;
+	struct vmxnet3_rx_data_ring *data_ring = &rq->data_ring;
 	int size;
 
 	if (rq != NULL) {
@@ -280,6 +282,8 @@ vmxnet3_dev_rx_queue_reset(void *rxq)
 
 	size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
 	size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
+	if (VMXNET3_VERSION_GE_3(hw) && rq->data_desc_size)
+		size += rq->data_desc_size * data_ring->size;
 
 	memset(ring0->base, 0, size);
 }
@@ -758,7 +762,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		}
 
 		idx = rcd->rxdIdx;
-		ring_idx = (uint8_t)((rcd->rqID == rxq->qid1) ? 0 : 1);
+		ring_idx = vmxnet3_get_ring_idx(hw, rcd->rqID);
 		rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
 		RTE_SET_USED(rxd); /* used only for assert when enabled */
 		rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
@@ -824,6 +828,15 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 				goto rcd_done;
 			}
 
+			if (vmxnet3_rx_data_ring(hw, rcd->rqID)) {
+				uint8_t *rdd = rxq->data_ring.base +
+					idx * rxq->data_desc_size;
+
+				RTE_ASSERT(VMXNET3_VERSION_GE_3(hw));
+				rte_memcpy(rte_pktmbuf_mtod(rxm, char *),
+					   rdd, rcd->len);
+			}
+
 			rxq->start_seg = rxm;
 			vmxnet3_rx_offload(rcd, rxm);
 		} else {
@@ -1018,6 +1031,7 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	struct vmxnet3_cmd_ring *ring0, *ring1, *ring;
 	struct vmxnet3_comp_ring *comp_ring;
+	struct vmxnet3_rx_data_ring *data_ring;
 	int size;
 	uint8_t i;
 	char mem_name[32];
@@ -1038,11 +1052,14 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->hw = hw;
 	rxq->qid1 = queue_idx;
 	rxq->qid2 = queue_idx + hw->num_rx_queues;
+	rxq->data_ring_qid = queue_idx + 2 * hw->num_rx_queues;
+	rxq->data_desc_size = hw->rxdata_desc_size;
 	rxq->stopped = TRUE;
 
 	ring0 = &rxq->cmd_ring[0];
 	ring1 = &rxq->cmd_ring[1];
 	comp_ring = &rxq->comp_ring;
+	data_ring = &rxq->data_ring;
 
 	/* Rx vmxnet rings length should be between 256-4096 */
 	if (nb_desc < VMXNET3_DEF_RX_RING_SIZE) {
@@ -1058,6 +1075,7 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	}
 
 	comp_ring->size = ring0->size + ring1->size;
+	data_ring->size = ring0->size;
 
 	/* Rx vmxnet rings structure initialization */
 	ring0->next2fill = 0;
@@ -1071,6 +1089,8 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 
 	size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
 	size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
+	if (VMXNET3_VERSION_GE_3(hw) && rxq->data_desc_size)
+		size += rxq->data_desc_size * data_ring->size;
 
 	mz = ring_dma_zone_reserve(dev, "rxdesc", queue_idx, size, socket_id);
 	if (mz == NULL) {
@@ -1092,6 +1112,14 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	comp_ring->basePA = ring1->basePA + sizeof(struct Vmxnet3_RxDesc) *
 		ring1->size;
 
+	/* data_ring initialization */
+	if (VMXNET3_VERSION_GE_3(hw) && rxq->data_desc_size) {
+		data_ring->base =
+			(uint8_t *)(comp_ring->base + comp_ring->size);
+		data_ring->basePA = comp_ring->basePA +
+			sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
+	}
+
 	/* cmd_ring0-cmd_ring1 buf_info allocation */
 	for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++) {
 
Signature · 1 line
2.6.2
#5 lore raw

PATCH v3 5/7 net/vmxnet3: add reserved version 3 command

In reply to Shrikrishna Khare

This command is reserved.

---
 drivers/net/vmxnet3/base/vmxnet3_defs.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/vmxnet3/base/vmxnet3_defs.h +3 -1
index 746d709..c708498 100644
@@ -110,6 +110,7 @@ typedef enum {
    VMXNET3_CMD_LOAD_PLUGIN,
    VMXNET3_CMD_ACTIVATE_VF,
    VMXNET3_CMD_RESERVED3,
+   VMXNET3_CMD_RESERVED4,
 
    VMXNET3_CMD_FIRST_GET = 0xF00D0000,
    VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -122,7 +123,8 @@ typedef enum {
    VMXNET3_CMD_GET_DEV_EXTRA_INFO,
    VMXNET3_CMD_GET_CONF_INTR,
    VMXNET3_CMD_GET_ADAPTIVE_RING_INFO,
-   VMXNET3_CMD_GET_TXDATA_DESC_SIZE
+   VMXNET3_CMD_GET_TXDATA_DESC_SIZE,
+   VMXNET3_CMD_RESERVED5,
 } Vmxnet3_Cmd;
 
 /* Adaptive Ring Info Flags */
Signature · 1 line
2.6.2
#6 lore raw

PATCH v3 6/7 net/vmxnet3: add cmd to register memory region

In reply to Shrikrishna Khare

In vmxnet3 version 3, the emulation added support for the vmxnet3 driver to communicate information about the memory regions the driver will use for rx/tx buffers. The driver can also indicate which rx/tx queue the memory region is applicable for. If this information is communicated to the emulation, the emulation will always keep these memory regions mapped, thereby avoiding the mapping/unmapping overhead for every packet.

---
 drivers/net/vmxnet3/base/vmxnet3_defs.h |  25 ++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c    | 102 ++++++++++++++++++++++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.h    |   2 +
 3 files changed, 129 insertions(+)
drivers/net/vmxnet3/base/vmxnet3_defs.h +25 -0
index c708498..bfa9622 100644
@@ -111,6 +111,7 @@ typedef enum {
    VMXNET3_CMD_ACTIVATE_VF,
    VMXNET3_CMD_RESERVED3,
    VMXNET3_CMD_RESERVED4,
+   VMXNET3_CMD_REGISTER_MEMREGS,
 
    VMXNET3_CMD_FIRST_GET = 0xF00D0000,
    VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -722,6 +723,30 @@ struct Vmxnet3_SetPolling {
 #include "vmware_pack_end.h"
 Vmxnet3_SetPolling;
 
+typedef
+#include "vmware_pack_begin.h"
+struct Vmxnet3_MemoryRegion {
+	__le64            startPA;
+	__le32            length;
+	__le16            txQueueBits; /* bit n corresponding to tx queue n */
+	__le16            rxQueueBits; /* bit n corresponding to rx queue n */
+}
+#include "vmware_pack_end.h"
+Vmxnet3_MemoryRegion;
+
+#define MAX_MEMORY_REGION_PER_QUEUE 16
+#define MAX_MEMORY_REGION_PER_DEVICE 256
+
+typedef
+#include "vmware_pack_begin.h"
+struct Vmxnet3_MemRegs {
+	__le16           numRegs;
+	__le16           pad[3];
+	Vmxnet3_MemoryRegion memRegs[1];
+}
+#include "vmware_pack_end.h"
+Vmxnet3_MemRegs;
+
 /*
  * If the command data <= 16 bytes, use the shared memory direcly.
  * Otherwise, use the variable length configuration descriptor.
drivers/net/vmxnet3/vmxnet3_ethdev.c +102 -0

120 lines not on this page · raw message

drivers/net/vmxnet3/vmxnet3_ethdev.h +2 -0
index 9d00cd1..7a03262 100644
@@ -119,6 +119,8 @@ struct vmxnet3_hw {
 	uint64_t              rss_confPA;
 	vmxnet3_mf_table_t    *mf_table;
 	uint32_t              shadow_vfta[VMXNET3_VFT_SIZE];
+	Vmxnet3_MemRegs	      *memRegs;
+	uint64_t	      memRegsPA;
 #define VMXNET3_VFT_TABLE_SIZE     (VMXNET3_VFT_SIZE * sizeof(uint32_t))
 };
 
Signature · 1 line
2.6.2
#7 lore raw

PATCH v3 7/7 net/vmxnet3: update to version 3

In reply to Shrikrishna Khare

With all vmxnet3 version 3 changes incorporated in the vmxnet3 driver, the driver can configure emulation to run at vmxnet3 version 3, provided the emulation advertises support for version 3.

This patch also updates release notes.

---
 doc/guides/rel_notes/release_17_05.rst | 6 ++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c   | 6 +++++-
 2 files changed, 11 insertions(+), 1 deletion(-)
doc/guides/rel_notes/release_17_05.rst +6 -0
index e25ea9f..cbe6233 100644
@@ -41,6 +41,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+   * **Added vmxnet3 version 3 support.**
+
+     Added support for vmxnet3 version 3 which includes several
+     performance enhancements viz. configurable TX data ring, Receive
+     Data Ring, ability to register memory regions.
+
 
 Resolved Issues
 ---------------
drivers/net/vmxnet3/vmxnet3_ethdev.c +5 -1
index 96f1585..01da7e3 100644
@@ -284,7 +284,11 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_VRRS);
 	PMD_INIT_LOG(DEBUG, "Hardware version : %d", ver);
 
-	if (ver & (1 << VMXNET3_REV_2)) {
+	if (ver & (1 << VMXNET3_REV_3)) {
+		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
+				       1 << VMXNET3_REV_3);
+		hw->version = VMXNET3_REV_3 + 1;
+	} else if (ver & (1 << VMXNET3_REV_2)) {
 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
 				       1 << VMXNET3_REV_2);
 		hw->version = VMXNET3_REV_2 + 1;
Signature · 1 line
2.6.2
#8 lore raw
In reply to Shrikrishna Khare
Quoted 59 lines · Shrikrishna Khare

vmxnet3 emulation has recently added several new features which includes support for new commands the driver can issue to emulation, change in descriptor fields etc. This patch series extends the vmxnet3 driver to leverage these new features.

Compatibility is maintained using existing vmxnet3 versioning mechanism as follows:
- new features added to vmxnet3 emulation are associated with new vmxnet3 version viz. vmxnet3 version 3.
- emulation advertises all the versions it supports to the driver.
- during initialization, vmxnet3 driver picks the highest version number supported by both the emulation and the driver and configures emulation to run at that version.

In particular, following changes are introduced:

Patch 1:
Trivial cleanup in preparation of version 3 changes.

Patch 2:
This patch introduces generalized command interface which allows for easily adding new commands that vmxnet3 driver can issue to the emulation. Further patches in this series make use of this facility.

Patch 3:
Transmit data ring buffer is used to copy packet headers or small packets. It is a fixed size buffer. This patch extends the driver to allow variable sized transmit data ring buffer.

Patch 4:
This patch introduces receive data ring buffer - a set of small sized buffers that are always mapped by the emulation. This avoids memory mapping/unmapping overhead for small packets.

Patch 5:
This patch adds reserved commands.

Patch 6:
In vmxnet3 version 3, the emulation added support for the vmxnet3 driver to communicate information about the memory regions the driver will use for rx/tx buffers. This patch exposes related commands to the driver. The driver is also extended to make use of this feaeture.

Patch 7:
With all vmxnet3 version 3 changes incorporated in the vmxnet3 driver, with this patch, the driver can configure emulation to run at vmxnet3 version 3.

---

Changes in v2:
- updated release notes to document vmxnet3 version 3 support.
- fixed coding style issues identified by checkpatches.sh.
- fixed patch title style issued identified by check-git-log.sh.
- fixed compilation issues hit when debug logging is turned on.

Change in v3:
- fix a typo in commit message for add receive data ring change

Quoted 8 lines

Shrikrishna Khare (7):
net/vmxnet3: prepare for version 3 changes net/vmxnet3: introduce generalized cmd interface net/vmxnet3: variable length transmit data ring net/vmxnet3: add receive data ring support net/vmxnet3: add reserved version 3 command net/vmxnet3: add cmd to register memory region net/vmxnet3: update to version 3

Series applied to dpdk-next-net/master, thanks.