* Re: [PATCH v4 1/6] ethdev: add Tx preparation
From: Kulasek, TomaszX @ 2016-10-13 10:47 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev@dpdk.org, Ananyev, Konstantin
In-Reply-To: <1506813.gKiMgNqmq7@xps13>
Hi Thomas,
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, October 13, 2016 09:09
> To: Kulasek, TomaszX <tomaszx.kulasek@intel.com>
> Cc: dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v4 1/6] ethdev: add Tx preparation
>
> Hi Tomasz,
>
> Any news?
> Sorry to speed up, we are very very late for RC1.
>
> 2016-10-10 16:08, Thomas Monjalon:
> > Hi,
> >
> > Now that the feature seems to meet a consensus, I've looked at it more
> > closely before integrating. Sorry if it appears like a late review.
> >
> > 2016-09-30 11:00, Tomasz Kulasek:
> > > Added API for `rte_eth_tx_prep`
> >
> > I would love to read the usability and performance considerations here.
> > No need for something as long as the cover letter. Just few lines
> > about why it is needed and why it is a good choice for performance.
> >
> > > uint16_t rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id,
> > > struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
> > >
> > > Added fields to the `struct rte_eth_desc_lim`:
> > >
> > > uint16_t nb_seg_max;
> > > /**< Max number of segments per whole packet. */
> > >
> > > uint16_t nb_mtu_seg_max;
> > > /**< Max number of segments per one MTU */
> > [...]
> > > +#else
> > > +
> > > +static inline uint16_t
> > > +rte_eth_tx_prep(uint8_t port_id __rte_unused, uint16_t queue_id
> __rte_unused,
> > > + struct rte_mbuf **tx_pkts __rte_unused, uint16_t nb_pkts)
> >
> > Doxygen is failing here.
> > Have you tried to move __rte_unused before the identifier?
> >
> > [...]
> > > +#define PKT_TX_OFFLOAD_MASK ( \
> > > + PKT_TX_IP_CKSUM | \
> > > + PKT_TX_L4_MASK | \
> > > + PKT_TX_OUTER_IP_CKSUM | \
> > > + PKT_TX_TCP_SEG | \
> > > + PKT_TX_QINQ_PKT | \
> > > + PKT_TX_VLAN_PKT)
> >
> > We should really stop adding some public constants without the proper
> > RTE prefix.
> > And by the way, should not we move such flags into rte_net?
>
> Do not worry with this comment. It was just a thought which could be
> addressed in a separate patch by someone else.
I've used this name convention to be consistent with other offload flag names, and this is the only reason. The place of these flags was chosen for easier management (flags and mask in one place).
I will leave it as is.
>
> > [...]
> > > -SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h
> > > rte_udp.h rte_sctp.h rte_icmp.h rte_arp.h
> > > +SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h
> > > +rte_udp.h rte_sctp.h rte_icmp.h rte_arp.h rte_pkt.h
> >
> > You can use the += operator on a new line for free :)
> >
> > No more comments, the rest seems OK. Thanks
>
Some additional work was needed due to the new tx tunnel type flags and changes in csum engine.
I will send v5 today.
Tomasz
^ permalink raw reply
* Re: [PATCH] net/i40e: add additional prefetch instructions for bulk rx
From: Ananyev, Konstantin @ 2016-10-13 10:30 UTC (permalink / raw)
To: Richardson, Bruce
Cc: Vladyslav Buslov, Wu, Jingjing, Yigit, Ferruh, Zhang, Helin,
dev@dpdk.org
In-Reply-To: <20161013101849.GA132256@bricha3-MOBL3>
> -----Original Message-----
> From: Richardson, Bruce
> Sent: Thursday, October 13, 2016 11:19 AM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: Vladyslav Buslov <Vladyslav.Buslov@harmonicinc.com>; Wu, Jingjing <jingjing.wu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> Zhang, Helin <helin.zhang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] net/i40e: add additional prefetch instructions for bulk rx
>
> On Wed, Oct 12, 2016 at 12:04:39AM +0000, Ananyev, Konstantin wrote:
> > Hi Vladislav,
> >
> > > > > > >
> > > > > > > On 7/14/2016 6:27 PM, Vladyslav Buslov wrote:
> > > > > > > > Added prefetch of first packet payload cacheline in
> > > > > > > > i40e_rx_scan_hw_ring Added prefetch of second mbuf cacheline in
> > > > > > > > i40e_rx_alloc_bufs
> > > > > > > >
> > > > > > > > Signed-off-by: Vladyslav Buslov
> > > > > > > > <vladyslav.buslov@harmonicinc.com>
> > > > > > > > ---
> > > > > > > > drivers/net/i40e/i40e_rxtx.c | 7 +++++--
> > > > > > > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/net/i40e/i40e_rxtx.c
> > > > > > > > b/drivers/net/i40e/i40e_rxtx.c index d3cfb98..e493fb4 100644
> > > > > > > > --- a/drivers/net/i40e/i40e_rxtx.c
> > > > > > > > +++ b/drivers/net/i40e/i40e_rxtx.c
> > > > > > > > @@ -1003,6 +1003,7 @@ i40e_rx_scan_hw_ring(struct
> > > > i40e_rx_queue
> > > > > > *rxq)
> > > > > > > > /* Translate descriptor info to mbuf parameters */
> > > > > > > > for (j = 0; j < nb_dd; j++) {
> > > > > > > > mb = rxep[j].mbuf;
> > > > > > > > + rte_prefetch0(RTE_PTR_ADD(mb->buf_addr,
> > > > > > > RTE_PKTMBUF_HEADROOM));
> > > > > >
> > > > > > Why did prefetch here? I think if application need to deal with
> > > > > > packet, it is more suitable to put it in application.
> > > > > >
> > > > > > > > qword1 = rte_le_to_cpu_64(\
> > > > > > > > rxdp[j].wb.qword1.status_error_len);
> > > > > > > > pkt_len = ((qword1 &
> > > > > > > I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
> > > > > > > > @@ -1086,9 +1087,11 @@ i40e_rx_alloc_bufs(struct i40e_rx_queue
> > > > > > *rxq)
> > > > > > > >
> > > > > > > > rxdp = &rxq->rx_ring[alloc_idx];
> > > > > > > > for (i = 0; i < rxq->rx_free_thresh; i++) {
> > > > > > > > - if (likely(i < (rxq->rx_free_thresh - 1)))
> > > > > > > > + if (likely(i < (rxq->rx_free_thresh - 1))) {
> > > > > > > > /* Prefetch next mbuf */
> > > > > > > > - rte_prefetch0(rxep[i + 1].mbuf);
> > > > > > > > + rte_prefetch0(&rxep[i + 1].mbuf->cacheline0);
> > > > > > > > + rte_prefetch0(&rxep[i +
> > > > > > > > + 1].mbuf->cacheline1);
> > > >
> > > > I think there are rte_mbuf_prefetch_part1/part2 defined in rte_mbuf.h,
> > > > specially for that case.
> > >
> > > Thanks for pointing that out.
> > > I'll submit new patch if you decide to move forward with this development.
> > >
> > > >
> > > > > > > > + }
> > > > > > Agree with this change. And when I test it by testpmd with iofwd, no
> > > > > > performance increase is observed but minor decrease.
> > > > > > Can you share will us when it will benefit the performance in your
> > > > scenario ?
> > > > > >
> > > > > >
> > > > > > Thanks
> > > > > > Jingjing
> > > > >
> > > > > Hello Jingjing,
> > > > >
> > > > > Thanks for code review.
> > > > >
> > > > > My use case: We have simple distributor thread that receives packets
> > > > > from port and distributes them among worker threads according to VLAN
> > > > and MAC address hash.
> > > > >
> > > > > While working on performance optimization we determined that most of
> > > > CPU usage of this thread is in DPDK.
> > > > > As and optimization we decided to switch to rx burst alloc function,
> > > > > however that caused additional performance degradation compared to
> > > > scatter rx mode.
> > > > > In profiler two major culprits were:
> > > > > 1. Access to packet data Eth header in application code. (cache miss)
> > > > > 2. Setting next packet descriptor field to NULL in DPDK
> > > > > i40e_rx_alloc_bufs code. (this field is in second descriptor cache
> > > > > line that was not
> > > > > prefetched)
> > > >
> > > > I wonder what will happen if we'll remove any prefetches here?
> > > > Would it make things better or worse (and by how much)?
> > >
> > > In our case it causes few per cent PPS degradation on next=NULL assignment but it seems that JingJing's test doesn't confirm it.
> > >
> > > >
> > > > > After applying my fixes performance improved compared to scatter rx
> > > > mode.
> > > > >
> > > > > I assumed that prefetch of first cache line of packet data belongs to
> > > > > DPDK because it is done in scatter rx mode. (in
> > > > > i40e_recv_scattered_pkts)
> > > > > It can be moved to application side but IMO it is better to be consistent
> > > > across all rx modes.
> > > >
> > > > I would agree with Jingjing here, probably PMD should avoid to prefetch
> > > > packet's data.
> > >
> > > Actually I can see some valid use cases where it is beneficial to have this prefetch in driver.
> > > In our sw distributor case it is trivial to just prefetch next packet on each iteration because packets are processed one by one.
> > > However when we move this functionality to hw by means of RSS/vfunction/FlowDirector(our long term goal) worker threads will
> receive
> > > packets directly from rx queues of NIC.
> > > First operation of worker thread is to perform bulk lookup in hash table by destination MAC. This will cause cache miss on accessing
> each
> > > eth header and can't be easily mitigated in application code.
> > > I assume it is ubiquitous use case for DPDK.
> >
> > Yes it is a quite common use-case.
> > Though I many cases it is possible to reorder user code to hide (or minimize) that data-access latency.
> > From other side there are scenarios where this prefetch is excessive and can cause some drop in performance.
> > Again, as I know, none of PMDs for Intel devices prefetches packet's data in simple (single segment) RX mode.
> > Another thing that some people may argue then - why only one cache line is prefetched,
> > in some use-cases might need to look at 2-nd one.
> >
> There is a build-time config setting for this behaviour for exactly the reasons
> called out here - in some apps you get a benefit, in others you see a perf
> hit. The default is "on", which makes sense for most cases, I think.
> From common_base:
>
> CONFIG_RTE_PMD_PACKET_PREFETCH=y$
Yes, but right now i40e and ixgbe non-scattered RX (both vector and scalar) just ignore that flag.
Though yes, might be a good thing to make them to obey that flag properly.
Konstantin
^ permalink raw reply
* Re: [PATCH] net/ring: fix param string info
From: Bruce Richardson @ 2016-10-13 10:22 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev
In-Reply-To: <1472662431-22080-1-git-send-email-ferruh.yigit@intel.com>
On Wed, Aug 31, 2016 at 05:53:51PM +0100, Ferruh Yigit wrote:
> Fixes: 65eca099f405 ("drivers: split parameters infos in multiple lines")
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply
* Re: [PATCH] net/ring: fix ring eth dev creation via devargs
From: Bruce Richardson @ 2016-10-13 10:21 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, Neil Horman
In-Reply-To: <1472662271-21880-1-git-send-email-ferruh.yigit@intel.com>
On Wed, Aug 31, 2016 at 05:51:11PM +0100, Ferruh Yigit wrote:
> Using nodeaction devarg lets creating multiple ring eth devices:
> "eth_ring0,nodeaction=R0:0:CREATE,nodeaction=R1:0:CREATE"
>
> Trying to create all devices with same name fails. Since first part of
> the nodeaction devarg is name (in above sample R0,R1), this name field
> can be used as eth dev name.
>
> Fixes: 61934c0956d4 ("ring: convert to use of PMD_REGISTER_DRIVER and fix linking")
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply
* Re: [PATCH] net/i40e: add additional prefetch instructions for bulk rx
From: Bruce Richardson @ 2016-10-13 10:18 UTC (permalink / raw)
To: Ananyev, Konstantin
Cc: Vladyslav Buslov, Wu, Jingjing, Yigit, Ferruh, Zhang, Helin,
dev@dpdk.org
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0C09AD@irsmsx105.ger.corp.intel.com>
On Wed, Oct 12, 2016 at 12:04:39AM +0000, Ananyev, Konstantin wrote:
> Hi Vladislav,
>
> > > > > >
> > > > > > On 7/14/2016 6:27 PM, Vladyslav Buslov wrote:
> > > > > > > Added prefetch of first packet payload cacheline in
> > > > > > > i40e_rx_scan_hw_ring Added prefetch of second mbuf cacheline in
> > > > > > > i40e_rx_alloc_bufs
> > > > > > >
> > > > > > > Signed-off-by: Vladyslav Buslov
> > > > > > > <vladyslav.buslov@harmonicinc.com>
> > > > > > > ---
> > > > > > > drivers/net/i40e/i40e_rxtx.c | 7 +++++--
> > > > > > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/net/i40e/i40e_rxtx.c
> > > > > > > b/drivers/net/i40e/i40e_rxtx.c index d3cfb98..e493fb4 100644
> > > > > > > --- a/drivers/net/i40e/i40e_rxtx.c
> > > > > > > +++ b/drivers/net/i40e/i40e_rxtx.c
> > > > > > > @@ -1003,6 +1003,7 @@ i40e_rx_scan_hw_ring(struct
> > > i40e_rx_queue
> > > > > *rxq)
> > > > > > > /* Translate descriptor info to mbuf parameters */
> > > > > > > for (j = 0; j < nb_dd; j++) {
> > > > > > > mb = rxep[j].mbuf;
> > > > > > > + rte_prefetch0(RTE_PTR_ADD(mb->buf_addr,
> > > > > > RTE_PKTMBUF_HEADROOM));
> > > > >
> > > > > Why did prefetch here? I think if application need to deal with
> > > > > packet, it is more suitable to put it in application.
> > > > >
> > > > > > > qword1 = rte_le_to_cpu_64(\
> > > > > > > rxdp[j].wb.qword1.status_error_len);
> > > > > > > pkt_len = ((qword1 &
> > > > > > I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
> > > > > > > @@ -1086,9 +1087,11 @@ i40e_rx_alloc_bufs(struct i40e_rx_queue
> > > > > *rxq)
> > > > > > >
> > > > > > > rxdp = &rxq->rx_ring[alloc_idx];
> > > > > > > for (i = 0; i < rxq->rx_free_thresh; i++) {
> > > > > > > - if (likely(i < (rxq->rx_free_thresh - 1)))
> > > > > > > + if (likely(i < (rxq->rx_free_thresh - 1))) {
> > > > > > > /* Prefetch next mbuf */
> > > > > > > - rte_prefetch0(rxep[i + 1].mbuf);
> > > > > > > + rte_prefetch0(&rxep[i + 1].mbuf->cacheline0);
> > > > > > > + rte_prefetch0(&rxep[i +
> > > > > > > + 1].mbuf->cacheline1);
> > >
> > > I think there are rte_mbuf_prefetch_part1/part2 defined in rte_mbuf.h,
> > > specially for that case.
> >
> > Thanks for pointing that out.
> > I'll submit new patch if you decide to move forward with this development.
> >
> > >
> > > > > > > + }
> > > > > Agree with this change. And when I test it by testpmd with iofwd, no
> > > > > performance increase is observed but minor decrease.
> > > > > Can you share will us when it will benefit the performance in your
> > > scenario ?
> > > > >
> > > > >
> > > > > Thanks
> > > > > Jingjing
> > > >
> > > > Hello Jingjing,
> > > >
> > > > Thanks for code review.
> > > >
> > > > My use case: We have simple distributor thread that receives packets
> > > > from port and distributes them among worker threads according to VLAN
> > > and MAC address hash.
> > > >
> > > > While working on performance optimization we determined that most of
> > > CPU usage of this thread is in DPDK.
> > > > As and optimization we decided to switch to rx burst alloc function,
> > > > however that caused additional performance degradation compared to
> > > scatter rx mode.
> > > > In profiler two major culprits were:
> > > > 1. Access to packet data Eth header in application code. (cache miss)
> > > > 2. Setting next packet descriptor field to NULL in DPDK
> > > > i40e_rx_alloc_bufs code. (this field is in second descriptor cache
> > > > line that was not
> > > > prefetched)
> > >
> > > I wonder what will happen if we'll remove any prefetches here?
> > > Would it make things better or worse (and by how much)?
> >
> > In our case it causes few per cent PPS degradation on next=NULL assignment but it seems that JingJing's test doesn't confirm it.
> >
> > >
> > > > After applying my fixes performance improved compared to scatter rx
> > > mode.
> > > >
> > > > I assumed that prefetch of first cache line of packet data belongs to
> > > > DPDK because it is done in scatter rx mode. (in
> > > > i40e_recv_scattered_pkts)
> > > > It can be moved to application side but IMO it is better to be consistent
> > > across all rx modes.
> > >
> > > I would agree with Jingjing here, probably PMD should avoid to prefetch
> > > packet's data.
> >
> > Actually I can see some valid use cases where it is beneficial to have this prefetch in driver.
> > In our sw distributor case it is trivial to just prefetch next packet on each iteration because packets are processed one by one.
> > However when we move this functionality to hw by means of RSS/vfunction/FlowDirector(our long term goal) worker threads will receive
> > packets directly from rx queues of NIC.
> > First operation of worker thread is to perform bulk lookup in hash table by destination MAC. This will cause cache miss on accessing each
> > eth header and can't be easily mitigated in application code.
> > I assume it is ubiquitous use case for DPDK.
>
> Yes it is a quite common use-case.
> Though I many cases it is possible to reorder user code to hide (or minimize) that data-access latency.
> From other side there are scenarios where this prefetch is excessive and can cause some drop in performance.
> Again, as I know, none of PMDs for Intel devices prefetches packet's data in simple (single segment) RX mode.
> Another thing that some people may argue then - why only one cache line is prefetched,
> in some use-cases might need to look at 2-nd one.
>
There is a build-time config setting for this behaviour for exactly the reasons
called out here - in some apps you get a benefit, in others you see a perf
hit. The default is "on", which makes sense for most cases, I think.
>From common_base:
CONFIG_RTE_PMD_PACKET_PREFETCH=y$
/Bruce
^ permalink raw reply
* [PATCH] app/test: add tests with corrupted data for QAT test suite
From: Arek Kusztal @ 2016-10-13 10:03 UTC (permalink / raw)
To: dev
Cc: fiona.trahe, deepak.k.jain, pablo.de.lara.guarch, john.griffin,
Arek Kusztal
This commit adds tests with corrupted data to the Intel QuickAssist
Technology tests suite in test_cryptodev.c
Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
---
app/test/test_cryptodev.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 2917454..83b8253 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -6135,6 +6135,20 @@ static struct unit_test_suite cryptodev_qat_testsuite = {
TEST_CASE_ST(ut_setup, ut_teardown,
test_kasumi_cipher_auth_test_case_1),
+ /** Negative tests */
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_HMAC_SHA1_fail_data_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_HMAC_SHA1_fail_tag_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_AES128_GMAC_fail_data_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ authentication_verify_AES128_GMAC_fail_tag_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt),
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt),
+
TEST_CASES_END() /**< NULL terminate unit test array */
}
};
--
2.1.0
^ permalink raw reply related
* Re: [PATCH] mempool: fix search of maximum contiguous pages
From: Ananyev, Konstantin @ 2016-10-13 9:59 UTC (permalink / raw)
To: Ananyev, Konstantin, Dai, Wei, dev@dpdk.org,
Gonzalez Monroy, Sergio, Tan, Jianfeng, Dai, Wei
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0C1178@irsmsx105.ger.corp.intel.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ananyev, Konstantin
> Sent: Thursday, October 13, 2016 10:54 AM
> To: Dai, Wei <wei.dai@intel.com>; dev@dpdk.org; Gonzalez Monroy, Sergio <sergio.gonzalez.monroy@intel.com>; Tan, Jianfeng
> <jianfeng.tan@intel.com>; Dai, Wei <wei.dai@intel.com>
> Subject: Re: [dpdk-dev] [PATCH] mempool: fix search of maximum contiguous pages
>
> Hi
>
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > ---
> > lib/librte_mempool/rte_mempool.c | 5 ++++-
> > 1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> > index 71017e1..e3e254a 100644
> > --- a/lib/librte_mempool/rte_mempool.c
> > +++ b/lib/librte_mempool/rte_mempool.c
> > @@ -426,9 +426,12 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr,
> >
> > for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {
> >
> > + phys_addr_t paddr_next;
> > + paddr_next = paddr[i] + pg_sz;
> > +
> > /* populate with the largest group of contiguous pages */
> > for (n = 1; (i + n) < pg_num &&
> > - paddr[i] + pg_sz == paddr[i+n]; n++)
> > + paddr_next == paddr[i+n]; n++, paddr_next += pg_sz)
> > ;
>
> Good catch.
> Why not just paddr[i + n - 1] != paddr[i + n]?
Sorry, I meant 'paddr[i + n - 1] + pg_sz == paddr[i+n]' off course.
> Then you don't need extra variable (paddr_next) here.
> Konstantin
>
> >
> > ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz,
> > --
> > 2.7.4
^ permalink raw reply
* Re: [PATCH 0/4] bnxt patch series
From: Bruce Richardson @ 2016-10-13 9:56 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Ajit Khaparde, DPDK
In-Reply-To: <027f4f71-f93e-c4b9-f63c-34348960e183@intel.com>
On Thu, Sep 29, 2016 at 06:32:59PM +0100, Ferruh Yigit wrote:
> On 9/29/2016 6:03 PM, Ajit Khaparde wrote:
> > Please consider applying this patch series.
> > This series is expected to be applied over the previous patchset
> > once it is accepted.
> > Depends on: [v2,15/15] bnxt: Update struct definitions to use the 1.5.1
> > HWRM API
> > http://dpdk.org/dev/patchwork/patch/16154/
> >
> > Ajit Khaparde (4):
> > testpmd: Add support to configure 25G and 50G speeds
> > bnxt: Fix a segfault encountered during KNI exit
> > bnxt: Add support for Async Link Notification
> > bnxt: Update the Broadcom PMD driver documentation
> >
> > app/test-pmd/cmdline.c | 14 ++-
> > doc/guides/nics/bnxt.rst | 18 ++--
> > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
> > drivers/net/bnxt/Makefile | 1 +
> > drivers/net/bnxt/bnxt.h | 7 +-
> > drivers/net/bnxt/bnxt_cpr.c | 21 ++--
> > drivers/net/bnxt/bnxt_ethdev.c | 148 +++++++++++++++++++++-----
> > drivers/net/bnxt/bnxt_hwrm.c | 93 +++++++++--------
> > drivers/net/bnxt/bnxt_irq.c | 156 ++++++++++++++++++++++++++++
> > drivers/net/bnxt/bnxt_irq.h | 51 +++++++++
> > 10 files changed, 409 insertions(+), 102 deletions(-)
> > create mode 100644 drivers/net/bnxt/bnxt_irq.c
> > create mode 100644 drivers/net/bnxt/bnxt_irq.h
> >
>
> Hi Ajit,
>
> Can you please prefer sending patches in a threaded manner, that helps
> keeping them organized.
>
> All other patches in patchset should be as reply to first patch of
> patchset (and if it is a patchset, first patch is most probably a
> cover-letter):
>
> [0/x] ...
> [1/x] ...
> ....
> [x/x] ...
>
> if you use git send-email, it does this automatically for you (with
> proper configuration), more details on:
> http://dpdk.org/doc/guides/contributing/patches.html#sending-patches
>
>
> Thanks,
> ferruh
Patches 2 and 4 of this V1 set applied, along with V2 of patch 3, to
dpdk-next-net/rel_16_11. [Remaining patch has been resubmitted as a separate
testpmd patch: http://dpdk.org/dev/patchwork/patch/16526/]
/Bruce
^ permalink raw reply
* Re: [PATCH] mempool: fix search of maximum contiguous pages
From: Ananyev, Konstantin @ 2016-10-13 9:53 UTC (permalink / raw)
To: Dai, Wei, dev@dpdk.org, Gonzalez Monroy, Sergio, Tan, Jianfeng,
Dai, Wei
In-Reply-To: <1476351445-18102-1-git-send-email-wei.dai@intel.com>
Hi
>
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> ---
> lib/librte_mempool/rte_mempool.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index 71017e1..e3e254a 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -426,9 +426,12 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr,
>
> for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {
>
> + phys_addr_t paddr_next;
> + paddr_next = paddr[i] + pg_sz;
> +
> /* populate with the largest group of contiguous pages */
> for (n = 1; (i + n) < pg_num &&
> - paddr[i] + pg_sz == paddr[i+n]; n++)
> + paddr_next == paddr[i+n]; n++, paddr_next += pg_sz)
> ;
Good catch.
Why not just paddr[i + n - 1] != paddr[i + n]?
Then you don't need extra variable (paddr_next) here.
Konstantin
>
> ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz,
> --
> 2.7.4
^ permalink raw reply
* Re: [PATCH] mempool: fix search of maximum contiguous pages
From: Sergio Gonzalez Monroy @ 2016-10-13 9:46 UTC (permalink / raw)
To: Wei Dai, dev, jianfeng.tan, Olivier MATZ
In-Reply-To: <1476351445-18102-1-git-send-email-wei.dai@intel.com>
+Olivier
On 13/10/2016 10:37, Wei Dai wrote:
> paddr[i] + pg_sz always points to the start physical address of the
> 2nd page after pddr[i], so only up to 2 pages can be combinded to
> be used. With this revision, more than 2 pages can be used.
>
> Fixes: 84121f197187 ("mempool: store memory chunks in a list")
>
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> ---
> lib/librte_mempool/rte_mempool.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index 71017e1..e3e254a 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -426,9 +426,12 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr,
>
> for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {
>
> + phys_addr_t paddr_next;
> + paddr_next = paddr[i] + pg_sz;
> +
> /* populate with the largest group of contiguous pages */
> for (n = 1; (i + n) < pg_num &&
> - paddr[i] + pg_sz == paddr[i+n]; n++)
> + paddr_next == paddr[i+n]; n++, paddr_next += pg_sz)
> ;
>
> ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz,
^ permalink raw reply
* Re: [PATCH v3 01/10] net/bnx2x: set cache line based on build configuration
From: Bruce Richardson @ 2016-10-13 9:45 UTC (permalink / raw)
To: Chas Williams; +Cc: dev, harish.patil
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
On Tue, Oct 11, 2016 at 07:04:52PM -0400, Chas Williams wrote:
> Correctly hint the cache line size. Remove unused macros associated
> with the cache line size.
>
> Fixes: 540a211084a7 ("bnx2x: driver core")
>
> Signed-off-by: Chas Williams <3chas3@gmail.com>
> Acked-by: Harish Patil <harish.patil@qlogic.com>
Series applied to dpdk-next-net/rel_16_11
/Bruce
^ permalink raw reply
* Re: [PATCH 0/2] Two offloading issues of tep_term
From: Thomas Monjalon @ 2016-10-13 9:39 UTC (permalink / raw)
To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, jingjing.wu, mark.b.kavanagh
In-Reply-To: <1470297529-100773-1-git-send-email-jianfeng.tan@intel.com>
2016-08-04 07:58, Jianfeng Tan:
> This patch set depends on:
> - http://dpdk.org/ml/archives/dev/2016-August/044924.html
>
> Patch 1: fill tunneling type.
> Patch 2: inner L4 checksum error.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Applied, thanks
^ permalink raw reply
* Re: [PATCH] net/mlx5: fix Rx function selection
From: Bruce Richardson @ 2016-10-13 9:39 UTC (permalink / raw)
To: Adrien Mazarguil; +Cc: Nelio Laranjeiro, dev
In-Reply-To: <20161011150136.GP17252@6wind.com>
On Tue, Oct 11, 2016 at 05:01:36PM +0200, Adrien Mazarguil wrote:
> On Tue, Oct 11, 2016 at 04:44:50PM +0200, Nelio Laranjeiro wrote:
> > mlx5_rx_queue_setup() was setting the Rx function by itself instead of
> > using priv_select_rx_function() written for that purpose.
> >
> > Fixes: cdab90cb5c8d ("net/mlx5: add Tx/Rx burst function selection wrapper")
> >
> > Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>
Applied to dpdk-next-net/rel_16_11
/Bruce
^ permalink raw reply
* [PATCH] mempool: fix search of maximum contiguous pages
From: Wei Dai @ 2016-10-13 9:37 UTC (permalink / raw)
To: dev, sergio.gonzalez.monroy, jianfeng.tan, wei.dai
paddr[i] + pg_sz always points to the start physical address of the
2nd page after pddr[i], so only up to 2 pages can be combinded to
be used. With this revision, more than 2 pages can be used.
Fixes: 84121f197187 ("mempool: store memory chunks in a list")
Signed-off-by: Wei Dai <wei.dai@intel.com>
---
lib/librte_mempool/rte_mempool.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 71017e1..e3e254a 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -426,9 +426,12 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr,
for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {
+ phys_addr_t paddr_next;
+ paddr_next = paddr[i] + pg_sz;
+
/* populate with the largest group of contiguous pages */
for (n = 1; (i + n) < pg_num &&
- paddr[i] + pg_sz == paddr[i+n]; n++)
+ paddr_next == paddr[i+n]; n++, paddr_next += pg_sz)
;
ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz,
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] net/enic: add Ethernet VLAN ptype
From: Bruce Richardson @ 2016-10-13 9:37 UTC (permalink / raw)
To: John Daley; +Cc: dev, olivier.matz
In-Reply-To: <1472065622-17886-1-git-send-email-johndale@cisco.com>
On Wed, Aug 24, 2016 at 12:07:02PM -0700, John Daley wrote:
> Enic is capable of recognizing packets to be delivered to the
> app with single VLAN tags. Advertise this with the ptype
> RTE_PTYPE_L2_ETHER_VLAN and set the ptype for VLAN packets.
>
> Signed-off-by: John Daley <johndale@cisco.com>
> ---
Applied to dpdk-next-net/rel_16_11
/Bruce
^ permalink raw reply
* Re: [PATCH] doc: add ixgbe supported chipsets and NICs
From: Bruce Richardson @ 2016-10-13 9:34 UTC (permalink / raw)
To: Mcnamara, John
Cc: Dai, Wei, dev@dpdk.org, thomas.monjalon@6wind.com,
Butler, Siobhan A, Zhang, Helin, Ananyev, Konstantin
In-Reply-To: <B27915DBBA3421428155699D51E4CFE202620BCB@IRSMSX103.ger.corp.intel.com>
On Mon, Sep 26, 2016 at 10:11:39AM +0000, Mcnamara, John wrote:
> > -----Original Message-----
> > From: Dai, Wei
> > Sent: Monday, September 26, 2016 2:24 AM
> > To: dev@dpdk.org; thomas.monjalon@6wind.com; Butler, Siobhan A
> > <siobhan.a.butler@intel.com>; Mcnamara, John <john.mcnamara@intel.com>;
> > Zhang, Helin <helin.zhang@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; Dai, Wei <wei.dai@intel.com>
> > Subject: [PATCH] doc: add ixgbe supported chipsets and NICs
> >
> > get the list of all chipsets and NICs supported by ixgbe driver from
> > https://downloadcenter.intel.com/download/14687
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
>
> Acked-by: John McNamara <john.mcnamara@intel.com>
>
Applied to dpdk-next-net/rel_16_11
/Bruce
^ permalink raw reply
* Re: [PATCH v2 0/4] random fixes for bugs identified by Coverity
From: Bruce Richardson @ 2016-10-13 9:31 UTC (permalink / raw)
To: John W. Linville; +Cc: dev, dpdk stable
In-Reply-To: <1475170776-10130-1-git-send-email-linville@tuxdriver.com>
On Thu, Sep 29, 2016 at 01:39:32PM -0400, John W. Linville wrote:
> Today I attempted to exercise my brain between meetings by handling
> a few bugs identified by Coverity.
>
> All of the fixes are simple and (hopefully) obvious. They are
> compile-tested only.
>
> v2: fix-up changelog entries based-on comments from Ferruh Yigit
>
Series applied to dpdk-next-net/rel_16_11
/Bruce
^ permalink raw reply
* Re: [PATCH v3 0/5] vhost: optimize enqueue
From: Maxime Coquelin @ 2016-10-13 9:23 UTC (permalink / raw)
To: Wang, Zhihong, Yuanhan Liu; +Cc: Jianbo Liu, Thomas Monjalon, dev@dpdk.org
In-Reply-To: <76ec0b90-3748-e3c0-abbb-257570086268@redhat.com>
On 10/13/2016 09:54 AM, Maxime Coquelin wrote:
>
>
> On 10/13/2016 08:02 AM, Wang, Zhihong wrote:
>>> > Yes, that's great effort! With your hardwork, we know what the
>>> bottleneck
>>> > is and how it could be improved.
>>> >
>>> > However, you don't have to do code refactor (merge two code path to
>>> one)
>>> > to apply those improvements. From what I know, in this patchset, there
>>> > are two factors could improve the performance:
>>> >
>>> > - copy hdr together with packet data
>>> >
>>> > - shadow used ring update and update at once
>>> >
>>> > The overall performance boost I got with your v6 patchset with mrg-Rx
>>> > code path is about 27% (in PVP case). And I have just applied the 1st
>>> > optimization, it yields about 20% boosts. The left could be covered if
>>> > we apply the 2nd optimization (I guess).
>>> >
>>> > That would be a clean way to optimize vhost mergeable Rx path:
>>> >
>>> > - you don't touch non-mrg Rx path (well, you may could apply the
>>> > shadow_used_ring trick to it as wel)
>>> >
>>> > This would at least make sure we will have no such performance
>>> > regression issue reported by ARM guys.
>>> >
>>> > - you don't refactor the code
>>> >
>>> > The rewrite from scratch could introduce other issues, besides the
>>> > performance regression. We may just don't know it yet.
>>> >
>>> >
>>> > Make sense to you? If you agree, I think we could still make it in
>>> > this release: they would be some small changes after all. For example,
>>> > below is the patch applies the 1st optimization tip on top of
>>> > dpdk-next-virtio
>>
>> Thanks for this great idea. I think it's a better way to do it.
>> I'll start to make the patch then.
>>
>>
>
> I personally find having two paths better for maintenance as it is
> easier to understand (IMHO).
> So if we can have the performance gain while keeping the two paths,
> I definitely support the idea.
I was going to re-run some PVP benchmark with 0% pkt loss, as I had
some strange results last week.
Problem is that your series no more apply cleanly due to
next-virtio's master branch history rewrite.
Any chance you send me a rebased version so that I can apply the series?
Thanks,
Maxime
^ permalink raw reply
* [PATCH v3 3/3] examples/ip_pipeline: add sample config file with TAP port usage
From: Jasvinder Singh @ 2016-10-13 9:17 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
In-Reply-To: <1476350269-225965-1-git-send-email-jasvinder.singh@intel.com>
To illustrate the TAP port usage, the sample configuration file with
passthrough pipeline connected to TAP interface is added.
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
examples/ip_pipeline/config/tap.cfg | 64 +++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 examples/ip_pipeline/config/tap.cfg
diff --git a/examples/ip_pipeline/config/tap.cfg b/examples/ip_pipeline/config/tap.cfg
new file mode 100644
index 0000000..10d35eb
--- /dev/null
+++ b/examples/ip_pipeline/config/tap.cfg
@@ -0,0 +1,64 @@
+; BSD LICENSE
+;
+; Copyright(c) 2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in
+; the documentation and/or other materials provided with the
+; distribution.
+; * Neither the name of Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived
+; from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+; ______________ ______________________
+; | | TAP0 | |
+; RXQ0.0 --->| |------->|--+ |
+; | | TAP1 | | br0 |
+; TXQ1.0 <---| |<-------|<-+ |
+; | Pass-through | | Linux Kernel |
+; | (P1) | | Network Stack |
+; | | TAP1 | |
+; RXQ1.0 --->| |------->|--+ |
+; | | TAP0 | | br0 |
+; TXQ0.0 <---| |<-------|<-+ |
+; |______________| |______________________|
+;
+; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
+; [Linux]$ ifconfig TAP0 up
+; [Linux]$ ifconfig TAP1 up
+; [Linux]$ brctl addbr "br0"
+; [Linux]$ brctl addif br0 TAP0
+; [Linux]$ brctl addif br0 TAP1
+; [Linux]$ ifconfig br0 up
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = PASS-THROUGH
+core = 1
+pktq_in = RXQ0.0 TAP1 RXQ1.0 TAP0
+pktq_out = TAP0 TXQ1.0 TAP1 TXQ0.0
--
2.5.5
^ permalink raw reply related
* [PATCH v3 2/3] examples/ip_pipeline: integrate TAP port
From: Jasvinder Singh @ 2016-10-13 9:17 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
In-Reply-To: <1476350269-225965-1-git-send-email-jasvinder.singh@intel.com>
The TAP port support is added to ip_pipeline app. To parse
configuration file with TAP port entries, parsing function is implemented.
The TAP ports configuration check and initialization routines have been
included in application code.
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
examples/ip_pipeline/app.h | 140 +++++++++++++++++++++
examples/ip_pipeline/config_check.c | 31 +++++
examples/ip_pipeline/config_parse.c | 135 ++++++++++++++++++++
examples/ip_pipeline/init.c | 62 +++++++++
examples/ip_pipeline/pipeline/pipeline_common_fe.c | 1 +
examples/ip_pipeline/pipeline_be.h | 13 ++
6 files changed, 382 insertions(+)
diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 4fdf0d9..564996e 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -177,6 +177,16 @@ struct app_pktq_tm_params {
uint32_t burst_write;
};
+struct app_pktq_tap_params {
+ char *name;
+ uint32_t parsed;
+ uint32_t burst_read;
+ uint32_t burst_write;
+ uint32_t dropless;
+ uint64_t n_retries;
+ uint32_t mempool_id; /* Position in the app->mempool_params */
+};
+
struct app_pktq_source_params {
char *name;
uint32_t parsed;
@@ -204,6 +214,7 @@ enum app_pktq_in_type {
APP_PKTQ_IN_HWQ,
APP_PKTQ_IN_SWQ,
APP_PKTQ_IN_TM,
+ APP_PKTQ_IN_TAP,
APP_PKTQ_IN_KNI,
APP_PKTQ_IN_SOURCE,
};
@@ -217,6 +228,7 @@ enum app_pktq_out_type {
APP_PKTQ_OUT_HWQ,
APP_PKTQ_OUT_SWQ,
APP_PKTQ_OUT_TM,
+ APP_PKTQ_OUT_TAP,
APP_PKTQ_OUT_KNI,
APP_PKTQ_OUT_SINK,
};
@@ -441,6 +453,10 @@ struct app_eal_params {
#define APP_MAX_PKTQ_TM APP_MAX_LINKS
+#ifndef APP_MAX_PKTQ_TAP
+#define APP_MAX_PKTQ_TAP APP_MAX_LINKS
+#endif
+
#define APP_MAX_PKTQ_KNI APP_MAX_LINKS
#ifndef APP_MAX_PKTQ_SOURCE
@@ -494,6 +510,7 @@ struct app_params {
struct app_pktq_hwq_out_params hwq_out_params[APP_MAX_HWQ_OUT];
struct app_pktq_swq_params swq_params[APP_MAX_PKTQ_SWQ];
struct app_pktq_tm_params tm_params[APP_MAX_PKTQ_TM];
+ struct app_pktq_tap_params tap_params[APP_MAX_PKTQ_TAP];
struct app_pktq_kni_params kni_params[APP_MAX_PKTQ_KNI];
struct app_pktq_source_params source_params[APP_MAX_PKTQ_SOURCE];
struct app_pktq_sink_params sink_params[APP_MAX_PKTQ_SINK];
@@ -506,6 +523,7 @@ struct app_params {
uint32_t n_pktq_hwq_out;
uint32_t n_pktq_swq;
uint32_t n_pktq_tm;
+ uint32_t n_pktq_tap;
uint32_t n_pktq_kni;
uint32_t n_pktq_source;
uint32_t n_pktq_sink;
@@ -520,6 +538,7 @@ struct app_params {
struct app_link_data link_data[APP_MAX_LINKS];
struct rte_ring *swq[APP_MAX_PKTQ_SWQ];
struct rte_sched_port *tm[APP_MAX_PKTQ_TM];
+ int tap[APP_MAX_PKTQ_TAP];
#ifdef RTE_LIBRTE_KNI
struct rte_kni *kni[APP_MAX_PKTQ_KNI];
#endif /* RTE_LIBRTE_KNI */
@@ -786,6 +805,66 @@ app_tm_get_reader(struct app_params *app,
}
static inline uint32_t
+app_tap_get_readers(struct app_params *app, struct app_pktq_tap_params *tap)
+{
+ uint32_t pos = tap - app->tap_params;
+ uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+ RTE_DIM(app->pipeline_params));
+ uint32_t n_readers = 0, i;
+
+ for (i = 0; i < n_pipelines; i++) {
+ struct app_pipeline_params *p = &app->pipeline_params[i];
+ uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+ uint32_t j;
+
+ for (j = 0; j < n_pktq_in; j++) {
+ struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+ if ((pktq->type == APP_PKTQ_IN_TAP) &&
+ (pktq->id == pos))
+ n_readers++;
+ }
+ }
+
+ return n_readers;
+}
+
+static inline struct app_pipeline_params *
+app_tap_get_reader(struct app_params *app,
+ struct app_pktq_tap_params *tap,
+ uint32_t *pktq_in_id)
+{
+ struct app_pipeline_params *reader = NULL;
+ uint32_t pos = tap - app->tap_params;
+ uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+ RTE_DIM(app->pipeline_params));
+ uint32_t n_readers = 0, id = 0, i;
+
+ for (i = 0; i < n_pipelines; i++) {
+ struct app_pipeline_params *p = &app->pipeline_params[i];
+ uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+ uint32_t j;
+
+ for (j = 0; j < n_pktq_in; j++) {
+ struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+ if ((pktq->type == APP_PKTQ_IN_TAP) &&
+ (pktq->id == pos)) {
+ n_readers++;
+ reader = p;
+ id = j;
+ }
+ }
+ }
+
+ if (n_readers != 1)
+ return NULL;
+
+ *pktq_in_id = id;
+ return reader;
+}
+
+static inline uint32_t
app_kni_get_readers(struct app_params *app, struct app_pktq_kni_params *kni)
{
uint32_t pos = kni - app->kni_params;
@@ -1043,6 +1122,67 @@ app_tm_get_writer(struct app_params *app,
}
static inline uint32_t
+app_tap_get_writers(struct app_params *app, struct app_pktq_tap_params *tap)
+{
+ uint32_t pos = tap - app->tap_params;
+ uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+ RTE_DIM(app->pipeline_params));
+ uint32_t n_writers = 0, i;
+
+ for (i = 0; i < n_pipelines; i++) {
+ struct app_pipeline_params *p = &app->pipeline_params[i];
+ uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+ RTE_DIM(p->pktq_out));
+ uint32_t j;
+
+ for (j = 0; j < n_pktq_out; j++) {
+ struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+ if ((pktq->type == APP_PKTQ_OUT_TAP) &&
+ (pktq->id == pos))
+ n_writers++;
+ }
+ }
+
+ return n_writers;
+}
+
+static inline struct app_pipeline_params *
+app_tap_get_writer(struct app_params *app,
+ struct app_pktq_tap_params *tap,
+ uint32_t *pktq_out_id)
+{
+ struct app_pipeline_params *writer;
+ uint32_t pos = tap - app->tap_params;
+ uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+ RTE_DIM(app->pipeline_params));
+ uint32_t n_writers = 0, id = 0, i;
+
+ for (i = 0; i < n_pipelines; i++) {
+ struct app_pipeline_params *p = &app->pipeline_params[i];
+ uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+ RTE_DIM(p->pktq_out));
+ uint32_t j;
+
+ for (j = 0; j < n_pktq_out; j++) {
+ struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+ if ((pktq->type == APP_PKTQ_OUT_TAP) &&
+ (pktq->id == pos))
+ n_writers++;
+ writer = p;
+ id = j;
+ }
+ }
+
+ if (n_writers != 1)
+ return NULL;
+
+ *pktq_out_id = id;
+ return writer;
+}
+
+static inline uint32_t
app_kni_get_writers(struct app_params *app, struct app_pktq_kni_params *kni)
{
uint32_t pos = kni - app->kni_params;
diff --git a/examples/ip_pipeline/config_check.c b/examples/ip_pipeline/config_check.c
index af1b628..dd9d4d8 100644
--- a/examples/ip_pipeline/config_check.c
+++ b/examples/ip_pipeline/config_check.c
@@ -316,6 +316,36 @@ check_tms(struct app_params *app)
}
static void
+check_taps(struct app_params *app)
+{
+ uint32_t i;
+
+ for (i = 0; i < app->n_pktq_tap; i++) {
+ struct app_pktq_tap_params *p = &app->tap_params[i];
+ uint32_t n_readers = app_tap_get_readers(app, p);
+ uint32_t n_writers = app_tap_get_writers(app, p);
+
+ APP_CHECK((n_readers != 0),
+ "%s has no reader\n", p->name);
+
+ APP_CHECK((n_readers == 1),
+ "%s has more than one reader\n", p->name);
+
+ APP_CHECK((n_writers != 0),
+ "%s has no writer\n", p->name);
+
+ APP_CHECK((n_writers == 1),
+ "%s has more than one writer\n", p->name);
+
+ APP_CHECK((p->burst_read > 0),
+ "%s read burst size is 0\n", p->name);
+
+ APP_CHECK((p->burst_write > 0),
+ "%s write burst size is 0\n", p->name);
+ }
+}
+
+static void
check_knis(struct app_params *app) {
uint32_t i;
@@ -476,6 +506,7 @@ app_config_check(struct app_params *app)
check_txqs(app);
check_swqs(app);
check_tms(app);
+ check_taps(app);
check_knis(app);
check_sources(app);
check_sinks(app);
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 48c9923..8b372e9 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -189,6 +189,15 @@ struct app_pktq_tm_params default_tm_params = {
.burst_write = 32,
};
+struct app_pktq_tap_params default_tap_params = {
+ .parsed = 0,
+ .burst_read = 32,
+ .burst_write = 32,
+ .dropless = 0,
+ .n_retries = 0,
+ .mempool_id = 0,
+};
+
struct app_pktq_kni_params default_kni_params = {
.parsed = 0,
.socket_id = 0,
@@ -852,6 +861,9 @@ parse_pipeline_pktq_in(struct app_params *app,
type = APP_PKTQ_IN_TM;
id = APP_PARAM_ADD(app->tm_params, name);
APP_PARAM_ADD_LINK_FOR_TM(app, name);
+ } else if (validate_name(name, "TAP", 1) == 0) {
+ type = APP_PKTQ_IN_TAP;
+ id = APP_PARAM_ADD(app->tap_params, name);
} else if (validate_name(name, "KNI", 1) == 0) {
type = APP_PKTQ_IN_KNI;
id = APP_PARAM_ADD(app->kni_params, name);
@@ -901,6 +913,9 @@ parse_pipeline_pktq_out(struct app_params *app,
type = APP_PKTQ_OUT_TM;
id = APP_PARAM_ADD(app->tm_params, name);
APP_PARAM_ADD_LINK_FOR_TM(app, name);
+ } else if (validate_name(name, "TAP", 1) == 0) {
+ type = APP_PKTQ_OUT_TAP;
+ id = APP_PARAM_ADD(app->tap_params, name);
} else if (validate_name(name, "KNI", 1) == 0) {
type = APP_PKTQ_OUT_KNI;
id = APP_PARAM_ADD(app->kni_params, name);
@@ -1896,6 +1911,88 @@ parse_tm(struct app_params *app,
}
static void
+parse_tap(struct app_params *app,
+ const char *section_name,
+ struct rte_cfgfile *cfg)
+{
+ struct app_pktq_tap_params *param;
+ struct rte_cfgfile_entry *entries;
+ int n_entries, i;
+ ssize_t param_idx;
+
+ n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
+ PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
+
+ entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
+ PARSE_ERROR_MALLOC(entries != NULL);
+
+ rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
+
+ param_idx = APP_PARAM_ADD(app->tap_params, section_name);
+ param = &app->tap_params[param_idx];
+ PARSE_CHECK_DUPLICATE_SECTION(param);
+
+ for (i = 0; i < n_entries; i++) {
+ struct rte_cfgfile_entry *ent = &entries[i];
+
+ if (strcmp(ent->name, "burst_read") == 0) {
+ int status = parser_read_uint32(
+ ¶m->burst_read, ent->value);
+
+ PARSE_ERROR((status == 0), section_name,
+ ent->name);
+ continue;
+ }
+
+ if (strcmp(ent->name, "burst_write") == 0) {
+ int status = parser_read_uint32(
+ ¶m->burst_write, ent->value);
+
+ PARSE_ERROR((status == 0), section_name,
+ ent->name);
+ continue;
+ }
+
+ if (strcmp(ent->name, "dropless") == 0) {
+ int status = parser_read_arg_bool(ent->value);
+
+ PARSE_ERROR((status != -EINVAL), section_name,
+ ent->name);
+ param->dropless = status;
+ continue;
+ }
+
+ if (strcmp(ent->name, "n_retries") == 0) {
+ int status = parser_read_uint64(¶m->n_retries,
+ ent->value);
+
+ PARSE_ERROR((status == 0), section_name,
+ ent->name);
+ continue;
+ }
+
+ if (strcmp(ent->name, "mempool") == 0) {
+ int status = validate_name(ent->value,
+ "MEMPOOL", 1);
+ ssize_t idx;
+
+ PARSE_ERROR((status == 0), section_name,
+ ent->name);
+
+ idx = APP_PARAM_ADD(app->mempool_params, ent->value);
+ param->mempool_id = idx;
+
+ continue;
+ }
+
+ /* unrecognized */
+ PARSE_ERROR_INVALID(0, section_name, ent->name);
+ }
+
+ free(entries);
+}
+
+static void
parse_kni(struct app_params *app,
const char *section_name,
struct rte_cfgfile *cfg)
@@ -2286,6 +2383,7 @@ static const struct config_section cfg_file_scheme[] = {
{"TXQ", 2, parse_txq},
{"SWQ", 1, parse_swq},
{"TM", 1, parse_tm},
+ {"TAP", 1, parse_tap},
{"KNI", 1, parse_kni},
{"SOURCE", 1, parse_source},
{"SINK", 1, parse_sink},
@@ -2425,6 +2523,7 @@ app_config_parse(struct app_params *app, const char *file_name)
APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out);
APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq);
APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm);
+ APP_PARAM_COUNT(app->tap_params, app->n_pktq_tap);
APP_PARAM_COUNT(app->kni_params, app->n_pktq_kni);
APP_PARAM_COUNT(app->source_params, app->n_pktq_source);
APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink);
@@ -2789,6 +2888,30 @@ save_tm_params(struct app_params *app, FILE *f)
}
static void
+save_tap_params(struct app_params *app, FILE *f)
+{
+ struct app_pktq_tap_params *p;
+ size_t i, count;
+
+ count = RTE_DIM(app->tap_params);
+ for (i = 0; i < count; i++) {
+ p = &app->tap_params[i];
+ if (!APP_PARAM_VALID(p))
+ continue;
+
+ fprintf(f, "[%s]\n", p->name);
+ fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
+ fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
+ fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
+ fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
+ fprintf(f, "%s = %s\n", "mempool",
+ app->mempool_params[p->mempool_id].name);
+
+ fputc('\n', f);
+ }
+}
+
+static void
save_kni_params(struct app_params *app, FILE *f)
{
struct app_pktq_kni_params *p;
@@ -2942,6 +3065,9 @@ save_pipeline_params(struct app_params *app, FILE *f)
case APP_PKTQ_IN_TM:
name = app->tm_params[pp->id].name;
break;
+ case APP_PKTQ_IN_TAP:
+ name = app->tap_params[pp->id].name;
+ break;
case APP_PKTQ_IN_KNI:
name = app->kni_params[pp->id].name;
break;
@@ -2979,6 +3105,9 @@ save_pipeline_params(struct app_params *app, FILE *f)
case APP_PKTQ_OUT_TM:
name = app->tm_params[pp->id].name;
break;
+ case APP_PKTQ_OUT_TAP:
+ name = app->tap_params[pp->id].name;
+ break;
case APP_PKTQ_OUT_KNI:
name = app->kni_params[pp->id].name;
break;
@@ -3067,6 +3196,7 @@ app_config_save(struct app_params *app, const char *file_name)
save_txq_params(app, file);
save_swq_params(app, file);
save_tm_params(app, file);
+ save_tap_params(app, file);
save_kni_params(app, file);
save_source_params(app, file);
save_sink_params(app, file);
@@ -3113,6 +3243,11 @@ app_config_init(struct app_params *app)
&default_tm_params,
sizeof(default_tm_params));
+ for (i = 0; i < RTE_DIM(app->tap_params); i++)
+ memcpy(&app->tap_params[i],
+ &default_tap_params,
+ sizeof(default_tap_params));
+
for (i = 0; i < RTE_DIM(app->kni_params); i++)
memcpy(&app->kni_params[i],
&default_kni_params,
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index d580ddf..4fed474 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -34,6 +34,12 @@
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
+#include <netinet/in.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
#include <rte_cycles.h>
#include <rte_ethdev.h>
@@ -1154,6 +1160,34 @@ app_init_tm(struct app_params *app)
}
}
+static void
+app_init_tap(struct app_params *app)
+{
+ uint32_t i;
+
+ for (i = 0; i < app->n_pktq_tap; i++) {
+ struct app_pktq_tap_params *p_tap = &app->tap_params[i];
+ struct ifreq ifr;
+ int fd, status;
+
+ APP_LOG(app, HIGH, "Initializing %s ...", p_tap->name);
+
+ fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
+ if (fd < 0)
+ rte_panic("Cannot open file /dev/net/tun\n");
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", p_tap->name);
+
+ status = ioctl(fd, TUNSETIFF, (void *) &ifr);
+ if (status < 0)
+ rte_panic("TAP setup error\n");
+
+ app->tap[i] = fd;
+ }
+}
+
#ifdef RTE_LIBRTE_KNI
static int
kni_config_network_interface(uint8_t port_id, uint8_t if_up) {
@@ -1370,6 +1404,22 @@ void app_pipeline_params_get(struct app_params *app,
out->burst_size = app->tm_params[in->id].burst_read;
break;
}
+ case APP_PKTQ_IN_TAP:
+ {
+ struct app_pktq_tap_params *tap_params =
+ &app->tap_params[in->id];
+ struct app_mempool_params *mempool_params =
+ &app->mempool_params[tap_params->mempool_id];
+ struct rte_mempool *mempool =
+ app->mempool[tap_params->mempool_id];
+
+ out->type = PIPELINE_PORT_IN_FD_READER;
+ out->params.fd.fd = app->tap[in->id];
+ out->params.fd.mtu = mempool_params->buffer_size;
+ out->params.fd.mempool = mempool;
+ out->burst_size = app->tap_params[in->id].burst_read;
+ break;
+ }
#ifdef RTE_LIBRTE_KNI
case APP_PKTQ_IN_KNI:
{
@@ -1514,6 +1564,17 @@ void app_pipeline_params_get(struct app_params *app,
app->tm_params[in->id].burst_write;
break;
}
+ case APP_PKTQ_OUT_TAP:
+ {
+ struct rte_port_fd_writer_params *params =
+ &out->params.fd;
+
+ out->type = PIPELINE_PORT_OUT_FD_WRITER;
+ params->fd = app->tap[in->id];
+ params->tx_burst_sz =
+ app->tap_params[in->id].burst_write;
+ break;
+ }
#ifdef RTE_LIBRTE_KNI
case APP_PKTQ_OUT_KNI:
{
@@ -1730,6 +1791,7 @@ int app_init(struct app_params *app)
app_init_link(app);
app_init_swq(app);
app_init_tm(app);
+ app_init_tap(app);
app_init_kni(app);
app_init_msgq(app);
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
index 7e41071..7521187 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
@@ -156,6 +156,7 @@ app_pipeline_track_pktq_out_to_link(struct app_params *app,
break;
}
+ case APP_PKTQ_OUT_TAP:
case APP_PKTQ_OUT_SINK:
default:
return NULL;
diff --git a/examples/ip_pipeline/pipeline_be.h b/examples/ip_pipeline/pipeline_be.h
index b562472..0cfcc80 100644
--- a/examples/ip_pipeline/pipeline_be.h
+++ b/examples/ip_pipeline/pipeline_be.h
@@ -39,6 +39,7 @@
#include <rte_port_frag.h>
#include <rte_port_ras.h>
#include <rte_port_sched.h>
+#include <rte_port_fd.h>
#include <rte_port_source_sink.h>
#ifdef RTE_LIBRTE_KNI
#include <rte_port_kni.h>
@@ -52,6 +53,7 @@ enum pipeline_port_in_type {
PIPELINE_PORT_IN_RING_READER_IPV4_FRAG,
PIPELINE_PORT_IN_RING_READER_IPV6_FRAG,
PIPELINE_PORT_IN_SCHED_READER,
+ PIPELINE_PORT_IN_FD_READER,
PIPELINE_PORT_IN_KNI_READER,
PIPELINE_PORT_IN_SOURCE,
};
@@ -65,6 +67,7 @@ struct pipeline_port_in_params {
struct rte_port_ring_reader_ipv4_frag_params ring_ipv4_frag;
struct rte_port_ring_reader_ipv6_frag_params ring_ipv6_frag;
struct rte_port_sched_reader_params sched;
+ struct rte_port_fd_reader_params fd;
#ifdef RTE_LIBRTE_KNI
struct rte_port_kni_reader_params kni;
#endif
@@ -89,6 +92,8 @@ pipeline_port_in_params_convert(struct pipeline_port_in_params *p)
return (void *) &p->params.ring_ipv6_frag;
case PIPELINE_PORT_IN_SCHED_READER:
return (void *) &p->params.sched;
+ case PIPELINE_PORT_IN_FD_READER:
+ return (void *) &p->params.fd;
#ifdef RTE_LIBRTE_KNI
case PIPELINE_PORT_IN_KNI_READER:
return (void *) &p->params.kni;
@@ -116,6 +121,8 @@ pipeline_port_in_params_get_ops(struct pipeline_port_in_params *p)
return &rte_port_ring_reader_ipv6_frag_ops;
case PIPELINE_PORT_IN_SCHED_READER:
return &rte_port_sched_reader_ops;
+ case PIPELINE_PORT_IN_FD_READER:
+ return &rte_port_fd_reader_ops;
#ifdef RTE_LIBRTE_KNI
case PIPELINE_PORT_IN_KNI_READER:
return &rte_port_kni_reader_ops;
@@ -137,6 +144,7 @@ enum pipeline_port_out_type {
PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS,
PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS,
PIPELINE_PORT_OUT_SCHED_WRITER,
+ PIPELINE_PORT_OUT_FD_WRITER,
PIPELINE_PORT_OUT_KNI_WRITER,
PIPELINE_PORT_OUT_KNI_WRITER_NODROP,
PIPELINE_PORT_OUT_SINK,
@@ -154,6 +162,7 @@ struct pipeline_port_out_params {
struct rte_port_ring_writer_ipv4_ras_params ring_ipv4_ras;
struct rte_port_ring_writer_ipv6_ras_params ring_ipv6_ras;
struct rte_port_sched_writer_params sched;
+ struct rte_port_fd_writer_params fd;
#ifdef RTE_LIBRTE_KNI
struct rte_port_kni_writer_params kni;
struct rte_port_kni_writer_nodrop_params kni_nodrop;
@@ -184,6 +193,8 @@ pipeline_port_out_params_convert(struct pipeline_port_out_params *p)
return (void *) &p->params.ring_ipv6_ras;
case PIPELINE_PORT_OUT_SCHED_WRITER:
return (void *) &p->params.sched;
+ case PIPELINE_PORT_OUT_FD_WRITER:
+ return (void *) &p->params.fd;
#ifdef RTE_LIBRTE_KNI
case PIPELINE_PORT_OUT_KNI_WRITER:
return (void *) &p->params.kni;
@@ -219,6 +230,8 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params *p)
return &rte_port_ring_writer_ipv6_ras_ops;
case PIPELINE_PORT_OUT_SCHED_WRITER:
return &rte_port_sched_writer_ops;
+ case PIPELINE_PORT_OUT_FD_WRITER:
+ return &rte_port_fd_writer_ops;
#ifdef RTE_LIBRTE_KNI
case PIPELINE_PORT_OUT_KNI_WRITER:
return &rte_port_kni_writer_ops;
--
2.5.5
^ permalink raw reply related
* [PATCH v3 1/3] lib/librte_port: enable file descriptor port support
From: Jasvinder Singh @ 2016-10-13 9:17 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
In-Reply-To: <1472999921-43283-1-git-send-email-jasvinder.singh@intel.com>
This patch adds File Descriptor(FD) port type (e.g. TAP port) to the
packet framework library that allows interface with the kernel network
stack. The FD port APIs are defined that allow port creation, writing
and reading packet from the kernel interface.
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
v3:
- fix compilation error when stats collection enabled
v2:
- fix checkpatch warnings
lib/librte_port/Makefile | 2 +
lib/librte_port/rte_port_fd.c | 552 +++++++++++++++++++++++++++++++++++
lib/librte_port/rte_port_fd.h | 105 +++++++
lib/librte_port/rte_port_version.map | 9 +
4 files changed, 668 insertions(+)
create mode 100644 lib/librte_port/rte_port_fd.c
create mode 100644 lib/librte_port/rte_port_fd.h
diff --git a/lib/librte_port/Makefile b/lib/librte_port/Makefile
index 3d84a0e..44fa735 100644
--- a/lib/librte_port/Makefile
+++ b/lib/librte_port/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PORT) += rte_port_frag.c
SRCS-$(CONFIG_RTE_LIBRTE_PORT) += rte_port_ras.c
endif
SRCS-$(CONFIG_RTE_LIBRTE_PORT) += rte_port_sched.c
+SRCS-$(CONFIG_RTE_LIBRTE_PORT) += rte_port_fd.c
ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
SRCS-$(CONFIG_RTE_LIBRTE_PORT) += rte_port_kni.c
endif
@@ -70,6 +71,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_PORT)-include += rte_port_frag.h
SYMLINK-$(CONFIG_RTE_LIBRTE_PORT)-include += rte_port_ras.h
endif
SYMLINK-$(CONFIG_RTE_LIBRTE_PORT)-include += rte_port_sched.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_PORT)-include += rte_port_fd.h
ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
SYMLINK-$(CONFIG_RTE_LIBRTE_PORT)-include += rte_port_kni.h
endif
diff --git a/lib/librte_port/rte_port_fd.c b/lib/librte_port/rte_port_fd.c
new file mode 100644
index 0000000..0d640f3
--- /dev/null
+++ b/lib/librte_port/rte_port_fd.c
@@ -0,0 +1,552 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+
+#include "rte_port_fd.h"
+
+/*
+ * Port FD Reader
+ */
+#ifdef RTE_PORT_STATS_COLLECT
+
+#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val) \
+ do { port->stats.n_pkts_in += val; } while (0)
+#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val) \
+ do { port->stats.n_pkts_drop += val; } while (0)
+
+#else
+
+#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
+struct rte_port_fd_reader {
+ struct rte_port_in_stats stats;
+ int fd;
+ uint32_t mtu;
+ struct rte_mempool *mempool;
+};
+
+static void *
+rte_port_fd_reader_create(void *params, int socket_id)
+{
+ struct rte_port_fd_reader_params *conf =
+ (struct rte_port_fd_reader_params *) params;
+ struct rte_port_fd_reader *port;
+
+ /* Check input parameters */
+ if (conf == NULL) {
+ RTE_LOG(ERR, PORT, "%s: params is NULL\n", __func__);
+ return NULL;
+ }
+ if (conf->fd < 0) {
+ RTE_LOG(ERR, PORT, "%s: Invalid file descriptor\n", __func__);
+ return NULL;
+ }
+ if (conf->mtu == 0) {
+ RTE_LOG(ERR, PORT, "%s: Invalid MTU\n", __func__);
+ return NULL;
+ }
+ if (conf->mempool == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Invalid mempool\n", __func__);
+ return NULL;
+ }
+
+ /* Memory allocation */
+ port = rte_zmalloc_socket("PORT", sizeof(*port),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__);
+ return NULL;
+ }
+
+ /* Initialization */
+ port->fd = conf->fd;
+ port->mtu = conf->mtu;
+ port->mempool = conf->mempool;
+
+ return port;
+}
+
+static int
+rte_port_fd_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
+{
+ struct rte_port_fd_reader *p = (struct rte_port_fd_reader *) port;
+ uint32_t i;
+
+ if (rte_mempool_get_bulk(p->mempool, (void **) pkts, n_pkts) != 0)
+ return 0;
+
+ for (i = 0; i < n_pkts; i++) {
+ rte_mbuf_refcnt_set(pkts[i], 1);
+ rte_pktmbuf_reset(pkts[i]);
+ }
+
+ for (i = 0; i < n_pkts; i++) {
+ struct rte_mbuf *pkt = pkts[i];
+ void *pkt_data = rte_pktmbuf_mtod(pkt, void *);
+ ssize_t n_bytes;
+
+ n_bytes = read(p->fd, pkt_data, (size_t) p->mtu);
+ if (n_bytes <= 0)
+ break;
+
+ pkt->data_len = n_bytes;
+ pkt->pkt_len = n_bytes;
+ }
+
+ for ( ; i < n_pkts; i++)
+ rte_pktmbuf_free(pkts[i]);
+
+ RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(p, i);
+
+ return n_pkts;
+}
+
+static int
+rte_port_fd_reader_free(void *port)
+{
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: port is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ rte_free(port);
+
+ return 0;
+}
+
+static int rte_port_fd_reader_stats_read(void *port,
+ struct rte_port_in_stats *stats, int clear)
+{
+ struct rte_port_fd_reader *p =
+ (struct rte_port_fd_reader *) port;
+
+ if (stats != NULL)
+ memcpy(stats, &p->stats, sizeof(p->stats));
+
+ if (clear)
+ memset(&p->stats, 0, sizeof(p->stats));
+
+ return 0;
+}
+
+/*
+ * Port FD Writer
+ */
+#ifdef RTE_PORT_STATS_COLLECT
+
+#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val) \
+ do { port->stats.n_pkts_in += val; } while (0)
+#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val) \
+ do { port->stats.n_pkts_drop += val; } while (0)
+
+#else
+
+#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
+struct rte_port_fd_writer {
+ struct rte_port_out_stats stats;
+
+ struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
+ uint32_t tx_burst_sz;
+ uint16_t tx_buf_count;
+ uint32_t fd;
+};
+
+static void *
+rte_port_fd_writer_create(void *params, int socket_id)
+{
+ struct rte_port_fd_writer_params *conf =
+ (struct rte_port_fd_writer_params *) params;
+ struct rte_port_fd_writer *port;
+
+ /* Check input parameters */
+ if ((conf == NULL) ||
+ (conf->tx_burst_sz == 0) ||
+ (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
+ (!rte_is_power_of_2(conf->tx_burst_sz))) {
+ RTE_LOG(ERR, PORT, "%s: Invalid input parameters\n", __func__);
+ return NULL;
+ }
+
+ /* Memory allocation */
+ port = rte_zmalloc_socket("PORT", sizeof(*port),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__);
+ return NULL;
+ }
+
+ /* Initialization */
+ port->fd = conf->fd;
+ port->tx_burst_sz = conf->tx_burst_sz;
+ port->tx_buf_count = 0;
+
+ return port;
+}
+
+static inline void
+send_burst(struct rte_port_fd_writer *p)
+{
+ uint32_t i;
+
+ for (i = 0; i < p->tx_buf_count; i++) {
+ struct rte_mbuf *pkt = p->tx_buf[i];
+ void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
+ size_t n_bytes = rte_pktmbuf_data_len(pkt);
+ ssize_t ret;
+
+ ret = write(p->fd, pkt_data, n_bytes);
+ if (ret < 0)
+ break;
+ }
+
+ RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
+
+ for (i = 0; i < p->tx_buf_count; i++)
+ rte_pktmbuf_free(p->tx_buf[i]);
+
+ p->tx_buf_count = 0;
+}
+
+static int
+rte_port_fd_writer_tx(void *port, struct rte_mbuf *pkt)
+{
+ struct rte_port_fd_writer *p =
+ (struct rte_port_fd_writer *) port;
+
+ p->tx_buf[p->tx_buf_count++] = pkt;
+ RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
+ if (p->tx_buf_count >= p->tx_burst_sz)
+ send_burst(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_tx_bulk(void *port,
+ struct rte_mbuf **pkts,
+ uint64_t pkts_mask)
+{
+ struct rte_port_fd_writer *p =
+ (struct rte_port_fd_writer *) port;
+ uint32_t tx_buf_count = p->tx_buf_count;
+
+ if ((pkts_mask & (pkts_mask + 1)) == 0) {
+ uint64_t n_pkts = __builtin_popcountll(pkts_mask);
+ uint32_t i;
+
+ for (i = 0; i < n_pkts; i++)
+ p->tx_buf[tx_buf_count++] = pkts[i];
+ RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
+ } else
+ for ( ; pkts_mask; ) {
+ uint32_t pkt_index = __builtin_ctzll(pkts_mask);
+ uint64_t pkt_mask = 1LLU << pkt_index;
+ struct rte_mbuf *pkt = pkts[pkt_index];
+
+ p->tx_buf[tx_buf_count++] = pkt;
+ RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
+ pkts_mask &= ~pkt_mask;
+ }
+
+ p->tx_buf_count = tx_buf_count;
+ if (tx_buf_count >= p->tx_burst_sz)
+ send_burst(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_flush(void *port)
+{
+ struct rte_port_fd_writer *p =
+ (struct rte_port_fd_writer *) port;
+
+ if (p->tx_buf_count > 0)
+ send_burst(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_free(void *port)
+{
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Port is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ rte_port_fd_writer_flush(port);
+ rte_free(port);
+
+ return 0;
+}
+
+static int rte_port_fd_writer_stats_read(void *port,
+ struct rte_port_out_stats *stats, int clear)
+{
+ struct rte_port_fd_writer *p =
+ (struct rte_port_fd_writer *) port;
+
+ if (stats != NULL)
+ memcpy(stats, &p->stats, sizeof(p->stats));
+
+ if (clear)
+ memset(&p->stats, 0, sizeof(p->stats));
+
+ return 0;
+}
+
+/*
+ * Port FD Writer Nodrop
+ */
+#ifdef RTE_PORT_STATS_COLLECT
+
+#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
+ do { port->stats.n_pkts_in += val; } while (0)
+#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
+ do { port->stats.n_pkts_drop += val; } while (0)
+
+#else
+
+#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
+struct rte_port_fd_writer_nodrop {
+ struct rte_port_out_stats stats;
+
+ struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
+ uint32_t tx_burst_sz;
+ uint16_t tx_buf_count;
+ uint64_t n_retries;
+ uint32_t fd;
+};
+
+static void *
+rte_port_fd_writer_nodrop_create(void *params, int socket_id)
+{
+ struct rte_port_fd_writer_nodrop_params *conf =
+ (struct rte_port_fd_writer_nodrop_params *) params;
+ struct rte_port_fd_writer_nodrop *port;
+
+ /* Check input parameters */
+ if ((conf == NULL) ||
+ (conf->fd < 0) ||
+ (conf->tx_burst_sz == 0) ||
+ (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
+ (!rte_is_power_of_2(conf->tx_burst_sz))) {
+ RTE_LOG(ERR, PORT, "%s: Invalid input parameters\n", __func__);
+ return NULL;
+ }
+
+ /* Memory allocation */
+ port = rte_zmalloc_socket("PORT", sizeof(*port),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__);
+ return NULL;
+ }
+
+ /* Initialization */
+ port->fd = conf->fd;
+ port->tx_burst_sz = conf->tx_burst_sz;
+ port->tx_buf_count = 0;
+
+ /*
+ * When n_retries is 0 it means that we should wait for every packet to
+ * send no matter how many retries should it take. To limit number of
+ * branches in fast path, we use UINT64_MAX instead of branching.
+ */
+ port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
+
+ return port;
+}
+
+static inline void
+send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)
+{
+ uint64_t n_retries;
+ uint32_t i;
+
+ n_retries = 0;
+ for (i = 0; (i < p->tx_buf_count) && (n_retries < p->n_retries); i++) {
+ struct rte_mbuf *pkt = p->tx_buf[i];
+ void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
+ size_t n_bytes = rte_pktmbuf_data_len(pkt);
+
+ for ( ; n_retries < p->n_retries; n_retries++) {
+ ssize_t ret;
+
+ ret = write(p->fd, pkt_data, n_bytes);
+ if (ret)
+ break;
+ }
+ }
+
+ RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
+
+ for (i = 0; i < p->tx_buf_count; i++)
+ rte_pktmbuf_free(p->tx_buf[i]);
+
+ p->tx_buf_count = 0;
+}
+
+static int
+rte_port_fd_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
+{
+ struct rte_port_fd_writer_nodrop *p =
+ (struct rte_port_fd_writer_nodrop *) port;
+
+ p->tx_buf[p->tx_buf_count++] = pkt;
+ RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
+ if (p->tx_buf_count >= p->tx_burst_sz)
+ send_burst_nodrop(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_nodrop_tx_bulk(void *port,
+ struct rte_mbuf **pkts,
+ uint64_t pkts_mask)
+{
+ struct rte_port_fd_writer_nodrop *p =
+ (struct rte_port_fd_writer_nodrop *) port;
+ uint32_t tx_buf_count = p->tx_buf_count;
+
+ if ((pkts_mask & (pkts_mask + 1)) == 0) {
+ uint64_t n_pkts = __builtin_popcountll(pkts_mask);
+ uint32_t i;
+
+ for (i = 0; i < n_pkts; i++)
+ p->tx_buf[tx_buf_count++] = pkts[i];
+ RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
+ } else
+ for ( ; pkts_mask; ) {
+ uint32_t pkt_index = __builtin_ctzll(pkts_mask);
+ uint64_t pkt_mask = 1LLU << pkt_index;
+ struct rte_mbuf *pkt = pkts[pkt_index];
+
+ p->tx_buf[tx_buf_count++] = pkt;
+ RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
+ pkts_mask &= ~pkt_mask;
+ }
+
+ p->tx_buf_count = tx_buf_count;
+ if (tx_buf_count >= p->tx_burst_sz)
+ send_burst_nodrop(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_nodrop_flush(void *port)
+{
+ struct rte_port_fd_writer_nodrop *p =
+ (struct rte_port_fd_writer_nodrop *) port;
+
+ if (p->tx_buf_count > 0)
+ send_burst_nodrop(p);
+
+ return 0;
+}
+
+static int
+rte_port_fd_writer_nodrop_free(void *port)
+{
+ if (port == NULL) {
+ RTE_LOG(ERR, PORT, "%s: Port is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ rte_port_fd_writer_nodrop_flush(port);
+ rte_free(port);
+
+return 0;
+}
+
+static int rte_port_fd_writer_nodrop_stats_read(void *port,
+ struct rte_port_out_stats *stats, int clear)
+{
+ struct rte_port_fd_writer_nodrop *p =
+ (struct rte_port_fd_writer_nodrop *) port;
+
+ if (stats != NULL)
+ memcpy(stats, &p->stats, sizeof(p->stats));
+
+ if (clear)
+ memset(&p->stats, 0, sizeof(p->stats));
+
+ return 0;
+}
+
+/*
+ * Summary of port operations
+ */
+struct rte_port_in_ops rte_port_fd_reader_ops = {
+ .f_create = rte_port_fd_reader_create,
+ .f_free = rte_port_fd_reader_free,
+ .f_rx = rte_port_fd_reader_rx,
+ .f_stats = rte_port_fd_reader_stats_read,
+};
+
+struct rte_port_out_ops rte_port_fd_writer_ops = {
+ .f_create = rte_port_fd_writer_create,
+ .f_free = rte_port_fd_writer_free,
+ .f_tx = rte_port_fd_writer_tx,
+ .f_tx_bulk = rte_port_fd_writer_tx_bulk,
+ .f_flush = rte_port_fd_writer_flush,
+ .f_stats = rte_port_fd_writer_stats_read,
+};
+
+struct rte_port_out_ops rte_port_fd_writer_nodrop_ops = {
+ .f_create = rte_port_fd_writer_nodrop_create,
+ .f_free = rte_port_fd_writer_nodrop_free,
+ .f_tx = rte_port_fd_writer_nodrop_tx,
+ .f_tx_bulk = rte_port_fd_writer_nodrop_tx_bulk,
+ .f_flush = rte_port_fd_writer_nodrop_flush,
+ .f_stats = rte_port_fd_writer_nodrop_stats_read,
+};
diff --git a/lib/librte_port/rte_port_fd.h b/lib/librte_port/rte_port_fd.h
new file mode 100644
index 0000000..77a2d31
--- /dev/null
+++ b/lib/librte_port/rte_port_fd.h
@@ -0,0 +1,105 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INCLUDE_RTE_PORT_FD_H__
+#define __INCLUDE_RTE_PORT_FD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * RTE Port FD Device
+ *
+ * fd_reader: input port built on top of valid non-blocking file descriptor
+ * fd_writer: output port built on top of valid non-blocking file descriptor
+ *
+ ***/
+
+#include <stdint.h>
+
+#include <rte_mempool.h>
+#include "rte_port.h"
+
+/** fd_reader port parameters */
+struct rte_port_fd_reader_params {
+ /** File descriptor */
+ int fd;
+
+ /** Maximum Transfer Unit (MTU) */
+ uint32_t mtu;
+
+ /** Pre-initialized buffer pool */
+ struct rte_mempool *mempool;
+};
+
+/** fd_reader port operations */
+extern struct rte_port_in_ops rte_port_fd_reader_ops;
+
+/** fd_writer port parameters */
+struct rte_port_fd_writer_params {
+ /** File descriptor */
+ int fd;
+
+ /**< Recommended write burst size. The actual burst size can be
+ * bigger or smaller than this value.
+ */
+ uint32_t tx_burst_sz;
+};
+
+/** fd_writer port operations */
+extern struct rte_port_out_ops rte_port_fd_writer_ops;
+
+/** fd_writer_nodrop port parameters */
+struct rte_port_fd_writer_nodrop_params {
+ /** File descriptor */
+ int fd;
+
+ /**< Recommended write burst size. The actual burst size can be
+ * bigger or smaller than this value.
+ */
+ uint32_t tx_burst_sz;
+
+ /** Maximum number of retries, 0 for no limit */
+ uint32_t n_retries;
+};
+
+/** fd_writer_nodrop port operations */
+extern struct rte_port_out_ops rte_port_fd_writer_nodrop_ops;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map
index 048c20d..6470629 100644
--- a/lib/librte_port/rte_port_version.map
+++ b/lib/librte_port/rte_port_version.map
@@ -42,3 +42,12 @@ DPDK_16.07 {
rte_port_kni_writer_nodrop_ops;
} DPDK_2.2;
+
+DPDK_16.11 {
+ global:
+
+ rte_port_fd_reader_ops;
+ rte_port_fd_writer_ops;
+ rte_port_fd_writer_nodrop_ops;
+
+} DPDK_16.07;
--
2.5.5
^ permalink raw reply related
* Re: [PATCH] examples/l2fwd-crypto: fix verify with decrypt in chain
From: Jastrzebski, MichalX K @ 2016-10-13 8:48 UTC (permalink / raw)
To: Azarewicz, PiotrX T, De Lara Guarch, Pablo, Yang, GangX; +Cc: dev@dpdk.org
In-Reply-To: <1476262724-164925-1-git-send-email-piotrx.t.azarewicz@intel.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Piotr Azarewicz
> Sent: Wednesday, October 12, 2016 10:59 AM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Yang, GangX
> <gangx.yang@intel.com>
> Cc: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH] examples/l2fwd-crypto: fix verify with decrypt
> in chain
>
> This patch fix setting crypto operation data parameters in l2fwd-crypto
> application.
> From now decryption in chain with auth verify work fine.
>
> How to reproduce the issue:
>
> 1. Run l2fwd_crypto with command:
> -c 0x3 -n 4 --vdev "crypto_aesni_mb" \
> --vdev "crypto_aesni_mb" \
> -- -p 0x3 --chain CIPHER_HASH \
> --cipher_op ENCRYPT --cipher_algo AES_CBC \
> --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f \
> --iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff \
> --auth_op GENERATE --auth_algo SHA1_HMAC \
> --auth_key
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
>
> 2. Send packet with payload and capture forwarded packet.
> Payload in forwarded packet is encrypted, what is good.
>
> 3. Run l2fwd_crypto with command:
> -c 0x3 -n 4 --vdev "crypto_aesni_mb" \
> --vdev "crypto_aesni_mb" \
> -- -p 0x3 --chain HASH_CIPHER \
> --cipher_op DECRYPT --cipher_algo AES_CBC \
> --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f \
> --iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff \
> --auth_op VERIFY --auth_algo SHA1_HMAC \
> --auth_key
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:
> 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
>
> 4. Send earlier captured packet and capture forwarded packet.
> Payload in newly captured packet is not decrypted, what is wrong.
>
> Fixes: 387259bd6c67 ("examples/l2fwd-crypto: add sample application")
>
> Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
> ---
> examples/l2fwd-crypto/main.c | 23 ++++++++---------------
> 1 file changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
> index dae45f5..43fef59 100644
> --- a/examples/l2fwd-crypto/main.c
> +++ b/examples/l2fwd-crypto/main.c
> @@ -451,6 +451,10 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf
> *m,
>
> /* Zero pad data to be crypto'd so it is block aligned */
> data_len = rte_pktmbuf_data_len(m) - ipdata_offset;
> +
> + if (cparams->do_hash && cparams->hash_verify)
> + data_len -= cparams->digest_length;
> +
> pad_len = data_len % cparams->block_size ? cparams->block_size -
> (data_len % cparams->block_size) : 0;
>
> @@ -472,8 +476,8 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m,
> op->sym->auth.digest.data = (uint8_t
> *)rte_pktmbuf_append(m,
> cparams->digest_length);
> } else {
> - op->sym->auth.digest.data = (uint8_t
> *)rte_pktmbuf_append(m,
> - cparams->digest_length);
> + op->sym->auth.digest.data = rte_pktmbuf_mtod(m,
> + uint8_t *) + ipdata_offset + data_len;
> }
>
> op->sym->auth.digest.phys_addr =
> rte_pktmbuf_mtophys_offset(m,
> @@ -508,21 +512,10 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf
> *m,
> cparams->cipher_algo ==
> RTE_CRYPTO_CIPHER_KASUMI_F8 ||
> cparams->cipher_algo ==
> RTE_CRYPTO_CIPHER_ZUC_EEA3) {
> op->sym->cipher.data.offset = ipdata_offset << 3;
> - if (cparams->do_hash && cparams->hash_verify)
> - /* Do not cipher the hash tag */
> - op->sym->cipher.data.length = (data_len -
> - cparams->digest_length) << 3;
> - else
> - op->sym->cipher.data.length = data_len << 3;
> -
> + op->sym->cipher.data.length = data_len << 3;
> } else {
> op->sym->cipher.data.offset = ipdata_offset;
> - if (cparams->do_hash && cparams->hash_verify)
> - /* Do not cipher the hash tag */
> - op->sym->cipher.data.length = data_len -
> - cparams->digest_length;
> - else
> - op->sym->cipher.data.length = data_len;
> + op->sym->cipher.data.length = data_len;
> }
> }
>
> --
> 1.7.9.5
Acked-by: Michal Jastrzebski <michalx.k.jastrzebski@intel.com>
^ permalink raw reply
* Re: [PATCH v2] app/test: fix crypto mbuf pool size
From: Jastrzebski, MichalX K @ 2016-10-13 8:47 UTC (permalink / raw)
To: Azarewicz, PiotrX T, Trahe, Fiona; +Cc: dev@dpdk.org
In-Reply-To: <1476180413-241502-1-git-send-email-piotrx.t.azarewicz@intel.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Piotr Azarewicz
> Sent: Tuesday, October 11, 2016 12:07 PM
> To: Trahe, Fiona <fiona.trahe@intel.com>
> Cc: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2] app/test: fix crypto mbuf pool size
>
> This patch fix that created pool for crypto mbufs may be too big in some
> environments.
> To avoid the issue, mbuf pool is reverted to its previous size.
> Moreover, here is added additional small pool with one large mbuf, what
> is needed in large data test scenarios.
>
> Fixes: ffbe3be0d4b5 ("app/test: add libcrypto")
>
> Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
> ---
>
> v2 change:
> - changed check if aad.len > MBUF_SIZE
> - added assertion check for rte_pktmbuf_alloc
>
> app/test/test_cryptodev.c | 32 +++++++++++++++++++++++++++++---
> 1 file changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
> index 2917454..7d03899 100644
> --- a/app/test/test_cryptodev.c
> +++ b/app/test/test_cryptodev.c
> @@ -60,6 +60,7 @@ static enum rte_cryptodev_type gbl_cryptodev_type;
>
> struct crypto_testsuite_params {
> struct rte_mempool *mbuf_pool;
> + struct rte_mempool *large_mbuf_pool;
> struct rte_mempool *op_mpool;
> struct rte_cryptodev_config conf;
> struct rte_cryptodev_qp_conf qp_conf;
> @@ -169,7 +170,7 @@ testsuite_setup(void)
> /* Not already created so create */
> ts_params->mbuf_pool = rte_pktmbuf_pool_create(
> "CRYPTO_MBUFPOOL",
> - NUM_MBUFS, MBUF_CACHE_SIZE, 0,
> UINT16_MAX,
> + NUM_MBUFS, MBUF_CACHE_SIZE, 0,
> MBUF_SIZE,
> rte_socket_id());
> if (ts_params->mbuf_pool == NULL) {
> RTE_LOG(ERR, USER1, "Can't create
> CRYPTO_MBUFPOOL\n");
> @@ -177,6 +178,21 @@ testsuite_setup(void)
> }
> }
>
> + ts_params->large_mbuf_pool = rte_mempool_lookup(
> + "CRYPTO_LARGE_MBUFPOOL");
> + if (ts_params->large_mbuf_pool == NULL) {
> + /* Not already created so create */
> + ts_params->large_mbuf_pool = rte_pktmbuf_pool_create(
> + "CRYPTO_LARGE_MBUFPOOL",
> + 1, 0, 0, UINT16_MAX,
> + rte_socket_id());
> + if (ts_params->large_mbuf_pool == NULL) {
> + RTE_LOG(ERR, USER1,
> + "Can't create
> CRYPTO_LARGE_MBUFPOOL\n");
> + return TEST_FAILED;
> + }
> + }
> +
> ts_params->op_mpool = rte_crypto_op_pool_create(
> "MBUF_CRYPTO_SYM_OP_POOL",
> RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> @@ -5149,7 +5165,12 @@ test_AES_GMAC_authentication(const struct
> gmac_test_data *tdata)
> if (retval < 0)
> return retval;
>
> - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
> + if (tdata->aad.len > MBUF_SIZE)
> + ut_params->ibuf = rte_pktmbuf_alloc(ts_params-
> >large_mbuf_pool);
> + else
> + ut_params->ibuf = rte_pktmbuf_alloc(ts_params-
> >mbuf_pool);
> + TEST_ASSERT_NOT_NULL(ut_params->ibuf,
> + "Failed to allocate input buffer in mempool");
>
> memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
> rte_pktmbuf_tailroom(ut_params->ibuf));
> @@ -5233,7 +5254,12 @@ test_AES_GMAC_authentication_verify(const
> struct gmac_test_data *tdata)
> if (retval < 0)
> return retval;
>
> - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
> + if (tdata->aad.len > MBUF_SIZE)
> + ut_params->ibuf = rte_pktmbuf_alloc(ts_params-
> >large_mbuf_pool);
> + else
> + ut_params->ibuf = rte_pktmbuf_alloc(ts_params-
> >mbuf_pool);
> + TEST_ASSERT_NOT_NULL(ut_params->ibuf,
> + "Failed to allocate input buffer in mempool");
>
> memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
> rte_pktmbuf_tailroom(ut_params->ibuf));
> --
> 1.7.9.5
Acked-by: Michal Jastrzebski <michalx.k.jastrzebski@intel.com>
^ permalink raw reply
* Re: [PATCH v2 10/12] virtio: add Tx checksum offload support
From: Yuanhan Liu @ 2016-10-13 8:38 UTC (permalink / raw)
To: Olivier Matz
Cc: dev, konstantin.ananyev, sugesh.chandran, bruce.richardson,
jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
xiao.w.wang
In-Reply-To: <1475485223-30566-11-git-send-email-olivier.matz@6wind.com>
On Mon, Oct 03, 2016 at 11:00:21AM +0200, Olivier Matz wrote:
> + /* Checksum Offload */
> + switch (cookie->ol_flags & PKT_TX_L4_MASK) {
> + case PKT_TX_UDP_CKSUM:
> + hdr->csum_start = cookie->l2_len + cookie->l3_len;
> + hdr->csum_offset = 6;
> + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
> + break;
> +
> + case PKT_TX_TCP_CKSUM:
> + hdr->csum_start = cookie->l2_len + cookie->l3_len;
> + hdr->csum_offset = 16;
I would suggest to use "offsetof(...)" here, instead of some magic
number like 16.
--yliu
^ permalink raw reply
* Re: [PATCH] examples/l3fwd: enabling 4m hash for all 64 bit archs
From: Thomas Monjalon @ 2016-10-13 8:22 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev
In-Reply-To: <1471964080-29958-2-git-send-email-hemant.agrawal@nxp.com>
2016-08-23 20:24, Hemant Agrawal:
> This patch enables the support for 4 million hash entries
> for all 64 bit architectures.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Applied, thanks
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox