DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] e1000/base: announce supported NICs
From: Wenzhuo Lu @ 2016-11-27 18:11 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Wenzhuo Lu

Announce the support of I219 NICs. Also add all the
other supported NICs.

Add Intel I219 NICs support in release note too.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 doc/guides/rel_notes/release_17_02.rst |  4 ++++
 drivers/net/e1000/base/README          | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 3b65038..a9380a4 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -38,6 +38,10 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+   * **Support I219 NICs.**
+
+     Add the support for the I219 NICs, which is Intel 1 Gigabit NICs.
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/e1000/base/README b/drivers/net/e1000/base/README
index 6cdd9b3..de1ae4c 100644
--- a/drivers/net/e1000/base/README
+++ b/drivers/net/e1000/base/README
@@ -34,6 +34,27 @@ This directory contains source code of FreeBSD em & igb drivers of version
 cid-shared-code.2016.11.22 released by ND. The sub-directory of base/
 contains the original source package.
 
+This driver is valid for the product(s) listed below
+* Intel® Ethernet Controller 82540
+* Intel® Ethernet Controller 82545 Series
+* Intel® Ethernet Controller 82546 Series
+* Intel® Ethernet Controller 82571 Series
+* Intel® Ethernet Controller 82572 Series
+* Intel® Ethernet Controller 82573
+* Intel® Ethernet Controller 82574
+* Intel® Ethernet Controller 82583
+* Intel® Ethernet Controller I217 Series
+* Intel® Ethernet Controller I218 Series
+* Intel® Ethernet Controller I219 Series
+* Intel® Ethernet Controller 82576 Series
+* Intel® Ethernet Controller 82575 Series
+* Intel® Ethernet Controller 82580 Series
+* Intel® Ethernet Controller I350 Series
+* Intel® Ethernet Controller I210 Series
+* Intel® Ethernet Controller I211
+* Intel® Ethernet Controller I354 Series
+* Intel® Ethernet Controller DH89XXCC Series
+
 Updating the driver
 ===================
 
-- 
1.9.3

^ permalink raw reply related

* Re: [PATCH] i40e: fix oversize packet counter not incrementing for large packets
From: Wu, Jingjing @ 2016-11-28  2:19 UTC (permalink / raw)
  To: Michael Bieniek, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1480098063-29246-1-git-send-email-michaelbieniekdpdk@gmail.com>



> -----Original Message-----
> From: Michael Bieniek [mailto:michaelbieniekdpdk@gmail.com]
> Sent: Saturday, November 26, 2016 2:21 AM
> To: Zhang, Helin <helin.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Michael Bieniek <michaelbieniekdpdk@gmail.com>
> Subject: [PATCH] i40e: fix oversize packet counter not incrementing for large
> packets
> 
> The XL710 requires that the Set MAC Config command be used to define the
> maximum frame size in order for the Receive Oversize Count register
> (GLPRT_ROC) to be incremented for packets received that are greater than the
> MTU. Without this change, the XL710 will drop the oversized packets without
> incrementing the corresponding counter.
> 
> Signed-off-by: Michael Bieniek <michaelbieniekdpdk@gmail.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 67778ba..c11c80b 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -9709,6 +9709,7 @@ static int
>  i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)  {
>  	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> +	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct rte_eth_dev_data *dev_data = pf->dev_data;
>  	uint32_t frame_size = mtu + ETHER_HDR_LEN
>  			      + ETHER_CRC_LEN + I40E_VLAN_TAG_SIZE; @@ -
> 9732,6 +9733,7 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  		dev_data->dev_conf.rxmode.jumbo_frame = 0;
> 
>  	dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
> +	i40e_aq_set_mac_config(hw, frame_size, TRUE, 0, NULL);
> 
>  	return ret;
>  }

If you look into the eth_i40e_dev_init, you will find the mac's maximum frame size
Has been set to I40E_FRAME_SIZE_MAX (0x2600). Then the changing of maximum
frame size is by the setting in queues.

If change the frame size on mac, the maximum frame size will not only works on
PF but also VF. 

Thanks
Jingjing

^ permalink raw reply

* Re: [PATCH 00/16] e1000 base code update
From: Lu, Wenzhuo @ 2016-11-28  1:16 UTC (permalink / raw)
  To: Yigit, Ferruh, dev@dpdk.org
In-Reply-To: <b3bc9072-3532-544d-5c59-219eae9d56e3@intel.com>

Hi Ferruh,


> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Friday, November 25, 2016 8:58 PM
> To: Lu, Wenzhuo; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 00/16] e1000 base code update
> 
> Hi Wenzhuo,
> 
> On 11/23/2016 5:22 PM, Wenzhuo Lu wrote:
> > Updated e1000 base code to fix several bugs and support
> > i219 NICs.
> >
> > Wenzhuo Lu (16):
> >   e1000/base: increased ULP timer
> >   e1000/base: increase PHY PLL clock gate timing
> >   e1000/base: try more times to get HW mailbox lock
> >   e1000/base: add getting HW version support for i354
> >   e1000/base: expose e1000_write_vfta_i350
> >   e1000/base: add max RX jumbo frame define
> >   e1000/base: restore link speed after ULP exit
> >   e1000/base: clear ULP configuration register on ULP exit
> >   e1000/base: increase LANPHYPC low duration
> >   e1000/base: workaround for ULP entry flow
> >   e1000/base: enable new i219 devices
> >   e1000/base: always request clock during K1 at 1G link speed
> >   e1000/base: ability to force K1-off disabled
> >   e1000/base: support more i219 devices
> >   e1000/base: update readme
> >   e1000: add new i219 devices
> >
> >  drivers/net/e1000/base/README          |   4 +-
> >  drivers/net/e1000/base/e1000_82575.c   |   1 -
> >  drivers/net/e1000/base/e1000_82575.h   |   1 +
> >  drivers/net/e1000/base/e1000_api.c     |  19 +
> >  drivers/net/e1000/base/e1000_defines.h |   9 +
> >  drivers/net/e1000/base/e1000_hw.h      |  21 +-
> >  drivers/net/e1000/base/e1000_ich8lan.c | 865
> > +++++++++++++++++++++++++++++++--
> drivers/net/e1000/base/e1000_ich8lan.h |  21 +-
> >  drivers/net/e1000/base/e1000_mbx.c     |  36 +-
> >  drivers/net/e1000/base/e1000_nvm.c     |   1 +
> >  drivers/net/e1000/base/e1000_regs.h    |   7 +
> >  drivers/net/e1000/em_ethdev.c          |  34 +-
> >  12 files changed, 949 insertions(+), 70 deletions(-)
> >
> 
> Based on this pathset.
> 
> Can you also please send another patch to:
> 1- add I219 to supported nics list
> 2- announce new supported nic in release notes.
> 
> Also as far as I can see there is no igb/e1000 documentation under
> doc/guides/nics/*, it can good to provide one, not with above requested
> patches perhaps, but in some suitable time.
I'll handle them. Thanks for the reminder :)

> 
> Thanks,
> Ferruh

^ permalink raw reply

* Re: [PATCH 00/16] e1000 base code update
From: Lu, Wenzhuo @ 2016-11-28  1:15 UTC (permalink / raw)
  To: Yigit, Ferruh, dev@dpdk.org
In-Reply-To: <d39368c9-b337-29cd-905a-bc6f93638cd1@intel.com>

Hi Ferruh,

> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Friday, November 25, 2016 8:54 PM
> To: Lu, Wenzhuo; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 00/16] e1000 base code update
> 
> On 11/23/2016 5:22 PM, Wenzhuo Lu wrote:
> > Updated e1000 base code to fix several bugs and support
> > i219 NICs.
> >
> > Wenzhuo Lu (16):
> >   e1000/base: increased ULP timer
> >   e1000/base: increase PHY PLL clock gate timing
> >   e1000/base: try more times to get HW mailbox lock
> >   e1000/base: add getting HW version support for i354
> >   e1000/base: expose e1000_write_vfta_i350
> >   e1000/base: add max RX jumbo frame define
> >   e1000/base: restore link speed after ULP exit
> >   e1000/base: clear ULP configuration register on ULP exit
> >   e1000/base: increase LANPHYPC low duration
> >   e1000/base: workaround for ULP entry flow
> >   e1000/base: enable new i219 devices
> >   e1000/base: always request clock during K1 at 1G link speed
> >   e1000/base: ability to force K1-off disabled
> >   e1000/base: support more i219 devices
> >   e1000/base: update readme
> >   e1000: add new i219 devices
> >
> >  drivers/net/e1000/base/README          |   4 +-
> >  drivers/net/e1000/base/e1000_82575.c   |   1 -
> >  drivers/net/e1000/base/e1000_82575.h   |   1 +
> >  drivers/net/e1000/base/e1000_api.c     |  19 +
> >  drivers/net/e1000/base/e1000_defines.h |   9 +
> >  drivers/net/e1000/base/e1000_hw.h      |  21 +-
> >  drivers/net/e1000/base/e1000_ich8lan.c | 865
> > +++++++++++++++++++++++++++++++--
> drivers/net/e1000/base/e1000_ich8lan.h |  21 +-
> >  drivers/net/e1000/base/e1000_mbx.c     |  36 +-
> >  drivers/net/e1000/base/e1000_nvm.c     |   1 +
> >  drivers/net/e1000/base/e1000_regs.h    |   7 +
> >  drivers/net/e1000/em_ethdev.c          |  34 +-
> >  12 files changed, 949 insertions(+), 70 deletions(-)
> >
> 
> Series applied to dpdk-next-net/master, thanks.
> 
> Some modifications done in both commit subject and logs, can you please
> double check the updates.
Thanks for applying these patches!
I've checked them. Everything is fine:)

^ permalink raw reply

* [PATCH] net/i40evf: fix casting between structs
From: Jingjing Wu @ 2016-11-27  9:35 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

Casting from structs which lay out data in typed members
to structs which have flat memory buffers, will cause
problems if the alignment of the former isn't as expected.
This patch removes the casting between structs.

Fixes: ae19955e7c86 ("i40evf: support reporting PF reset")
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..53d7c87 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1336,8 +1336,9 @@ i40evf_handle_aq_msg(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_arq_event_info info;
-	struct i40e_virtchnl_msg *v_msg;
-	uint16_t pending, opcode;
+	uint16_t pending, aq_opc;
+	enum i40e_virtchnl_ops msg_opc;
+	enum i40e_status_code msg_ret;
 	int ret;
 
 	info.buf_len = I40E_AQ_BUF_SZ;
@@ -1346,7 +1347,6 @@ i40evf_handle_aq_msg(struct rte_eth_dev *dev)
 		return;
 	}
 	info.msg_buf = vf->aq_resp;
-	v_msg = (struct i40e_virtchnl_msg *)&info.desc;
 
 	pending = 1;
 	while (pending) {
@@ -1357,32 +1357,35 @@ i40evf_handle_aq_msg(struct rte_eth_dev *dev)
 				    "ret: %d", ret);
 			break;
 		}
-		opcode = rte_le_to_cpu_16(info.desc.opcode);
-
-		switch (opcode) {
+		aq_opc = rte_le_to_cpu_16(info.desc.opcode);
+		msg_opc = (enum i40e_virtchnl_ops)rte_le_to_cpu_32(
+						  info.desc.cookie_high);
+		msg_ret = (enum i40e_status_code)rte_le_to_cpu_32(
+						  info.desc.cookie_low);
+		switch (aq_opc) {
 		case i40e_aqc_opc_send_msg_to_vf:
-			if (v_msg->v_opcode == I40E_VIRTCHNL_OP_EVENT)
+			if (msg_opc == I40E_VIRTCHNL_OP_EVENT)
 				/* process event*/
 				i40evf_handle_pf_event(dev, info.msg_buf,
 						       info.msg_len);
 			else {
 				/* read message and it's expected one */
-				if (v_msg->v_opcode == vf->pend_cmd) {
-					vf->cmd_retval = v_msg->v_retval;
+				if (msg_opc == vf->pend_cmd) {
+					vf->cmd_retval = msg_ret;
 					/* prevent compiler reordering */
 					rte_compiler_barrier();
 					_clear_cmd(vf);
 				} else
 					PMD_DRV_LOG(ERR, "command mismatch,"
 						"expect %u, get %u",
-						vf->pend_cmd, v_msg->v_opcode);
+						vf->pend_cmd, msg_ret);
 				PMD_DRV_LOG(DEBUG, "adminq response is received,"
-					     " opcode = %d\n", v_msg->v_opcode);
+					     " opcode = %d\n", msg_ret);
 			}
 			break;
 		default:
 			PMD_DRV_LOG(ERR, "Request %u is not supported yet",
-				    opcode);
+				    aq_opc);
 			break;
 		}
 	}
-- 
2.4.11

^ permalink raw reply related

* [PATCH] net/i40e: fix log when check Tx free thresh
From: Jingjing Wu @ 2016-11-27  9:11 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

Fixes: 4861cde46116 ("i40e: new poll mode driver")
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_rxtx.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 7ae7d9f..d359dae 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1916,8 +1916,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		return I40E_ERR_PARAM;
 	}
 	if (tx_free_thresh >= (nb_desc - 3)) {
-		PMD_INIT_LOG(ERR, "tx_rs_thresh must be less than the "
-			     "tx_free_thresh must be less than the "
+		PMD_INIT_LOG(ERR, "tx_free_thresh must be less than the "
 			     "number of TX descriptors minus 3. "
 			     "(tx_free_thresh=%u port=%d queue=%d)",
 			     (unsigned int)tx_free_thresh,
-- 
2.4.11

^ permalink raw reply related

* Re: [PATCH] i40evf: add set maximum frame size support
From: Wu, Jingjing @ 2016-11-27  9:10 UTC (permalink / raw)
  To: Michael Bieniek, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <1480106855-3287-1-git-send-email-michaelbieniekdpdk@gmail.com>



-----Original Message-----
From: Michael Bieniek [mailto:michaelbieniekdpdk@gmail.com] 
Sent: Saturday, November 26, 2016 4:48 AM
To: Zhang, Helin <helin.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
Cc: dev@dpdk.org; Michael Bieniek <michaelbieniekdpdk@gmail.com>
Subject: [PATCH] i40evf: add set maximum frame size support

This adds the ability to set maximum frame size for an i40e virtual interface. This patch is based on the i40e physical function maximum frame size implementation. This was tested on an system configured with multiple i40e virtual functions. Verified that the MTU was configurable and that sending packets greater than the configured MTU resulted in a drop.

Signed-off-by: Michael Bieniek <michaelbieniekdpdk@gmail.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>

^ permalink raw reply

* [PATCH v2] mempool: remove a redundant socket_id assignment
From: Wei Zhao @ 2016-11-27  2:44 UTC (permalink / raw)
  To: dev; +Cc: olivier.matz, zhao wei

From: zhao wei <wei.zhao1@intel.com>

There is a redundant repetition mempool socket_id assignment in the
file rte_mempool.c in function rte_mempool_create_empty.The
statement "mp->socket_id = socket_id;"appear twice in line 821
and 824.One of them is redundant, so delete it.

Fixes: 85226f9c526b ("mempool:introduce a function to create an empty pool")
Signed-off-by: zhao wei <wei.zhao1@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mempool/rte_mempool.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index aa513b9..1c2aed8 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -818,7 +818,6 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
 		goto exit_unlock;
 	}
 	mp->mz = mz;
-	mp->socket_id = socket_id;
 	mp->size = n;
 	mp->flags = flags;
 	mp->socket_id = socket_id;
-- 
2.5.5

^ permalink raw reply related

* [PATCH v2] mempool: remove a redundant word "for" in comment
From: Wei Zhao @ 2016-11-27  2:43 UTC (permalink / raw)
  To: dev; +Cc: olivier.matz, zhao wei

From: zhao wei <wei.zhao1@intel.com>

There is a redundant repetition word "for" in commnet line of the
file rte_mempool.h after the definition of RTE_MEMPOOL_OPS_NAMESIZE.
The word "for"appear twice in line 359 and 360.One of them is
redundant, so delete it.

Fixes: 449c49b93a6b (" mempool: support handler operations")
Signed-off-by: zhao wei <wei.zhao1@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 lib/librte_mempool/rte_mempool.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 440f3b1..911102b 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -357,7 +357,7 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp,
  * Prototype for implementation specific data provisioning function.
  *
  * The function should provide the implementation specific memory for
- * for use by the other mempool ops functions in a given mempool ops struct.
+ * use by the other mempool ops functions in a given mempool ops struct.
  * E.g. the default ops provides an instance of the rte_ring for this purpose.
  * it will most likely point to a different type of data structure, and
  * will be transparent to the application programmer.
-- 
2.5.5

^ permalink raw reply related

* [PATCH] tools: add tags and cscope index file generation support
From: Jerin Jacob @ 2016-11-27  0:12 UTC (permalink / raw)
  To: dev; +Cc: thomas.monjalon, Jerin Jacob

This script generates cscope, gtags, and tags
index files based on EAL environment.
(architecture and OS(linux/bsd))

Selection of the architecture and OS environment
is based on dpdk configuration target(T=)

example usage:
make tags T=x86_64-native-linuxapp-gcc
make cscope T=x86_64-native-linuxapp-gcc
make gtags T=x86_64-native-linuxapp-gcc

Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
 .gitignore        |   8 ++
 mk/rte.sdkroot.mk |   4 +
 scripts/tags.sh   | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 263 insertions(+)
 create mode 100755 scripts/tags.sh

diff --git a/.gitignore b/.gitignore
index a722abe..76bcae2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,9 @@
 doc/guides/nics/overview_table.txt
+cscope.out.po
+cscope.out.in
+cscope.out
+cscope.files
+GTAGS
+GPATH
+GRTAGS
+tags
diff --git a/mk/rte.sdkroot.mk b/mk/rte.sdkroot.mk
index 04ad523..de6355a 100644
--- a/mk/rte.sdkroot.mk
+++ b/mk/rte.sdkroot.mk
@@ -92,6 +92,10 @@ default: all
 config showconfigs showversion showversionum:
 	$(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkconfig.mk $@
 
+.PHONY: cscope gtags tags
+cscope gtags tags:
+	$(Q)$(RTE_SDK)/scripts/tags.sh $@
+
 .PHONY: test fast_test ring_test mempool_test perf_test coverage
 test fast_test ring_test mempool_test perf_test coverage:
 	$(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdktest.mk $@
diff --git a/scripts/tags.sh b/scripts/tags.sh
new file mode 100755
index 0000000..82c1a2a
--- /dev/null
+++ b/scripts/tags.sh
@@ -0,0 +1,251 @@
+#!/bin/bash
+# Generate tags or gtags or cscope files
+# Usage tags.sh <mode> T=<target> [VERBOSE=1]
+# set -x
+
+verbose=false
+linuxapp=false
+bsdapp=false
+x86_64=false
+arm=false
+arm64=false
+ia_32=false
+ppc_64=false
+tile=false
+
+if [ "$VERBOSE" = "1" ]; then
+	verbose=true
+fi
+
+#ignore version control files
+ignore="( -name .svn -o -name CVS -o -name .hg -o -name .git ) -prune -o"
+
+source_dirs="app buildtools drivers examples lib"
+
+skip_bsd="( -name bsdapp ) -prune -o"
+skip_linux="( -name linuxapp ) -prune -o"
+skip_arch="( -name arch ) -prune -o"
+skip_sse="( -name *_sse*.[chS] ) -prune -o"
+skip_avx="( -name *_avx*.[chS] ) -prune -o"
+skip_neon="( -name *_neon*.[chS] ) -prune -o"
+skip_altivec="( -name *_altivec*.[chS] ) -prune -o"
+skip_arm64="( -name *arm64*.[chS] ) -prune -o"
+skip_x86="( -name *x86*.[chS] ) -prune -o"
+skip_32b_files="( -name *_32.h ) -prune -o"
+skip_64b_files="( -name *_64.h ) -prune -o"
+
+skiplist="${skip_bsd} ${skip_linux} ${skip_arch} ${skip_sse} ${skip_avx} \
+		 ${skip_neon} ${skip_altivec} ${skip_x86} ${skip_arm64}"
+
+find_sources()
+{
+	find $1 $ignore $3 -name $2 -not -type l -print
+}
+
+common_sources()
+{
+	find_sources "${source_dirs}" '*.[chS]' "$skiplist"
+}
+
+linuxapp_sources()
+{
+	find_sources "lib/librte_eal/linuxapp" '*.[chS]'
+}
+
+bsdapp_sources()
+{
+	find_sources "lib/librte_eal/bsdapp" '*.[chS]'
+}
+
+arm_common()
+{
+	find_sources "lib/librte_eal/common/arch/arm" '*.[chS]'
+	find_sources "${source_dirs}" '*neon*.[chS]'
+}
+
+arm_sources()
+{
+	arm_common
+	find_sources "lib/librte_eal/common/include/arch/arm" '*.[chS]' \
+					"$skip_64b_files"
+}
+
+arm64_sources()
+{
+	arm_common
+	find_sources "lib/librte_eal/common/include/arch/arm" '*.[chS]' \
+					 "$skip_32b_files"
+	find_sources "${source_dirs}" '*arm64.[chS]'
+}
+
+ia_common()
+{
+	find_sources "lib/librte_eal/common/arch/x86" '*.[chS]'
+
+	find_sources "examples/performance-thread/common/arch/x86" '*.[chS]'
+	find_sources "${source_dirs}" '*_sse*.[chS]'
+	find_sources "${source_dirs}" '*_avx*.[chS]'
+	find_sources "${source_dirs}" '*x86.[chS]'
+}
+
+i686_sources()
+{
+	ia_common
+	find_sources "lib/librte_eal/common/include/arch/x86" '*.[chS]' \
+					"$skip_64b_files"
+}
+
+x86_64_sources()
+{
+	ia_common
+	find_sources "lib/librte_eal/common/include/arch/x86" '*.[chS]' \
+					"$skip_32b_files"
+}
+
+ppc64_sources()
+{
+	find_sources "lib/librte_eal/common/arch/ppc_64" '*.[chS]'
+	find_sources "lib/librte_eal/common/include/arch/ppc_64" '*.[chS]'
+	find_sources "${source_dirs}" '*altivec*.[chS]'
+}
+
+tile_sources()
+{
+	find_sources "lib/librte_eal/common/arch/tile" '*.[chS]'
+	find_sources "lib/librte_eal/common/include/arch/tile" '*.[chS]'
+}
+
+config_file()
+{
+	if [ -f $RTE_OUTPUT/include/rte_config.h ]; then
+		ls $RTE_OUTPUT/include/rte_config.h
+	fi
+}
+
+usage()
+{
+	if [ "$1" = 'tags' ] ; then
+		echo "Generate tags file for editors"
+	fi
+	if [ "$1" = 'cscope' ] ; then
+		echo "Generate cscope index"
+	fi
+	if [ "$1" = 'gtags' ] ; then
+		echo "Generate GNU GLOBAL index"
+	fi
+	echo "Usage: make tags|cscope|gtags T=<target> [VERBOSE=1]"
+	echo "Valid targets are:"
+	make showconfigs | sed 's,^,\t,'
+}
+
+check_valid_config()
+{
+	cfgfound=false
+	allconfigs=`make showconfigs`
+	for cfg in $allconfigs
+	do
+		if [ "$cfg" = "$1" ] ; then
+			cfgfound=true
+		fi
+	done
+	$cfgfound || echo "Invalid config: $1"
+	$cfgfound || usage $2
+	$cfgfound || exit 0
+}
+
+if [ -n "$T" ]; then
+	check_valid_config $T $1
+
+	if [ `echo $T | grep -c "linuxapp-" ` -gt 0 ]; then
+		linuxapp=true
+	fi
+
+	if [ `echo $T | grep -c "bsdapp-" ` -gt 0 ]; then
+		bsdapp=true
+	fi
+
+	if [ `echo $T | grep -c "x86_64-" ` -gt 0  ]; then
+		x86_64=true
+	fi
+
+	if [ `echo $T | grep -c "i686-" ` -gt 0 ]; then
+		ia_32=true
+	fi
+
+	if [ `echo $T | grep -c "x32-" ` -gt 0 ]; then
+		ia_32=true
+	fi
+
+	if [ `echo $T | grep -c "arm-" ` -gt 0 ]; then
+		arm=true
+	fi
+
+	if [ `echo $T | grep -c "arm64-" ` -gt 0 ]; then
+		arm64=true
+	fi
+
+	if [ `echo $T | grep -c "ppc_64-" ` -gt 0 ]; then
+		ppc_64=true
+	fi
+
+	if [ `echo $T | grep -c "tile-" ` -gt 0 ]; then
+		tile=true
+	fi
+
+	$verbose && echo "linuxapp: $linuxapp"
+	$verbose && echo "bsdapp:   $bsdapp"
+	$verbose && echo "ia_32:    $ia_32"
+	$verbose && echo "x86_64:   $x86_64"
+	$verbose && echo "arm:      $arm"
+	$verbose && echo "arm64:    $arm64"
+	$verbose && echo "ppc_64:   $ppc_64"
+	$verbose && echo "tile:     $tile"
+	$verbose && echo "build:    $RTE_OUTPUT"
+else
+	usage $1
+	exit
+fi
+
+all_sources()
+{
+	common_sources
+	$linuxapp && linuxapp_sources
+	$bsdapp && bsdapp_sources
+	$x86_64 && x86_64_sources
+	$ia_32 && i686_sources
+	$arm && arm_sources
+	$arm64 && arm64_sources
+	$ppc_64 && ppc64_sources
+	$tile && tile_sources
+	config_file
+}
+
+docscope()
+{
+	all_sources > cscope.files
+	cscope -q -b -f cscope.out
+}
+
+dogtags()
+{
+	all_sources | gtags -i -f -
+}
+
+doctags()
+{
+	all_sources | xargs ctags -a
+}
+
+case "$1" in
+	"cscope")
+		docscope
+		;;
+
+	"gtags")
+		dogtags
+		;;
+	"tags")
+		rm -f tags
+		doctags
+		;;
+esac
-- 
2.5.5

^ permalink raw reply related

* Re: [PATCH 1/4] eventdev: introduce event driven programming model
From: Jerin Jacob @ 2016-11-26  2:54 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Thomas Monjalon, dev, harry.van.haaren, hemant.agrawal, gage.eads
In-Reply-To: <20161125110053.GA149796@bricha3-MOBL3.ger.corp.intel.com>

On Fri, Nov 25, 2016 at 11:00:53AM +0000, Bruce Richardson wrote:
> On Fri, Nov 25, 2016 at 05:53:34AM +0530, Jerin Jacob wrote:
> > On Thu, Nov 24, 2016 at 04:35:56PM +0100, Thomas Monjalon wrote:
> > > 2016-11-24 07:29, Jerin Jacob:
> > > > On Wed, Nov 23, 2016 at 07:39:09PM +0100, Thomas Monjalon wrote:
> > > > > 2016-11-18 11:14, Jerin Jacob:
> > > > > > +Eventdev API - EXPERIMENTAL
> > > > > > +M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > > > > > +F: lib/librte_eventdev/
> > > > > 
> > 
> > I don't think there is any portability issue here, I can explain.
> > 
> > The application level, we have two more use case to deal with non burst
> > variant
> > 
> > - latency critical work
> > - on dequeue, if application wants to deal with only one flow(i.e to
> >   avoid processing two different application flows to avoid cache trashing)
> > 
> > Selection of the burst variants will be based on
> > rte_event_dev_info_get() and rte_event_dev_configure()(see, max_event_port_dequeue_depth,
> > max_event_port_enqueue_depth, nb_event_port_dequeue_depth, nb_event_port_enqueue_depth )
> > So I don't think their is portability issue here and I don't want to waste my
> > CPU cycles on the for loop if application known to be working with non
> > bursts variant like below
> > 
> 
> If the application is known to be working on non-burst varients, then
> they always request a burst-size of 1, and skip the loop completely.
> There is no extra performance hit in that case in either the app or the
> driver (since the non-burst driver always returns 1, irrespective of the
> number requested).

Hmm. I am afraid, There is.
On the app side, the const "1" can not be optimized by the compiler as
on downside it is function pointer based driver interface
On the driver side, the implementation would be for loop based instead
of plain access.
(compiler never can see the const "1" in driver interface)

We are planning to implement burst mode as kind of emulation mode and
have a different scheme for burst and nonburst. The similar approach we have
taken in introducing rte_event_schedule() and split the responsibility so
that SW driver can work without additional performance overhead and neat
driver interface.

If you are concerned about the usability part and regression on the SW
driver, then it's not the case, application will use nonburst variant only if
dequeue_depth == 1 and/or explicit case where latency matters.

On the portability side, we support both case and application if written based
on dequeue_depth it will perform well in both implementations.IMO, There is
no another shortcut for performance optimized application running on different
set of model.I think it is not an issue as, in event model as each cores
identical and main loop can be changed based on dequeue_depth
if needs performance(anyway mainloop will be function pointer based).

> 
> > nb_events = rte_event_dequeue_burst();
> > for(i=0; i < nb_events; i++){
> > 	process ev[i]
> > }
> > 
> > And mostly importantly the NPU can get almost same throughput
> > without burst variant so why not?
> > 
> > > 
> > > > > > +/**
> > > > > > + * Converts nanoseconds to *wait* value for rte_event_dequeue()
> > > > > > + *
> > > > > > + * If the device is configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_WAIT flag then
> > > > > > + * application can use this function to convert wait value in nanoseconds to
> > > > > > + * implementations specific wait value supplied in rte_event_dequeue()
> > > > > 
> > > > > Why is it implementation-specific?
> > > > > Why this conversion is not internal in the driver?
> > > > 
> > > > This is for performance optimization, otherwise in drivers
> > > > need to convert ns to ticks in "fast path"
> > > 
> > > So why not defining the unit of this timeout as CPU cycles like the ones
> > > returned by rte_get_timer_cycles()?
> > 
> > Because HW co-processor can run in different clock domain. Need not be at
> > CPU frequency.
> > 
> While I've no huge objection to this API, since it will not be
> implemented by our SW implementation, I'm just curious as to how much
> having this will save. How complicated is the arithmetic that needs to
> be done, and how many cycles on your platform is that going to take?

one load, division and/or multiplication of (floating) numbers. I could be
6isl cycles or more, but it matters when burst size is less(worst case 1).
I think the software implementation could use rte_get_timer_cycles() here
if required.I think there is no harm in moving some-work in slow-path if it
can be, like this case.

^ permalink raw reply

* Re: [PATCH 1/4] eventdev: introduce event driven programming model
From: Jerin Jacob @ 2016-11-26  0:57 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Bruce Richardson, dev, harry.van.haaren, hemant.agrawal,
	gage.eads
In-Reply-To: <4424470.41x0ShzqNA@xps13>

On Fri, Nov 25, 2016 at 02:09:22PM +0100, Thomas Monjalon wrote:
> 2016-11-25 11:00, Bruce Richardson:
> > On Fri, Nov 25, 2016 at 05:53:34AM +0530, Jerin Jacob wrote:
> > > On Thu, Nov 24, 2016 at 04:35:56PM +0100, Thomas Monjalon wrote:
> > > > 2016-11-24 07:29, Jerin Jacob:
> > > > > On Wed, Nov 23, 2016 at 07:39:09PM +0100, Thomas Monjalon wrote:
> > > > > > 2016-11-18 11:14, Jerin Jacob:
> > > > > > > +#define EVENTDEV_NAME_SKELETON_PMD event_skeleton
> > > > > > > +/**< Skeleton event device PMD name */
> > > > > > 
> > > > > > I do not understand this #define.
> > > > > 
> > > > > Applications can explicitly request the a specific driver though driver
> > > > > name. This will go as argument to rte_event_dev_get_dev_id(const char *name).
> > > > > The reason for keeping this #define in rte_eventdev.h is that,
> > > > > application needs to include only rte_eventdev.h not rte_eventdev_pmd.h.
> > > > 
> > > > So each driver must register its name in the API?
> > > > Is it really needed?
> > > 
> > > Otherwise how application knows the name of the driver.
> > > The similar scheme used in cryptodev.
> > > http://dpdk.org/browse/dpdk/tree/lib/librte_cryptodev/rte_cryptodev.h#n53
> > > No strong opinion here. Open for suggestions.
> > > 
> > 
> > I like having a name registered. I think we need a scheme where an app
> > can find and use an implementation using a specific driver.
> 
> I do not like having the driver names in the API.
> An API should not know its drivers.
> If an application do some driver-specific processing, it knows
> the driver name as well. The driver name is written in the driver.

If Bruce don't have further objection, Then I will go with Thomas's
suggestion.

^ permalink raw reply

* Re: [PATCH 2/4] eventdev: implement the northbound APIs
From: Jerin Jacob @ 2016-11-25 23:08 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: Thomas Monjalon, dev@dpdk.org, Van Haaren, Harry,
	hemant.agrawal@nxp.com, Eads, Gage
In-Reply-To: <59AF69C657FD0841A61C55336867B5B035B4EB9F@IRSMSX103.ger.corp.intel.com>

On Fri, Nov 25, 2016 at 09:55:39AM +0000, Richardson, Bruce wrote:
> > > > +/* Macros to check for valid device */ #define
> > > > +RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, retval) do { \
> > >
> > > Sometimes you use RTE_EVENT_DEV_ and sometimes RTE_EVENTDEV.
> > > (I prefer the latter).
> > 
> > I choose the naming conversion based on the interface. API side it is
> > rte_event_ and driver side it is rte_eventdev_*
> > 
> > rte_event_dev_count;
> > rte_event_dev_get_dev_id
> > rte_event_dev_socket_id;
> > rte_event_dev_info_get;
> > rte_event_dev_configure;
> > rte_event_dev_start;
> > rte_event_dev_stop;
> > rte_event_dev_close;
> > rte_event_dev_dump;
> > 
> > rte_event_port_default_conf_get;
> > rte_event_port_setup;
> > rte_event_port_dequeue_depth;
> > rte_event_port_enqueue_depth;
> > rte_event_port_count;
> > rte_event_port_link;
> > rte_event_port_unlink;
> > rte_event_port_links_get;
> > 
> > rte_event_queue_default_conf_get
> > rte_event_queue_setup;
> > rte_event_queue_count;
> > rte_event_queue_priority;
> > 
> > rte_event_dequeue_wait_time;
> > 
> > rte_eventdev_pmd_allocate;
> > rte_eventdev_pmd_release;
> > rte_eventdev_pmd_vdev_init;
> > rte_eventdev_pmd_pci_probe;
> > rte_eventdev_pmd_pci_remove;
> 
> For this last set, you probably are ok prefixing with just "rte_event_pmd_", and drop the "dev" as unnecessary. That makes everything have a prefix of "rte_event_" and thereafter dev, port, queue, or pmd as appropriate.

OK. I will change the last set to rte_event_pmd_*

> 
> /Bruce

^ permalink raw reply

* [PATCH] i40evf: add set maximum frame size support
From: Michael Bieniek @ 2016-11-25 20:47 UTC (permalink / raw)
  To: helin.zhang, jingjing.wu; +Cc: dev, Michael Bieniek

This adds the ability to set maximum frame size for an i40e virtual
interface. This patch is based on the i40e physical function maximum
frame size implementation. This was tested on an system configured with
multiple i40e virtual functions. Verified that the MTU was configurable
and that sending packets greater than the configured MTU resulted in a
drop.

Signed-off-by: Michael Bieniek <michaelbieniekdpdk@gmail.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..8477c98 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -158,6 +158,7 @@ i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
 static void i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
 				   uint8_t *msg,
 				   uint16_t msglen);
+static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t);
 
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
@@ -225,6 +226,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.reta_query           = i40evf_dev_rss_reta_query,
 	.rss_hash_update      = i40evf_dev_rss_hash_update,
 	.rss_hash_conf_get    = i40evf_dev_rss_hash_conf_get,
+	.mtu_set              = i40evf_dev_mtu_set,
 };
 
 /*
@@ -2635,3 +2637,34 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	return 0;
 }
+
+static int
+i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_dev_data *dev_data = dev->data;
+	uint32_t frame_size = mtu + ETHER_HDR_LEN
+			      + ETHER_CRC_LEN + I40E_VLAN_TAG_SIZE;
+	int ret = 0;
+
+	/* check if mtu is within the allowed range */
+	if ((mtu < ETHER_MIN_MTU) || (frame_size > I40E_FRAME_SIZE_MAX))
+		return -EINVAL;
+
+	/* mtu setting is forbidden if port is started */
+	if (dev_data->dev_started) {
+		PMD_DRV_LOG(ERR,
+			    "port %d must be stopped before configuration\n",
+			    dev_data->port_id);
+		return -EBUSY;
+	}
+
+	if (frame_size > ETHER_MAX_LEN)
+		dev_data->dev_conf.rxmode.jumbo_frame = 1;
+	else
+		dev_data->dev_conf.rxmode.jumbo_frame = 0;
+
+	dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+
+	return ret;
+}
-- 
2.4.11

^ permalink raw reply related

* Re: Proposal for a new Committer model
From: Neil Horman @ 2016-11-25 20:05 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: Mcnamara, John, Thomas Monjalon, dev@dpdk.org, Jerin Jacob,
	Stephen Hemminger
In-Reply-To: <20161124055355.GD5048@yliu-dev.sh.intel.com>

On Thu, Nov 24, 2016 at 01:53:55PM +0800, Yuanhan Liu wrote:
> On Wed, Nov 23, 2016 at 03:19:19PM -0500, Neil Horman wrote:
> > On Wed, Nov 23, 2016 at 11:41:20PM +0800, Yuanhan Liu wrote:
> > > On Wed, Nov 23, 2016 at 09:11:54AM -0500, Neil Horman wrote:
> > > > > Could we define some of the potential subtrees now and look to introduce them in the this release cycle? EAL and the Core libs, as suggested by Thomas, seem like 2 obvious ones.
> > > > > 
> > > > Sure, I'd suggest the following:
> > > 
> > > I would pull the git history to see which components are in
> > > active status in last release (or even, in last few release).
> > > And try to make a sub-tree if corresponding component is hot.
> > > 
> > > # the 2nd volume shows how many patches prefixed with a related component
> > > [yliu@yliu-dev ~/dpdk]$ git log --oneline v16.07..v16.11 | awk '{print $2}' | \
> > > 		        sort | uniq -c  | sort -nr | head -30 | nl
> > >      1       52 doc:
> > >      2       40 net/ixgbe/base:
> > >      3       38 app/test:
> > >      4       37 kni:
> > >      5       27 vhost:
> > >      6       27 net/virtio:
> > >      7       27 net/mlx5:
> > >      8       26 app/testpmd:
> > >      9       25 net/i40e:
> > >     10       23 net/pcap:
> > >     11       22 net/bnxt:
> > >     12       20 net/enic:
> > >     13       18 net/qede:
> > >     14       17 net/thunderx:
> > >     15       16 net/qede/base:
> > >     16       16 eal:
> > >     17       15 net/ixgbe:
> > >     18       14 net:
> > >     19       14 crypto/qat:
> > >     20       13 scripts:
> > >     21       13 net/bnx2x:
> > >     22       12 net/i40e/base:
> > >     23       12 examples/ipsec-secgw:
> > >     24       11 mbuf:
> > >     25       11 hash:
> > >     26       10 lib:
> > >     27       10 examples/ip_pipeline:
> > >     28       10 ethdev:
> > >     29        9 pci:
> > >     30        7 net/vmxnet3:
> > >     ...
> > >     46        3 pdump:
> > >     47        3 net/virtio_user:
> > >     48        3 net/ring:
> > >     49        3 net/nfp:
> > >     50        3 net/mlx:
> > >     51        3 net/ena:
> > >     52        3 net/e1000:
> > >     53        3 net/bonding:
> > >     ...
> > >     56        2 sched:
> > >     57        2 port:
> > >     ...
> > >     65        1 timer:
> > >     66        1 remove
> > >     67        1 pmdinfogen:
> > >     68        1 net/igb:
> > >     69        1 net/enic/base:
> > >     70        1 meter:
> > >     ...
> > >     84        1 cfgfile:
> > >     85        1 app/procinfo:
> > >     86        1 app/proc_info:
> > >     87        1 acl:
> > > 
> > > Something obvious is that:
> > > 
> > > - "doc" deserves a sub-tree, and John is a perfect committer for that
> > >   if he's willing to.
> > > 
> > > - generally, I'd agree with Neil that most (if not all) pmds may need
> > >   a sub-tree. While, some others may not, for example, net/ring, net/pcap.
> > > 
> > No, thats the opposite of what I think.  I think all net pmds should flow
> > through a single subtree, all crypto pmds through another, etc.
> 
> I misunderstood it. I was think you were suggesting to create a sub-tree
> for most (or all) pmds. Some of my comments didn't apply then.
> 
> But yes, we have already done that: we have next-net and next-crypto.
> 
Yes, I'm speaking elsewhere in this thread on the topic of how that merge
process works, and how it can be improved.  But this granularity I think is
correct.

> > >   For those non-active pmds, I think it's okay to let the generic
> > >   pmd committer to cover them.
> > > 
> > Not sure what you're getting at here.  Low volume pms (or any library) can still
> > go through a subtree.  The goal is to fragmet the commit work so one person
> > doesn't have to do it all.
> > 
> > > - it's not that wise to me to list all the components we have so far
> > >   and make a sub-tree for each of them.
> > > 
> > I think you misunderstood the organization of my last note.  I agree with you
> > here.  When I listed the core and listed several libraries under it, my intent
> > was to create a core subtree that accepted patches for all of those libraries.
> > 
> > >   For example, some components like librte_{port, pdump, cfgfile, acl,
> > >   and etc} just have few (or even, just one) commits in last release.
> > >   It makes no sense to me to introduce a tree for each of them.
> > > 
> > Yes, this is what I was saying in my last note.
> > 
> > > Another thought is we could also create sub-trees based on category
> > > but not on components like Neil suggested, especially that EAL looks
> > > way too big to be maintained in one tree. Instead, it could be something
> > > like:
> > > 
> > > - a tree for BSD
> > > 
> > This gets tricky, because then several libraries will be covered by multiple
> > trees, and that leads to merge conflicts.
> 
> If we go that way, I meant a sub-sub-tree under EAL sub-tree. And conflicts
Hmmm.....I'm not sure we're quite there yet.  I'm not opposed to such a subtree
per-se, but I'd be somewhat curious to see how much BSD specific change or
linux-specific change was going into EAL before we broke that out separately.
Perhaps the best approach is to break out EAL and let that subtree maintainer
choose to further subdivide it as needed

> is almost impossible to avoid when we have multiple trees.
> 
I don't think thats particularly true.  Especially if the divisions are made on
a rough file basis.  A high percentage of  files should rarely if ever conflict.

Of course, there is always the possibility of a conflict, but we can minimize
it.

> > > - a tree for ARM (and some other trees for other platforms)
> > > 
> > > - a tree for mem related (mempool, mbuf, hugepage, etc)
> > > 
> > > - a tree for BUS
> > > 
> > > - ...
> > > 
> > > 
> > > Last but not the least, I think it's general good to have more and
> > > more trees in the end. But I don't think it's a good idea to go
> > > radically and create all those trees once (say in one release).
> > > 
> > > Something I would like to suggest is one or two (or a bit more) at
> > > a release. For example, if I remember them well, we have next-net
> > > tree at 16.04, and next-virtio (including vhost) at 16.07, and a
> > > recent one, next-crypto at 16.11.
> > > 
> > I'm not sure what you mean by this.
> 
> I meant we already add more and more trees, from 0 and 1, and then
> from 1 to 3 (and more), a bit slowly but not radically.
> 
Ah, you're commenting on the frequency with which we create new trees.  I tend
to think that we shouldn't really limit ourselves artificially there.  That is
to say, lets do what makes sense in terms of community organization, and in
terms of resources.  Creating new trees at release boundaries seems natural, but
lets not assert that there is a 'right' number of trees to create in any single
given release.

> >  -next trees rather by definition should e
> > rebased on a release to start at the head of thomas's tree and add commits from
> > there based on their subject area.
> 
> Yep, and that's we are doing.
> 
Ok

> And maybe we could revisit your suggested list:
> 
> > > > 	* net-pmds:
> > > > 		- all network pmds located under drivers/net
> > > > 		- librte_net
> > > > 		- libtre_ether
> > > > 		- librte_ip_frag
> > > > 		- librte_pdump
> > > > 		- librte_port
> > > > 	* crypto-pmds:
> > > > 		- all crypto pmds located under drivers/crypto
> > > > 		- librte_cryptodev
> 
> We already have the two.
> 
> > > > 	* eal:
> > > > 		- librte_eal
> 
> I think EAL deserves to have a sub-tree.
> 
> > > > 	* core:
> > > > 		- librte_cfgfile
> > > > 		- librte_cmdline
> > > > 		- librte_compat
> > > > 		- librte_kvargs
> > > > 		- librte_kni
> > > > 		- librte_compat
> > > > 	* misc:
> 
> It may be vague to define which belongs to core and which belongs to
> misc. It might be better to have a lib sub-tree, to hold all others
> that don't belong to other sub-trees.
> 
Sure, I'm not tied to any particular names, just trying to find a sane
subdivision more than anything else

Neil

^ permalink raw reply

* Re: Proposal for a new Committer model
From: Neil Horman @ 2016-11-25 19:55 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Ferruh Yigit, dev, Mcnamara, John
In-Reply-To: <1598958.4NzbtDc3LW@xps13>

On Thu, Nov 24, 2016 at 10:17:09AM +0100, Thomas Monjalon wrote:
> 2016-11-23 15:13, Neil Horman:
> > Can either you or thomas provide some detail as to how you are doing patch
> > management between trees (details of the commands you use are what I would be
> > interested in). It sounds to me like there may be some optimization to be made
> > here before we even make changes to the subtrees.
> 
> Until now, we preferred avoiding merge commits.
> That's why I rebase sub-trees to integrate them in the mainline.
> As Ferruh explained, it does not require more work because sub-trees are
> regularly rebased anyway.
> And I use a script to keep original committer name and date.
> 
> Hope it's clear now
> 
It is clear, but I would make the assertion that performing that rebase
yourselves (and arguably having the subtree maintainers do that too), you are
undoing all the speedup that you would otherwise have gained.

To illustrate, from what it sounds like to me, this is your workflow, from the
moment that a merge window starts:

1) Each subtree maintainer syncrhonizes with your tree (either via a rebase, or
a simple pull and creation of a new next version branch), the specific method
can really be left up to the preference of the subtree maintainer

2) Developent procedes in parallel on multiple subtrees, and to your tree (for
those patches that have no other designated subtree)

3) At some point, you opt to merge subtrees to your trees.  For each tree you
ostensibly then need to:

3a) Inform the subtree maintainer (or otherwise record the point up to which you
decided to integrate)

3b) Grab a copy of that tree from the start to the end point (either via a
remote branch clone or some other method)

3c) Rebase the branch in 3(b) to the HEAD of your tree, correcting any errors
along the way

3d) preform a merge to your master branch, which, after 3(c), will by definition
be a fast forward branch

While thats a workable solution, it suffers from many drawbacks:

a) It looses your commit history.  That is to say, with a true merge, you record
several other relevant pieces of information, including:
	* The branch/tree that the series came from
	* The changes that needed to be made to make the series fit (conflict
	  tracking)
	* The sha1 sums of the commits (immutable changeset tracking).
   By rebasing you loose all of that, especially that last piece because the
rebase you preform changes your shasums.  With a non-merge, you keep all that
information properly.

b) You increase your error risk.  With a true merge, all the changes you need to
make to get a merge to resolve properly are contained in a single commit (the
merge commit),  providing easy review of your updates (not that they should
happen frequently).  By rebasing, you are left with potentially changed commits
that aren't trackable or easily comparable to the origional submission.

c) Perhaps most importantly, you serialize the entire process.  To follow the
above, you need to merge one branch at a time, rebasing each until it works
properly, then merging it.  With a true merge, you are afforded the opportunity
to merge any number of branches in parallel (see git-octopus-merge).


Apologies if this was discussed on list previously, but what was the percieved
advantage to avoiding merge commits?  It seems like alot of lost opportunity to
avoid something that is actually fairly informative in the toolchain.

Regards
Neil

^ permalink raw reply

* Re: [PATCH v9] drivers/net:new PMD using tun/tap host interface
From: Aws Ismail @ 2016-11-25 19:38 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Keith Wiles, DPDK, pmatilai, yuanhan.liu
In-Reply-To: <d6672d14-6740-0737-0f82-ac9978a06c32@intel.com>

Keith,

This won't build when integrated with v16.11. The register macro
prefix has been renamed. a v10 is needed.

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 7f303db..297d4b6 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -752,5 +752,6 @@ static struct rte_vdev_driver pmd_tap_drv = {
        .remove = rte_pmd_tap_remove,
 };

-DRIVER_REGISTER_VDEV(net_tap, pmd_tap_drv);
-DRIVER_REGISTER_PARAM_STRING(net_tap, "iface=<string>,speed=N");
+RTE_PMD_REGISTER_VDEV(net_tap, pmd_tap_drv);
+RTE_PMD_REGISTER_ALIAS(net_tap, eth_tap);
+RTE_PMD_REGISTER_PARAM_STRING(net_tap, "iface=<string>,speed=N");

On Mon, Nov 21, 2016 at 7:56 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> On 10/13/2016 11:03 PM, Keith Wiles wrote:
>> The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces
>> on the local host. The PMD allows for DPDK and the host to
>> communicate using a raw device interface on the host and in
>> the DPDK application. The device created is a Tap device with
>> a L2 packet header.
>>
>> v9 - Fix up the docs to use correct syntax
>> v8 - Fix issue with tap_tx_queue_setup() not return zero on success.
>> v7 - Reword the comment in common_base and fix the data->name issue
>> v6 - fixed the checkpatch issues
>> v5 - merge in changes from list review see related emails
>>      fixed many minor edits
>> v4 - merge with latest driver changes
>> v3 - fix includes by removing ifdef for other type besides Linux
>>      Fix the copyright notice in the Makefile
>> v2 - merge all of the patches into one patch
>>      Fix a typo on naming the tap device
>>      Update the maintainers list
>>
>> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>> ---
>
> Just a reminder, this is a new PMD and waiting for community review.

^ permalink raw reply related

* [PATCH] i40e: fix oversize packet counter not incrementing for large packets
From: Michael Bieniek @ 2016-11-25 18:21 UTC (permalink / raw)
  To: helin.zhang, jingjing.wu; +Cc: dev, Michael Bieniek

The XL710 requires that the Set MAC Config command be used to define the
maximum frame size in order for the Receive Oversize Count register
(GLPRT_ROC) to be incremented for packets received that are greater than
the MTU. Without this change, the XL710 will drop the oversized packets
without incrementing the corresponding counter.

Signed-off-by: Michael Bieniek <michaelbieniekdpdk@gmail.com>
---
 drivers/net/i40e/i40e_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..c11c80b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -9709,6 +9709,7 @@ static int
 i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_dev_data *dev_data = pf->dev_data;
 	uint32_t frame_size = mtu + ETHER_HDR_LEN
 			      + ETHER_CRC_LEN + I40E_VLAN_TAG_SIZE;
@@ -9732,6 +9733,7 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 		dev_data->dev_conf.rxmode.jumbo_frame = 0;
 
 	dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+	i40e_aq_set_mac_config(hw, frame_size, TRUE, 0, NULL);
 
 	return ret;
 }
-- 
2.4.11

^ permalink raw reply related

* [PATCH 3/3] net/mlx5: add rte_flow rule creation
From: Nelio Laranjeiro @ 2016-11-25 18:14 UTC (permalink / raw)
  To: dev; +Cc: Adrien Mazarguil
In-Reply-To: <cover.1480096192.git.nelio.laranjeiro@6wind.com>

Convert Ethernet, IPv4, IPv6, TCP, UDP layers into ibv_flow and create
those rules when after validation (i.e. NIC supports the rule).

VLAN is still not supported in this commit.

Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/mlx5_flow.c | 645 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 631 insertions(+), 14 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 54807ad..e948000 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -31,6 +31,17 @@
  */
 
 #include <sys/queue.h>
+#include <string.h>
+
+/* Verbs header. */
+/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+#include <infiniband/verbs.h>
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
 
 #include <rte_ethdev.h>
 #include <rte_flow.h>
@@ -39,11 +50,82 @@
 
 #include "mlx5.h"
 
+/** Define a value to use as index for the drop queue. */
+#define MLX5_FLOW_DROP_QUEUE ((uint32_t)-1)
+
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next;
+	struct ibv_exp_flow_attr *ibv_attr;
+	struct ibv_exp_rwq_ind_table *ind_table;
+	struct ibv_qp *qp;
+	struct ibv_exp_flow *ibv_flow;
+	struct ibv_exp_wq *wq;
+	struct ibv_cq *cq;
+	uint8_t drop;
 };
 
 /**
+ * Check support for a given item.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param mask[in]
+ *   Bit-mask covering supported fields to compare with spec, last and mask in
+ *   \item.
+ * @param size
+ *   Bit-Mask size in bytes.
+ *
+ * @return
+ *   0 on success.
+ */
+static int
+mlx5_flow_item_validate(const struct rte_flow_item *item,
+			const uint8_t *mask, unsigned int size)
+{
+	int ret = 0;
+
+	if (item->spec && !item->mask) {
+		unsigned int i;
+		const uint8_t *spec = item->spec;
+
+		for (i = 0; i < size; ++i)
+			if ((spec[i] | mask[i]) != mask[i])
+				return -1;
+	}
+	if (item->last && !item->mask) {
+		unsigned int i;
+		const uint8_t *spec = item->last;
+
+		for (i = 0; i < size; ++i)
+			if ((spec[i] | mask[i]) != mask[i])
+				return -1;
+	}
+	if (item->mask) {
+		unsigned int i;
+		const uint8_t *spec = item->mask;
+
+		for (i = 0; i < size; ++i)
+			if ((spec[i] | mask[i]) != mask[i])
+				return -1;
+	}
+	if (item->spec && item->last) {
+		uint8_t spec[size];
+		uint8_t last[size];
+		const uint8_t *apply = mask;
+		unsigned int i;
+
+		if (item->mask)
+			apply = item->mask;
+		for (i = 0; i < size; ++i) {
+			spec[i] = ((const uint8_t *)item->spec)[i] & apply[i];
+			last[i] = ((const uint8_t *)item->last)[i] & apply[i];
+		}
+		ret = memcmp(spec, last, size);
+	}
+	return ret;
+}
+
+/**
  * Validate a flow supported by the NIC.
  *
  * @param priv
@@ -67,9 +149,43 @@ priv_flow_validate(struct priv *priv,
 		   const struct rte_flow_action actions[],
 		   struct rte_flow_error *error)
 {
-	(void)priv;
 	const struct rte_flow_item *ilast = NULL;
 	const struct rte_flow_action *alast = NULL;
+	/* Supported mask. */
+	const struct rte_flow_item_eth eth_mask = {
+		.dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+		.src.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+	};
+	const struct rte_flow_item_ipv4 ipv4_mask = {
+		.hdr = {
+			.src_addr = -1,
+			.dst_addr = -1,
+		},
+	};
+	const struct rte_flow_item_ipv6 ipv6_mask = {
+		.hdr = {
+			.src_addr = {
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			},
+			.dst_addr = {
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			},
+		},
+	};
+	const struct rte_flow_item_udp udp_mask = {
+		.hdr = {
+			.src_port = -1,
+			.dst_port = -1,
+		},
+	};
+	const struct rte_flow_item_tcp tcp_mask = {
+		.hdr = {
+			.src_port = -1,
+			.dst_port = -1,
+		},
+	};
 
 	if (attr->group) {
 		rte_flow_error_set(error, ENOTSUP,
@@ -100,27 +216,70 @@ priv_flow_validate(struct priv *priv,
 		return -rte_errno;
 	}
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
+		int err = 0;
+
 		if (items->type == RTE_FLOW_ITEM_TYPE_VOID) {
 			continue;
 		} else if (items->type == RTE_FLOW_ITEM_TYPE_ETH) {
 			if (ilast)
 				goto exit_item_not_supported;
 			ilast = items;
-		} else if ((items->type == RTE_FLOW_ITEM_TYPE_IPV4) ||
-			   (items->type == RTE_FLOW_ITEM_TYPE_IPV6)) {
+			err = mlx5_flow_item_validate(
+					items,
+					(const uint8_t *)&eth_mask,
+					sizeof(eth_mask));
+			if (err)
+				goto exit_item_not_supported;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_IPV4) {
 			if (!ilast)
 				goto exit_item_not_supported;
 			else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH)
 				goto exit_item_not_supported;
 			ilast = items;
-		} else if ((items->type == RTE_FLOW_ITEM_TYPE_UDP) ||
-			   (items->type == RTE_FLOW_ITEM_TYPE_TCP)) {
+			err = mlx5_flow_item_validate(
+					items,
+					(const uint8_t *)&ipv4_mask,
+					sizeof(ipv4_mask));
+			if (err)
+				goto exit_item_not_supported;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_IPV6) {
+			if (!ilast)
+				goto exit_item_not_supported;
+			else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH)
+				goto exit_item_not_supported;
+			ilast = items;
+			err = mlx5_flow_item_validate(
+					items,
+					(const uint8_t *)&ipv6_mask,
+					sizeof(ipv6_mask));
+			if (err)
+				goto exit_item_not_supported;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_UDP) {
 			if (!ilast)
 				goto exit_item_not_supported;
 			else if ((ilast->type != RTE_FLOW_ITEM_TYPE_IPV4) &&
 				 (ilast->type != RTE_FLOW_ITEM_TYPE_IPV6))
 				goto exit_item_not_supported;
 			ilast = items;
+			err = mlx5_flow_item_validate(
+					items,
+					(const uint8_t *)&udp_mask,
+					sizeof(udp_mask));
+			if (err)
+				goto exit_item_not_supported;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_TCP) {
+			if (!ilast)
+				goto exit_item_not_supported;
+			else if ((ilast->type != RTE_FLOW_ITEM_TYPE_IPV4) &&
+				 (ilast->type != RTE_FLOW_ITEM_TYPE_IPV6))
+				goto exit_item_not_supported;
+			ilast = items;
+			err = mlx5_flow_item_validate(
+					items,
+					(const uint8_t *)&tcp_mask,
+					sizeof(tcp_mask));
+			if (err)
+				goto exit_item_not_supported;
 		} else {
 			goto exit_item_not_supported;
 		}
@@ -128,8 +287,23 @@ priv_flow_validate(struct priv *priv,
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
 		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
 			continue;
-		} else if ((actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) ||
-			   (actions->type == RTE_FLOW_ACTION_TYPE_DROP)) {
+		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
+			const struct rte_flow_action_queue *queue =
+				(const struct rte_flow_action_queue *)
+				actions->conf;
+
+			if (alast &&
+			    alast->type != actions->type)
+				goto exit_action_not_supported;
+			if (queue->index > (priv->rxqs_n - 1)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION,
+						   actions,
+						   "queue index error");
+				goto exit;
+			}
+			alast = actions;
+		} else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) {
 			if (alast &&
 			    alast->type != actions->type)
 				goto exit_action_not_supported;
@@ -146,6 +320,7 @@ priv_flow_validate(struct priv *priv,
 exit_action_not_supported:
 	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
 			   actions, "action not supported");
+exit:
 	return -rte_errno;
 }
 
@@ -172,6 +347,310 @@ mlx5_flow_validate(struct rte_eth_dev *dev,
 }
 
 /**
+ * Convert Ethernet item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param eth[in, out]
+ *   Verbs Ethernet specification structure.
+ */
+static void
+mlx5_flow_create_eth(const struct rte_flow_item *item,
+		     struct ibv_exp_flow_spec_eth *eth)
+{
+	const struct rte_flow_item_eth *spec = item->spec;
+	const struct rte_flow_item_eth *mask = item->mask;
+	unsigned int i;
+
+	memset(eth, 0, sizeof(struct ibv_exp_flow_spec_eth));
+	*eth = (struct ibv_exp_flow_spec_eth) {
+		.type = IBV_EXP_FLOW_SPEC_ETH,
+		.size = sizeof(struct ibv_exp_flow_spec_eth),
+	};
+	if (spec) {
+		memcpy(eth->val.dst_mac, spec->dst.addr_bytes, ETHER_ADDR_LEN);
+		memcpy(eth->val.src_mac, spec->src.addr_bytes, ETHER_ADDR_LEN);
+	}
+	if (mask) {
+		memcpy(eth->mask.dst_mac, mask->dst.addr_bytes, ETHER_ADDR_LEN);
+		memcpy(eth->mask.src_mac, mask->src.addr_bytes, ETHER_ADDR_LEN);
+	}
+	/* Remove unwanted bits from values. */
+	for (i = 0; i < ETHER_ADDR_LEN; ++i) {
+		eth->val.dst_mac[i] &= eth->mask.dst_mac[i];
+		eth->val.src_mac[i] &= eth->mask.src_mac[i];
+	}
+	eth->val.ether_type &= eth->mask.ether_type;
+	eth->val.vlan_tag &= eth->mask.vlan_tag;
+}
+
+/**
+ * Convert IPv4 item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param ipv4[in, out]
+ *   Verbs IPv4 specification structure.
+ */
+static void
+mlx5_flow_create_ipv4(const struct rte_flow_item *item,
+		      struct ibv_exp_flow_spec_ipv4 *ipv4)
+{
+	const struct rte_flow_item_ipv4 *spec = item->spec;
+	const struct rte_flow_item_ipv4 *mask = item->mask;
+
+	memset(ipv4, 0, sizeof(struct ibv_exp_flow_spec_ipv4));
+	*ipv4 = (struct ibv_exp_flow_spec_ipv4) {
+		.type = IBV_EXP_FLOW_SPEC_IPV4,
+		.size = sizeof(struct ibv_exp_flow_spec_ipv4),
+	};
+	if (spec) {
+		ipv4->val = (struct ibv_exp_flow_ipv4_filter){
+			.src_ip = spec->hdr.src_addr,
+			.dst_ip = spec->hdr.dst_addr,
+		};
+	}
+	if (mask) {
+		ipv4->mask = (struct ibv_exp_flow_ipv4_filter){
+			.src_ip = mask->hdr.src_addr,
+			.dst_ip = mask->hdr.dst_addr,
+		};
+	}
+	/* Remove unwanted bits from values. */
+	ipv4->val.src_ip &= ipv4->mask.src_ip;
+	ipv4->val.dst_ip &= ipv4->mask.dst_ip;
+}
+
+/**
+ * Convert IPv6 item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param ipv6[in, out]
+ *   Verbs IPv6 specification structure.
+ */
+static void
+mlx5_flow_create_ipv6(const struct rte_flow_item *item,
+		      struct ibv_exp_flow_spec_ipv6 *ipv6)
+{
+	const struct rte_flow_item_ipv6 *spec = item->spec;
+	const struct rte_flow_item_ipv6 *mask = item->mask;
+	unsigned int i;
+
+	memset(ipv6, 0, sizeof(struct ibv_exp_flow_spec_ipv6));
+	ipv6->type = IBV_EXP_FLOW_SPEC_IPV6;
+	ipv6->size = sizeof(struct ibv_exp_flow_spec_ipv6);
+	if (spec) {
+		memcpy(ipv6->val.src_ip, spec->hdr.src_addr,
+		       RTE_DIM(ipv6->val.src_ip));
+		memcpy(ipv6->val.dst_ip, spec->hdr.dst_addr,
+		       RTE_DIM(ipv6->val.dst_ip));
+	}
+	if (mask) {
+		memcpy(ipv6->mask.src_ip, mask->hdr.src_addr,
+		       RTE_DIM(ipv6->mask.src_ip));
+		memcpy(ipv6->mask.dst_ip, mask->hdr.dst_addr,
+		       RTE_DIM(ipv6->mask.dst_ip));
+	}
+	/* Remove unwanted bits from values. */
+	for (i = 0; i < RTE_DIM(ipv6->val.src_ip); ++i) {
+		ipv6->val.src_ip[i] &= ipv6->mask.src_ip[i];
+		ipv6->val.dst_ip[i] &= ipv6->mask.dst_ip[i];
+	}
+}
+
+/**
+ * Convert UDP item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param udp[in, out]
+ *   Verbs UDP specification structure.
+ */
+static void
+mlx5_flow_create_udp(const struct rte_flow_item *item,
+		     struct ibv_exp_flow_spec_tcp_udp *udp)
+{
+	const struct rte_flow_item_udp *spec = item->spec;
+	const struct rte_flow_item_udp *mask = item->mask;
+
+	memset(udp, 0, sizeof(struct ibv_exp_flow_spec_tcp_udp));
+	*udp = (struct ibv_exp_flow_spec_tcp_udp) {
+		.type = IBV_EXP_FLOW_SPEC_UDP,
+		.size = sizeof(struct ibv_exp_flow_spec_tcp_udp),
+	};
+	udp->type = IBV_EXP_FLOW_SPEC_UDP;
+	if (spec) {
+		udp->val.dst_port = spec->hdr.dst_port;
+		udp->val.src_port = spec->hdr.src_port;
+	}
+	if (mask) {
+		udp->mask.dst_port = mask->hdr.dst_port;
+		udp->mask.src_port = mask->hdr.src_port;
+	}
+	/* Remove unwanted bits from values. */
+	udp->val.src_port &= udp->mask.src_port;
+	udp->val.dst_port &= udp->mask.dst_port;
+}
+
+/**
+ * Convert TCP item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param tcp[in, out]
+ *   Verbs TCP specification structure.
+ */
+static void
+mlx5_flow_create_tcp(const struct rte_flow_item *item,
+		     struct ibv_exp_flow_spec_tcp_udp *tcp)
+{
+	const struct rte_flow_item_tcp *spec = item->spec;
+	const struct rte_flow_item_tcp *mask = item->mask;
+
+	memset(tcp, 0, sizeof(struct ibv_exp_flow_spec_tcp_udp));
+	*tcp = (struct ibv_exp_flow_spec_tcp_udp) {
+		.type = IBV_EXP_FLOW_SPEC_TCP,
+		.size = sizeof(struct ibv_exp_flow_spec_tcp_udp),
+	};
+	tcp->type = IBV_EXP_FLOW_SPEC_TCP;
+	if (spec) {
+		tcp->val.dst_port = spec->hdr.dst_port;
+		tcp->val.src_port = spec->hdr.src_port;
+	}
+	if (mask) {
+		tcp->mask.dst_port = mask->hdr.dst_port;
+		tcp->mask.src_port = mask->hdr.src_port;
+	}
+	/* Remove unwanted bits from values. */
+	tcp->val.src_port &= tcp->mask.src_port;
+	tcp->val.dst_port &= tcp->mask.dst_port;
+}
+
+/**
+ * Complete flow rule creation.
+ *
+ * @param  priv
+ *   Pointer to private structure.
+ * @param  ibv_attr
+ *   Verbs flow attributes.
+ * @param  queue
+ *   Destination queue.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *
+ * @return
+ *   A flow if the rule could be created.
+ */
+static struct rte_flow *
+priv_flow_create_action_queue(struct priv *priv,
+			      struct ibv_exp_flow_attr *ibv_attr,
+			      uint32_t queue,
+			      struct rte_flow_error *error)
+{
+	struct rxq_ctrl *rxq;
+	struct rte_flow *rte_flow;
+
+	assert(priv->pd);
+	assert(priv->ctx);
+	rte_flow = rte_calloc(__func__, 1, sizeof(*rte_flow), 0);
+	if (!rte_flow) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION,
+				   NULL, "cannot allocate flow memory");
+		return NULL;
+	}
+	if (queue == MLX5_FLOW_DROP_QUEUE) {
+		rte_flow->drop = 1;
+		rte_flow->cq =
+			ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
+					  &(struct ibv_exp_cq_init_attr){
+						  .comp_mask = 0,
+					  });
+		if (!rte_flow->cq) {
+			rte_flow_error_set(error, ENOMEM,
+					   RTE_FLOW_ERROR_TYPE_ACTION,
+					   NULL, "cannot allocate CQ");
+			goto error;
+		}
+		rte_flow->wq = ibv_exp_create_wq(
+			priv->ctx,
+			&(struct ibv_exp_wq_init_attr){
+				.wq_type = IBV_EXP_WQT_RQ,
+				.max_recv_wr = 1,
+				.max_recv_sge = 1,
+				.pd = priv->pd,
+				.cq = rte_flow->cq,
+			});
+	} else {
+		rxq = container_of((*priv->rxqs)[queue], struct rxq_ctrl, rxq);
+		rte_flow->drop = 0;
+		rte_flow->wq = rxq->wq;
+	}
+	rte_flow->ibv_attr = ibv_attr;
+	rte_flow->ind_table = ibv_exp_create_rwq_ind_table(
+		priv->ctx,
+		&(struct ibv_exp_rwq_ind_table_init_attr){
+			.pd = priv->pd,
+			.log_ind_tbl_size = 0,
+			.ind_tbl = &rte_flow->wq,
+			.comp_mask = 0,
+		});
+	if (!rte_flow->ind_table) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION,
+				   NULL, "cannot allocate indirection table");
+		goto error;
+	}
+	rte_flow->qp = ibv_exp_create_qp(
+		priv->ctx,
+		&(struct ibv_exp_qp_init_attr){
+			.qp_type = IBV_QPT_RAW_PACKET,
+			.comp_mask =
+				IBV_EXP_QP_INIT_ATTR_PD |
+				IBV_EXP_QP_INIT_ATTR_PORT |
+				IBV_EXP_QP_INIT_ATTR_RX_HASH,
+			.pd = priv->pd,
+			.rx_hash_conf = &(struct ibv_exp_rx_hash_conf){
+				.rx_hash_function =
+					IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
+				.rx_hash_key_len = rss_hash_default_key_len,
+				.rx_hash_key = rss_hash_default_key,
+				.rx_hash_fields_mask = 0,
+				.rwq_ind_tbl = rte_flow->ind_table,
+			},
+			.port_num = priv->port,
+		});
+	if (!rte_flow->qp) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION,
+				   NULL, "cannot allocate QP");
+		goto error;
+	}
+	rte_flow->ibv_flow = ibv_exp_create_flow(rte_flow->qp,
+						 rte_flow->ibv_attr);
+	if (!rte_flow->ibv_flow) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION,
+				   NULL, "flow rule creation failure");
+		goto error;
+	}
+	if (LIST_EMPTY(&priv->flows))
+		LIST_INIT(&priv->flows);
+	LIST_INSERT_HEAD(&priv->flows, rte_flow, next);
+	return rte_flow;
+error:
+	assert(rte_flow);
+	if (rte_flow->qp)
+		ibv_destroy_qp(rte_flow->qp);
+	if (rte_flow->ind_table)
+		ibv_exp_destroy_rwq_ind_table(rte_flow->ind_table);
+	if (rte_flow->drop && rte_flow->wq)
+		ibv_exp_destroy_wq(rte_flow->wq);
+	if (rte_flow->drop && rte_flow->cq)
+		ibv_destroy_cq(rte_flow->cq);
+	rte_free(rte_flow->ibv_attr);
+	rte_free(rte_flow);
+	return NULL;
+}
+
+/**
  * Create a flow.
  *
  * @see rte_flow_create()
@@ -185,17 +664,143 @@ mlx5_flow_create(struct rte_eth_dev *dev,
 		 struct rte_flow_error *error)
 {
 	struct priv *priv = dev->data->dev_private;
-	struct rte_flow *flow;
+	struct rte_flow *rte_flow = NULL;
+	struct ibv_exp_flow_attr *ibv_attr;
+	unsigned int flow_size = sizeof(struct ibv_exp_flow_attr);
 
 	priv_lock(priv);
-	if (priv_flow_validate(priv, attr, items, actions, error)) {
-		priv_unlock(priv);
-		return NULL;
+	if (priv_flow_validate(priv, attr, items, actions, error))
+		goto exit;
+	ibv_attr = rte_malloc(__func__, flow_size, 0);
+	if (!ibv_attr) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
+				   NULL, "cannot allocate ibv_attr memory");
+		goto exit;
+	}
+	*ibv_attr = (struct ibv_exp_flow_attr){
+		.type = IBV_EXP_FLOW_ATTR_NORMAL,
+		.size = sizeof(struct ibv_exp_flow_attr),
+		.priority = attr->priority,
+		.num_of_specs = 0,
+		.port = 0,
+		.flags = 0,
+		.reserved = 0,
+	};
+	/* Update ibv_flow_spec. */
+	for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
+		if (items->type == RTE_FLOW_ITEM_TYPE_VOID) {
+			continue;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_ETH) {
+			struct ibv_exp_flow_spec_eth *eth;
+			unsigned int eth_size =
+				sizeof(struct ibv_exp_flow_spec_eth);
+
+			ibv_attr = rte_realloc(ibv_attr,
+					       flow_size + eth_size, 0);
+			if (!ibv_attr)
+				goto error_no_memory;
+			eth = (void *)((uintptr_t)ibv_attr + flow_size);
+			mlx5_flow_create_eth(items, eth);
+			flow_size += eth_size;
+			++ibv_attr->num_of_specs;
+			ibv_attr->priority = 2;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_IPV4) {
+			struct ibv_exp_flow_spec_ipv4 *ipv4;
+			unsigned int ipv4_size =
+				sizeof(struct ibv_exp_flow_spec_ipv4);
+
+			ibv_attr = rte_realloc(ibv_attr,
+					       flow_size + ipv4_size, 0);
+			if (!ibv_attr)
+				goto error_no_memory;
+			ipv4 = (void *)((uintptr_t)ibv_attr + flow_size);
+			mlx5_flow_create_ipv4(items, ipv4);
+			flow_size += ipv4_size;
+			++ibv_attr->num_of_specs;
+			ibv_attr->priority = 1;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_IPV6) {
+			struct ibv_exp_flow_spec_ipv6 *ipv6;
+			unsigned int ipv6_size =
+				sizeof(struct ibv_exp_flow_spec_ipv6);
+
+			ibv_attr = rte_realloc(ibv_attr,
+					       flow_size + ipv6_size, 0);
+			if (!ibv_attr)
+				goto error_no_memory;
+			ipv6 = (void *)((uintptr_t)ibv_attr + flow_size);
+			mlx5_flow_create_ipv6(items, ipv6);
+			flow_size += ipv6_size;
+			++ibv_attr->num_of_specs;
+			ibv_attr->priority = 1;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_UDP) {
+			struct ibv_exp_flow_spec_tcp_udp *udp;
+			unsigned int udp_size =
+				sizeof(struct ibv_exp_flow_spec_tcp_udp);
+
+			ibv_attr = rte_realloc(ibv_attr,
+					       flow_size + udp_size, 0);
+			if (!ibv_attr)
+				goto error_no_memory;
+			udp = (void *)((uintptr_t)ibv_attr + flow_size);
+			mlx5_flow_create_udp(items, udp);
+			flow_size += udp_size;
+			++ibv_attr->num_of_specs;
+			ibv_attr->priority = 0;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_TCP) {
+			struct ibv_exp_flow_spec_tcp_udp *tcp;
+			unsigned int tcp_size =
+				sizeof(struct ibv_exp_flow_spec_tcp_udp);
+
+			ibv_attr = rte_realloc(ibv_attr,
+					       flow_size + tcp_size, 0);
+			if (!ibv_attr)
+				goto error_no_memory;
+			tcp = (void *)((uintptr_t)ibv_attr + flow_size);
+			mlx5_flow_create_tcp(items, tcp);
+			flow_size += tcp_size;
+			++ibv_attr->num_of_specs;
+			ibv_attr->priority = 0;
+		} else {
+			/* This default rule should not happen. */
+			rte_free(ibv_attr);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+				items, "unsupported item");
+			goto exit;
+		}
 	}
-	flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
-	LIST_INSERT_HEAD(&priv->flows, flow, next);
+	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
+		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
+			continue;
+		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
+			const struct rte_flow_action_queue *queue =
+				(const struct rte_flow_action_queue *)
+				actions->conf;
+
+			rte_flow = priv_flow_create_action_queue(
+					priv, ibv_attr,
+					queue->index, error);
+		} else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) {
+			rte_flow = priv_flow_create_action_queue(
+					priv, ibv_attr,
+					MLX5_FLOW_DROP_QUEUE, error);
+		} else {
+			rte_flow_error_set(error, ENOTSUP,
+					   RTE_FLOW_ERROR_TYPE_ACTION,
+					   actions, "unsupported action");
+			goto exit;
+		}
+	}
+	priv_unlock(priv);
+	return rte_flow;
+error_no_memory:
+	rte_flow_error_set(error, ENOMEM,
+			   RTE_FLOW_ERROR_TYPE_ITEM,
+			   items,
+			   "cannot allocate memory");
+exit:
 	priv_unlock(priv);
-	return flow;
+	return NULL;
 }
 
 /**
@@ -212,6 +817,18 @@ priv_flow_destroy(struct priv *priv,
 {
 	(void)priv;
 	LIST_REMOVE(flow, next);
+	claim_zero(ibv_exp_destroy_flow(flow->ibv_flow));
+	if (flow->qp)
+		claim_zero(ibv_destroy_qp(flow->qp));
+	if (flow->ind_table)
+		claim_zero(
+			ibv_exp_destroy_rwq_ind_table(
+				flow->ind_table));
+	if (flow->drop && flow->wq)
+		claim_zero(ibv_exp_destroy_wq(flow->wq));
+	if (flow->drop && flow->cq)
+		claim_zero(ibv_destroy_cq(flow->cq));
+	rte_free(flow->ibv_attr);
 	rte_free(flow);
 }
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH 2/3] net/mlx5: add software support for rte_flow
From: Nelio Laranjeiro @ 2016-11-25 18:14 UTC (permalink / raw)
  To: dev; +Cc: Adrien Mazarguil
In-Reply-To: <cover.1480096192.git.nelio.laranjeiro@6wind.com>

Introduce initial software validation for rte_flow rules.

Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/mlx5.h         |   1 +
 drivers/net/mlx5/mlx5_flow.c    | 196 ++++++++++++++++++++++++++++++++++------
 drivers/net/mlx5/mlx5_trigger.c |   1 +
 3 files changed, 169 insertions(+), 29 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 04f4eaa..df0e77c 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -136,6 +136,7 @@ struct priv {
 	unsigned int reta_idx_n; /* RETA index size. */
 	struct fdir_filter_list *fdir_filter_list; /* Flow director rules. */
 	struct fdir_queue *fdir_drop_queue; /* Flow director drop queue. */
+	LIST_HEAD(mlx5_flows, rte_flow) flows; /* RTE Flow rules. */
 	uint32_t link_speed_capa; /* Link speed capabilities. */
 	rte_spinlock_t lock; /* Lock for control functions. */
 };
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index a514dff..54807ad 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -30,11 +30,125 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/queue.h>
+
 #include <rte_ethdev.h>
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
+#include <rte_malloc.h>
+
 #include "mlx5.h"
 
+struct rte_flow {
+	LIST_ENTRY(rte_flow) next;
+};
+
+/**
+ * Validate a flow supported by the NIC.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ * @param[in] attr
+ *   Flow rule attributes.
+ * @param[in] pattern
+ *   Pattern specification (list terminated by the END pattern item).
+ * @param[in] actions
+ *   Associated actions (list terminated by the END action).
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+priv_flow_validate(struct priv *priv,
+		   const struct rte_flow_attr *attr,
+		   const struct rte_flow_item items[],
+		   const struct rte_flow_action actions[],
+		   struct rte_flow_error *error)
+{
+	(void)priv;
+	const struct rte_flow_item *ilast = NULL;
+	const struct rte_flow_action *alast = NULL;
+
+	if (attr->group) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
+				   NULL,
+				   "groups are not supported");
+		return -rte_errno;
+	}
+	if (attr->priority) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+				   NULL,
+				   "priorities are not supported");
+		return -rte_errno;
+	}
+	if (attr->egress) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
+				   NULL,
+				   "egress is not supported");
+		return -rte_errno;
+	}
+	if (!attr->ingress) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+				   NULL,
+				   "only ingress is supported");
+		return -rte_errno;
+	}
+	for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
+		if (items->type == RTE_FLOW_ITEM_TYPE_VOID) {
+			continue;
+		} else if (items->type == RTE_FLOW_ITEM_TYPE_ETH) {
+			if (ilast)
+				goto exit_item_not_supported;
+			ilast = items;
+		} else if ((items->type == RTE_FLOW_ITEM_TYPE_IPV4) ||
+			   (items->type == RTE_FLOW_ITEM_TYPE_IPV6)) {
+			if (!ilast)
+				goto exit_item_not_supported;
+			else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH)
+				goto exit_item_not_supported;
+			ilast = items;
+		} else if ((items->type == RTE_FLOW_ITEM_TYPE_UDP) ||
+			   (items->type == RTE_FLOW_ITEM_TYPE_TCP)) {
+			if (!ilast)
+				goto exit_item_not_supported;
+			else if ((ilast->type != RTE_FLOW_ITEM_TYPE_IPV4) &&
+				 (ilast->type != RTE_FLOW_ITEM_TYPE_IPV6))
+				goto exit_item_not_supported;
+			ilast = items;
+		} else {
+			goto exit_item_not_supported;
+		}
+	}
+	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
+		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
+			continue;
+		} else if ((actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) ||
+			   (actions->type == RTE_FLOW_ACTION_TYPE_DROP)) {
+			if (alast &&
+			    alast->type != actions->type)
+				goto exit_action_not_supported;
+			alast = actions;
+		} else {
+			goto exit_action_not_supported;
+		}
+	}
+	return 0;
+exit_item_not_supported:
+	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+			   items, "item not supported");
+	return -rte_errno;
+exit_action_not_supported:
+	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
+			   actions, "action not supported");
+	return -rte_errno;
+}
+
 /**
  * Validate a flow supported by the NIC.
  *
@@ -48,15 +162,13 @@ mlx5_flow_validate(struct rte_eth_dev *dev,
 		   const struct rte_flow_action actions[],
 		   struct rte_flow_error *error)
 {
-	(void)dev;
-	(void)attr;
-	(void)items;
-	(void)actions;
-	(void)error;
-	rte_flow_error_set(error, ENOTSUP,
-			   RTE_FLOW_ERROR_TYPE_NONE,
-			   NULL, "not implemented yet");
-	return -rte_errno;
+	struct priv *priv = dev->data->dev_private;
+	int ret;
+
+	priv_lock(priv);
+	ret = priv_flow_validate(priv, attr, items, actions, error);
+	priv_unlock(priv);
+	return ret;
 }
 
 /**
@@ -72,15 +184,35 @@ mlx5_flow_create(struct rte_eth_dev *dev,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *error)
 {
-	(void)dev;
-	(void)attr;
-	(void)items;
-	(void)actions;
-	(void)error;
-	rte_flow_error_set(error, ENOTSUP,
-			   RTE_FLOW_ERROR_TYPE_NONE,
-			   NULL, "not implemented yet");
-	return NULL;
+	struct priv *priv = dev->data->dev_private;
+	struct rte_flow *flow;
+
+	priv_lock(priv);
+	if (priv_flow_validate(priv, attr, items, actions, error)) {
+		priv_unlock(priv);
+		return NULL;
+	}
+	flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+	LIST_INSERT_HEAD(&priv->flows, flow, next);
+	priv_unlock(priv);
+	return flow;
+}
+
+/**
+ * Destroy a flow.
+ *
+ * @param  priv
+ *   Pointer to private structure.
+ * @param[in] flow
+ *   Pointer to the flow to destroy.
+ */
+static void
+priv_flow_destroy(struct priv *priv,
+		  struct rte_flow *flow)
+{
+	(void)priv;
+	LIST_REMOVE(flow, next);
+	rte_free(flow);
 }
 
 /**
@@ -94,13 +226,13 @@ mlx5_flow_destroy(struct rte_eth_dev *dev,
 		  struct rte_flow *flow,
 		  struct rte_flow_error *error)
 {
-	(void)dev;
-	(void)flow;
+	struct priv *priv = dev->data->dev_private;
+
 	(void)error;
-	rte_flow_error_set(error, ENOTSUP,
-			   RTE_FLOW_ERROR_TYPE_NONE,
-			   NULL, "not implemented yet");
-	return -rte_errno;
+	priv_lock(priv);
+	priv_flow_destroy(priv, flow);
+	priv_unlock(priv);
+	return 0;
 }
 
 /**
@@ -113,10 +245,16 @@ int
 mlx5_flow_flush(struct rte_eth_dev *dev,
 		struct rte_flow_error *error)
 {
-	(void)dev;
+	struct priv *priv = dev->data->dev_private;
+
 	(void)error;
-	rte_flow_error_set(error, ENOTSUP,
-			   RTE_FLOW_ERROR_TYPE_NONE,
-			   NULL, "not implemented yet");
-	return -rte_errno;
+	priv_lock(priv);
+	while (!LIST_EMPTY(&priv->flows)) {
+		struct rte_flow *flow;
+
+		flow = LIST_FIRST(&priv->flows);
+		priv_flow_destroy(priv, flow);
+	}
+	priv_unlock(priv);
+	return 0;
 }
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index d4dccd8..98a2803 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -90,6 +90,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 	if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE)
 		priv_fdir_enable(priv);
 	priv_dev_interrupt_handler_install(priv, dev);
+	LIST_INIT(&priv->flows);
 	priv_unlock(priv);
 	return -err;
 }
-- 
2.1.4

^ permalink raw reply related

* [PATCH 1/3] net/mlx5: add preliminary support for rte_flow
From: Nelio Laranjeiro @ 2016-11-25 18:14 UTC (permalink / raw)
  To: dev; +Cc: Adrien Mazarguil
In-Reply-To: <cover.1480096192.git.nelio.laranjeiro@6wind.com>

Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/Makefile    |   1 +
 drivers/net/mlx5/mlx5.h      |  16 ++++++
 drivers/net/mlx5/mlx5_fdir.c |  15 ++++++
 drivers/net/mlx5/mlx5_flow.c | 122 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 drivers/net/mlx5/mlx5_flow.c

diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index cf87f0b..6d1338a 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -48,6 +48,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_stats.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rss.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_fdir.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mr.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c
 
 # Dependencies.
 DEPDIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += lib/librte_ether
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 79b7a60..04f4eaa 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -59,6 +59,7 @@
 #include <rte_spinlock.h>
 #include <rte_interrupts.h>
 #include <rte_errno.h>
+#include <rte_flow.h>
 #ifdef PEDANTIC
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
@@ -268,4 +269,19 @@ void priv_fdir_enable(struct priv *);
 int mlx5_dev_filter_ctrl(struct rte_eth_dev *, enum rte_filter_type,
 			 enum rte_filter_op, void *);
 
+/* mlx5_flow.c */
+
+int mlx5_flow_validate(struct rte_eth_dev *, const struct rte_flow_attr *,
+		       const struct rte_flow_item [],
+		       const struct rte_flow_action [],
+		       struct rte_flow_error *);
+struct rte_flow *mlx5_flow_create(struct rte_eth_dev *,
+				  const struct rte_flow_attr *,
+				  const struct rte_flow_item [],
+				  const struct rte_flow_action [],
+				  struct rte_flow_error *);
+int mlx5_flow_destroy(struct rte_eth_dev *, struct rte_flow *,
+		      struct rte_flow_error *);
+int mlx5_flow_flush(struct rte_eth_dev *, struct rte_flow_error *);
+
 #endif /* RTE_PMD_MLX5_H_ */
diff --git a/drivers/net/mlx5/mlx5_fdir.c b/drivers/net/mlx5/mlx5_fdir.c
index 1acf682..f80c58b 100644
--- a/drivers/net/mlx5/mlx5_fdir.c
+++ b/drivers/net/mlx5/mlx5_fdir.c
@@ -55,6 +55,8 @@
 #include <rte_malloc.h>
 #include <rte_ethdev.h>
 #include <rte_common.h>
+#include <rte_flow.h>
+#include <rte_flow_driver.h>
 #ifdef PEDANTIC
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
@@ -1042,6 +1044,14 @@ priv_fdir_ctrl_func(struct priv *priv, enum rte_filter_op filter_op, void *arg)
 	return ret;
 }
 
+static const struct rte_flow_ops mlx5_flow_ops = {
+	.validate = mlx5_flow_validate,
+	.create = mlx5_flow_create,
+	.destroy = mlx5_flow_destroy,
+	.flush = mlx5_flow_flush,
+	.query = NULL,
+};
+
 /**
  * Manage filter operations.
  *
@@ -1067,6 +1077,11 @@ mlx5_dev_filter_ctrl(struct rte_eth_dev *dev,
 	struct priv *priv = dev->data->dev_private;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_GENERIC:
+		if (filter_op != RTE_ETH_FILTER_GET)
+			return -EINVAL;
+		*(const void **)arg = &mlx5_flow_ops;
+		return 0;
 	case RTE_ETH_FILTER_FDIR:
 		priv_lock(priv);
 		ret = priv_fdir_ctrl_func(priv, filter_op, arg);
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
new file mode 100644
index 0000000..a514dff
--- /dev/null
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -0,0 +1,122 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2016 6WIND S.A.
+ *
+ *   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 6WIND S.A. 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 <rte_ethdev.h>
+#include <rte_flow.h>
+#include <rte_flow_driver.h>
+#include "mlx5.h"
+
+/**
+ * Validate a flow supported by the NIC.
+ *
+ * @see rte_flow_validate()
+ * @see rte_flow_ops
+ */
+int
+mlx5_flow_validate(struct rte_eth_dev *dev,
+		   const struct rte_flow_attr *attr,
+		   const struct rte_flow_item items[],
+		   const struct rte_flow_action actions[],
+		   struct rte_flow_error *error)
+{
+	(void)dev;
+	(void)attr;
+	(void)items;
+	(void)actions;
+	(void)error;
+	rte_flow_error_set(error, ENOTSUP,
+			   RTE_FLOW_ERROR_TYPE_NONE,
+			   NULL, "not implemented yet");
+	return -rte_errno;
+}
+
+/**
+ * Create a flow.
+ *
+ * @see rte_flow_create()
+ * @see rte_flow_ops
+ */
+struct rte_flow *
+mlx5_flow_create(struct rte_eth_dev *dev,
+		 const struct rte_flow_attr *attr,
+		 const struct rte_flow_item items[],
+		 const struct rte_flow_action actions[],
+		 struct rte_flow_error *error)
+{
+	(void)dev;
+	(void)attr;
+	(void)items;
+	(void)actions;
+	(void)error;
+	rte_flow_error_set(error, ENOTSUP,
+			   RTE_FLOW_ERROR_TYPE_NONE,
+			   NULL, "not implemented yet");
+	return NULL;
+}
+
+/**
+ * Destroy a flow.
+ *
+ * @see rte_flow_destroy()
+ * @see rte_flow_ops
+ */
+int
+mlx5_flow_destroy(struct rte_eth_dev *dev,
+		  struct rte_flow *flow,
+		  struct rte_flow_error *error)
+{
+	(void)dev;
+	(void)flow;
+	(void)error;
+	rte_flow_error_set(error, ENOTSUP,
+			   RTE_FLOW_ERROR_TYPE_NONE,
+			   NULL, "not implemented yet");
+	return -rte_errno;
+}
+
+/**
+ * Destroy all flows.
+ *
+ * @see rte_flow_flush()
+ * @see rte_flow_ops
+ */
+int
+mlx5_flow_flush(struct rte_eth_dev *dev,
+		struct rte_flow_error *error)
+{
+	(void)dev;
+	(void)error;
+	rte_flow_error_set(error, ENOTSUP,
+			   RTE_FLOW_ERROR_TYPE_NONE,
+			   NULL, "not implemented yet");
+	return -rte_errno;
+}
-- 
2.1.4

^ permalink raw reply related

* [PATCH 0/3] net/mlx5: support flow_rte
From: Nelio Laranjeiro @ 2016-11-25 18:14 UTC (permalink / raw)
  To: dev; +Cc: Adrien Mazarguil

This series requires rte_flow [1].

It brings rte_flow support to the same level as flow director (FDIR) in mlx5.

 [1] http://dpdk.org/ml/archives/dev/2016-November/050262.html

Nelio Laranjeiro (3):
  net/mlx5: add preliminary support for rte_flow
  net/mlx5: add software support for rte_flow
  net/mlx5: add rte_flow rule creation

 drivers/net/mlx5/Makefile       |   1 +
 drivers/net/mlx5/mlx5.h         |  17 +
 drivers/net/mlx5/mlx5_fdir.c    |  15 +
 drivers/net/mlx5/mlx5_flow.c    | 877 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_trigger.c |   1 +
 5 files changed, 911 insertions(+)
 create mode 100644 drivers/net/mlx5/mlx5_flow.c

-- 
2.1.4

^ permalink raw reply

* Re: [PATCH 30/56] net/sfc: include libefx in build
From: Andrew Rybchenko @ 2016-11-25 15:05 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: Artem Andreev
In-Reply-To: <54c39a0a-0092-4f3e-bc21-e4a0bf8d36c8@intel.com>

On 11/25/2016 01:24 PM, Ferruh Yigit wrote:
> On 11/24/2016 3:44 PM, Andrew Rybchenko wrote:
>> See one question below.
>>
>> On 11/23/2016 06:26 PM, Ferruh Yigit wrote:
>>> On 11/21/2016 3:00 PM, Andrew Rybchenko wrote:
>>>> From: Artem Andreev <Artem.Andreev@oktetlabs.ru>
>>>>
>>>> Implement efsys.h for the PMD.
>>>>
>>>> Reviewed-by: Andy Moreton <amoreton@solarflare.com>
>>>> Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
>>>> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
>>>> ---
>>>>    drivers/net/sfc/efx/Makefile |  54 +++
>>>>    drivers/net/sfc/efx/efsys.h  | 767 +++++++++++++++++++++++++++++++++++++++++++
>>>>    2 files changed, 821 insertions(+)
>>>>    create mode 100644 drivers/net/sfc/efx/efsys.h

<...>

>>>> diff --git a/drivers/net/sfc/efx/efsys.h b/drivers/net/sfc/efx/efsys.h
>>>> new file mode 100644
>>>> index 0000000..2eef996
>>>> --- /dev/null
>>>> +++ b/drivers/net/sfc/efx/efsys.h
>>>> @@ -0,0 +1,767 @@
>>> <...>
>>>
>>> I guess below is hardcoded compile time configuration for libefx, do you
>>> think does it make sense to document this default configuration?
>> Yes, it is libefx configuration and more options will be enabled when
>> corresponding
>> functionality is supported in the PMD.
>> I'm sorry, but I don't understand what would you like to see in the
>> documentation.
>> Could you clarify, please?
> This is mostly a question, following defines how libefx behaves, and a
> little hard to find, do you think does it make sense to document these
> in nic documentation, guides/nics/sfc_efx.rst, to highlight default
> configuration.
>
> Like by default filtering capabilities and SFN7xxx family support
> enabled but 5xxx/6xxx family support disabled... These can be listed in
> a bullet listed way in two groups (default enabled / default disabled) ?

I think that the information about dependencies is not very useful in 
the user
guide documentation. For almost all options is not sufficient just to 
enable it
here. Support in the PMD is required to bind libefx to corresponding 
external
interfaces.

I think it is a good idea to document here why some options are enabled
and why SFN5xxx/SFN6xxx (Siena) support is disabled. Will do in v2.

>>>> +
>>>> +#define	EFSYS_OPT_NAMES 0
>>>> +
>>>> +#define	EFSYS_OPT_SIENA 0
>>>> +#define	EFSYS_OPT_HUNTINGTON 1
>>>> +#define	EFSYS_OPT_MEDFORD 1
>>>> +#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
>>>> +#define	EFSYS_OPT_CHECK_REG 1
>>>> +#else
>>>> +#define	EFSYS_OPT_CHECK_REG 0
>>>> +#endif
>>>> +
>>>> +#define	EFSYS_OPT_MCDI 1
>>>> +#define	EFSYS_OPT_MCDI_LOGGING 0
>>>> +#define	EFSYS_OPT_MCDI_PROXY_AUTH 0
>>>> +
>>>> +#define	EFSYS_OPT_MAC_STATS 0
>>>> +
>>>> +#define	EFSYS_OPT_LOOPBACK 0
>>>> +
>>>> +#define	EFSYS_OPT_MON_MCDI 0
>>>> +#define	EFSYS_OPT_MON_STATS 0
>>>> +
>>>> +#define	EFSYS_OPT_PHY_STATS 0
>>>> +#define	EFSYS_OPT_BIST 0
>>>> +#define	EFSYS_OPT_PHY_LED_CONTROL 0
>>>> +#define	EFSYS_OPT_PHY_FLAGS 0
>>>> +
>>>> +#define	EFSYS_OPT_VPD 0
>>>> +#define	EFSYS_OPT_NVRAM 0
>>>> +#define	EFSYS_OPT_BOOTCFG 0
>>>> +
>>>> +#define	EFSYS_OPT_DIAG 0
>>>> +#define	EFSYS_OPT_RX_SCALE 0
>>>> +#define	EFSYS_OPT_QSTATS 0
>>>> +#define	EFSYS_OPT_FILTER 1
>>>> +#define	EFSYS_OPT_RX_SCATTER 0
>>>> +
>>>> +#define	EFSYS_OPT_EV_PREFETCH 0
>>>> +
>>>> +#define	EFSYS_OPT_DECODE_INTR_FATAL 0
>>>> +
>>>> +#define	EFSYS_OPT_LICENSING 0
>>>> +
>>>> +#define	EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0
>>>> +
>>>> +#define	EFSYS_OPT_RX_PACKED_STREAM 0
>>> <...>

^ permalink raw reply

* Re: [PATCH 01/56] net/sfc: libefx-based PMD stub sufficient to build and init
From: Andrew Rybchenko @ 2016-11-25 14:22 UTC (permalink / raw)
  To: Ferruh Yigit, dev
In-Reply-To: <f0c8aca8-e043-6187-6ab8-a782d3cba1c7@intel.com>

On 11/25/2016 01:17 PM, Ferruh Yigit wrote:
> On 11/24/2016 3:59 PM, Andrew Rybchenko wrote:
>> On 11/23/2016 06:26 PM, Ferruh Yigit wrote:
>>> On 11/21/2016 3:00 PM, Andrew Rybchenko wrote:
>>>> The PMD is put into the sfc/efx subdirectory to have a place for
>>>> the second PMD and library shared by both.
>>>>
>>>> Enable the PMD by default on supported configuratons.
>>>>
>>>> Reviewed-by: Andy Moreton <amoreton@solarflare.com>
>>>> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
>>>> ---
>>>>    MAINTAINERS                                     |   6 ++
>>>>    config/common_base                              |   6 ++
>>>>    config/defconfig_arm-armv7a-linuxapp-gcc        |   1 +
>>>>    config/defconfig_arm64-armv8a-linuxapp-gcc      |   1 +
>>>>    config/defconfig_i686-native-linuxapp-gcc       |   5 +
>>>>    config/defconfig_i686-native-linuxapp-icc       |   5 +
>>>>    config/defconfig_ppc_64-power8-linuxapp-gcc     |   1 +
>>>>    config/defconfig_tile-tilegx-linuxapp-gcc       |   1 +
>>>>    config/defconfig_x86_64-native-linuxapp-icc     |   5 +
>>>>    config/defconfig_x86_x32-native-linuxapp-gcc    |   5 +
>>>>    doc/guides/nics/features/sfc_efx.ini            |  10 ++
>>>>    doc/guides/nics/index.rst                       |   1 +
>>>>    doc/guides/nics/sfc_efx.rst                     | 109 +++++++++++++++++++++

<...>

>>> And you can add extra options here, please keep in mind that there are
>>> three compiler supported right now: gcc, clang and icc. You may require
>>> to add compiler and version checks..
>> I've tried to disable the driver build on ICC since we've never tested it.
> I believe we don't support selective config per compiler. Currently if a
> code is enabled by default, it should support compilation with all three
> compilers.

I thought that the following lines in 
config/defconfig_x86_64-native-linuxapp-icc
do the job:
#
# Solarflare PMD build is not supported using icc toolchain
#
CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n

>> I've failed to find list of compiler versions which must/should be checked.
> That list is not clear as far as I know. Mostly version related fixes
> added based on reported build errors. So you can leave as it is right
> now, or can test with default compiler versions of some common
> distributions.

I see. Thanks.

<...>

^ permalink raw reply

* Re: [PATCH] test: adding AES cipher-only tests on QAT PMD
From: Kusztal, ArkadiuszX @ 2016-11-25 14:13 UTC (permalink / raw)
  To: Trahe, Fiona, dev@dpdk.org; +Cc: De Lara Guarch, Pablo, Griffin, John
In-Reply-To: <1480012164-17395-1-git-send-email-fiona.trahe@intel.com>



> -----Original Message-----
> From: Trahe, Fiona
> Sent: Thursday, November 24, 2016 6:29 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Griffin, John <john.griffin@intel.com>; Kusztal,
> ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Subject: [PATCH] test: adding AES cipher-only tests on QAT PMD
> 
> Extended functional AES-CBC and AES-CTR cipher-only tests to run on QAT
> PMD.
> Added AES_CBC cipher-only performance tests on QAT PMD.
> No driver changes, but as now tested, QAT documentation is updated to
> remove constraint.
> 
> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com>
> ---
>  app/test/test_cryptodev.c                  | 18 ++++++
>  app/test/test_cryptodev_aes_test_vectors.h | 36 +++++++----
>  app/test/test_cryptodev_perf.c             | 96 +++++++++++++++++++----------
> -
>  doc/guides/cryptodevs/qat.rst              |  1 -
>  4 files changed, 102 insertions(+), 49 deletions(-)
> 
> --
> 2.5.0
Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox