[dpdk-dev] [PATCH V2] net/thunderx: add support for hardware first skip feature
This feature is used to create a hole between HEADROOM and actual data.Size of hole is specified in bytes as module param to pmd Signed-off-by: Rakesh Kudurumalla --- V1: https://dpdk.org/ml/archives/dev/2018-May/103058.html V2: Includes changes in thunder.rst to render outupt correctly in html doc/guides/nics/thunderx.rst | 18 + drivers/net/thunderx/base/nicvf_hw.c | 12 ++ drivers/net/thunderx/base/nicvf_hw.h | 1 + drivers/net/thunderx/nicvf_ethdev.c | 76 +++- drivers/net/thunderx/nicvf_ethdev.h | 1 + drivers/net/thunderx/nicvf_struct.h | 1 + 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/thunderx.rst b/doc/guides/nics/thunderx.rst index 2642374..7825b43 100644 --- a/doc/guides/nics/thunderx.rst +++ b/doc/guides/nics/thunderx.rst @@ -30,6 +30,7 @@ Features of the ThunderX PMD are: - SR-IOV VF - NUMA support - Multi queue set support (up to 96 queues (12 queue sets)) per port +- First skip support Supported ThunderX SoCs --- @@ -312,6 +313,18 @@ We will choose four secondary queue sets from the ending of the list (0002:01:01 The nicvf thunderx driver will make use of attached secondary VFs automatically during the interface configuration stage. + +Module params +-- + +This feature is used to create a hole between HEADROOM and actual data.Size of hole is specified +in bytes as module param("skip_data_bytes") to pmd. +This scheme is useful when application would like to insert vlan header without disturbing HEADROOM + + +use ``-w pci_id,skip_data_bytes="number of bytes to skip"`` + + Limitations --- @@ -335,3 +348,8 @@ Maximum packet segments The ThunderX SoC family NICs support up to 12 segments per packet when working in scatter/gather mode. So, setting MTU will result with ``EINVAL`` when the frame size does not fit in the maximum number of segments. + +First_skip +~~ + +Maximum limit on first_skip is 128 bytes and number of bytes should be multiple of 8. diff --git a/drivers/net/thunderx/base/nicvf_hw.c b/drivers/net/thunderx/base/nicvf_hw.c index ea8092c..b07a293 100644 --- a/drivers/net/thunderx/base/nicvf_hw.c +++ b/drivers/net/thunderx/base/nicvf_hw.c @@ -703,6 +703,18 @@ nicvf_vlan_hw_strip(struct nicvf *nic, bool enable) } void +nicvf_first_skip_config(struct nicvf *nic, uint8_t num_dwords) +{ + uint64_t val; + + val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG); + val &= ~(0xfULL); + val |= (num_dwords & 0xf); + + nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val); +} + +void nicvf_apad_config(struct nicvf *nic, bool enable) { uint64_t val; diff --git a/drivers/net/thunderx/base/nicvf_hw.h b/drivers/net/thunderx/base/nicvf_hw.h index 284d0bd..fd13ea8 100644 --- a/drivers/net/thunderx/base/nicvf_hw.h +++ b/drivers/net/thunderx/base/nicvf_hw.h @@ -193,6 +193,7 @@ uint32_t nicvf_qsize_sq_roundup(uint32_t val); void nicvf_vlan_hw_strip(struct nicvf *nic, bool enable); void nicvf_apad_config(struct nicvf *nic, bool enable); +void nicvf_first_skip_config(struct nicvf *nic, uint8_t dwords); int nicvf_rss_config(struct nicvf *nic, uint32_t qcnt, uint64_t cfg); int nicvf_rss_term(struct nicvf *nic); diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c index 99fcd51..466cb86 100644 --- a/drivers/net/thunderx/nicvf_ethdev.c +++ b/drivers/net/thunderx/nicvf_ethdev.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "base/nicvf_plat.h" @@ -1230,6 +1232,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq) { uintptr_t p; struct rte_mbuf mb_def; + struct nicvf *nic = rxq->nic; RTE_BUILD_BUG_ON(sizeof(union mbuf_initializer) != 8); RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0); @@ -1240,7 +1243,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq) RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - offsetof(struct rte_mbuf, data_off) != 6); mb_def.nb_segs = 1; - mb_def.data_off = RTE_PKTMBUF_HEADROOM; + mb_def.data_off = RTE_PKTMBUF_HEADROOM + (nic->skip_bytes); mb_def.port = rxq->port_id; rte_mbuf_refcnt_set(&mb_def, 1); @@ -1260,9 +1263,19 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, struct nicvf_rxq *rxq; struct nicvf *nic = nicvf_pmd_priv(dev); uint64_t offloads; + uint32_t buffsz; + struct rte_pktmbuf_pool_private *mbp_priv; PMD_INIT_FUNC_TRACE(); + /* First skip check */ + mbp_priv = rte_mempool_get_priv(mp); + buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM; + if (buffsz < (uint32_t)(nic->skip_bytes)) { + PMD_INIT_LOG(ERR, "First skip is more than configured buffer size"); + return -EINVAL; + } + if (qidx >= MAX_RCV_QUEUES_PER_QS)
Re: [dpdk-dev] [PATCH] net/thunderx: add support for Rx VLAN offload
On 07/04/2018 11:06 PM, Ferruh Yigit wrote: > External Email > > On 7/1/2018 5:46 PM, Pavan Nikhilesh wrote: >> From: "Kudurumalla, Rakesh" >> >> This feature is used to offload stripping of vlan header from recevied >> packets and update vlan_tci field in mbuf when >> DEV_RX_OFFLOAD_VLAN_STRIP & ETH_VLAN_STRIP_MASK flag is set. >> >> Signed-off-by: Rakesh Kudurumalla >> Signed-off-by: Pavan Nikhilesh >> --- >> drivers/net/thunderx/base/nicvf_hw.c | 1 + >> drivers/net/thunderx/nicvf_ethdev.c | 59 +-- >> drivers/net/thunderx/nicvf_rxtx.c| 70 >> drivers/net/thunderx/nicvf_rxtx.h| 15 -- >> drivers/net/thunderx/nicvf_struct.h | 1 + > > In thunderx.ini, "VLAN offload" already marked as P(Partially) is it still > partially? Why? > > It is still partial because Tx VLAN offload(insertion of vlan header > for tx packets) is yet to be Implemented > > <...> > >> @@ -1590,9 +1595,9 @@ nicvf_vf_start(struct rte_eth_dev *dev, struct nicvf >> *nic, uint32_t rbdrsz) >>nic->rbdr->tail, nb_rbdr_desc, nic->vf_id); >> >> /* Configure VLAN Strip */ >> - vlan_strip = !!(dev->data->dev_conf.rxmode.offloads & >> - DEV_RX_OFFLOAD_VLAN_STRIP); >> - nicvf_vlan_hw_strip(nic, vlan_strip); >> + mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK | >> + ETH_VLAN_EXTEND_MASK; > > You don't need anything more than ETH_VLAN_STRIP_MASK but agreed no issue add > more if you prefer. > >> + ret = nicvf_vlan_offload_config(dev, mask); >> >> /* Based on the packet type(IPv4 or IPv6), the nicvf HW aligns L3 data >>* to the 64bit memory address. >> @@ -1983,6 +1988,7 @@ static const struct eth_dev_ops nicvf_eth_dev_ops = { >> .dev_infos_get= nicvf_dev_info_get, >> .dev_supported_ptypes_get = nicvf_dev_supported_ptypes_get, >> .mtu_set = nicvf_dev_set_mtu, >> + .vlan_offload_set = nicvf_vlan_offload_set, > > Not related to this patch but I believe this name 'vlan_offload_set' is > confusing, it enable/disable VLAN related config: > - vlan strip offload > - vlan filtering package (drop/accept specific vlans) > - double vlan feature (not offload if I am not missing anything) > We can think about a more proper name later... > > Also rte_eth_dev_set_vlan_offload() API may have a defect, it seems not taking > capability flags into account, cc'ed Shahaf and Andrew for information. > > And I have a question about DEV_TX_OFFLOAD_VLAN_INSERT, perhaps goes to > Olivier, > if DEV_TX_OFFLOAD_VLAN_INSERT enabled what is the correct way to provide > vlan_tci to insert? > And do we need something like PKT_RX_VLAN_INSERT and use mbuf->vlan_tci value > to > have the ability to insert VLAN to some packets? > > <...> > >> +static int >> +nicvf_vlan_offload_set(struct rte_eth_dev *dev, int mask) >> +{ >> + nicvf_vlan_offload_config(dev, mask); > > Don't you need to change rx_pkt_burst function according request here. > > Like if driver was using nicvf_recv_pkts_vlan_strip() and application disabled > vlan_strip, what will happen? > if application disables vlan_strip under this condition, hardware doesn't strip vlan header from the packets and hence cqe_rx_w0.vlan_stripped field is zero and pkt->ol_flags is update with zero > > <...> > >> +uint16_t __hot >> +nicvf_recv_pkts_vlan_strip(void *rx_queue, struct rte_mbuf **rx_pkts, >> + uint16_t nb_pkts) >> +{ >> + return nicvf_recv_pkts(rx_queue, rx_pkts, nb_pkts, >> + NICVF_RX_OFFLOAD_NONE | NICVF_RX_OFFLOAD_VLAN_STRIP); > > Why do you OR NICVF_RX_OFFLOAD_NONE, this cause zeroing the pkt->ol_flags > which > will be overriten because of NICVF_RX_OFFLOAD_VLAN_STRIP alread> > After enabling vlan strip , if we receive plain packets pkt->ol_flags is updated with zero value.
[dpdk-dev] [PATCH] net/thunderx: add support for hardware first skip feature
This feature is used to create a hole between HEADROOM and actual data.Size of hole is specified in bytes as module param to pmd Signed-off-by: Rakesh Kudurumalla --- doc/guides/nics/thunderx.rst | 26 drivers/net/thunderx/base/nicvf_hw.c | 12 ++ drivers/net/thunderx/base/nicvf_hw.h | 1 + drivers/net/thunderx/nicvf_ethdev.c | 76 +++- drivers/net/thunderx/nicvf_ethdev.h | 1 + drivers/net/thunderx/nicvf_struct.h | 1 + 6 files changed, 116 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/thunderx.rst b/doc/guides/nics/thunderx.rst index 2642374..3d68c61 100644 --- a/doc/guides/nics/thunderx.rst +++ b/doc/guides/nics/thunderx.rst @@ -30,6 +30,7 @@ Features of the ThunderX PMD are: - SR-IOV VF - NUMA support - Multi queue set support (up to 96 queues (12 queue sets)) per port +- First skip support Supported ThunderX SoCs --- @@ -312,6 +313,26 @@ We will choose four secondary queue sets from the ending of the list (0002:01:01 The nicvf thunderx driver will make use of attached secondary VFs automatically during the interface configuration stage. + +# Module params + +This feature is used to create a hole between HEADROOM and actual data. +Size of hole is specified in bytes as module param to pmd. + +Configuration and Options +- +Use ``-w pci_id,skip_data_bytes="number of bytes to skip"`` in the EAL options +Example: + +.. code-block:: console + +./your_application -w pci_id=skip_data_bytes=bytes_to_skip + +Ex: ./build/app/testpmd -w 0001:01:00.1,skip_data_bytes=8 -- --rxq=1 --txq=1 --nb-cores=1 --port-topology=chained -i -- -c 0x1 +This will create a hole of 8 bytes between HEADROOM and actual data. + +Use case: The hole created with first_skip can be used to insert vlan header without disturbing HEADROOM + Limitations --- @@ -335,3 +356,8 @@ Maximum packet segments The ThunderX SoC family NICs support up to 12 segments per packet when working in scatter/gather mode. So, setting MTU will result with ``EINVAL`` when the frame size does not fit in the maximum number of segments. + +First_skip +~~ + +Maximum limit on first_skip is 128 bytes and number of bytes should be multiple of 8 diff --git a/drivers/net/thunderx/base/nicvf_hw.c b/drivers/net/thunderx/base/nicvf_hw.c index ea8092c..b07a293 100644 --- a/drivers/net/thunderx/base/nicvf_hw.c +++ b/drivers/net/thunderx/base/nicvf_hw.c @@ -703,6 +703,18 @@ nicvf_vlan_hw_strip(struct nicvf *nic, bool enable) } void +nicvf_first_skip_config(struct nicvf *nic, uint8_t num_dwords) +{ + uint64_t val; + + val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG); + val &= ~(0xfULL); + val |= (num_dwords & 0xf); + + nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val); +} + +void nicvf_apad_config(struct nicvf *nic, bool enable) { uint64_t val; diff --git a/drivers/net/thunderx/base/nicvf_hw.h b/drivers/net/thunderx/base/nicvf_hw.h index 284d0bd..fd13ea8 100644 --- a/drivers/net/thunderx/base/nicvf_hw.h +++ b/drivers/net/thunderx/base/nicvf_hw.h @@ -193,6 +193,7 @@ uint32_t nicvf_qsize_sq_roundup(uint32_t val); void nicvf_vlan_hw_strip(struct nicvf *nic, bool enable); void nicvf_apad_config(struct nicvf *nic, bool enable); +void nicvf_first_skip_config(struct nicvf *nic, uint8_t dwords); int nicvf_rss_config(struct nicvf *nic, uint32_t qcnt, uint64_t cfg); int nicvf_rss_term(struct nicvf *nic); diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c index 99fcd51..466cb86 100644 --- a/drivers/net/thunderx/nicvf_ethdev.c +++ b/drivers/net/thunderx/nicvf_ethdev.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "base/nicvf_plat.h" @@ -1230,6 +1232,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq) { uintptr_t p; struct rte_mbuf mb_def; + struct nicvf *nic = rxq->nic; RTE_BUILD_BUG_ON(sizeof(union mbuf_initializer) != 8); RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0); @@ -1240,7 +1243,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq) RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - offsetof(struct rte_mbuf, data_off) != 6); mb_def.nb_segs = 1; - mb_def.data_off = RTE_PKTMBUF_HEADROOM; + mb_def.data_off = RTE_PKTMBUF_HEADROOM + (nic->skip_bytes); mb_def.port = rxq->port_id; rte_mbuf_refcnt_set(&mb_def, 1); @@ -1260,9 +1263,19 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, struct nicvf_rxq *rxq; struct nicvf *nic = nicvf_pmd_priv(dev); uint64_t offloads; + uint32_t buffsz; + struct rte_pktmbuf_pool_private *mbp_priv; PMD_INIT_FUNC_TRACE(); + /* First skip check */ + mbp_priv = rte_mempool_get_priv(mp); + buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBU