* [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering
@ 2015-02-26 2:31 Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:31 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
Support the VLAN filter functionality of the VMXNET3 interface.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 -- incorporate comments from Yong Wang
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 105 +++++++++++++++++++++++++++++---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 3 +-
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 31 +---------
3 files changed, 101 insertions(+), 38 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 6068c60..23b4558 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -87,6 +87,12 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
+static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
+ uint16_t vid, int on);
+static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static void vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
+ int mask, int clear);
+
#if PROCESS_SYS_EVENTS == 1
static void vmxnet3_process_events(struct vmxnet3_hw *);
#endif
@@ -113,6 +119,8 @@ static struct eth_dev_ops vmxnet3_eth_dev_ops = {
.link_update = vmxnet3_dev_link_update,
.stats_get = vmxnet3_dev_stats_get,
.dev_infos_get = vmxnet3_dev_info_get,
+ .vlan_filter_set = vmxnet3_dev_vlan_filter_set,
+ .vlan_offload_set = vmxnet3_dev_vlan_offload_set,
.rx_queue_setup = vmxnet3_dev_rx_queue_setup,
.rx_queue_release = vmxnet3_dev_rx_queue_release,
.tx_queue_setup = vmxnet3_dev_tx_queue_setup,
@@ -371,7 +379,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
Vmxnet3_DSDevRead *devRead = &shared->devRead;
uint32_t *mac_ptr;
uint32_t val, i;
- int ret;
+ int ret, mask;
shared->magic = VMXNET3_REV1_MAGIC;
devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
@@ -442,9 +450,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
if (dev->data->dev_conf.rxmode.hw_ip_checksum)
devRead->misc.uptFeatures |= VMXNET3_F_RXCSUM;
- if (dev->data->dev_conf.rxmode.hw_vlan_strip)
- devRead->misc.uptFeatures |= VMXNET3_F_RXVLAN;
-
if (port_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
ret = vmxnet3_rss_configure(dev);
if (ret != VMXNET3_SUCCESS)
@@ -456,11 +461,14 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->rssConfDesc.confPA = hw->rss_confPA;
}
- if (dev->data->dev_conf.rxmode.hw_vlan_filter) {
- ret = vmxnet3_vlan_configure(dev);
- if (ret != VMXNET3_SUCCESS)
- return ret;
- }
+ mask = 0;
+ if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+ mask |= ETH_VLAN_STRIP_MASK;
+
+ if (dev->data->dev_conf.rxmode.hw_vlan_filter)
+ mask |= ETH_VLAN_FILTER_MASK;
+
+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 1);
PMD_INIT_LOG(DEBUG,
"Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
@@ -696,8 +704,13 @@ static void
vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+ memset(vf_table, 0, VMXNET3_VFT_TABLE_SIZE);
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 1);
+
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
}
/* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
@@ -705,8 +718,12 @@ static void
vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+ memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE);
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0);
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
}
/* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */
@@ -727,6 +744,76 @@ vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev)
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 0);
}
+/* Enable/disable filter on vlan */
+static int
+vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on)
+{
+ struct vmxnet3_hw *hw = dev->data->dev_private;
+ struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf;
+ uint32_t *vf_table = rxConf->vfTable;
+
+ /* save state for restore */
+ if (on)
+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, vid);
+ else
+ VMXNET3_CLEAR_VFTABLE_ENTRY(hw->shadow_vfta, vid);
+
+ /* don't change active filter if in promiscious mode */
+ if (rxConf->rxMode & VMXNET3_RXM_PROMISC)
+ return 0;
+
+ /* set in hardware */
+ if (on)
+ VMXNET3_SET_VFTABLE_ENTRY(vf_table, vid);
+ else
+ VMXNET3_CLEAR_VFTABLE_ENTRY(vf_table, vid);
+
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+ return 0;
+}
+
+static void
+vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
+ int mask, int clear)
+{
+ struct vmxnet3_hw *hw = dev->data->dev_private;
+ Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
+ uint32_t *vf_table = devRead->rxFilterConf.vfTable;
+
+ if (mask & ETH_VLAN_STRIP_MASK)
+ devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+ else
+ devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
+
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_FEATURE);
+
+ if (mask & ETH_VLAN_FILTER_MASK) {
+ if (clear) {
+ memset(hw->shadow_vfta, 0,
+ VMXNET3_VFT_TABLE_SIZE);
+ /* allow untagged pkts */
+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
+ }
+ memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE);
+ } else {
+ /* allow any pkts -- no filtering */
+ if (clear)
+ memset(hw->shadow_vfta, 0xff, VMXNET3_VFT_TABLE_SIZE);
+ memset(vf_table, 0xff, VMXNET3_VFT_TABLE_SIZE);
+ }
+
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
+static void
+vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 0);
+}
+
#if PROCESS_SYS_EVENTS == 1
static void
vmxnet3_process_events(struct vmxnet3_hw *hw)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
index 09993cf..e97e3ca 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
@@ -121,6 +121,8 @@ struct vmxnet3_hw {
VMXNET3_RSSConf *rss_conf;
uint64_t rss_confPA;
vmxnet3_mf_table_t *mf_table;
+ uint32_t shadow_vfta[VMXNET3_VFT_SIZE];
+#define VMXNET3_VFT_TABLE_SIZE (VMXNET3_VFT_SIZE * sizeof(uint32_t))
};
#define VMXNET3_GET_ADDR_LO(reg) ((uint32_t)(reg))
@@ -173,7 +175,6 @@ int vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
int vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev);
int vmxnet3_rss_configure(struct rte_eth_dev *dev);
-int vmxnet3_vlan_configure(struct rte_eth_dev *dev);
uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 4d8a010..5fe3de5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -738,9 +738,9 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
return -EINVAL;
}
- if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS) !=
- ETH_TXQ_FLAGS_NOOFFLOADS) {
- PMD_INIT_LOG(ERR, "TX not support offload function yet");
+ if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMS) !=
+ ETH_TXQ_FLAGS_NOXSUMS) {
+ PMD_INIT_LOG(ERR, "TX no support for checksum offload yet");
return -EINVAL;
}
@@ -1045,28 +1045,3 @@ vmxnet3_rss_configure(struct rte_eth_dev *dev)
return VMXNET3_SUCCESS;
}
-
-/*
- * Configure VLAN Filter feature
- */
-int
-vmxnet3_vlan_configure(struct rte_eth_dev *dev)
-{
- uint8_t i;
- struct vmxnet3_hw *hw = dev->data->dev_private;
- uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
-
- PMD_INIT_FUNC_TRACE();
-
- /* Verify if this tag is already set */
- for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
- /* Filter all vlan tags out by default */
- vf_table[i] = 0;
- /* To-Do: Provide another routine in dev_ops for user config */
-
- PMD_INIT_LOG(DEBUG, "Registering VLAN portid: %"PRIu8" tag %u",
- dev->data->port_id, vf_table[i]);
- }
-
- return VMXNET3_SUCCESS;
-}
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
@ 2015-02-26 2:31 ` Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats Stephen Hemminger
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:31 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
Remove check for packets greater than MTU. No other driver does
this, it should be handled at higher layer
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Yong Wang <yongwang@vmware.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 2 --
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 1 -
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 10 ----------
3 files changed, 13 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 23b4558..570565a 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -219,7 +219,6 @@ eth_vmxnet3_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
hw->num_rx_queues = 1;
hw->num_tx_queues = 1;
- hw->cur_mtu = ETHER_MTU;
hw->bufs_per_pkt = 1;
/* Check h/w version compatibility with driver. */
@@ -394,7 +393,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
- devRead->misc.mtu = hw->cur_mtu;
devRead->misc.numTxQueues = hw->num_tx_queues;
devRead->misc.numRxQueues = hw->num_rx_queues;
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
index e97e3ca..b392061 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
@@ -107,7 +107,6 @@ struct vmxnet3_hw {
uint8_t num_tx_queues;
uint8_t num_rx_queues;
uint8_t bufs_per_pkt;
- uint16_t cur_mtu;
Vmxnet3_TxQueueDesc *tqd_start; /* start address of all tx queue desc */
Vmxnet3_RxQueueDesc *rqd_start; /* start address of all rx queue desc */
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 5fe3de5..38ac811 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -369,16 +369,6 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
continue;
}
- /* Needs to minus ether header len */
- if (txm->data_len > (hw->cur_mtu + ETHER_HDR_LEN)) {
- PMD_TX_LOG(DEBUG, "Packet data_len higher than MTU");
- rte_pktmbuf_free(tx_pkts[nb_tx]);
- txq->stats.drop_total++;
-
- nb_tx++;
- continue;
- }
-
txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base + txq->cmd_ring.next2fill);
if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
struct Vmxnet3_TxDataDesc *tdd;
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
@ 2015-02-26 2:31 ` Stephen Hemminger
2015-03-05 19:48 ` Yong Wang
2015-02-26 2:31 ` [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit Stephen Hemminger
` (4 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:31 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
There are several stats here which are never set, and have no way
to be displayed. Assume in future xstats could be used.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
index c5abdb6..ebe6268 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
@@ -121,16 +121,12 @@ vmxnet3_comp_ring_adv_next2proc(struct vmxnet3_comp_ring *ring)
}
struct vmxnet3_txq_stats {
- uint64_t drop_total; /* # of pkts dropped by the driver, the
- * counters below track droppings due to
- * different reasons
- */
- uint64_t drop_oversized;
- uint64_t drop_hdr_inspect_err;
- uint64_t drop_tso;
- uint64_t deferred;
- uint64_t tx_ring_full;
- uint64_t linearized; /* # of pkts linearized */
+ uint64_t drop_total; /* # of pkts dropped by the driver,
+ * the counters below track droppings due to
+ * different reasons
+ */
+ uint64_t drop_tso;
+ uint64_t tx_ring_full;
};
typedef struct vmxnet3_tx_ctx {
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats
2015-02-26 2:31 ` [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats Stephen Hemminger
@ 2015-03-05 19:48 ` Yong Wang
0 siblings, 0 replies; 12+ messages in thread
From: Yong Wang @ 2015-03-05 19:48 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On 2/25/15, 6:31 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>There are several stats here which are never set, and have no way
>to be displayed. Assume in future xstats could be used.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Yong Wang <yongwang@vmware.com>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 16 ++++++----------
> 1 file changed, 6 insertions(+), 10 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>index c5abdb6..ebe6268 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>@@ -121,16 +121,12 @@ vmxnet3_comp_ring_adv_next2proc(struct
>vmxnet3_comp_ring *ring)
> }
>
> struct vmxnet3_txq_stats {
>- uint64_t drop_total; /* # of pkts dropped by the driver,
>the
>- * counters below track droppings due to
>- * different reasons
>- */
>- uint64_t drop_oversized;
>- uint64_t drop_hdr_inspect_err;
>- uint64_t drop_tso;
>- uint64_t deferred;
>- uint64_t tx_ring_full;
>- uint64_t linearized; /* # of pkts linearized */
>+ uint64_t drop_total; /* # of pkts dropped by the driver,
>+ * the counters below track droppings due to
>+ * different reasons
>+ */
>+ uint64_t drop_tso;
>+ uint64_t tx_ring_full;
> };
>
> typedef struct vmxnet3_tx_ctx {
>--
>2.1.4
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats Stephen Hemminger
@ 2015-02-26 2:31 ` Stephen Hemminger
2015-03-05 19:35 ` Yong Wang
2015-02-26 2:32 ` [dpdk-dev] [PATCH 5/7] vmxnet3: fix link state handling Stephen Hemminger
` (3 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:31 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
Change sending loop to support multi-segment mbufs.
The VMXNET3 api has start-of-packet and end-packet flags, so it
is not hard to send multi-segment mbuf's.
Also, update descriptor in 32 bit value rather than toggling
bitfields which is slower and error prone.
Based on code in earlier driver, and the Linux kernel driver.
Add a compiler barrier to make sure that update of earlier descriptor
are completed prior to update of generation bit on start of packet.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 -- incorporate # of segments check
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 1 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 137 ++++++++++++++++------------------
2 files changed, 65 insertions(+), 73 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
index ebe6268..612487e 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
@@ -125,6 +125,7 @@ struct vmxnet3_txq_stats {
* the counters below track droppings due to
* different reasons
*/
+ uint64_t drop_too_many_segs;
uint64_t drop_tso;
uint64_t tx_ring_full;
};
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 38ac811..884b57f 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -312,20 +312,22 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
#endif
mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
- if (unlikely(mbuf == NULL))
- rte_panic("EOP desc does not point to a valid mbuf");
- else
- rte_pktmbuf_free(mbuf);
+ rte_pktmbuf_free_seg(mbuf);
+ txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
+ while (txq->cmd_ring.next2comp != tcd->txdIdx) {
+ mbuf = txq->cmd_ring.buf_info[txq->cmd_ring.next2comp].m;
+ txq->cmd_ring.buf_info[txq->cmd_ring.next2comp].m = NULL;
+ rte_pktmbuf_free_seg(mbuf);
- txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
- /* Mark the txd for which tcd was generated as completed */
- vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
+ /* Mark the txd for which tcd was generated as completed */
+ vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
+ completed++;
+ }
vmxnet3_comp_ring_adv_next2proc(comp_ring);
tcd = (struct Vmxnet3_TxCompDesc *)(comp_ring->base +
comp_ring->next2proc);
- completed++;
}
PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
@@ -336,13 +338,8 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
uint16_t nb_tx;
- Vmxnet3_TxDesc *txd = NULL;
- vmxnet3_buf_info_t *tbi = NULL;
- struct vmxnet3_hw *hw;
- struct rte_mbuf *txm;
vmxnet3_tx_queue_t *txq = tx_queue;
-
- hw = txq->hw;
+ struct vmxnet3_hw *hw = txq->hw;
if (unlikely(txq->stopped)) {
PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
@@ -354,75 +351,69 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
nb_tx = 0;
while (nb_tx < nb_pkts) {
+ Vmxnet3_GenericDesc *gdesc;
+ vmxnet3_buf_info_t *tbi;
+ uint32_t first2fill, avail, dw2;
+ struct rte_mbuf *txm = tx_pkts[nb_tx];
+ struct rte_mbuf *m_seg = txm;
+
+ /* Is this packet execessively fragmented, then drop */
+ if (unlikely(txm->nb_segs > VMXNET3_MAX_TXD_PER_PKT)) {
+ ++txq->stats.drop_too_many_segs;
+ ++txq->stats.drop_total;
+ rte_pktmbuf_free(txm);
+ ++nb_tx;
+ continue;
+ }
- if (vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring)) {
- int copy_size = 0;
-
- txm = tx_pkts[nb_tx];
- /* Don't support scatter packets yet, free them if met */
- if (txm->nb_segs != 1) {
- PMD_TX_LOG(DEBUG, "Don't support scatter packets yet, drop!");
- rte_pktmbuf_free(tx_pkts[nb_tx]);
- txq->stats.drop_total++;
-
- nb_tx++;
- continue;
- }
-
- txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base + txq->cmd_ring.next2fill);
- if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
- struct Vmxnet3_TxDataDesc *tdd;
-
- tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
- copy_size = rte_pktmbuf_pkt_len(txm);
- rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
- }
+ /* Is command ring full? */
+ avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
+ if (txm->nb_segs > avail) {
+ ++txq->stats.tx_ring_full;
+ break;
+ }
- /* Fill the tx descriptor */
+ /* use the previous gen bit for the SOP desc */
+ dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
+ first2fill = txq->cmd_ring.next2fill;
+ do {
+ /* Remember the transmit buffer for cleanup */
tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
- tbi->bufPA = RTE_MBUF_DATA_DMA_ADDR(txm);
- if (copy_size)
- txd->addr = rte_cpu_to_le_64(txq->data_ring.basePA +
- txq->cmd_ring.next2fill *
- sizeof(struct Vmxnet3_TxDataDesc));
- else
- txd->addr = tbi->bufPA;
- txd->len = txm->data_len;
+ tbi->m = m_seg;
- /* Mark the last descriptor as End of Packet. */
- txd->cq = 1;
- txd->eop = 1;
+ /* NB: the following assumes that VMXNET3 maximum
+ transmit buffer size (16K) is greater than
+ maximum sizeof mbuf segment size. */
+ gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
+ gdesc->txd.addr = RTE_MBUF_DATA_DMA_ADDR(m_seg);
+ gdesc->dword[2] = dw2 | m_seg->data_len;
+ gdesc->dword[3] = 0;
- /* Add VLAN tag if requested */
- if (txm->ol_flags & PKT_TX_VLAN_PKT) {
- txd->ti = 1;
- txd->tci = rte_cpu_to_le_16(txm->vlan_tci);
- }
+ /* move to the next2fill descriptor */
+ vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
- /* Record current mbuf for freeing it later in tx complete */
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
- VMXNET3_ASSERT(txm);
-#endif
- tbi->m = txm;
+ /* use the right gen for non-SOP desc */
+ dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+ } while ( (m_seg = m_seg->next) != NULL);
- /* Set the offloading mode to default */
- txd->hlen = 0;
- txd->om = VMXNET3_OM_NONE;
- txd->msscof = 0;
+ /* Update the EOP descriptor */
+ gdesc->dword[3] |= VMXNET3_TXD_EOP | VMXNET3_TXD_CQ;
- /* finally flip the GEN bit of the SOP desc */
- txd->gen = txq->cmd_ring.gen;
- txq->shared->ctrl.txNumDeferred++;
+ /* Add VLAN tag if present */
+ gdesc = txq->cmd_ring.base + first2fill;
+ if (txm->ol_flags & PKT_TX_VLAN_PKT) {
+ gdesc->txd.ti = 1;
+ gdesc->txd.tci = txm->vlan_tci;
+ }
- /* move to the next2fill descriptor */
- vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
- nb_tx++;
+ /* TODO: Add transmit checksum offload here */
- } else {
- PMD_TX_LOG(DEBUG, "No free tx cmd desc(s)");
- txq->stats.drop_total += (nb_pkts - nb_tx);
- break;
- }
+ /* flip the GEN bit on the SOP */
+ rte_compiler_barrier();
+ gdesc->dword[2] ^= VMXNET3_TXD_GEN;
+
+ txq->shared->ctrl.txNumDeferred++;
+ nb_tx++;
}
PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u", txq->shared->ctrl.txThreshold);
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit
2015-02-26 2:31 ` [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit Stephen Hemminger
@ 2015-03-05 19:35 ` Yong Wang
0 siblings, 0 replies; 12+ messages in thread
From: Yong Wang @ 2015-03-05 19:35 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
A quick glance over v2 shows that it only made the change for max segment
check. I am not sure if all the other comments on v1 of this patch are
missed or ignored? If it¹s the latter, can you explain your reasoning why
they are not addressed?
On 2/25/15, 6:31 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>Change sending loop to support multi-segment mbufs.
>The VMXNET3 api has start-of-packet and end-packet flags, so it
>is not hard to send multi-segment mbuf's.
>
>Also, update descriptor in 32 bit value rather than toggling
>bitfields which is slower and error prone.
>Based on code in earlier driver, and the Linux kernel driver.
>
>Add a compiler barrier to make sure that update of earlier descriptor
>are completed prior to update of generation bit on start of packet.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>---
>v2 -- incorporate # of segments check
>
> lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 1 +
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 137
>++++++++++++++++------------------
> 2 files changed, 65 insertions(+), 73 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>index ebe6268..612487e 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>@@ -125,6 +125,7 @@ struct vmxnet3_txq_stats {
> * the counters below track droppings due to
> * different reasons
> */
>+ uint64_t drop_too_many_segs;
> uint64_t drop_tso;
> uint64_t tx_ring_full;
> };
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 38ac811..884b57f 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -312,20 +312,22 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
> VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
> #endif
> mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
>- if (unlikely(mbuf == NULL))
>- rte_panic("EOP desc does not point to a valid mbuf");
>- else
>- rte_pktmbuf_free(mbuf);
>+ rte_pktmbuf_free_seg(mbuf);
>+ txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
>
>+ while (txq->cmd_ring.next2comp != tcd->txdIdx) {
>+ mbuf = txq->cmd_ring.buf_info[txq->cmd_ring.next2comp].m;
>+ txq->cmd_ring.buf_info[txq->cmd_ring.next2comp].m = NULL;
>+ rte_pktmbuf_free_seg(mbuf);
>
>- txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
>- /* Mark the txd for which tcd was generated as completed */
>- vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
>+ /* Mark the txd for which tcd was generated as completed */
>+ vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
>+ completed++;
>+ }
>
> vmxnet3_comp_ring_adv_next2proc(comp_ring);
> tcd = (struct Vmxnet3_TxCompDesc *)(comp_ring->base +
> comp_ring->next2proc);
>- completed++;
> }
>
> PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
>@@ -336,13 +338,8 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
> uint16_t nb_pkts)
> {
> uint16_t nb_tx;
>- Vmxnet3_TxDesc *txd = NULL;
>- vmxnet3_buf_info_t *tbi = NULL;
>- struct vmxnet3_hw *hw;
>- struct rte_mbuf *txm;
> vmxnet3_tx_queue_t *txq = tx_queue;
>-
>- hw = txq->hw;
>+ struct vmxnet3_hw *hw = txq->hw;
>
> if (unlikely(txq->stopped)) {
> PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
>@@ -354,75 +351,69 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
>
> nb_tx = 0;
> while (nb_tx < nb_pkts) {
>+ Vmxnet3_GenericDesc *gdesc;
>+ vmxnet3_buf_info_t *tbi;
>+ uint32_t first2fill, avail, dw2;
>+ struct rte_mbuf *txm = tx_pkts[nb_tx];
>+ struct rte_mbuf *m_seg = txm;
>+
>+ /* Is this packet execessively fragmented, then drop */
>+ if (unlikely(txm->nb_segs > VMXNET3_MAX_TXD_PER_PKT)) {
>+ ++txq->stats.drop_too_many_segs;
>+ ++txq->stats.drop_total;
>+ rte_pktmbuf_free(txm);
>+ ++nb_tx;
>+ continue;
>+ }
>
>- if (vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring)) {
>- int copy_size = 0;
>-
>- txm = tx_pkts[nb_tx];
>- /* Don't support scatter packets yet, free them if met */
>- if (txm->nb_segs != 1) {
>- PMD_TX_LOG(DEBUG, "Don't support scatter packets yet, drop!");
>- rte_pktmbuf_free(tx_pkts[nb_tx]);
>- txq->stats.drop_total++;
>-
>- nb_tx++;
>- continue;
>- }
>-
>- txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base +
>txq->cmd_ring.next2fill);
>- if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
>- struct Vmxnet3_TxDataDesc *tdd;
>-
>- tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
>- copy_size = rte_pktmbuf_pkt_len(txm);
>- rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
>- }
>+ /* Is command ring full? */
>+ avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
>+ if (txm->nb_segs > avail) {
>+ ++txq->stats.tx_ring_full;
>+ break;
>+ }
>
>- /* Fill the tx descriptor */
>+ /* use the previous gen bit for the SOP desc */
>+ dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
>+ first2fill = txq->cmd_ring.next2fill;
>+ do {
>+ /* Remember the transmit buffer for cleanup */
> tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
>- tbi->bufPA = RTE_MBUF_DATA_DMA_ADDR(txm);
>- if (copy_size)
>- txd->addr = rte_cpu_to_le_64(txq->data_ring.basePA +
>- txq->cmd_ring.next2fill *
>- sizeof(struct Vmxnet3_TxDataDesc));
>- else
>- txd->addr = tbi->bufPA;
>- txd->len = txm->data_len;
>+ tbi->m = m_seg;
>
>- /* Mark the last descriptor as End of Packet. */
>- txd->cq = 1;
>- txd->eop = 1;
>+ /* NB: the following assumes that VMXNET3 maximum
>+ transmit buffer size (16K) is greater than
>+ maximum sizeof mbuf segment size. */
>+ gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
>+ gdesc->txd.addr = RTE_MBUF_DATA_DMA_ADDR(m_seg);
>+ gdesc->dword[2] = dw2 | m_seg->data_len;
>+ gdesc->dword[3] = 0;
>
>- /* Add VLAN tag if requested */
>- if (txm->ol_flags & PKT_TX_VLAN_PKT) {
>- txd->ti = 1;
>- txd->tci = rte_cpu_to_le_16(txm->vlan_tci);
>- }
>+ /* move to the next2fill descriptor */
>+ vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
>
>- /* Record current mbuf for freeing it later in tx complete */
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
>- VMXNET3_ASSERT(txm);
>-#endif
>- tbi->m = txm;
>+ /* use the right gen for non-SOP desc */
>+ dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT;
>+ } while ( (m_seg = m_seg->next) != NULL);
>
>- /* Set the offloading mode to default */
>- txd->hlen = 0;
>- txd->om = VMXNET3_OM_NONE;
>- txd->msscof = 0;
>+ /* Update the EOP descriptor */
>+ gdesc->dword[3] |= VMXNET3_TXD_EOP | VMXNET3_TXD_CQ;
>
>- /* finally flip the GEN bit of the SOP desc */
>- txd->gen = txq->cmd_ring.gen;
>- txq->shared->ctrl.txNumDeferred++;
>+ /* Add VLAN tag if present */
>+ gdesc = txq->cmd_ring.base + first2fill;
>+ if (txm->ol_flags & PKT_TX_VLAN_PKT) {
>+ gdesc->txd.ti = 1;
>+ gdesc->txd.tci = txm->vlan_tci;
>+ }
>
>- /* move to the next2fill descriptor */
>- vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
>- nb_tx++;
>+ /* TODO: Add transmit checksum offload here */
>
>- } else {
>- PMD_TX_LOG(DEBUG, "No free tx cmd desc(s)");
>- txq->stats.drop_total += (nb_pkts - nb_tx);
>- break;
>- }
>+ /* flip the GEN bit on the SOP */
>+ rte_compiler_barrier();
>+ gdesc->dword[2] ^= VMXNET3_TXD_GEN;
>+
>+ txq->shared->ctrl.txNumDeferred++;
>+ nb_tx++;
> }
>
> PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u",
>txq->shared->ctrl.txThreshold);
>--
>2.1.4
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 5/7] vmxnet3: fix link state handling
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
` (2 preceding siblings ...)
2015-02-26 2:31 ` [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit Stephen Hemminger
@ 2015-02-26 2:32 ` Stephen Hemminger
2015-02-26 2:32 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:32 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
The Intel version of VMXNET3 driver does not handle link state properly.
The VMXNET3 API returns 1 if connected and 0 if disconnected.
Also need to return correct value to indicate state change.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Yong Wang <yongwang@vmware.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 54 ++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 15 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 570565a..35bb561 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -157,9 +157,36 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
* - On success, zero.
* - On failure, negative value.
*/
-static inline int
-rte_vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
+
+static int
+vmxnet3_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+{
+ struct rte_eth_link *dst = link;
+ struct rte_eth_link *src = &(dev->data->dev_link);
+
+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+ *(uint64_t *)src) == 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ * - Pointer to the structure rte_eth_dev to write to.
+ * - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, negative value.
+ */
+static int
+vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
{
struct rte_eth_link *dst = &(dev->data->dev_link);
struct rte_eth_link *src = link;
@@ -391,6 +418,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.driverInfo.vmxnet3RevSpt = 1;
devRead->misc.driverInfo.uptVerSpt = 1;
+ devRead->misc.mtu = rte_le_to_cpu_32(dev->data->mtu);
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
devRead->misc.numTxQueues = hw->num_tx_queues;
@@ -576,7 +604,7 @@ vmxnet3_dev_stop(struct rte_eth_dev *dev)
/* Clear recorded link status */
memset(&link, 0, sizeof(link));
- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
+ vmxnet3_dev_atomic_write_link_status(dev, &link);
}
/*
@@ -659,28 +687,24 @@ static int
vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
- struct rte_eth_link link;
+ struct rte_eth_link old, link;
uint32_t ret;
+ memset(&link, 0, sizeof(link));
+ vmxnet3_dev_atomic_read_link_status(dev, &old);
+
VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
- if (!ret) {
- PMD_INIT_LOG(ERR, "Link Status Negative : %s()", __func__);
- return -1;
- }
-
if (ret & 0x1) {
link.link_status = 1;
link.link_duplex = ETH_LINK_FULL_DUPLEX;
link.link_speed = ETH_LINK_SPEED_10000;
-
- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
-
- return 0;
}
- return -1;
+ vmxnet3_dev_atomic_write_link_status(dev, &link);
+
+ return (old.link_status == link.link_status) ? -1 : 0;
}
/* Updating rxmode through Vmxnet3_DriverShared structure in adapter */
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
` (3 preceding siblings ...)
2015-02-26 2:32 ` [dpdk-dev] [PATCH 5/7] vmxnet3: fix link state handling Stephen Hemminger
@ 2015-02-26 2:32 ` Stephen Hemminger
2015-03-05 19:27 ` Yong Wang
2015-02-26 2:32 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
2015-02-26 11:43 ` [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Thomas Monjalon
6 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:32 UTC (permalink / raw)
To: Yong Wang; +Cc: dev, Bill Hong
Refactor the logic to compute receive offload flags to a simpler
function. And add support for putting RSS flow hash into packet.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bill Hong <bhong@brocade.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 69 ++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 29 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 884b57f..82bcae6 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -505,6 +505,43 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
return i;
}
+
+/* Receive side checksum and other offloads */
+static void
+vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
+{
+ /* Check for hardware stripped VLAN tag */
+ if (rcd->ts) {
+ rxm->ol_flags |= PKT_RX_VLAN_PKT;
+ rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
+ }
+
+ /* Check for RSS */
+ if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
+ rxm->ol_flags |= PKT_RX_RSS_HASH;
+ rxm->hash.rss = rcd->rssHash;
+ }
+
+ /* Check packet type, checksum errors, etc. Only support IPv4 for now. */
+ if (rcd->v4) {
+ struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
+ struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
+
+ if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
+ rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
+ else
+ rxm->ol_flags |= PKT_RX_IPV4_HDR;
+
+ if (!rcd->cnc) {
+ if (!rcd->ipc)
+ rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+ if ((rcd->tcp || rcd->udp) && !rcd->tuc)
+ rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+ }
+ }
+}
+
/*
* Process the Rx Completion Ring of given vmxnet3_rx_queue
* for nb_pkts burst and return the number of packets received
@@ -605,17 +642,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
goto rcd_done;
}
- /* Check for hardware stripped VLAN tag */
- if (rcd->ts) {
- PMD_RX_LOG(DEBUG, "Received packet with vlan ID: %d.",
- rcd->tci);
- rxm->ol_flags = PKT_RX_VLAN_PKT;
- /* Copy vlan tag in packet buffer */
- rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
- } else {
- rxm->ol_flags = 0;
- rxm->vlan_tci = 0;
- }
/* Initialize newly received packet buffer */
rxm->port = rxq->port_id;
@@ -624,25 +650,10 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm->pkt_len = (uint16_t)rcd->len;
rxm->data_len = (uint16_t)rcd->len;
rxm->data_off = RTE_PKTMBUF_HEADROOM;
+ rxm->ol_flags = 0;
+ rxm->vlan_tci = 0;
- /* Check packet type, checksum errors, etc. Only support IPv4 for now. */
- if (rcd->v4) {
- struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
- struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
-
- if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
- rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
- else
- rxm->ol_flags |= PKT_RX_IPV4_HDR;
-
- if (!rcd->cnc) {
- if (!rcd->ipc)
- rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
-
- if ((rcd->tcp || rcd->udp) && !rcd->tuc)
- rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
- }
- }
+ vmxnet3_rx_offload(rcd, rxm);
rx_pkts[nb_rx++] = rxm;
rcd_done:
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload
2015-02-26 2:32 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
@ 2015-03-05 19:27 ` Yong Wang
0 siblings, 0 replies; 12+ messages in thread
From: Yong Wang @ 2015-03-05 19:27 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Bill Hong
I believe I have ACKed v1 of this commit but I didn't see ACKed-by in v2.
Or is there any changes from v1? If that’s the case, can you explain the
changes in the changelog?
On 2/25/15, 6:32 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>Refactor the logic to compute receive offload flags to a simpler
>function. And add support for putting RSS flow hash into packet.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>Signed-off-by: Bill Hong <bhong@brocade.com>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 69
>++++++++++++++++++++---------------
> 1 file changed, 40 insertions(+), 29 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 884b57f..82bcae6 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -505,6 +505,43 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq,
>uint8_t ring_id)
> return i;
> }
>
>+
>+/* Receive side checksum and other offloads */
>+static void
>+vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
>+{
>+ /* Check for hardware stripped VLAN tag */
>+ if (rcd->ts) {
>+ rxm->ol_flags |= PKT_RX_VLAN_PKT;
>+ rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
>+ }
>+
>+ /* Check for RSS */
>+ if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
>+ rxm->ol_flags |= PKT_RX_RSS_HASH;
>+ rxm->hash.rss = rcd->rssHash;
>+ }
>+
>+ /* Check packet type, checksum errors, etc. Only support IPv4 for now.
>*/
>+ if (rcd->v4) {
>+ struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
>+ struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
>+
>+ if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
>+ rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
>+ else
>+ rxm->ol_flags |= PKT_RX_IPV4_HDR;
>+
>+ if (!rcd->cnc) {
>+ if (!rcd->ipc)
>+ rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
>+
>+ if ((rcd->tcp || rcd->udp) && !rcd->tuc)
>+ rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
>+ }
>+ }
>+}
>+
> /*
> * Process the Rx Completion Ring of given vmxnet3_rx_queue
> * for nb_pkts burst and return the number of packets received
>@@ -605,17 +642,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
> goto rcd_done;
> }
>
>- /* Check for hardware stripped VLAN tag */
>- if (rcd->ts) {
>- PMD_RX_LOG(DEBUG, "Received packet with vlan ID: %d.",
>- rcd->tci);
>- rxm->ol_flags = PKT_RX_VLAN_PKT;
>- /* Copy vlan tag in packet buffer */
>- rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
>- } else {
>- rxm->ol_flags = 0;
>- rxm->vlan_tci = 0;
>- }
>
> /* Initialize newly received packet buffer */
> rxm->port = rxq->port_id;
>@@ -624,25 +650,10 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
> rxm->pkt_len = (uint16_t)rcd->len;
> rxm->data_len = (uint16_t)rcd->len;
> rxm->data_off = RTE_PKTMBUF_HEADROOM;
>+ rxm->ol_flags = 0;
>+ rxm->vlan_tci = 0;
>
>- /* Check packet type, checksum errors, etc. Only support IPv4 for now.
>*/
>- if (rcd->v4) {
>- struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
>- struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
>-
>- if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
>- rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
>- else
>- rxm->ol_flags |= PKT_RX_IPV4_HDR;
>-
>- if (!rcd->cnc) {
>- if (!rcd->ipc)
>- rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
>-
>- if ((rcd->tcp || rcd->udp) && !rcd->tuc)
>- rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
>- }
>- }
>+ vmxnet3_rx_offload(rcd, rxm);
>
> rx_pkts[nb_rx++] = rxm;
> rcd_done:
>--
>2.1.4
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
` (4 preceding siblings ...)
2015-02-26 2:32 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
@ 2015-02-26 2:32 ` Stephen Hemminger
2015-02-26 11:43 ` [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Thomas Monjalon
6 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2015-02-26 2:32 UTC (permalink / raw)
To: Yong Wang; +Cc: dev
Add support for linking multi-segment buffers together to
handle Jumbo packets.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 -- add missing pieces from last version
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 3 +-
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 2 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 76 ++++++++++++++++++++-------------
3 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 35bb561..4f1bc4f 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -401,6 +401,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
{
struct rte_eth_conf port_conf = dev->data->dev_conf;
struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t mtu = dev->data->mtu;
Vmxnet3_DriverShared *shared = hw->shared;
Vmxnet3_DSDevRead *devRead = &shared->devRead;
uint32_t *mac_ptr;
@@ -418,7 +419,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.driverInfo.vmxnet3RevSpt = 1;
devRead->misc.driverInfo.uptVerSpt = 1;
- devRead->misc.mtu = rte_le_to_cpu_32(dev->data->mtu);
+ devRead->misc.mtu = rte_le_to_cpu_32(mtu);
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
devRead->misc.numTxQueues = hw->num_tx_queues;
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
index 612487e..55ceadf 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
@@ -171,6 +171,8 @@ typedef struct vmxnet3_rx_queue {
uint32_t qid1;
uint32_t qid2;
Vmxnet3_RxQueueDesc *shared;
+ struct rte_mbuf *start_seg;
+ struct rte_mbuf *last_seg;
struct vmxnet3_rxq_stats stats;
bool stopped;
uint16_t queue_id; /**< Device RX queue index. */
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 82bcae6..b7babea 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -555,7 +555,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
vmxnet3_rx_queue_t *rxq;
Vmxnet3_RxCompDesc *rcd;
vmxnet3_buf_info_t *rbi;
- Vmxnet3_RxDesc *rxd;
struct rte_mbuf *rxm = NULL;
struct vmxnet3_hw *hw;
@@ -580,42 +579,18 @@ 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);
- rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
- if (unlikely(rcd->sop != 1 || rcd->eop != 1)) {
- rte_pktmbuf_free_seg(rbi->m);
- PMD_RX_LOG(DEBUG, "Packet spread across multiple buffers\n)");
- goto rcd_done;
- }
PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
+ Vmxnet3_RxDesc *rxd
+ = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
VMXNET3_ASSERT(rcd->len <= rxd->len);
VMXNET3_ASSERT(rbi->m);
#endif
- if (unlikely(rcd->len == 0)) {
- PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
- ring_idx, idx);
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
- VMXNET3_ASSERT(rcd->sop && rcd->eop);
-#endif
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
- /* Assuming a packet is coming in a single packet buffer */
- if (unlikely(rxd->btype != VMXNET3_RXD_BTYPE_HEAD)) {
- PMD_RX_LOG(DEBUG,
- "Alert : Misbehaving device, incorrect "
- " buffer type used. iPacket dropped.");
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
- VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
-#endif
/* Get the packet buffer pointer from buf_info */
rxm = rbi->m;
@@ -627,7 +602,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxq->cmd_ring[ring_idx].next2comp = idx;
/* For RCD with EOP set, check if there is frame error */
- if (unlikely(rcd->err)) {
+ if (unlikely(rcd->eop && rcd->err)) {
rxq->stats.drop_total++;
rxq->stats.drop_err++;
@@ -653,9 +628,49 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm->ol_flags = 0;
rxm->vlan_tci = 0;
- vmxnet3_rx_offload(rcd, rxm);
+ /*
+ * If this is the first buffer of the received packet,
+ * set the pointer to the first mbuf of the packet
+ * Otherwise, update the total length and the number of segments
+ * of the current scattered packet, and update the pointer to
+ * the last mbuf of the current packet.
+ */
+ if (rcd->sop) {
+#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
+ VMXNET3_ASSERT(!rxq->start_seg);
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
+#endif
+
+ if (unlikely(rcd->len == 0)) {
+ PMD_RX_LOG(DEBUG,
+ "Rx buf was skipped. rxring[%d][%d])",
+ ring_idx, idx);
+ rte_pktmbuf_free_seg(rbi->m);
+ goto rcd_done;
+ }
+
+ rxq->start_seg = rxm;
+ vmxnet3_rx_offload(rcd, rxm);
+ } else {
+ struct rte_mbuf *start = rxq->start_seg;
+
+#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY);
+ VMXNET3_ASSERT(start != NULL);
+#endif
+
+ start->pkt_len += rxm->data_len;
+ start->nb_segs++;
+
+ rxq->last_seg->next = rxm;
+ }
+ rxq->last_seg = rxm;
+
+ if (rcd->eop) {
+ rx_pkts[nb_rx++] = rxq->start_seg;
+ rxq->start_seg = NULL;
+ }
- rx_pkts[nb_rx++] = rxm;
rcd_done:
rxq->cmd_ring[ring_idx].next2comp = idx;
VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp, rxq->cmd_ring[ring_idx].size);
@@ -965,6 +980,7 @@ vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev)
}
}
rxq->stopped = FALSE;
+ rxq->start_seg = NULL;
}
for (i = 0; i < dev->data->nb_tx_queues; i++) {
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
` (5 preceding siblings ...)
2015-02-26 2:32 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
@ 2015-02-26 11:43 ` Thomas Monjalon
6 siblings, 0 replies; 12+ messages in thread
From: Thomas Monjalon @ 2015-02-26 11:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
2015-02-25 18:31, Stephen Hemminger:
> Support the VLAN filter functionality of the VMXNET3 interface.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v2 -- incorporate comments from Yong Wang
You forgot v2 in the title.
Please prefer a cover letter threading when sending a series of patches;
it's easier to manage.
Thanks
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements
@ 2014-12-17 5:13 Stephen Hemminger
2014-12-17 5:13 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
0 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev
This set of patches updates the vmxnet3 in the DPDK to match
the features in the driver I wrote. The most important critical
feature is support for multi-segment jumbo frames.
Stephen Hemminger (7):
vmxnet3: add support for VLAN filtering
vmxnet3: remove mtu check
vmxnet3: add support for mulit-segment transmit
vmxnet3: fix link state handling
vmxnet3: get rid of DEBUG ifdefs
vmxnet3: support RSS and refactor offload
vmxnet3: support jumbo frames
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 163 ++++++++++++++---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 9 +-
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 2 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 306 +++++++++++++-------------------
4 files changed, 265 insertions(+), 215 deletions(-)
--
2.1.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
0 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Bill Hong, Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
Add support for linking multi-segment buffers together to
handle Jumbo packets
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bill Hong <bhong@brocade.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 1 +
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 2 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 81 ++++++++++++++++-----------------
3 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 7afb43f..bcf48f5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -418,6 +418,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.driverInfo.vmxnet3RevSpt = 1;
devRead->misc.driverInfo.uptVerSpt = 1;
+ devRead->misc.mtu = rte_le_to_cpu_32(dev->data->mtu);
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
devRead->misc.numTxQueues = hw->num_tx_queues;
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
index c5abdb6..ee4e970 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
@@ -174,6 +174,8 @@ typedef struct vmxnet3_rx_queue {
uint32_t qid1;
uint32_t qid2;
Vmxnet3_RxQueueDesc *shared;
+ struct rte_mbuf *start_seg;
+ struct rte_mbuf *last_seg;
struct vmxnet3_rxq_stats stats;
bool stopped;
uint16_t queue_id; /**< Device RX queue index. */
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 53ddb2c..c47ba2e 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -488,7 +488,6 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
return i;
}
-
/* Receive side checksum and other offloads */
static void
vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
@@ -566,34 +565,11 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
- if (unlikely(rcd->sop != 1 || rcd->eop != 1)) {
- rte_pktmbuf_free_seg(rbi->m);
- PMD_RX_LOG(DEBUG, "Packet spread across multiple buffers\n)");
- goto rcd_done;
- }
-
PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
VMXNET3_ASSERT(rcd->len <= rxd->len);
VMXNET3_ASSERT(rbi->m);
- if (unlikely(rcd->len == 0)) {
- PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
- ring_idx, idx);
- VMXNET3_ASSERT(rcd->sop && rcd->eop);
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
-
- /* Assuming a packet is coming in a single packet buffer */
- if (unlikely(rxd->btype != VMXNET3_RXD_BTYPE_HEAD)) {
- PMD_RX_LOG(DEBUG,
- "Alert : Misbehaving device, incorrect "
- " buffer type used. iPacket dropped.");
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
- VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
/* Get the packet buffer pointer from buf_info */
rxm = rbi->m;
@@ -605,7 +581,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxq->cmd_ring[ring_idx].next2comp = idx;
/* For RCD with EOP set, check if there is frame error */
- if (unlikely(rcd->err)) {
+ if (unlikely(rcd->eop && rcd->err)) {
rxq->stats.drop_total++;
rxq->stats.drop_err++;
@@ -620,7 +596,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
goto rcd_done;
}
-
/* Initialize newly received packet buffer */
rxm->port = rxq->port_id;
rxm->nb_segs = 1;
@@ -631,9 +606,44 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm->ol_flags = 0;
rxm->vlan_tci = 0;
- vmxnet3_rx_offload(rcd, rxm);
+ /*
+ * If this is the first buffer of the received packet,
+ * set the pointer to the first mbuf of the packet
+ * Otherwise, update the total length and the number of segments
+ * of the current scattered packet, and update the pointer to
+ * the last mbuf of the current packet.
+ */
+ if (rcd->sop) {
+ VMXNET3_ASSERT(!rxq->start_seg);
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
+
+ if (unlikely(rcd->len == 0)) {
+ PMD_RX_LOG(DEBUG,
+ "Rx buf was skipped. rxring[%d][%d])",
+ ring_idx, idx);
+ rte_pktmbuf_free_seg(rbi->m);
+ goto rcd_done;
+ }
+
+ rxq->start_seg = rxm;
+ vmxnet3_rx_offload(rcd, rxm);
+ } else {
+ struct rte_mbuf *start = rxq->start_seg;
+
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY);
+ VMXNET3_ASSERT(start != NULL);
+
+ start->pkt_len += rxm->data_len;
+ start->nb_segs++;
+
+ rxq->last_seg->next = rxm;
+ }
+ rxq->last_seg = rxm;
- rx_pkts[nb_rx++] = rxm;
+ if (rcd->eop) {
+ rx_pkts[nb_rx++] = rxq->start_seg;
+ rxq->start_seg = NULL;
+ }
rcd_done:
rxq->cmd_ring[ring_idx].next2comp = idx;
VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp, rxq->cmd_ring[ring_idx].size);
@@ -802,23 +812,9 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
int size;
uint8_t i;
char mem_name[32];
- uint16_t buf_size;
- struct rte_pktmbuf_pool_private *mbp_priv;
PMD_INIT_FUNC_TRACE();
- mbp_priv = (struct rte_pktmbuf_pool_private *)
- rte_mempool_get_priv(mp);
- buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
- RTE_PKTMBUF_HEADROOM);
-
- if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
- PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
- "VMXNET3 don't support scatter packets yet",
- buf_size, dev->data->dev_conf.rxmode.max_rx_pkt_len);
- return -EINVAL;
- }
-
rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue), RTE_CACHE_LINE_SIZE);
if (rxq == NULL) {
PMD_INIT_LOG(ERR, "Can not allocate rx queue structure");
@@ -937,6 +933,7 @@ vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev)
}
}
rxq->stopped = FALSE;
+ rxq->start_seg = NULL;
}
for (i = 0; i < dev->data->nb_tx_queues; i++) {
--
2.1.3
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2015-03-05 19:48 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-26 2:31 [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
2015-02-26 2:31 ` [dpdk-dev] [PATCH 3/7] vmxnet3: cleanup txq stats Stephen Hemminger
2015-03-05 19:48 ` Yong Wang
2015-02-26 2:31 ` [dpdk-dev] [PATCH 4/7] vmxnet3: add support for multi-segment transmit Stephen Hemminger
2015-03-05 19:35 ` Yong Wang
2015-02-26 2:32 ` [dpdk-dev] [PATCH 5/7] vmxnet3: fix link state handling Stephen Hemminger
2015-02-26 2:32 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
2015-03-05 19:27 ` Yong Wang
2015-02-26 2:32 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
2015-02-26 11:43 ` [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering Thomas Monjalon
-- strict thread matches above, loose matches on Subject: below --
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
2014-12-17 5:13 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
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).