DPDK patches and discussions
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* Re: [dpdk-dev] [RFC 2/2] librte_ether: add new fields to rte_eth_dev_info struct
  @ 2016-04-15 10:36  3%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-15 10:36 UTC (permalink / raw)
  To: Reshma Pattan; +Cc: dev

2016-04-14 10:44, Reshma Pattan:
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -908,6 +908,9 @@ struct rte_eth_dev_info {
>  	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
>  	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
>  	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
> +	/** number of queues configured by software*/
> +	uint16_t nb_rx_queues; /**< Number of RX queues. */
> +	uint16_t nb_tx_queues; /**< Number of TX queues. */
>  };

I think the ethdev design is strange for these structures.
struct rte_eth_dev is internal to be used inside the ethdev API
or by the drivers.
It contains struct rte_eth_dev_data which can be of interest for
the application, except the dev_private part (which could be
directly in struct rte_eth_dev).

So the global question is: how to share the device data with the
application?
Instead of giving a pointer or a copy of struct rte_eth_dev_data,
we have some different accessors:
	- rte_eth_dev_info_get() with a specific struct rte_eth_dev_info
which gathers a lot of info, not only from struct rte_eth_dev_data
	- rte_eth_macaddr_get()
	- rte_eth_dev_socket_id()
	- rte_eth_link_get() which is more than an accessor

I think having some specialized accessors is good.
But the rte_eth_dev_info_get() looks like to be a big request
without precise goal and going to break ABI really often.
There are some queues informations, some (not so precise)
offload capabilities, some steering (RSS/VMDq) informations,
the default configuration of some Intel NIC thresholds,
the speed capabilities, etc.

Shouldn't we try to streamline this API?

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] port: bump ABI for pcap file support
  2016-04-14 18:33 25% [dpdk-dev] [PATCH] port: bump ABI for pcap file support Thomas Monjalon
@ 2016-04-15 10:32  4% ` Dumitrescu, Cristian
  0 siblings, 0 replies; 200+ results
From: Dumitrescu, Cristian @ 2016-04-15 10:32 UTC (permalink / raw)
  To: Thomas Monjalon, Zhang, Roy Fan; +Cc: dev, Singh, Jasvinder



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, April 14, 2016 7:34 PM
> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>
> Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com>;
> Singh, Jasvinder <jasvinder.singh@intel.com>
> Subject: [PATCH] port: bump ABI for pcap file support
> 
> Support of PCAP file has been added to rte_port in release 16.04
> as NEXT_ABI. It is in the standard ABI of the release 16.07.
> 
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> ---
>  doc/guides/rel_notes/deprecation.rst   |  5 -----
>  doc/guides/rel_notes/release_16_07.rst |  5 ++++-
>  examples/ip_pipeline/init.c            |  4 ----
>  lib/librte_port/Makefile               |  2 +-
>  lib/librte_port/rte_port_source_sink.c | 14 --------------
>  lib/librte_port/rte_port_source_sink.h |  3 ---
>  6 files changed, 5 insertions(+), 28 deletions(-)
> 


Acked-by: Cristian Dumitrescu <Cristian.Dumitrescu@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC 1/2] doc: announce ABI change for rte_eth_dev_info structure
  2016-04-14  9:44  9% ` [dpdk-dev] [RFC 1/2] doc: announce ABI change for " Reshma Pattan
  2016-04-15  9:42  4%   ` Mcnamara, John
@ 2016-04-15 10:02  8%   ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-15 10:02 UTC (permalink / raw)
  To: Reshma Pattan; +Cc: dev

2016-04-14 10:44, Reshma Pattan:
> New fields nb_rx_queues and nb_tx_queues will be added to
> rte_eth_dev_info structure.
> Changes to API rte_eth_dev_info_get() will be done to update
> these new fields to rte_eth_dev_info object.
> 
> Signed-off-by:reshma Pattan<reshma.pattan@intel.com>

In general the Signed-off lines are the same as the From: field.
Here it would be:
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
(note the spaces and the uppercase)

> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -90,3 +90,9 @@ Deprecation Notices
>    a handle, like the way kernel exposes an fd to user for locating a
>    specific file, and to keep all major structures internally, so that
>    we are likely to be free from ABI violations in future.
> +
> +* A librte_ether public structure ``rte_eth_dev_info`` will be changed in 16.07.
> +  The proposed change will add new parameters ``nb_rx_queues``, ``nb_tx_queues``
> +  to the structure. These are the number of queues configured by software.
> +  Modification to definition of ``rte_eth_dev_info_get()`` will be done
> +  to update new parameters to ``rte_eth_dev_info`` object.

It is too late for this announce as it won't appear in the doc downloaded for
version 16.04. So it is obviously rejected.
The question here is: are you allowed to do a small ABI change given that
the ABI will be broken in this version?
I would say there can be some exceptional tolerance.
I have no strong opinion myself but maybe others will have one.

By the way, I have some comments about the patch.

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [RFC 1/2] doc: announce ABI change for rte_eth_dev_info structure
  2016-04-14  9:44  9% ` [dpdk-dev] [RFC 1/2] doc: announce ABI change for " Reshma Pattan
@ 2016-04-15  9:42  4%   ` Mcnamara, John
  2016-04-15 10:02  8%   ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Mcnamara, John @ 2016-04-15  9:42 UTC (permalink / raw)
  To: Pattan, Reshma, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Reshma Pattan
> Sent: Thursday, April 14, 2016 10:45 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [RFC 1/2] doc: announce ABI change for
> rte_eth_dev_info structure
> 
> New fields nb_rx_queues and nb_tx_queues will be added to rte_eth_dev_info
> structure.
> Changes to API rte_eth_dev_info_get() will be done to update these new
> fields to rte_eth_dev_info object.
> 
> Signed-off-by:reshma Pattan<reshma.pattan@intel.com>

Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] pci: remove deprecated specific config
@ 2016-04-14 21:33  4% Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-14 21:33 UTC (permalink / raw)
  To: helin.zhang; +Cc: dev

The driver i40e was using a specific PCI config before the release 16.04.
>From 16.04, it is always enabled in i40e (commit 56465cfaf).
The API has been deprecated in the commit 68f77593823cab.
The igb_uio implementation has been deprecated in commit b7cf8e155.
The config helper - through igb_uio sysfs entries - is now removed.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 config/common_base                        |  8 -----
 doc/guides/linux_gsg/enable_func.rst      | 15 ---------
 doc/guides/rel_notes/deprecation.rst      |  7 -----
 lib/librte_eal/common/include/rte_pci.h   | 14 ---------
 lib/librte_eal/linuxapp/eal/eal_pci.c     | 12 -------
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 52 -------------------------------
 6 files changed, 108 deletions(-)

diff --git a/config/common_base b/config/common_base
index 0124e86..1a54e4c 100644
--- a/config/common_base
+++ b/config/common_base
@@ -101,14 +101,6 @@ CONFIG_RTE_MALLOC_DEBUG=n
 CONFIG_RTE_EAL_PMD_PATH=""
 
 #
-# Special configurations in PCI Config Space for high performance
-# They are all deprecated, and will be removed later.
-#
-CONFIG_RTE_PCI_CONFIG=n
-CONFIG_RTE_PCI_EXTENDED_TAG=""
-CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
-
-#
 # Compile Environment Abstraction Layer to support Vmware TSC map
 #
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
diff --git a/doc/guides/linux_gsg/enable_func.rst b/doc/guides/linux_gsg/enable_func.rst
index 076770f..ec0e04d 100644
--- a/doc/guides/linux_gsg/enable_func.rst
+++ b/doc/guides/linux_gsg/enable_func.rst
@@ -186,21 +186,6 @@ Check with the local Intel's Network Division application engineers for firmware
 The base driver to support firmware version of FVL3E will be integrated in the next
 DPDK release, so currently the validated firmware version is 4.2.6.
 
-Enabling Extended Tag
-~~~~~~~~~~~~~~~~~~~~~
-
-PCI configuration of ``extended_tag`` has big impact on small packet size
-performance of 40G ports. Enabling ``extended_tag`` can help 40G port to
-achieve the best performance, especially for small packet size.
-
-* Disabling/enabling ``extended_tag`` can be done in some BIOS implementations.
-
-* If BIOS does not enable it, and does not support changing it, tools
-  (e.g. ``setpci`` on Linux) can be used to enable or disable ``extended_tag``.
-
-* From release 16.04, ``extended_tag`` is enabled by default during port
-  initialization, users don't need to care about that anymore.
-
 Use 16 Bytes RX Descriptor Size
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index a3fdbb1..c78cde7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,13 +20,6 @@ Deprecation Notices
   do not need to care about the kind of devices that are being used, making it
   easier to add new buses later.
 
-* The EAL function pci_config_space_set is deprecated in release 16.04
-  and will be removed from 16.07.
-  Macros CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and
-  CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE will be removed.
-  The /sys entries extended_tag and max_read_request_size created by igb_uio
-  will be removed.
-
 * ABI changes are planned for struct rte_pci_id, i.e., add new field ``class``.
   This new added ``class`` field can be used to probe pci device by class
   related info. This change should impact size of struct rte_pci_id and struct
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index e692094..9f2301d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -577,20 +577,6 @@ void rte_eal_pci_ioport_read(struct rte_pci_ioport *p,
 void rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
 			      const void *data, size_t len, off_t offset);
 
-#ifdef RTE_PCI_CONFIG
-#include <rte_common.h>
-/**
- * Set special config space registers for performance purpose.
- * It is deprecated, as all configurations have been moved into
- * each PMDs respectively.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void pci_config_space_set(struct rte_pci_device *dev) __rte_deprecated;
-#endif /* RTE_PCI_CONFIG */
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index dbf12a8..bdc08a0 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -481,18 +481,6 @@ error:
 	return -1;
 }
 
-#ifdef RTE_PCI_CONFIG
-/*
- * It is deprecated, all its configurations have been moved into
- * each PMD respectively.
- */
-void
-pci_config_space_set(__rte_unused struct rte_pci_device *dev)
-{
-	RTE_LOG(DEBUG, EAL, "Nothing here, as it is deprecated\n");
-}
-#endif
-
 /* Read PCI config space. */
 int rte_eal_pci_read_config(const struct rte_pci_device *device,
 			    void *buf, size_t len, off_t offset)
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index 72b2692..45a5720 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -81,62 +81,10 @@ store_max_vfs(struct device *dev, struct device_attribute *attr,
 	return err ? err : count;
 }
 
-#ifdef RTE_PCI_CONFIG
-static ssize_t
-show_extended_tag(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	dev_info(dev, "Deprecated\n");
-
-	return 0;
-}
-
-static ssize_t
-store_extended_tag(struct device *dev,
-		   struct device_attribute *attr,
-		   const char *buf,
-		   size_t count)
-{
-	dev_info(dev, "Deprecated\n");
-
-	return 0;
-}
-
-static ssize_t
-show_max_read_request_size(struct device *dev,
-			   struct device_attribute *attr,
-			   char *buf)
-{
-	dev_info(dev, "Deprecated\n");
-
-	return 0;
-}
-
-static ssize_t
-store_max_read_request_size(struct device *dev,
-			    struct device_attribute *attr,
-			    const char *buf,
-			    size_t count)
-{
-	dev_info(dev, "Deprecated\n");
-
-	return 0;
-}
-#endif
-
 static DEVICE_ATTR(max_vfs, S_IRUGO | S_IWUSR, show_max_vfs, store_max_vfs);
-#ifdef RTE_PCI_CONFIG
-static DEVICE_ATTR(extended_tag, S_IRUGO | S_IWUSR, show_extended_tag,
-	store_extended_tag);
-static DEVICE_ATTR(max_read_request_size, S_IRUGO | S_IWUSR,
-	show_max_read_request_size, store_max_read_request_size);
-#endif
 
 static struct attribute *dev_attrs[] = {
 	&dev_attr_max_vfs.attr,
-#ifdef RTE_PCI_CONFIG
-	&dev_attr_extended_tag.attr,
-	&dev_attr_max_read_request_size.attr,
-#endif
 	NULL,
 };
 
-- 
2.7.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] port: bump ABI for pcap file support
@ 2016-04-14 18:33 25% Thomas Monjalon
  2016-04-15 10:32  4% ` Dumitrescu, Cristian
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-14 18:33 UTC (permalink / raw)
  To: roy.fan.zhang; +Cc: dev, cristian.dumitrescu, jasvinder.singh

Support of PCAP file has been added to rte_port in release 16.04
as NEXT_ABI. It is in the standard ABI of the release 16.07.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst   |  5 -----
 doc/guides/rel_notes/release_16_07.rst |  5 ++++-
 examples/ip_pipeline/init.c            |  4 ----
 lib/librte_port/Makefile               |  2 +-
 lib/librte_port/rte_port_source_sink.c | 14 --------------
 lib/librte_port/rte_port_source_sink.h |  3 ---
 6 files changed, 5 insertions(+), 28 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 327fc2b..a3fdbb1 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -79,11 +79,6 @@ Deprecation Notices
   modification of the API of rte_mempool_obj_iter(), implying a breakage
   of the ABI.
 
-* ABI changes are planned for struct rte_port_source_params in order to
-  support PCAP file reading feature. The release 16.04 contains this ABI
-  change wrapped by RTE_NEXT_ABI macro. Release 16.07 will contain this
-  change, and no backwards compatibility is planned.
-
 * A librte_vhost public structures refactor is planned for DPDK 16.07
   that requires both ABI and API change.
   The proposed refactor would expose DPDK vhost dev to applications as
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 701e827..001888f 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -94,6 +94,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ``rte_port_source_params`` structure has new fields to support PCAP file.
+  It was already in release 16.04 with ``RTE_NEXT_ABI`` flag.
+
 
 Shared Library Versions
 -----------------------
@@ -123,7 +126,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_pipeline.so.3
      librte_pmd_bond.so.1
      librte_pmd_ring.so.2
-     librte_port.so.2
+   + librte_port.so.3
      librte_power.so.1
      librte_reorder.so.1
      librte_ring.so.1
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 83422e8..02351f6 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -1221,8 +1221,6 @@ static void app_pipeline_params_get(struct app_params *app,
 			out->type = PIPELINE_PORT_IN_SOURCE;
 			out->params.source.mempool = app->mempool[mempool_id];
 			out->burst_size = app->source_params[in->id].burst;
-
-#ifdef RTE_NEXT_ABI
 			if (app->source_params[in->id].file_name
 				!= NULL) {
 				out->params.source.file_name = strdup(
@@ -1237,8 +1235,6 @@ static void app_pipeline_params_get(struct app_params *app,
 					app->source_params[in->id].
 					n_bytes_per_pkt;
 			}
-#endif
-
 			break;
 		default:
 			break;
diff --git a/lib/librte_port/Makefile b/lib/librte_port/Makefile
index 2c0ccbe..d4de5af 100644
--- a/lib/librte_port/Makefile
+++ b/lib/librte_port/Makefile
@@ -44,7 +44,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_port_version.map
 
-LIBABIVER := 2
+LIBABIVER := 3
 
 #
 # all source are stored in SRCS-y
diff --git a/lib/librte_port/rte_port_source_sink.c b/lib/librte_port/rte_port_source_sink.c
index 056c975..4cad710 100644
--- a/lib/librte_port/rte_port_source_sink.c
+++ b/lib/librte_port/rte_port_source_sink.c
@@ -38,17 +38,11 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 
-#ifdef RTE_NEXT_ABI
-
 #ifdef RTE_PORT_PCAP
 #include <rte_ether.h>
 #include <pcap.h>
 #endif
 
-#else
-#undef RTE_PORT_PCAP
-#endif
-
 #include "rte_port_source_sink.h"
 
 /*
@@ -81,8 +75,6 @@ struct rte_port_source {
 	uint32_t pkt_index;
 };
 
-#ifdef RTE_NEXT_ABI
-
 #ifdef RTE_PORT_PCAP
 
 static int
@@ -232,8 +224,6 @@ error_exit:
 
 #endif /* RTE_PORT_PCAP */
 
-#endif /* RTE_NEXT_ABI */
-
 static void *
 rte_port_source_create(void *params, int socket_id)
 {
@@ -258,8 +248,6 @@ rte_port_source_create(void *params, int socket_id)
 	/* Initialization */
 	port->mempool = (struct rte_mempool *) p->mempool;
 
-#ifdef RTE_NEXT_ABI
-
 	if (p->file_name) {
 		int status = PCAP_SOURCE_LOAD(port, p->file_name,
 			p->n_bytes_per_pkt, socket_id);
@@ -270,8 +258,6 @@ rte_port_source_create(void *params, int socket_id)
 		}
 	}
 
-#endif
-
 	return port;
 }
 
diff --git a/lib/librte_port/rte_port_source_sink.h b/lib/librte_port/rte_port_source_sink.h
index 917abe4..4db8a8a 100644
--- a/lib/librte_port/rte_port_source_sink.h
+++ b/lib/librte_port/rte_port_source_sink.h
@@ -53,7 +53,6 @@ extern "C" {
 struct rte_port_source_params {
 	/** Pre-initialized buffer pool */
 	struct rte_mempool *mempool;
-#ifdef RTE_NEXT_ABI
 
 	/** The full path of the pcap file to read packets from */
 	char *file_name;
@@ -62,8 +61,6 @@ struct rte_port_source_params {
 	 *  if it is bigger than packet size, the generated packets
 	 *  will contain the whole packet */
 	uint32_t n_bytes_per_pkt;
-
-#endif
 };
 
 /** source port operations */
-- 
2.7.0

^ permalink raw reply	[relevance 25%]

* Re: [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation
  2016-04-14 14:01  0%     ` Olivier MATZ
@ 2016-04-14 14:03  0%       ` Wiles, Keith
  0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-04-14 14:03 UTC (permalink / raw)
  To: Olivier MATZ, dev; +Cc: Richardson, Bruce, stephen

>
>
>On 04/14/2016 03:50 PM, Wiles, Keith wrote:
>>> This series is a rework of mempool. For those who don't want to read
>>> all the cover letter, here is a sumary:
>>>
>>> - it is not possible to allocate large mempools if there is not enough
>>>   contiguous memory, this series solves this issue
>>> - introduce new APIs with less arguments: "create, populate, obj_init"
>>> - allow to free a mempool
>>> - split code in smaller functions, will ease the introduction of ext_handler
>>> - remove test-pmd anonymous mempool creation
>>> - remove most of dom0-specific mempool code
>>> - opens the door for a eal_memory rework: we probably don't need large
>>>   contiguous memory area anymore, working with pages would work.
>>>
>>> This breaks the ABI as it was indicated in the deprecation for 16.04.
>>> The API stays almost the same, no modification is needed in examples app
>>> or in test-pmd. Only kni and mellanox drivers are slightly modified.
>>>
>>> This patch applies on top of 16.04 + v5 of Keith's patch:
>>> "mempool: reduce rte_mempool structure size"
>>
>> I have not digested this complete patch yet, but this one popped out at me as the External Memory Manager support is setting in the wings for 16.07 release. If this causes the EMM patch to be rewritten or updated that seems like a problem to me. Does this patch add the External Memory Manager support?
>> http://thread.gmane.org/gmane.comp.networking.dpdk.devel/32015/focus=35107
>
>I've reworked the series you are referring to, and rebased it on top
>of this series. Please see:
>http://dpdk.org/ml/archives/dev/2016-April/037509.html

Thanks I just saw that update :-)

>
>Regards,
>Olivier
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation
  2016-04-14 13:50  0%   ` Wiles, Keith
@ 2016-04-14 14:01  0%     ` Olivier MATZ
  2016-04-14 14:03  0%       ` Wiles, Keith
  0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2016-04-14 14:01 UTC (permalink / raw)
  To: Wiles, Keith, dev; +Cc: Richardson, Bruce, stephen



On 04/14/2016 03:50 PM, Wiles, Keith wrote:
>> This series is a rework of mempool. For those who don't want to read
>> all the cover letter, here is a sumary:
>>
>> - it is not possible to allocate large mempools if there is not enough
>>   contiguous memory, this series solves this issue
>> - introduce new APIs with less arguments: "create, populate, obj_init"
>> - allow to free a mempool
>> - split code in smaller functions, will ease the introduction of ext_handler
>> - remove test-pmd anonymous mempool creation
>> - remove most of dom0-specific mempool code
>> - opens the door for a eal_memory rework: we probably don't need large
>>   contiguous memory area anymore, working with pages would work.
>>
>> This breaks the ABI as it was indicated in the deprecation for 16.04.
>> The API stays almost the same, no modification is needed in examples app
>> or in test-pmd. Only kni and mellanox drivers are slightly modified.
>>
>> This patch applies on top of 16.04 + v5 of Keith's patch:
>> "mempool: reduce rte_mempool structure size"
>
> I have not digested this complete patch yet, but this one popped out at me as the External Memory Manager support is setting in the wings for 16.07 release. If this causes the EMM patch to be rewritten or updated that seems like a problem to me. Does this patch add the External Memory Manager support?
> http://thread.gmane.org/gmane.comp.networking.dpdk.devel/32015/focus=35107

I've reworked the series you are referring to, and rebased it on top
of this series. Please see:
http://dpdk.org/ml/archives/dev/2016-April/037509.html

Regards,
Olivier

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4 0/3] external mempool manager
  2016-03-09  9:50  3% ` [dpdk-dev] [PATCH v3 0/4] " David Hunt
  2016-03-09  9:50  4%   ` [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages David Hunt
@ 2016-04-14 13:57  2%   ` Olivier Matz
  1 sibling, 0 replies; 200+ results
From: Olivier Matz @ 2016-04-14 13:57 UTC (permalink / raw)
  To: dev, david.hunt; +Cc: yuanhan.liu, pmatilai

Here's a reworked version of the patch initially sent by David Hunt.
The main change is that it is rebased on top of the "mempool: rework
memory allocation" series [1], which simplifies a lot the first patch.

[1] http://dpdk.org/ml/archives/dev/2016-April/037464.html

v4 changes:
 * remove the rte_mempool_create_ext() function. To change the handler, the
   user has to do the following:
   - mp = rte_mempool_create_empty()
   - rte_mempool_set_handler(mp, "my_handler")
   - rte_mempool_populate_default(mp)
   This avoids to add another function with more than 10 arguments, duplicating
   the doxygen comments
 * change the api of rte_mempool_alloc_t: only the mempool pointer is required
   as all information is available in it
 * change the api of rte_mempool_free_t: remove return value
 * move inline wrapper functions from the .c to the .h (else they won't be
   inlined). This implies to have one header file (rte_mempool.h), or it
   would have generate cross dependencies issues.
 * remove now unused MEMPOOL_F_INT_HANDLER (note: it was misused anyway due
   to the use of && instead of &)
 * fix build in debug mode (__MEMPOOL_STAT_ADD(mp, put_pool, n) remaining)
 * fix build with shared libraries (global handler has to be declared in
   the .map file)
 * rationalize #include order
 * remove unused function rte_mempool_get_handler_name()
 * rename some structures, fields, functions
 * remove the static in front of rte_tailq_elem rte_mempool_tailq (comment
   from Yuanhan)
 * test the ext mempool handler in the same file than standard mempool tests,
   avoiding to duplicate the code
 * rework the custom handler in mempool_test
 * rework a bit the patch selecting default mbuf pool handler
 * fix some doxygen comments

Things that should still be discussed:

- Panu pointed out that having a compile-time configuration
  option for selecting the default mbuf handler is not a good idea.
  I mostly agree, except in one case (and that's why I kept this patch):
  if a specific architecture has its own way to provide an efficient
  pool handler for mbufs, it could be the proper place to have this
  option. But as far as I know, there is no such architecture today
  in dpdk.

- The other question I would like to raise is about the use cases.
  The cover letter below could be a bit more explicit about what this
  feature will be used for.



This is the initial unmodified cover letter from David Hunt:

Hi list.

Here's the v3 version patch for an external mempool manager

v3 changes:
 * simplified the file layout, renamed to rte_mempool_handler.[hc]
 * moved the default handlers into rte_mempool_default.c
 * moved the example handler out into app/test/test_ext_mempool.c
 * removed is_mc/is_mp change, slight perf degredation on sp cached operation
 * removed stack hanler, may re-introduce at a later date
 * Changes out of code reviews

v2 changes:
 * There was a lot of duplicate code between rte_mempool_xmem_create and
   rte_mempool_create_ext. This has now been refactored and is now
   hopefully cleaner.
 * The RTE_NEXT_ABI define is now used to allow building of the library
   in a format that is compatible with binaries built against previous
   versions of DPDK.
 * Changes out of code reviews. Hopefully I've got most of them included.

The External Mempool Manager is an extension to the mempool API that allows
users to add and use an external mempool manager, which allows external memory
subsystems such as external hardware memory management systems and software
based memory allocators to be used with DPDK.

The existing API to the internal DPDK mempool manager will remain unchanged
and will be backward compatible. However, there will be an ABI breakage, as
the mempool struct is changing. These changes are all contained withing
RTE_NEXT_ABI defs, and the current or next code can be changed with
the CONFIG_RTE_NEXT_ABI config setting

There are two aspects to external mempool manager.
  1. Adding the code for your new mempool handler. This is achieved by adding a
     new mempool handler source file into the librte_mempool library, and
     using the REGISTER_MEMPOOL_HANDLER macro.
  2. Using the new API to call rte_mempool_create_ext to create a new mempool
     using the name parameter to identify which handler to use.

New API calls added
 1. A new mempool 'create' function which accepts mempool handler name.
 2. A new mempool 'rte_get_mempool_handler' function which accepts mempool
    handler name, and returns the index to the relevant set of callbacks for
    that mempool handler

Several external mempool managers may be used in the same application. A new
mempool can then be created by using the new 'create' function, providing the
mempool handler name to point the mempool to the relevant mempool manager
callback structure.

The old 'create' function can still be called by legacy programs, and will
internally work out the mempool handle based on the flags provided (single
producer, single consumer, etc). By default handles are created internally to
implement the built-in DPDK mempool manager and mempool types.

The external mempool manager needs to provide the following functions.
 1. alloc     - allocates the mempool memory, and adds each object onto a ring
 2. put       - puts an object back into the mempool once an application has
                finished with it
 3. get       - gets an object from the mempool for use by the application
 4. get_count - gets the number of available objects in the mempool
 5. free      - frees the mempool memory

Every time a get/put/get_count is called from the application/PMD, the
callback for that mempool is called. These functions are in the fastpath,
and any unoptimised handlers may limit performance.

The new APIs are as follows:

1. rte_mempool_create_ext

struct rte_mempool *
rte_mempool_create_ext(const char * name, unsigned n,
        unsigned cache_size, unsigned private_data_size,
        int socket_id, unsigned flags,
        const char * handler_name);

2. rte_mempool_get_handler_name

char *
rte_mempool_get_handler_name(struct rte_mempool *mp);

Please see rte_mempool.h for further information on the parameters.


The important thing to note is that the mempool handler is passed by name
to rte_mempool_create_ext, and that in turn calls rte_get_mempool_handler to
get the handler index, which is stored in the rte_memool structure. This
allow multiple processes to use the same mempool, as the function pointers
are accessed via handler index.

The mempool handler structure contains callbacks to the implementation of
the handler, and is set up for registration as follows:

static struct rte_mempool_handler handler_sp_mc = {
    .name = "ring_sp_mc",
    .alloc = rte_mempool_common_ring_alloc,
    .put = common_ring_sp_put,
    .get = common_ring_mc_get,
    .get_count = common_ring_get_count,
    .free = common_ring_free,
};

And then the following macro will register the handler in the array of handlers

REGISTER_MEMPOOL_HANDLER(handler_mp_mc);

For and example of a simple malloc based mempool manager, see
lib/librte_mempool/custom_mempool.c

For an example of API usage, please see app/test/test_ext_mempool.c, which
implements a rudimentary mempool manager using simple mallocs for each
mempool object. This file also contains the callbacks and self registration
for the new handler.

David Hunt (2):
  mempool: support external handler
  mbuf: get default mempool handler from configuration

Olivier Matz (1):
  app/test: test external mempool handler

 app/test/test_mempool.c                    | 113 +++++++++++++++
 app/test/test_mempool_perf.c               |   1 -
 config/common_base                         |   1 +
 lib/librte_mbuf/rte_mbuf.c                 |  21 ++-
 lib/librte_mempool/Makefile                |   2 +
 lib/librte_mempool/rte_mempool.c           |  72 ++++------
 lib/librte_mempool/rte_mempool.h           | 212 +++++++++++++++++++++++++----
 lib/librte_mempool/rte_mempool_default.c   | 147 ++++++++++++++++++++
 lib/librte_mempool/rte_mempool_handler.c   | 139 +++++++++++++++++++
 lib/librte_mempool/rte_mempool_version.map |   4 +
 10 files changed, 637 insertions(+), 75 deletions(-)
 create mode 100644 lib/librte_mempool/rte_mempool_default.c
 create mode 100644 lib/librte_mempool/rte_mempool_handler.c

-- 
2.1.4

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH v5] mempool: reduce rte_mempool structure size
  2016-04-14  9:42  2% ` [dpdk-dev] [PATCH v5] " Olivier Matz
  2016-04-14 13:28  0%   ` Wiles, Keith
@ 2016-04-14 13:53  0%   ` Wiles, Keith
  1 sibling, 0 replies; 200+ results
From: Wiles, Keith @ 2016-04-14 13:53 UTC (permalink / raw)
  To: Olivier Matz, dev; +Cc: thomas.monjalon, pmatilai

>From: Keith Wiles <keith.wiles@intel.com>
>
>The rte_mempool structure is changed, which will cause an ABI change
>for this structure. Providing backward compat is not reasonable
>here as this structure is used in multiple defines/inlines.
>
>Allow mempool cache support to be dynamic depending on if the
>mempool being created needs cache support. Saves about 1.5M of
>memory used by the rte_mempool structure.
>
>Allocating small mempools which do not require cache can consume
>larges amounts of memory if you have a number of these mempools.
>
>Change to be effective in release 16.07.
>
>Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>Acked-by: Olivier Matz <olivier.matz@6wind.com>

For the change to this patch:
Acked-by: Keith Wiles <keith.wiles@intel.com>

>---
>
>Changes in v5:
>
>- use RTE_PTR_ADD() instead of cast to (char *) to fix compilation on tilera.
>  Error log was:
>
>  rte_mempool.c: In function ‘rte_mempool_xmem_create’:
>  rte_mempool.c:595: error: cast increases required alignment of target type
>
>
> app/test/test_mempool.c          |  4 +--
> lib/librte_mempool/rte_mempool.c | 55 ++++++++++++++++++----------------------
> lib/librte_mempool/rte_mempool.h | 29 ++++++++++-----------
> 3 files changed, 40 insertions(+), 48 deletions(-)
>
>diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
>index f0f823b..10e1fa4 100644
>--- a/app/test/test_mempool.c
>+++ b/app/test/test_mempool.c
>@@ -122,8 +122,8 @@ test_mempool_basic(void)
> 		return -1;
> 
> 	printf("get private data\n");
>-	if (rte_mempool_get_priv(mp) !=
>-			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
>+	if (rte_mempool_get_priv(mp) != (char *)mp +
>+			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))
> 		return -1;
> 
> 	printf("get physical address of an object\n");
>diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>index f8781e1..7a0e07e 100644
>--- a/lib/librte_mempool/rte_mempool.c
>+++ b/lib/librte_mempool/rte_mempool.c
>@@ -452,12 +452,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	/* compilation-time checks */
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>-	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
>-			  RTE_CACHE_LINE_MASK) != 0);
>-#endif
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>@@ -527,9 +523,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 		 */
> 		int head = sizeof(struct rte_mempool);
> 		int new_size = (private_data_size + head) % page_size;
>-		if (new_size) {
>+		if (new_size)
> 			private_data_size += page_size - new_size;
>-		}
> 	}
> 
> 	/* try to allocate tailq entry */
>@@ -544,7 +539,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	 * store mempool objects. Otherwise reserve a memzone that is large
> 	 * enough to hold mempool header and metadata plus mempool objects.
> 	 */
>-	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
>+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
>+	mempool_size += private_data_size;
> 	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
> 	if (vaddr == NULL)
> 		mempool_size += (size_t)objsz.total_size * n;
>@@ -591,8 +587,15 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
> 	mp->private_data_size = private_data_size;
> 
>+	/*
>+	 * local_cache pointer is set even if cache_size is zero.
>+	 * The local_cache points to just past the elt_pa[] array.
>+	 */
>+	mp->local_cache = (struct rte_mempool_cache *)
>+		RTE_PTR_ADD(mp, MEMPOOL_HEADER_SIZE(mp, pg_num, 0));
>+
> 	/* calculate address of the first element for continuous mempool. */
>-	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
>+	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size) +
> 		private_data_size;
> 	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
> 
>@@ -606,9 +609,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 		mp->elt_va_start = (uintptr_t)obj;
> 		mp->elt_pa[0] = mp->phys_addr +
> 			(mp->elt_va_start - (uintptr_t)mp);
>-
>-	/* mempool elements in a separate chunk of memory. */
> 	} else {
>+		/* mempool elements in a separate chunk of memory. */
> 		mp->elt_va_start = (uintptr_t)vaddr;
> 		memcpy(mp->elt_pa, paddr, sizeof (mp->elt_pa[0]) * pg_num);
> 	}
>@@ -643,19 +645,15 @@ unsigned
> rte_mempool_count(const struct rte_mempool *mp)
> {
> 	unsigned count;
>+	unsigned lcore_id;
> 
> 	count = rte_ring_count(mp->ring);
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>-	{
>-		unsigned lcore_id;
>-		if (mp->cache_size == 0)
>-			return count;
>+	if (mp->cache_size == 0)
>+		return count;
> 
>-		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
>-			count += mp->local_cache[lcore_id].len;
>-	}
>-#endif
>+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
>+		count += mp->local_cache[lcore_id].len;
> 
> 	/*
> 	 * due to race condition (access to len is not locked), the
>@@ -670,13 +668,16 @@ rte_mempool_count(const struct rte_mempool *mp)
> static unsigned
> rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
> {
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	unsigned lcore_id;
> 	unsigned count = 0;
> 	unsigned cache_count;
> 
> 	fprintf(f, "  cache infos:\n");
> 	fprintf(f, "    cache_size=%"PRIu32"\n", mp->cache_size);
>+
>+	if (mp->cache_size == 0)
>+		return count;
>+
> 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> 		cache_count = mp->local_cache[lcore_id].len;
> 		fprintf(f, "    cache_count[%u]=%u\n", lcore_id, cache_count);
>@@ -684,11 +685,6 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
> 	}
> 	fprintf(f, "    total_cache_count=%u\n", count);
> 	return count;
>-#else
>-	RTE_SET_USED(mp);
>-	fprintf(f, "  cache disabled\n");
>-	return 0;
>-#endif
> }
> 
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>@@ -753,13 +749,16 @@ mempool_audit_cookies(const struct rte_mempool *mp)
> #define mempool_audit_cookies(mp) do {} while(0)
> #endif
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> /* check cookies before and after objects */
> static void
> mempool_audit_cache(const struct rte_mempool *mp)
> {
> 	/* check cache size consistency */
> 	unsigned lcore_id;
>+
>+	if (mp->cache_size == 0)
>+		return;
>+
> 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> 		if (mp->local_cache[lcore_id].len > mp->cache_flushthresh) {
> 			RTE_LOG(CRIT, MEMPOOL, "badness on cache[%u]\n",
>@@ -768,10 +767,6 @@ mempool_audit_cache(const struct rte_mempool *mp)
> 		}
> 	}
> }
>-#else
>-#define mempool_audit_cache(mp) do {} while(0)
>-#endif
>-
> 
> /* check the consistency of mempool (size, cookies, ...) */
> void
>diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
>index 9745bf0..8595e77 100644
>--- a/lib/librte_mempool/rte_mempool.h
>+++ b/lib/librte_mempool/rte_mempool.h
>@@ -95,7 +95,6 @@ struct rte_mempool_debug_stats {
> } __rte_cache_aligned;
> #endif
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> /**
>  * A structure that stores a per-core object cache.
>  */
>@@ -107,7 +106,6 @@ struct rte_mempool_cache {
> 	 */
> 	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
> } __rte_cache_aligned;
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> /**
>  * A structure that stores the size of mempool elements.
>@@ -194,10 +192,7 @@ struct rte_mempool {
> 
> 	unsigned private_data_size;      /**< Size of private data. */
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>-	/** Per-lcore local cache. */
>-	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
>-#endif
>+	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
> 
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> 	/** Per-lcore statistics. */
>@@ -247,6 +242,13 @@ struct rte_mempool {
> #endif
> 
> /**
>+ * Size of elt_pa array size based on number of pages. (Internal use)
>+ */
>+#define __PA_SIZE(mp, pgn) \
>+	RTE_ALIGN_CEIL((((pgn) - RTE_DIM((mp)->elt_pa)) * \
>+	sizeof((mp)->elt_pa[0])), RTE_CACHE_LINE_SIZE)
>+
>+/**
>  * Calculate the size of the mempool header.
>  *
>  * @param mp
>@@ -254,9 +256,9 @@ struct rte_mempool {
>  * @param pgn
>  *   Number of pages used to store mempool objects.
>  */
>-#define	MEMPOOL_HEADER_SIZE(mp, pgn)	(sizeof(*(mp)) + \
>-	RTE_ALIGN_CEIL(((pgn) - RTE_DIM((mp)->elt_pa)) * \
>-	sizeof ((mp)->elt_pa[0]), RTE_CACHE_LINE_SIZE))
>+#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
>+	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
>+	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
> 
> /**
>  * Return true if the whole mempool is in contiguous memory.
>@@ -755,19 +757,16 @@ static inline void __attribute__((always_inline))
> __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
> 		    unsigned n, int is_mp)
> {
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	struct rte_mempool_cache *cache;
> 	uint32_t index;
> 	void **cache_objs;
> 	unsigned lcore_id = rte_lcore_id();
> 	uint32_t cache_size = mp->cache_size;
> 	uint32_t flushthresh = mp->cache_flushthresh;
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* increment stat now, adding in mempool always success */
> 	__MEMPOOL_STAT_ADD(mp, put, n);
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	/* cache is not enabled or single producer or non-EAL thread */
> 	if (unlikely(cache_size == 0 || is_mp == 0 ||
> 		     lcore_id >= RTE_MAX_LCORE))
>@@ -802,7 +801,6 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
> 	return;
> 
> ring_enqueue:
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* push remaining objects in ring */
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>@@ -946,7 +944,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
> 		   unsigned n, int is_mc)
> {
> 	int ret;
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	struct rte_mempool_cache *cache;
> 	uint32_t index, len;
> 	void **cache_objs;
>@@ -992,7 +989,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
> 	return 0;
> 
> ring_dequeue:
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* get remaining objects from ring */
> 	if (is_mc)
>@@ -1293,7 +1289,8 @@ void rte_mempool_audit(const struct rte_mempool *mp);
>  */
> static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
> {
>-	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
>+	return (char *)mp +
>+		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
> }
> 
> /**
>-- 
>2.1.4
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation
  2016-04-14 10:19  2% ` [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation Olivier Matz
@ 2016-04-14 13:50  0%   ` Wiles, Keith
  2016-04-14 14:01  0%     ` Olivier MATZ
  0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2016-04-14 13:50 UTC (permalink / raw)
  To: Olivier Matz, dev; +Cc: Richardson, Bruce, stephen

>This series is a rework of mempool. For those who don't want to read
>all the cover letter, here is a sumary:
>
>- it is not possible to allocate large mempools if there is not enough
>  contiguous memory, this series solves this issue
>- introduce new APIs with less arguments: "create, populate, obj_init"
>- allow to free a mempool
>- split code in smaller functions, will ease the introduction of ext_handler
>- remove test-pmd anonymous mempool creation
>- remove most of dom0-specific mempool code
>- opens the door for a eal_memory rework: we probably don't need large
>  contiguous memory area anymore, working with pages would work.
>
>This breaks the ABI as it was indicated in the deprecation for 16.04.
>The API stays almost the same, no modification is needed in examples app
>or in test-pmd. Only kni and mellanox drivers are slightly modified.
>
>This patch applies on top of 16.04 + v5 of Keith's patch:
>"mempool: reduce rte_mempool structure size"

I have not digested this complete patch yet, but this one popped out at me as the External Memory Manager support is setting in the wings for 16.07 release. If this causes the EMM patch to be rewritten or updated that seems like a problem to me. Does this patch add the External Memory Manager support?
http://thread.gmane.org/gmane.comp.networking.dpdk.devel/32015/focus=35107


>
>Changes RFC -> v1:
>
>- remove the rte_deconst macro, and remove some const qualifier in
>  dump/audit functions
>- rework modifications in mellanox drivers to ensure the mempool is
>  virtually contiguous
>- fix mempool memory chunk iteration (bad pointer was used)
>- fix compilation on freebsd: replace MAP_LOCKED flag by mlock()
>- fix compilation on tilera (pointer arithmetics)
>- slightly rework and clean the mempool autotest
>- fix mempool autotest on bsd
>- more validation (especially mellanox drivers and kni that were not
>  tested in RFC)
>- passed autotests (x86_64-native-linuxapp-gcc and x86_64-native-bsdapp-gcc)
>- rebase on head, reorder the patches a bit and fix minor split issues
>
>
>Description of the initial issue
>--------------------------------
>
>The allocation of mbuf pool can fail even if there is enough memory.
>The problem is related to the way the memory is allocated and used in
>dpdk. It is particularly annoying with mbuf pools, but it can also fail
>in other use cases allocating a large amount of memory.
>
>- rte_malloc() allocates physically contiguous memory, which is needed
>  for mempools, but useless most of the time.
>
>  Allocating a large physically contiguous zone is often impossible
>  because the system provide hugepages which may not be contiguous.
>
>- rte_mempool_create() (and therefore rte_pktmbuf_pool_create())
>  requires a physically contiguous zone.
>
>- rte_mempool_xmem_create() does not solve the issue as it still
>  needs the memory to be virtually contiguous, and there is no
>  way in dpdk to allocate a virtually contiguous memory that is
>  not also physically contiguous.
>
>How to reproduce the issue
>--------------------------
>
>- start the dpdk with some 2MB hugepages (it can also occur with 1GB)
>- allocate a large mempool
>- even if there is enough memory, the allocation can fail
>
>Example:
>
>  git clone http://dpdk.org/git/dpdk
>  cd dpdk
>  make config T=x86_64-native-linuxapp-gcc
>  make -j32
>  mkdir -p /mnt/huge
>  mount -t hugetlbfs nodev /mnt/huge
>  echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
>
>  # we try to allocate a mempool whose size is ~450MB, it fails
>  ./build/app/testpmd -l 2,4 -- --total-num-mbufs=200000 -i
>
>The EAL logs "EAL: Virtual area found at..." shows that there are
>several zones, but all smaller than 450MB.
>
>Workarounds:
>
>- Use 1GB hugepages: it sometimes work, but for very large
>  pools (millions of mbufs) there is the same issue. Moreover,
>  it would consume 1GB memory at least which can be a lot
>  in some cases.
>
>- Reboot the machine or allocate hugepages at boot time: this increases
>  the chances to have more contiguous memory, but does not completely
>  solve the issue
>
>Solutions
>---------
>
>Below is a list of proposed solutions. I implemented a quick and dirty
>PoC of solution 1, but it's not working in all conditions and it's
>really an ugly hack.  This series implement the solution 4 which looks
>the best to me, knowing it does not prevent to do more enhancements
>in dpdk memory in the future (solution 3 for instance).
>
>Solution 1: in application
>--------------------------
>
>- allocate several hugepages using rte_malloc() or rte_memzone_reserve()
>  (only keeping complete hugepages)
>- parse memsegs and /proc/maps to check which files mmaps these pages
>- mmap the files in a contiguous virtual area
>- use rte_mempool_xmem_create()
>
>Cons:
>
>- 1a. parsing the memsegs of rte config in the application does not
>  use a public API, and can be broken if internal dpdk code changes
>- 1b. some memory is lost due to malloc headers. Also, if the memory is
>  very fragmented (ex: all 2MB pages are physically separated), it does
>  not work at all because we cannot get any complete page. It is not
>  possible to use a lower level allocator since commit fafcc11985a.
>- 1c. we cannot use rte_pktmbuf_pool_create(), so we need to use mempool
>  api and do a part of the job manually
>- 1d. it breaks secondary processes as the virtual addresses won't be
>  mmap'd at the same place in secondary process
>- 1e. it only fixes the issue for the mbuf pool of the application,
>  internal pools in dpdk libraries are not modified
>- 1f. this is a pure linux solution (rte_map files)
>- 1g. The application has to be aware of RTE_EAL_SINGLE_SEGMENTS option
>  that changes the way hugepages are mapped. By the way, it's strange
>  to have such a compile-time option, we should probably have only
>  one behavior that works all the time.
>
>Solution 2: in dpdk memory allocator
>------------------------------------
>
>- do the same than solution 1 in a new function rte_malloc_non_contig():
>  allocate several chunks and mmap them in a contiguous virtual memory
>- a flag has to be added in malloc header to do the proper cleanup in
>  rte_free() (free all the chunks, munmap the memory)
>- introduce a new rte_mem_get_physmap(*physmap,addr, len) that returns
>  the virt2phys mapping of a virtual area in dpdk
>- add a mempool flag MEMPOOL_F_NON_PHYS_CONTIG to use
>  rte_malloc_non_contig() to allocate the area storing the objects
>
>Cons:
>
>- 2a. same than 1b: it breaks secondary processes if the mempool flag is
>  used.
>- 2b. same as 1d: some memory is lost due to malloc headers, and it
>  cannot work if memory is too fragmented.
>- 2c. rte_malloc_virt2phy() cannot be used on these zones. It would
>  return the physical address of the first page. It would be better to
>  return an error in this case.
>- 2d. need to check how to implement this on bsd (TBD)
>
>Solution 3: in dpdk eal memory
>------------------------------
>
>- Rework the way hugepages are mmap'd in dpdk: instead of having several
>  rte_map* files, just mmap one file per node. It may drastically
>  simplify EAL memory management in dpdk.
>- An API should be added to retrieve the physical mapping of a virtual
>  area (ex: rte_mem_get_physmap(*physmap, addr, len))
>- rte_malloc() and rte_memzone_reserve() won't allocate physically
>  contiguous memory anymore (TBD)
>- Update mempool to always use the rte_mempool_xmem_create() version
>
>Cons:
>
>- 3a. lot of rework in eal memory, it will induce some behavior changes
>  and maybe api changes
>- 3b. possible conflicts with xen_dom0 mempool
>
>Solution 4: in mempool
>----------------------
>
>- Introduce a new API to fill a mempool with zones that are not
>  virtually contiguous. It requires to add new functions to create and
>  populate a mempool. Example (TBD):
>
>  - rte_mempool_create_empty(name, n, elt_size, cache_size, priv_size)
>  - rte_mempool_populate(mp, addr, len): add virtual memory for objects
>  - rte_mempool_mempool_obj_iter(mp, obj_cb, arg): call a cb for each object
>
>- update rte_mempool_create() to allocate objects in several memory
>  chunks by default if there is no large enough physically contiguous
>  memory.
>
>Tests done
>----------
>
>Compilation
>~~~~~~~~~~~
>
>The following targets:
>
> x86_64-native-linuxapp-gcc
> i686-native-linuxapp-gcc
> x86_x32-native-linuxapp-gcc
> x86_64-native-linuxapp-clang
> x86_64-native-bsdapp-gcc
> ppc_64-power8-linuxapp-gcc
> tile-tilegx-linuxapp-gcc (only the mempool files, the target does not compile)
>
>Libraries with and without debug, in static and shared mode + examples.
>
>autotests
>~~~~~~~~~
>
>Passed all autotests on x86_64-native-linuxapp-gcc (including kni) and
>mempool-related autotests on x86_64-native-bsdapp-gcc.
>
>test-pmd
>~~~~~~~~
>
># now starts fine, was failing before if mempool was too fragmented
>./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -- -i --port-topology=chained
>
># still ok
>./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 -- -i --port-topology=chained --mp-anon
>set fwd txonly
>start
>stop
>
># fail, but was failing before too. The problem is because the physical
># addresses are not properly set when using --no-huge. The mempool phys addr
># are now correct, but the zones allocated through memzone_reserve() are
># still wrong. This could be fixed in a future series.
>./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 --no-huge -- -i ---port-topology=chained
>set fwd txonly
>start
>stop
>
>
>Olivier Matz (36):
>  mempool: fix comments and style
>  mempool: replace elt_size by total_elt_size
>  mempool: uninline function to check cookies
>  mempool: use sizeof to get the size of header and trailer
>  mempool: rename mempool_obj_ctor_t as mempool_obj_cb_t
>  mempool: update library version
>  mempool: list objects when added in the mempool
>  mempool: remove const attribute in mempool_walk
>  mempool: remove const qualifier in dump and audit
>  mempool: use the list to iterate the mempool elements
>  mempool: use the list to audit all elements
>  mempool: use the list to initialize mempool objects
>  mempool: create the internal ring in a specific function
>  mempool: store physaddr in mempool objects
>  mempool: remove MEMPOOL_IS_CONTIG()
>  mempool: store memory chunks in a list
>  mempool: new function to iterate the memory chunks
>  mempool: simplify xmem_usage
>  mempool: introduce a free callback for memory chunks
>  mempool: make page size optional when getting xmem size
>  mempool: default allocation in several memory chunks
>  eal: lock memory when using no-huge
>  mempool: support no-hugepage mode
>  mempool: replace mempool physaddr by a memzone pointer
>  mempool: introduce a function to free a mempool
>  mempool: introduce a function to create an empty mempool
>  eal/xen: return machine address without knowing memseg id
>  mempool: rework support of xen dom0
>  mempool: create the internal ring when populating
>  mempool: populate a mempool with anonymous memory
>  mempool: make mempool populate and free api public
>  test-pmd: remove specific anon mempool code
>  mem: avoid memzone/mempool/ring name truncation
>  mempool: new flag when phys contig mem is not needed
>  app/test: rework mempool test
>  mempool: update copyright
>
> app/test-pmd/Makefile                        |    4 -
> app/test-pmd/mempool_anon.c                  |  201 -----
> app/test-pmd/mempool_osdep.h                 |   54 --
> app/test-pmd/testpmd.c                       |   23 +-
> app/test/test_mempool.c                      |  243 +++---
> doc/guides/rel_notes/release_16_04.rst       |    2 +-
> drivers/net/mlx4/mlx4.c                      |  140 ++--
> drivers/net/mlx5/mlx5_rxtx.c                 |  140 ++--
> drivers/net/mlx5/mlx5_rxtx.h                 |    4 +-
> drivers/net/xenvirt/rte_eth_xenvirt.h        |    2 +-
> drivers/net/xenvirt/rte_mempool_gntalloc.c   |    4 +-
> lib/librte_eal/common/eal_common_log.c       |    2 +-
> lib/librte_eal/common/eal_common_memzone.c   |   10 +-
> lib/librte_eal/common/include/rte_memory.h   |   11 +-
> lib/librte_eal/linuxapp/eal/eal_memory.c     |    2 +-
> lib/librte_eal/linuxapp/eal/eal_xen_memory.c |   17 +-
> lib/librte_kni/rte_kni.c                     |   12 +-
> lib/librte_mempool/Makefile                  |    5 +-
> lib/librte_mempool/rte_dom0_mempool.c        |  133 ----
> lib/librte_mempool/rte_mempool.c             | 1042 +++++++++++++++++---------
> lib/librte_mempool/rte_mempool.h             |  594 +++++++--------
> lib/librte_mempool/rte_mempool_version.map   |   18 +-
> lib/librte_ring/rte_ring.c                   |   16 +-
> 23 files changed, 1377 insertions(+), 1302 deletions(-)
> delete mode 100644 app/test-pmd/mempool_anon.c
> delete mode 100644 app/test-pmd/mempool_osdep.h
> delete mode 100644 lib/librte_mempool/rte_dom0_mempool.c
>
>-- 
>2.1.4
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5] mempool: reduce rte_mempool structure size
  2016-04-14  9:42  2% ` [dpdk-dev] [PATCH v5] " Olivier Matz
@ 2016-04-14 13:28  0%   ` Wiles, Keith
  2016-04-14 13:53  0%   ` Wiles, Keith
  1 sibling, 0 replies; 200+ results
From: Wiles, Keith @ 2016-04-14 13:28 UTC (permalink / raw)
  To: Olivier Matz, dev; +Cc: thomas.monjalon, pmatilai

>From: Keith Wiles <keith.wiles@intel.com>
>
>The rte_mempool structure is changed, which will cause an ABI change
>for this structure. Providing backward compat is not reasonable
>here as this structure is used in multiple defines/inlines.
>
>Allow mempool cache support to be dynamic depending on if the
>mempool being created needs cache support. Saves about 1.5M of
>memory used by the rte_mempool structure.
>
>Allocating small mempools which do not require cache can consume
>larges amounts of memory if you have a number of these mempools.
>
>Change to be effective in release 16.07.
>
>Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>Acked-by: Olivier Matz <olivier.matz@6wind.com>
>---
>
>Changes in v5:
>
>- use RTE_PTR_ADD() instead of cast to (char *) to fix compilation on tilera.
>  Error log was:
>
>  rte_mempool.c: In function ‘rte_mempool_xmem_create’:
>  rte_mempool.c:595: error: cast increases required alignment of target type
>
>
> app/test/test_mempool.c          |  4 +--
> lib/librte_mempool/rte_mempool.c | 55 ++++++++++++++++++----------------------
> lib/librte_mempool/rte_mempool.h | 29 ++++++++++-----------
> 3 files changed, 40 insertions(+), 48 deletions(-)
>
>diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
>index f0f823b..10e1fa4 100644
>--- a/app/test/test_mempool.c
>+++ b/app/test/test_mempool.c
>@@ -122,8 +122,8 @@ test_mempool_basic(void)
> 		return -1;
> 
> 	printf("get private data\n");
>-	if (rte_mempool_get_priv(mp) !=
>-			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
>+	if (rte_mempool_get_priv(mp) != (char *)mp +
>+			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))

Should we not add the RTE_PTR_ADD() here as well?

> 		return -1;
> 
> 	printf("get physical address of an object\n");
>diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>index f8781e1..7a0e07e 100644
>--- a/lib/librte_mempool/rte_mempool.c
>+++ b/lib/librte_mempool/rte_mempool.c
>@@ -452,12 +452,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	/* compilation-time checks */
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>-	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
>-			  RTE_CACHE_LINE_MASK) != 0);
>-#endif
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
> 			  RTE_CACHE_LINE_MASK) != 0);
>@@ -527,9 +523,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 		 */
> 		int head = sizeof(struct rte_mempool);
> 		int new_size = (private_data_size + head) % page_size;
>-		if (new_size) {
>+		if (new_size)
> 			private_data_size += page_size - new_size;
>-		}
> 	}
> 
> 	/* try to allocate tailq entry */
>@@ -544,7 +539,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	 * store mempool objects. Otherwise reserve a memzone that is large
> 	 * enough to hold mempool header and metadata plus mempool objects.
> 	 */
>-	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
>+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
>+	mempool_size += private_data_size;
> 	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
> 	if (vaddr == NULL)
> 		mempool_size += (size_t)objsz.total_size * n;
>@@ -591,8 +587,15 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
> 	mp->private_data_size = private_data_size;
> 
>+	/*
>+	 * local_cache pointer is set even if cache_size is zero.
>+	 * The local_cache points to just past the elt_pa[] array.
>+	 */
>+	mp->local_cache = (struct rte_mempool_cache *)
>+		RTE_PTR_ADD(mp, MEMPOOL_HEADER_SIZE(mp, pg_num, 0));
>+
> 	/* calculate address of the first element for continuous mempool. */
>-	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
>+	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size) +
> 		private_data_size;
> 	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
> 
>@@ -606,9 +609,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> 		mp->elt_va_start = (uintptr_t)obj;
> 		mp->elt_pa[0] = mp->phys_addr +
> 			(mp->elt_va_start - (uintptr_t)mp);
>-
>-	/* mempool elements in a separate chunk of memory. */
> 	} else {
>+		/* mempool elements in a separate chunk of memory. */
> 		mp->elt_va_start = (uintptr_t)vaddr;
> 		memcpy(mp->elt_pa, paddr, sizeof (mp->elt_pa[0]) * pg_num);
> 	}
>@@ -643,19 +645,15 @@ unsigned
> rte_mempool_count(const struct rte_mempool *mp)
> {
> 	unsigned count;
>+	unsigned lcore_id;
> 
> 	count = rte_ring_count(mp->ring);
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>-	{
>-		unsigned lcore_id;
>-		if (mp->cache_size == 0)
>-			return count;
>+	if (mp->cache_size == 0)
>+		return count;
> 
>-		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
>-			count += mp->local_cache[lcore_id].len;
>-	}
>-#endif
>+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
>+		count += mp->local_cache[lcore_id].len;
> 
> 	/*
> 	 * due to race condition (access to len is not locked), the
>@@ -670,13 +668,16 @@ rte_mempool_count(const struct rte_mempool *mp)
> static unsigned
> rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
> {
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	unsigned lcore_id;
> 	unsigned count = 0;
> 	unsigned cache_count;
> 
> 	fprintf(f, "  cache infos:\n");
> 	fprintf(f, "    cache_size=%"PRIu32"\n", mp->cache_size);
>+
>+	if (mp->cache_size == 0)
>+		return count;
>+
> 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> 		cache_count = mp->local_cache[lcore_id].len;
> 		fprintf(f, "    cache_count[%u]=%u\n", lcore_id, cache_count);
>@@ -684,11 +685,6 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
> 	}
> 	fprintf(f, "    total_cache_count=%u\n", count);
> 	return count;
>-#else
>-	RTE_SET_USED(mp);
>-	fprintf(f, "  cache disabled\n");
>-	return 0;
>-#endif
> }
> 
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>@@ -753,13 +749,16 @@ mempool_audit_cookies(const struct rte_mempool *mp)
> #define mempool_audit_cookies(mp) do {} while(0)
> #endif
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> /* check cookies before and after objects */
> static void
> mempool_audit_cache(const struct rte_mempool *mp)
> {
> 	/* check cache size consistency */
> 	unsigned lcore_id;
>+
>+	if (mp->cache_size == 0)
>+		return;
>+
> 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> 		if (mp->local_cache[lcore_id].len > mp->cache_flushthresh) {
> 			RTE_LOG(CRIT, MEMPOOL, "badness on cache[%u]\n",
>@@ -768,10 +767,6 @@ mempool_audit_cache(const struct rte_mempool *mp)
> 		}
> 	}
> }
>-#else
>-#define mempool_audit_cache(mp) do {} while(0)
>-#endif
>-
> 
> /* check the consistency of mempool (size, cookies, ...) */
> void
>diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
>index 9745bf0..8595e77 100644
>--- a/lib/librte_mempool/rte_mempool.h
>+++ b/lib/librte_mempool/rte_mempool.h
>@@ -95,7 +95,6 @@ struct rte_mempool_debug_stats {
> } __rte_cache_aligned;
> #endif
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> /**
>  * A structure that stores a per-core object cache.
>  */
>@@ -107,7 +106,6 @@ struct rte_mempool_cache {
> 	 */
> 	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
> } __rte_cache_aligned;
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> /**
>  * A structure that stores the size of mempool elements.
>@@ -194,10 +192,7 @@ struct rte_mempool {
> 
> 	unsigned private_data_size;      /**< Size of private data. */
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>-	/** Per-lcore local cache. */
>-	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
>-#endif
>+	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
> 
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> 	/** Per-lcore statistics. */
>@@ -247,6 +242,13 @@ struct rte_mempool {
> #endif
> 
> /**
>+ * Size of elt_pa array size based on number of pages. (Internal use)
>+ */
>+#define __PA_SIZE(mp, pgn) \
>+	RTE_ALIGN_CEIL((((pgn) - RTE_DIM((mp)->elt_pa)) * \
>+	sizeof((mp)->elt_pa[0])), RTE_CACHE_LINE_SIZE)
>+
>+/**
>  * Calculate the size of the mempool header.
>  *
>  * @param mp
>@@ -254,9 +256,9 @@ struct rte_mempool {
>  * @param pgn
>  *   Number of pages used to store mempool objects.
>  */
>-#define	MEMPOOL_HEADER_SIZE(mp, pgn)	(sizeof(*(mp)) + \
>-	RTE_ALIGN_CEIL(((pgn) - RTE_DIM((mp)->elt_pa)) * \
>-	sizeof ((mp)->elt_pa[0]), RTE_CACHE_LINE_SIZE))
>+#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
>+	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
>+	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
> 
> /**
>  * Return true if the whole mempool is in contiguous memory.
>@@ -755,19 +757,16 @@ static inline void __attribute__((always_inline))
> __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
> 		    unsigned n, int is_mp)
> {
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	struct rte_mempool_cache *cache;
> 	uint32_t index;
> 	void **cache_objs;
> 	unsigned lcore_id = rte_lcore_id();
> 	uint32_t cache_size = mp->cache_size;
> 	uint32_t flushthresh = mp->cache_flushthresh;
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* increment stat now, adding in mempool always success */
> 	__MEMPOOL_STAT_ADD(mp, put, n);
> 
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	/* cache is not enabled or single producer or non-EAL thread */
> 	if (unlikely(cache_size == 0 || is_mp == 0 ||
> 		     lcore_id >= RTE_MAX_LCORE))
>@@ -802,7 +801,6 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
> 	return;
> 
> ring_enqueue:
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* push remaining objects in ring */
> #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>@@ -946,7 +944,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
> 		   unsigned n, int is_mc)
> {
> 	int ret;
>-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> 	struct rte_mempool_cache *cache;
> 	uint32_t index, len;
> 	void **cache_objs;
>@@ -992,7 +989,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
> 	return 0;
> 
> ring_dequeue:
>-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> 
> 	/* get remaining objects from ring */
> 	if (is_mc)
>@@ -1293,7 +1289,8 @@ void rte_mempool_audit(const struct rte_mempool *mp);
>  */
> static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
> {
>-	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
>+	return (char *)mp +
>+		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);

And here?

> }
> 
> /**
>-- 
>2.1.4
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation
  2016-03-09 16:19  2% [dpdk-dev] [RFC 00/35] mempool: rework memory allocation Olivier Matz
  2016-03-17  9:05 15% ` [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07 Olivier Matz
@ 2016-04-14 10:19  2% ` Olivier Matz
  2016-04-14 13:50  0%   ` Wiles, Keith
  1 sibling, 1 reply; 200+ results
From: Olivier Matz @ 2016-04-14 10:19 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, stephen

This series is a rework of mempool. For those who don't want to read
all the cover letter, here is a sumary:

- it is not possible to allocate large mempools if there is not enough
  contiguous memory, this series solves this issue
- introduce new APIs with less arguments: "create, populate, obj_init"
- allow to free a mempool
- split code in smaller functions, will ease the introduction of ext_handler
- remove test-pmd anonymous mempool creation
- remove most of dom0-specific mempool code
- opens the door for a eal_memory rework: we probably don't need large
  contiguous memory area anymore, working with pages would work.

This breaks the ABI as it was indicated in the deprecation for 16.04.
The API stays almost the same, no modification is needed in examples app
or in test-pmd. Only kni and mellanox drivers are slightly modified.

This patch applies on top of 16.04 + v5 of Keith's patch:
"mempool: reduce rte_mempool structure size"

Changes RFC -> v1:

- remove the rte_deconst macro, and remove some const qualifier in
  dump/audit functions
- rework modifications in mellanox drivers to ensure the mempool is
  virtually contiguous
- fix mempool memory chunk iteration (bad pointer was used)
- fix compilation on freebsd: replace MAP_LOCKED flag by mlock()
- fix compilation on tilera (pointer arithmetics)
- slightly rework and clean the mempool autotest
- fix mempool autotest on bsd
- more validation (especially mellanox drivers and kni that were not
  tested in RFC)
- passed autotests (x86_64-native-linuxapp-gcc and x86_64-native-bsdapp-gcc)
- rebase on head, reorder the patches a bit and fix minor split issues


Description of the initial issue
--------------------------------

The allocation of mbuf pool can fail even if there is enough memory.
The problem is related to the way the memory is allocated and used in
dpdk. It is particularly annoying with mbuf pools, but it can also fail
in other use cases allocating a large amount of memory.

- rte_malloc() allocates physically contiguous memory, which is needed
  for mempools, but useless most of the time.

  Allocating a large physically contiguous zone is often impossible
  because the system provide hugepages which may not be contiguous.

- rte_mempool_create() (and therefore rte_pktmbuf_pool_create())
  requires a physically contiguous zone.

- rte_mempool_xmem_create() does not solve the issue as it still
  needs the memory to be virtually contiguous, and there is no
  way in dpdk to allocate a virtually contiguous memory that is
  not also physically contiguous.

How to reproduce the issue
--------------------------

- start the dpdk with some 2MB hugepages (it can also occur with 1GB)
- allocate a large mempool
- even if there is enough memory, the allocation can fail

Example:

  git clone http://dpdk.org/git/dpdk
  cd dpdk
  make config T=x86_64-native-linuxapp-gcc
  make -j32
  mkdir -p /mnt/huge
  mount -t hugetlbfs nodev /mnt/huge
  echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

  # we try to allocate a mempool whose size is ~450MB, it fails
  ./build/app/testpmd -l 2,4 -- --total-num-mbufs=200000 -i

The EAL logs "EAL: Virtual area found at..." shows that there are
several zones, but all smaller than 450MB.

Workarounds:

- Use 1GB hugepages: it sometimes work, but for very large
  pools (millions of mbufs) there is the same issue. Moreover,
  it would consume 1GB memory at least which can be a lot
  in some cases.

- Reboot the machine or allocate hugepages at boot time: this increases
  the chances to have more contiguous memory, but does not completely
  solve the issue

Solutions
---------

Below is a list of proposed solutions. I implemented a quick and dirty
PoC of solution 1, but it's not working in all conditions and it's
really an ugly hack.  This series implement the solution 4 which looks
the best to me, knowing it does not prevent to do more enhancements
in dpdk memory in the future (solution 3 for instance).

Solution 1: in application
--------------------------

- allocate several hugepages using rte_malloc() or rte_memzone_reserve()
  (only keeping complete hugepages)
- parse memsegs and /proc/maps to check which files mmaps these pages
- mmap the files in a contiguous virtual area
- use rte_mempool_xmem_create()

Cons:

- 1a. parsing the memsegs of rte config in the application does not
  use a public API, and can be broken if internal dpdk code changes
- 1b. some memory is lost due to malloc headers. Also, if the memory is
  very fragmented (ex: all 2MB pages are physically separated), it does
  not work at all because we cannot get any complete page. It is not
  possible to use a lower level allocator since commit fafcc11985a.
- 1c. we cannot use rte_pktmbuf_pool_create(), so we need to use mempool
  api and do a part of the job manually
- 1d. it breaks secondary processes as the virtual addresses won't be
  mmap'd at the same place in secondary process
- 1e. it only fixes the issue for the mbuf pool of the application,
  internal pools in dpdk libraries are not modified
- 1f. this is a pure linux solution (rte_map files)
- 1g. The application has to be aware of RTE_EAL_SINGLE_SEGMENTS option
  that changes the way hugepages are mapped. By the way, it's strange
  to have such a compile-time option, we should probably have only
  one behavior that works all the time.

Solution 2: in dpdk memory allocator
------------------------------------

- do the same than solution 1 in a new function rte_malloc_non_contig():
  allocate several chunks and mmap them in a contiguous virtual memory
- a flag has to be added in malloc header to do the proper cleanup in
  rte_free() (free all the chunks, munmap the memory)
- introduce a new rte_mem_get_physmap(*physmap,addr, len) that returns
  the virt2phys mapping of a virtual area in dpdk
- add a mempool flag MEMPOOL_F_NON_PHYS_CONTIG to use
  rte_malloc_non_contig() to allocate the area storing the objects

Cons:

- 2a. same than 1b: it breaks secondary processes if the mempool flag is
  used.
- 2b. same as 1d: some memory is lost due to malloc headers, and it
  cannot work if memory is too fragmented.
- 2c. rte_malloc_virt2phy() cannot be used on these zones. It would
  return the physical address of the first page. It would be better to
  return an error in this case.
- 2d. need to check how to implement this on bsd (TBD)

Solution 3: in dpdk eal memory
------------------------------

- Rework the way hugepages are mmap'd in dpdk: instead of having several
  rte_map* files, just mmap one file per node. It may drastically
  simplify EAL memory management in dpdk.
- An API should be added to retrieve the physical mapping of a virtual
  area (ex: rte_mem_get_physmap(*physmap, addr, len))
- rte_malloc() and rte_memzone_reserve() won't allocate physically
  contiguous memory anymore (TBD)
- Update mempool to always use the rte_mempool_xmem_create() version

Cons:

- 3a. lot of rework in eal memory, it will induce some behavior changes
  and maybe api changes
- 3b. possible conflicts with xen_dom0 mempool

Solution 4: in mempool
----------------------

- Introduce a new API to fill a mempool with zones that are not
  virtually contiguous. It requires to add new functions to create and
  populate a mempool. Example (TBD):

  - rte_mempool_create_empty(name, n, elt_size, cache_size, priv_size)
  - rte_mempool_populate(mp, addr, len): add virtual memory for objects
  - rte_mempool_mempool_obj_iter(mp, obj_cb, arg): call a cb for each object

- update rte_mempool_create() to allocate objects in several memory
  chunks by default if there is no large enough physically contiguous
  memory.

Tests done
----------

Compilation
~~~~~~~~~~~

The following targets:

 x86_64-native-linuxapp-gcc
 i686-native-linuxapp-gcc
 x86_x32-native-linuxapp-gcc
 x86_64-native-linuxapp-clang
 x86_64-native-bsdapp-gcc
 ppc_64-power8-linuxapp-gcc
 tile-tilegx-linuxapp-gcc (only the mempool files, the target does not compile)

Libraries with and without debug, in static and shared mode + examples.

autotests
~~~~~~~~~

Passed all autotests on x86_64-native-linuxapp-gcc (including kni) and
mempool-related autotests on x86_64-native-bsdapp-gcc.

test-pmd
~~~~~~~~

# now starts fine, was failing before if mempool was too fragmented
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -- -i --port-topology=chained

# still ok
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 -- -i --port-topology=chained --mp-anon
set fwd txonly
start
stop

# fail, but was failing before too. The problem is because the physical
# addresses are not properly set when using --no-huge. The mempool phys addr
# are now correct, but the zones allocated through memzone_reserve() are
# still wrong. This could be fixed in a future series.
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 --no-huge -- -i ---port-topology=chained
set fwd txonly
start
stop


Olivier Matz (36):
  mempool: fix comments and style
  mempool: replace elt_size by total_elt_size
  mempool: uninline function to check cookies
  mempool: use sizeof to get the size of header and trailer
  mempool: rename mempool_obj_ctor_t as mempool_obj_cb_t
  mempool: update library version
  mempool: list objects when added in the mempool
  mempool: remove const attribute in mempool_walk
  mempool: remove const qualifier in dump and audit
  mempool: use the list to iterate the mempool elements
  mempool: use the list to audit all elements
  mempool: use the list to initialize mempool objects
  mempool: create the internal ring in a specific function
  mempool: store physaddr in mempool objects
  mempool: remove MEMPOOL_IS_CONTIG()
  mempool: store memory chunks in a list
  mempool: new function to iterate the memory chunks
  mempool: simplify xmem_usage
  mempool: introduce a free callback for memory chunks
  mempool: make page size optional when getting xmem size
  mempool: default allocation in several memory chunks
  eal: lock memory when using no-huge
  mempool: support no-hugepage mode
  mempool: replace mempool physaddr by a memzone pointer
  mempool: introduce a function to free a mempool
  mempool: introduce a function to create an empty mempool
  eal/xen: return machine address without knowing memseg id
  mempool: rework support of xen dom0
  mempool: create the internal ring when populating
  mempool: populate a mempool with anonymous memory
  mempool: make mempool populate and free api public
  test-pmd: remove specific anon mempool code
  mem: avoid memzone/mempool/ring name truncation
  mempool: new flag when phys contig mem is not needed
  app/test: rework mempool test
  mempool: update copyright

 app/test-pmd/Makefile                        |    4 -
 app/test-pmd/mempool_anon.c                  |  201 -----
 app/test-pmd/mempool_osdep.h                 |   54 --
 app/test-pmd/testpmd.c                       |   23 +-
 app/test/test_mempool.c                      |  243 +++---
 doc/guides/rel_notes/release_16_04.rst       |    2 +-
 drivers/net/mlx4/mlx4.c                      |  140 ++--
 drivers/net/mlx5/mlx5_rxtx.c                 |  140 ++--
 drivers/net/mlx5/mlx5_rxtx.h                 |    4 +-
 drivers/net/xenvirt/rte_eth_xenvirt.h        |    2 +-
 drivers/net/xenvirt/rte_mempool_gntalloc.c   |    4 +-
 lib/librte_eal/common/eal_common_log.c       |    2 +-
 lib/librte_eal/common/eal_common_memzone.c   |   10 +-
 lib/librte_eal/common/include/rte_memory.h   |   11 +-
 lib/librte_eal/linuxapp/eal/eal_memory.c     |    2 +-
 lib/librte_eal/linuxapp/eal/eal_xen_memory.c |   17 +-
 lib/librte_kni/rte_kni.c                     |   12 +-
 lib/librte_mempool/Makefile                  |    5 +-
 lib/librte_mempool/rte_dom0_mempool.c        |  133 ----
 lib/librte_mempool/rte_mempool.c             | 1042 +++++++++++++++++---------
 lib/librte_mempool/rte_mempool.h             |  594 +++++++--------
 lib/librte_mempool/rte_mempool_version.map   |   18 +-
 lib/librte_ring/rte_ring.c                   |   16 +-
 23 files changed, 1377 insertions(+), 1302 deletions(-)
 delete mode 100644 app/test-pmd/mempool_anon.c
 delete mode 100644 app/test-pmd/mempool_osdep.h
 delete mode 100644 lib/librte_mempool/rte_dom0_mempool.c

-- 
2.1.4

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [RFC 1/2] doc: announce ABI change for rte_eth_dev_info structure
  2016-04-14  9:44  4% [dpdk-dev] [RFC 0/2] add new fields to rte_eth_dev_info structure Reshma Pattan
@ 2016-04-14  9:44  9% ` Reshma Pattan
  2016-04-15  9:42  4%   ` Mcnamara, John
  2016-04-15 10:02  8%   ` Thomas Monjalon
    1 sibling, 2 replies; 200+ results
From: Reshma Pattan @ 2016-04-14  9:44 UTC (permalink / raw)
  To: dev

New fields nb_rx_queues and nb_tx_queues will be added to
rte_eth_dev_info structure.
Changes to API rte_eth_dev_info_get() will be done to update
these new fields to rte_eth_dev_info object.

Signed-off-by:reshma Pattan<reshma.pattan@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 327fc2b..78cedb7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -90,3 +90,9 @@ Deprecation Notices
   a handle, like the way kernel exposes an fd to user for locating a
   specific file, and to keep all major structures internally, so that
   we are likely to be free from ABI violations in future.
+
+* A librte_ether public structure ``rte_eth_dev_info`` will be changed in 16.07.
+  The proposed change will add new parameters ``nb_rx_queues``, ``nb_tx_queues``
+  to the structure. These are the number of queues configured by software.
+  Modification to definition of ``rte_eth_dev_info_get()`` will be done
+  to update new parameters to ``rte_eth_dev_info`` object.
-- 
2.5.0

^ permalink raw reply	[relevance 9%]

* [dpdk-dev] [RFC 0/2] add new fields to rte_eth_dev_info structure
@ 2016-04-14  9:44  4% Reshma Pattan
  2016-04-14  9:44  9% ` [dpdk-dev] [RFC 1/2] doc: announce ABI change for " Reshma Pattan
    0 siblings, 2 replies; 200+ results
From: Reshma Pattan @ 2016-04-14  9:44 UTC (permalink / raw)
  To: dev

New fields nb_rx_queues and nb_tx_queues are added to rte_eth_dev_info structure.
Changes to API rte_eth_dev_info_get() are done to update these new fields to rte_eth_dev_info object.

These changes are ABI breakage and we are late to announce deprecation notice for 16.07,
however the rte_ether library is already subject to a deprecation notice in 16.07.

Reshma Pattan (2):
  doc: announce ABI change for rte_eth_dev_info structure
  librte_ether: add new fields to rte_eth_dev_info struct

 doc/guides/rel_notes/deprecation.rst | 6 ++++++
 lib/librte_ether/rte_ethdev.c        | 2 ++
 lib/librte_ether/rte_ethdev.h        | 3 +++
 3 files changed, 11 insertions(+)

-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v5] mempool: reduce rte_mempool structure size
  @ 2016-04-14  9:42  2% ` Olivier Matz
  2016-04-14 13:28  0%   ` Wiles, Keith
  2016-04-14 13:53  0%   ` Wiles, Keith
  0 siblings, 2 replies; 200+ results
From: Olivier Matz @ 2016-04-14  9:42 UTC (permalink / raw)
  To: dev, keith.wiles; +Cc: thomas.monjalon, pmatilai

From: Keith Wiles <keith.wiles@intel.com>

The rte_mempool structure is changed, which will cause an ABI change
for this structure. Providing backward compat is not reasonable
here as this structure is used in multiple defines/inlines.

Allow mempool cache support to be dynamic depending on if the
mempool being created needs cache support. Saves about 1.5M of
memory used by the rte_mempool structure.

Allocating small mempools which do not require cache can consume
larges amounts of memory if you have a number of these mempools.

Change to be effective in release 16.07.

Signed-off-by: Keith Wiles <keith.wiles@intel.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---

Changes in v5:

- use RTE_PTR_ADD() instead of cast to (char *) to fix compilation on tilera.
  Error log was:

  rte_mempool.c: In function ‘rte_mempool_xmem_create’:
  rte_mempool.c:595: error: cast increases required alignment of target type


 app/test/test_mempool.c          |  4 +--
 lib/librte_mempool/rte_mempool.c | 55 ++++++++++++++++++----------------------
 lib/librte_mempool/rte_mempool.h | 29 ++++++++++-----------
 3 files changed, 40 insertions(+), 48 deletions(-)

diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
index f0f823b..10e1fa4 100644
--- a/app/test/test_mempool.c
+++ b/app/test/test_mempool.c
@@ -122,8 +122,8 @@ test_mempool_basic(void)
 		return -1;
 
 	printf("get private data\n");
-	if (rte_mempool_get_priv(mp) !=
-			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
+	if (rte_mempool_get_priv(mp) != (char *)mp +
+			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))
 		return -1;
 
 	printf("get physical address of an object\n");
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index f8781e1..7a0e07e 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -452,12 +452,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	/* compilation-time checks */
 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
 			  RTE_CACHE_LINE_MASK) != 0);
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
 			  RTE_CACHE_LINE_MASK) != 0);
-	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
-			  RTE_CACHE_LINE_MASK) != 0);
-#endif
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
 			  RTE_CACHE_LINE_MASK) != 0);
@@ -527,9 +523,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 		 */
 		int head = sizeof(struct rte_mempool);
 		int new_size = (private_data_size + head) % page_size;
-		if (new_size) {
+		if (new_size)
 			private_data_size += page_size - new_size;
-		}
 	}
 
 	/* try to allocate tailq entry */
@@ -544,7 +539,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	 * store mempool objects. Otherwise reserve a memzone that is large
 	 * enough to hold mempool header and metadata plus mempool objects.
 	 */
-	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
+	mempool_size += private_data_size;
 	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
 	if (vaddr == NULL)
 		mempool_size += (size_t)objsz.total_size * n;
@@ -591,8 +587,15 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
 	mp->private_data_size = private_data_size;
 
+	/*
+	 * local_cache pointer is set even if cache_size is zero.
+	 * The local_cache points to just past the elt_pa[] array.
+	 */
+	mp->local_cache = (struct rte_mempool_cache *)
+		RTE_PTR_ADD(mp, MEMPOOL_HEADER_SIZE(mp, pg_num, 0));
+
 	/* calculate address of the first element for continuous mempool. */
-	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
+	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size) +
 		private_data_size;
 	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
 
@@ -606,9 +609,8 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 		mp->elt_va_start = (uintptr_t)obj;
 		mp->elt_pa[0] = mp->phys_addr +
 			(mp->elt_va_start - (uintptr_t)mp);
-
-	/* mempool elements in a separate chunk of memory. */
 	} else {
+		/* mempool elements in a separate chunk of memory. */
 		mp->elt_va_start = (uintptr_t)vaddr;
 		memcpy(mp->elt_pa, paddr, sizeof (mp->elt_pa[0]) * pg_num);
 	}
@@ -643,19 +645,15 @@ unsigned
 rte_mempool_count(const struct rte_mempool *mp)
 {
 	unsigned count;
+	unsigned lcore_id;
 
 	count = rte_ring_count(mp->ring);
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
-	{
-		unsigned lcore_id;
-		if (mp->cache_size == 0)
-			return count;
+	if (mp->cache_size == 0)
+		return count;
 
-		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
-			count += mp->local_cache[lcore_id].len;
-	}
-#endif
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
+		count += mp->local_cache[lcore_id].len;
 
 	/*
 	 * due to race condition (access to len is not locked), the
@@ -670,13 +668,16 @@ rte_mempool_count(const struct rte_mempool *mp)
 static unsigned
 rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 {
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	unsigned lcore_id;
 	unsigned count = 0;
 	unsigned cache_count;
 
 	fprintf(f, "  cache infos:\n");
 	fprintf(f, "    cache_size=%"PRIu32"\n", mp->cache_size);
+
+	if (mp->cache_size == 0)
+		return count;
+
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		cache_count = mp->local_cache[lcore_id].len;
 		fprintf(f, "    cache_count[%u]=%u\n", lcore_id, cache_count);
@@ -684,11 +685,6 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 	}
 	fprintf(f, "    total_cache_count=%u\n", count);
 	return count;
-#else
-	RTE_SET_USED(mp);
-	fprintf(f, "  cache disabled\n");
-	return 0;
-#endif
 }
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -753,13 +749,16 @@ mempool_audit_cookies(const struct rte_mempool *mp)
 #define mempool_audit_cookies(mp) do {} while(0)
 #endif
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 /* check cookies before and after objects */
 static void
 mempool_audit_cache(const struct rte_mempool *mp)
 {
 	/* check cache size consistency */
 	unsigned lcore_id;
+
+	if (mp->cache_size == 0)
+		return;
+
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		if (mp->local_cache[lcore_id].len > mp->cache_flushthresh) {
 			RTE_LOG(CRIT, MEMPOOL, "badness on cache[%u]\n",
@@ -768,10 +767,6 @@ mempool_audit_cache(const struct rte_mempool *mp)
 		}
 	}
 }
-#else
-#define mempool_audit_cache(mp) do {} while(0)
-#endif
-
 
 /* check the consistency of mempool (size, cookies, ...) */
 void
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 9745bf0..8595e77 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -95,7 +95,6 @@ struct rte_mempool_debug_stats {
 } __rte_cache_aligned;
 #endif
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 /**
  * A structure that stores a per-core object cache.
  */
@@ -107,7 +106,6 @@ struct rte_mempool_cache {
 	 */
 	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
 } __rte_cache_aligned;
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 /**
  * A structure that stores the size of mempool elements.
@@ -194,10 +192,7 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
-	/** Per-lcore local cache. */
-	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
-#endif
+	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	/** Per-lcore statistics. */
@@ -247,6 +242,13 @@ struct rte_mempool {
 #endif
 
 /**
+ * Size of elt_pa array size based on number of pages. (Internal use)
+ */
+#define __PA_SIZE(mp, pgn) \
+	RTE_ALIGN_CEIL((((pgn) - RTE_DIM((mp)->elt_pa)) * \
+	sizeof((mp)->elt_pa[0])), RTE_CACHE_LINE_SIZE)
+
+/**
  * Calculate the size of the mempool header.
  *
  * @param mp
@@ -254,9 +256,9 @@ struct rte_mempool {
  * @param pgn
  *   Number of pages used to store mempool objects.
  */
-#define	MEMPOOL_HEADER_SIZE(mp, pgn)	(sizeof(*(mp)) + \
-	RTE_ALIGN_CEIL(((pgn) - RTE_DIM((mp)->elt_pa)) * \
-	sizeof ((mp)->elt_pa[0]), RTE_CACHE_LINE_SIZE))
+#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
+	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
+	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
 
 /**
  * Return true if the whole mempool is in contiguous memory.
@@ -755,19 +757,16 @@ static inline void __attribute__((always_inline))
 __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 		    unsigned n, int is_mp)
 {
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	struct rte_mempool_cache *cache;
 	uint32_t index;
 	void **cache_objs;
 	unsigned lcore_id = rte_lcore_id();
 	uint32_t cache_size = mp->cache_size;
 	uint32_t flushthresh = mp->cache_flushthresh;
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 	/* increment stat now, adding in mempool always success */
 	__MEMPOOL_STAT_ADD(mp, put, n);
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/* cache is not enabled or single producer or non-EAL thread */
 	if (unlikely(cache_size == 0 || is_mp == 0 ||
 		     lcore_id >= RTE_MAX_LCORE))
@@ -802,7 +801,6 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 	return;
 
 ring_enqueue:
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 	/* push remaining objects in ring */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -946,7 +944,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 		   unsigned n, int is_mc)
 {
 	int ret;
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	struct rte_mempool_cache *cache;
 	uint32_t index, len;
 	void **cache_objs;
@@ -992,7 +989,6 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 	return 0;
 
 ring_dequeue:
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 	/* get remaining objects from ring */
 	if (is_mc)
@@ -1293,7 +1289,8 @@ void rte_mempool_audit(const struct rte_mempool *mp);
  */
 static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
 {
-	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
+	return (char *)mp +
+		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
 }
 
 /**
-- 
2.1.4

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v1] doc: add template release notes for 16.07
@ 2016-04-12 12:55  6% John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2016-04-12 12:55 UTC (permalink / raw)
  To: dev; +Cc: thomas.monjalon, John McNamara

Added template release notes for DPDK 16.07 with inline
explanations of the various sections.

Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_16_07.rst | 160 +++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)
 create mode 100644 doc/guides/rel_notes/release_16_07.rst

diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 84317b8..52c63b4 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -36,6 +36,7 @@ Release Notes
     :numbered:
 
     rel_description
+    release_16_07
     release_16_04
     release_2_2
     release_2_1
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
new file mode 100644
index 0000000..701e827
--- /dev/null
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -0,0 +1,160 @@
+DPDK Release 16.07
+==================
+
+**Read this first.**
+
+The text below explains how to update the release notes.
+
+Use proper spelling, capitalization and punctuation in all sections.
+
+Variable and config names should be quoted as fixed width text: ``LIKE_THIS``.
+
+Build the docs and view the output file to ensure the changes are correct::
+
+   make doc-guides-html
+
+   firefox build/doc/html/guides/rel_notes/release_16_07.html
+
+
+New Features
+------------
+
+This section should contain new features added in this release. Sample format:
+
+* **Add a title in the past tense with a full stop.**
+
+  Add a short 1-2 sentence description in the past tense. The description
+  should be enough to allow someone scanning the release notes to understand
+  the new feature.
+
+  If the feature adds a lot of sub-features you can use a bullet list like this.
+
+  * Added feature foo to do something.
+  * Enhanced feature bar to do something else.
+
+  Refer to the previous release notes for examples.
+
+
+Resolved Issues
+---------------
+
+This section should contain bug fixes added to the relevant sections. Sample format:
+
+* **code/section Fixed issue in the past tense with a full stop.**
+
+  Add a short 1-2 sentence description of the resolved issue in the past tense.
+  The title should contain the code/lib section like a commit message.
+  Add the entries in alphabetic order in the relevant sections below.
+
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+This section should contain new known issues in this release. Sample format:
+
+* **Add title in present tense with full stop.**
+
+  Add a short 1-2 sentence description of the known issue in the present
+  tense. Add information on any known workarounds.
+
+
+API Changes
+-----------
+
+This section should contain API changes. Sample format:
+
+* Add a short 1-2 sentence description of the API change. Use fixed width
+  quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+
+ABI Changes
+-----------
+
+* Add a short 1-2 sentence description of the ABI change that was announced in
+  the previous releases and made in this release. Use fixed width quotes for
+  ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+
+Shared Library Versions
+-----------------------
+
+Update any library version updated in this release and prepend with a ``+`` sign.
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     libethdev.so.3
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_distributor.so.1
+     librte_eal.so.2
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ivshmem.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.2
+     librte_mempool.so.1
+     librte_meter.so.1
+     librte_pipeline.so.3
+     librte_pmd_bond.so.1
+     librte_pmd_ring.so.2
+     librte_port.so.2
+     librte_power.so.1
+     librte_reorder.so.1
+     librte_ring.so.1
+     librte_sched.so.1
+     librte_table.so.2
+     librte_timer.so.1
+     librte_vhost.so.2
+
+
+Tested Platforms
+----------------
+
+This section should contain a list of platforms that were tested with this
+release.
+
+The format is:
+
+#. Platform name.
+
+   - Platform details.
+   - Platform details.
+
+
+Tested NICs
+-----------
+
+This section should contain a list of NICs that were tested with this release.
+
+The format is:
+
+#. NIC name.
+
+   - NIC details.
+   - NIC details.
-- 
2.5.0

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
  2016-04-07 21:24  4%     ` Thomas Monjalon
@ 2016-04-12 12:39  4%       ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-12 12:39 UTC (permalink / raw)
  To: Zhang, Roy Fan; +Cc: dev, Azarewicz, PiotrX T, Singh, Jasvinder

Hi Fan Zhang,

2016-04-07 23:24, Thomas Monjalon:
> Please send a patch to remove NEXT_ABI early in the 16.07 cycle.

Please could you prepare a patch to remove NEXT_ABI from rte_port?
Thanks

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v1] doc: add template release notes for 16.11
@ 2016-04-12 12:01  6% John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2016-04-12 12:01 UTC (permalink / raw)
  To: dev; +Cc: thomas.monjalon, John McNamara

Added template release notes for DPDK 16.11 with inline
explanations of the various sections.

Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_16_11.rst | 160 +++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)
 create mode 100644 doc/guides/rel_notes/release_16_11.rst

diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 84317b8..b38a58c 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -36,6 +36,7 @@ Release Notes
     :numbered:
 
     rel_description
+    release_16_11
     release_16_04
     release_2_2
     release_2_1
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
new file mode 100644
index 0000000..1b2ca1b
--- /dev/null
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -0,0 +1,160 @@
+DPDK Release 16.11
+==================
+
+**Read this first.**
+
+The text below explains how to update the release notes.
+
+Use proper spelling, capitalization and punctuation in all sections.
+
+Variable and config names should be quoted as fixed width text: ``LIKE_THIS``.
+
+Build the docs and view the output file to ensure the changes are correct::
+
+   make doc-guides-html
+
+   firefox build/doc/html/guides/rel_notes/release_16_04.html
+
+
+New Features
+------------
+
+This section should contain new features added in this release. Sample format:
+
+* **Add a title in the past tense with a full stop.**
+
+  Add a short 1-2 sentence description in the past tense. The description
+  should be enough to allow someone scanning the release notes to understand
+  the new feature.
+
+  If the feature adds a lot of sub-features you can use a bullet list like this.
+
+  * Added feature foo to do something.
+  * Enhanced feature bar to do something else.
+
+  Refer to the previous release notes for examples.
+
+
+Resolved Issues
+---------------
+
+This section should contain bug fixes added to the relevant sections. Sample format:
+
+* **code/section Fixed issue in the past tense with a full stop.**
+
+  Add a short 1-2 sentence description of the resolved issue in the past tense.
+  The title should contain the code/lib section like a commit message.
+  Add the entries in alphabetic order in the relevant sections below.
+
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+This section should contain new known issues in this release. Sample format:
+
+* **Add title in present tense with full stop.**
+
+  Add a short 1-2 sentence description of the known issue in the present
+  tense. Add information on any known workarounds.
+
+
+API Changes
+-----------
+
+This section should contain API changes. Sample format:
+
+* Add a short 1-2 sentence description of the API change. Use fixed width
+  quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+
+ABI Changes
+-----------
+
+* Add a short 1-2 sentence description of the ABI change that was announced in
+  the previous releases and made in this release. Use fixed width quotes for
+  ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+
+Shared Library Versions
+-----------------------
+
+Update any library version updated in this release and prepend with a ``+`` sign.
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     libethdev.so.3
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_distributor.so.1
+     librte_eal.so.2
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ivshmem.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.2
+     librte_mempool.so.1
+     librte_meter.so.1
+     librte_pipeline.so.3
+     librte_pmd_bond.so.1
+     librte_pmd_ring.so.2
+     librte_port.so.2
+     librte_power.so.1
+     librte_reorder.so.1
+     librte_ring.so.1
+     librte_sched.so.1
+     librte_table.so.2
+     librte_timer.so.1
+     librte_vhost.so.2
+
+
+Tested Platforms
+----------------
+
+This section should contain a list of platforms that were tested with this
+release.
+
+The format is:
+
+#. Platform name.
+
+   - Platform details.
+   - Platform details.
+
+
+Tested NICs
+-----------
+
+This section should contain a list of NICs that were tested with this release.
+
+The format is:
+
+#. NIC name.
+
+   - NIC details.
+   - NIC details.
-- 
2.5.0

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor
  2016-04-10  9:58  4%   ` Thomas Monjalon
@ 2016-04-10 10:02  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-10 10:02 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: Panu Matilainen, dev, huawei.xie, Ilya Maximets

> > > +* A librte_vhost public structures refactor is planned for DPDK 16.07
> > > +  that requires both ABI and API change.
> > > +  The proposed refactor would expose DPDK vhost dev to applications as
> > > +  a handle, like the way kernel exposes an fd to user for locating a
> > > +  specific file, and to keep all major structures internally, so that
> > > +  we are likely to be free from ABI violations in future.
> > 
> > Acked-by: Panu Matilainen <pmatilai@redhat.com>
> > 
> > I applaud the initiative, public structs are by far the worst offender 
> > when trying to maintain a stable ABI because they're so hard to 
> > correctly version that hardly anybody besides glibc bothers.
> 
> Yes, nice cleanup to do.
> 
> Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied, thanks

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor
  2016-04-07  7:12  7% ` Panu Matilainen
@ 2016-04-10  9:58  4%   ` Thomas Monjalon
  2016-04-10 10:02  4%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-10  9:58 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: Panu Matilainen, dev, huawei.xie, Ilya Maximets

2016-04-07 10:12, Panu Matilainen:
> On 04/06/2016 09:53 AM, Yuanhan Liu wrote:
> > +* A librte_vhost public structures refactor is planned for DPDK 16.07
> > +  that requires both ABI and API change.
> > +  The proposed refactor would expose DPDK vhost dev to applications as
> > +  a handle, like the way kernel exposes an fd to user for locating a
> > +  specific file, and to keep all major structures internally, so that
> > +  we are likely to be free from ABI violations in future.
> 
> Acked-by: Panu Matilainen <pmatilai@redhat.com>
> 
> I applaud the initiative, public structs are by far the worst offender 
> when trying to maintain a stable ABI because they're so hard to 
> correctly version that hardly anybody besides glibc bothers.

Yes, nice cleanup to do.

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches
  2016-04-08 14:01  4%   ` Hunt, David
@ 2016-04-10  9:55  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-10  9:55 UTC (permalink / raw)
  To: Lazaros Koromilas; +Cc: dev, Hunt, David, Olivier Matz

> >> Deprecation notice for 16.04 for changes targeting release 16.07.
> >> The changes affect struct rte_mempool, rte_mempool_cache and the
> >> mempool API.
> >>
> >> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
> > Acked-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: David Hunt<david.hunt@intel.com>

It is the fourth change announced for rte_mempool in 16.07.

Applied, thanks

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches
  2016-04-05 15:42  4% ` Olivier Matz
@ 2016-04-08 14:01  4%   ` Hunt, David
  2016-04-10  9:55  4%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2016-04-08 14:01 UTC (permalink / raw)
  To: Olivier Matz, Lazaros Koromilas, dev



On 4/5/2016 4:42 PM, Olivier Matz wrote:
> On 04/05/2016 11:23 AM, Lazaros Koromilas wrote:
>> Deprecation notice for 16.04 for changes targeting release 16.07.
>> The changes affect struct rte_mempool, rte_mempool_cache and the
>> mempool API.
>>
>> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
> Acked-by: Olivier Matz <olivier.matz@6wind.com>
>

Acked-by: David Hunt<david.hunt@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] On DPDK ABI policy
  2016-04-07 11:51  9%       ` [dpdk-dev] On DPDK ABI policy Panu Matilainen
  2016-04-07 21:52  4%         ` Matthew Hall
@ 2016-04-08  8:47  9%         ` Marc Sune
  1 sibling, 0 replies; 200+ results
From: Marc Sune @ 2016-04-08  8:47 UTC (permalink / raw)
  To: Panu Matilainen, Matthew Hall; +Cc: Thomas Monjalon, dev

2016-04-07 13:51 GMT+02:00 Panu Matilainen <pmatilai@redhat.com>:

> [ change of subject since this is about ABI policy, not namespacing ]
>
> On 04/07/2016 01:16 PM, Marc Sune wrote:
>
>>
>>
>> 2016-04-07 11:33 GMT+02:00 Panu Matilainen <pmatilai@redhat.com
>> <mailto:pmatilai@redhat.com>>:
>>
>>     On 04/07/2016 12:18 PM, Thomas Monjalon wrote:
>>
>>         Thank you everyone for the feedbacks.
>>
>>         2016-04-05 15:56, Thomas Monjalon:
>>
>>             The goal of this email is to get some feedback on how
>>             important it is
>>             to fix the DPDK namespace.
>>
>>
>>         Everybody agree every symbols must be prefixed. Checking and
>>         fixing the
>>         namespace consistency will be in the roadmap.
>>
>>         It seems most of you agree renaming would be a nice improvement
>>         but not
>>         so important.
>>         The main drawback is the induced backporting pain, even if we have
>>         some scripts to convert the patches to the old namespace.
>>         Note: the backports can be in DPDK itself or in the applications.
>>
>>             If there is enough agreement that we should do something, I
>>             suggest to
>>             introduce the "dpdk_" prefix slowly and live with both
>>             "rte_" and "dpdk_"
>>             during some time.
>>             We could start using the new prefix for the new APIs
>>             (example: crypto)
>>             or when there is a significant API break (example: mempool).
>>
>>
>>         The slow change has been clearly rejected in favor of a complete
>>         change
>>         in one patch.
>>         The timing was also discussed as it could impact the pending
>>         patches.
>>         So it would be done at the end or the beginning of a release.
>>         Marc suggests to do it for 16.04 as the numbering scheme has
>>         changed.
>>
>>
>>     Just noting that it cannot be done in 16.04 because the ABI policy
>>     requires a deprecation cycle of at least one major release for every
>>     breakage. And we're discussing a total 100% breakage of everything
>>     here, even if its just a simple rename.
>>
>>
>> I keep not understanding the ABI policy, and particularly why ABI
>> changes have to be announced once cycle before _if_ there is already at
>> least one ABI change proposed. DPDK applications will have to recompile
>> anyway.
>>
>
> The point is to allow API/ABI consumers to assess in advance what sort of
> pains can they expect when moving their applications from one version to
> another. Otherwise all sorts of massive changes could ride the wave of
> whatever "change 16bit struct member to 32bit" trivialities that are
> nevertheless ABI breaks.
>
> There have already been quite a few exceptions to the rule when the ABI is
> already being broken, so its not entirely rigid. Another point that migth
> warrant some tweaking to the policy is the "core" libraries depending on
> each other so an ABI break in any one of them forces recompile of
> everything anyway.
>

In addition to what Matthew said:

I don't understand which sort of pains an announcement saying "we are going
to change this structure and this other, for those high level reasons, but
we don't know exactly how yet, because it is not fully implemented" can be
of any help to a DPDK user. At least it does not to me. This information
has to be in the release notes and users can read that before deciding to
upgrade to a new release.

On the other side, bug fixes still go to NEXT_VERSION. So in 1 ouf ot 2
cases (so far), next release is breaking ABI, so you will have to anyway
recompile your application.

And about ABI breakages; DPDK is not a standard library/library set. For
performance reasons it has a lot of inline code and other optimizations, so
even for small bug fixings can brake ABI, or to be precise, some bug fixes
in inline functions may be silently ignored. I don't know how many users
really use dynamic libraries for DPDK and if there is some warning
somewhere in the documentation for that.


> This aspect of the policy only slows down DPDK development and it
>>
>
> One could also think that slowing down development and forcing people to
> think ahead are not entirely unintentional or unwanted side-effects :)
>
> Look at the latest librte_vhost initiative to remove unnecessarily exposed
> structs to avoid having to deal with ABI breakages all the time: the policy
> is effectively encouraging people into better library design.
>
> pollutes the repository with commits announcing ABI changes that are
>> irrelevant after 2 cycles, as (code) diffs show that already (not
>> mentioning NEXT_ABI complexity and extra LOCs).
>>
>
> Fully agreed on NEXT_ABI, I never liked it at all.
>
> Maintaining LTS releases, and enforcing bug fixing in old LTS first,
>> upstreaming bugfixes is to me a much better approach to solve backwards
>> compatibility issues.
>>
>
> LTS releases could help the situation somewhat, but then again people tend
> to still want those new fancy things backported (you know, have the cake
> and eat it too) but that can't be done because of ABI breakage, so they're
> forced to run the latest version anyway.


> But this is probably another discussion.
>>
>
> Yup, changed subject to avoid mixing it up with the namespace discussion
> too much.


Yes, thanks for that
Marc


>
>
>         - Panu -
>
>

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] On DPDK ABI policy
  2016-04-07 21:52  4%         ` Matthew Hall
@ 2016-04-08  8:29  4%           ` Marc Sune
  0 siblings, 0 replies; 200+ results
From: Marc Sune @ 2016-04-08  8:29 UTC (permalink / raw)
  To: Matthew Hall; +Cc: Panu Matilainen, Thomas Monjalon, dev

2016-04-07 23:52 GMT+02:00 Matthew Hall <mhall@mhcomputing.net>:

> On Thu, Apr 07, 2016 at 02:51:35PM +0300, Panu Matilainen wrote:
> > LTS releases could help the situation somewhat, but then again
> > people tend to still want those new fancy things backported (you
> > know, have the cake and eat it too) but that can't be done because
> > of ABI breakage, so they're forced to run the latest version anyway.
>
> RH and Debian / Ubuntu don't put features in LTS except extremely rarely.
> Generally only if there's severe functionality breakage or security issues
> and
> the rest is ignored, and for good reason, as this is much more reliable and
> simple and predictable.
>
> If people are so irrational they can't deal with that simple of a policy,
> NEXT_ABI, LTS, etc. is never going to help them.
>
> If people like to have backported stuff, yes of course we can make trees
> and
> branches for this, they are basically free in Git. But at that point
> community
> people in need of LTS forks of features need to step up to the plate to
> help
> out.
>

Completely agree.

Marc


>
> Matthew.
>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] On DPDK ABI policy
  2016-04-07 11:51  9%       ` [dpdk-dev] On DPDK ABI policy Panu Matilainen
@ 2016-04-07 21:52  4%         ` Matthew Hall
  2016-04-08  8:29  4%           ` Marc Sune
  2016-04-08  8:47  9%         ` Marc Sune
  1 sibling, 1 reply; 200+ results
From: Matthew Hall @ 2016-04-07 21:52 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: Marc Sune, Thomas Monjalon, dev

On Thu, Apr 07, 2016 at 02:51:35PM +0300, Panu Matilainen wrote:
> LTS releases could help the situation somewhat, but then again
> people tend to still want those new fancy things backported (you
> know, have the cake and eat it too) but that can't be done because
> of ABI breakage, so they're forced to run the latest version anyway.

RH and Debian / Ubuntu don't put features in LTS except extremely rarely. 
Generally only if there's severe functionality breakage or security issues and 
the rest is ignored, and for good reason, as this is much more reliable and 
simple and predictable.

If people are so irrational they can't deal with that simple of a policy, 
NEXT_ABI, LTS, etc. is never going to help them.

If people like to have backported stuff, yes of course we can make trees and 
branches for this, they are basically free in Git. But at that point community 
people in need of LTS forks of features need to step up to the plate to help 
out.

Matthew.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-07 10:16  5%     ` Marc Sune
  2016-04-07 11:51  9%       ` [dpdk-dev] On DPDK ABI policy Panu Matilainen
@ 2016-04-07 21:48  0%       ` Matthew Hall
  1 sibling, 0 replies; 200+ results
From: Matthew Hall @ 2016-04-07 21:48 UTC (permalink / raw)
  To: Marc Sune; +Cc: Panu Matilainen, Thomas Monjalon, dev, techboard

On Thu, Apr 07, 2016 at 12:16:34PM +0200, Marc Sune wrote:
> I keep not understanding the ABI policy, and particularly why ABI changes
> have to be announced once cycle before _if_ there is already at least one
> ABI change proposed. DPDK applications will have to recompile anyway.
> 
> This aspect of the policy only slows down DPDK development and it pollutes
> the repository with commits announcing ABI changes that are irrelevant
> after 2 cycles, as (code) diffs show that already (not mentioning NEXT_ABI
> complexity and extra LOCs).
> 
> Maintaining LTS releases, and enforcing bug fixing in old LTS first,
> upstreaming bugfixes is to me a much better approach to solve backwards
> compatibility issues.
> 
> But this is probably another discussion.

Yes, separate discussion. But I agree 100,000%. As a community member in my 
spare time I get tripped up by NEXT_ABI pollution just trying to submit 
trivial patches all the time, then I don't really have any good idea how to 
fix it, and I have to annoy Thomas with dumb questions across the time zones.

I would really prefer to dump all the drama about ABIs and make a maintenance 
only LTS release which only gets bug fixes people specifically need and not 
random fixes or features.

Matthew.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
  2016-04-06  8:51  4%   ` Azarewicz, PiotrX T
@ 2016-04-07 21:24  4%     ` Thomas Monjalon
  2016-04-12 12:39  4%       ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-07 21:24 UTC (permalink / raw)
  To: Zhang, Roy Fan; +Cc: dev, Azarewicz, PiotrX T, Singh, Jasvinder

> > > Several new fields will be added to structure rte_port_source_params
> > > for source port enhancement with pcap file reading support.
> > >
> > > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > 
> > Acked-by: Jasvinder Singh <jasvinder.singh@intel.com>
> 
> Acked-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>

Applied, thanks

Please send a patch to remove NEXT_ABI early in the 16.07 cycle.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce API changes for device objects
  2016-04-07 17:09  3%     ` Jan Viktorin
@ 2016-04-07 17:24  0%       ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2016-04-07 17:24 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, Olivier Matz, Thomas Monjalon

On Thu, Apr 7, 2016 at 7:09 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> On Thu, 7 Apr 2016 19:00:43 +0200
> David Marchand <david.marchand@6wind.com> wrote:
>> >> Following discussions with Jan, here is a deprecation notice to prepare for
>> >> hotplug and rte_device changes to come in 16.07.
>> > As a result, the current rte_driver structure will be renamed to
>> > rte_module and probably reworked in some way due to its semantics and
>> > potential name clash with the new rte_driver struct.
>>
>> If we just introduce some macros like RTE_MODULE_INIT() /
>> RTE_MODULE_EXIT(), we don't need a rte_module object at the moment ?
>>
>
> Well, possibly, we don't need it. At least, it might be hidden and not
> being a part of the API/ABI. Do you need an ack for this?

Yes, please, the process requires 3 acks for this kind of changes.

-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce API changes for device objects
  2016-04-07 17:00  0%   ` David Marchand
@ 2016-04-07 17:09  3%     ` Jan Viktorin
  2016-04-07 17:24  0%       ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Jan Viktorin @ 2016-04-07 17:09 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Olivier Matz, Thomas Monjalon

On Thu, 7 Apr 2016 19:00:43 +0200
David Marchand <david.marchand@6wind.com> wrote:

> On Thu, Apr 7, 2016 at 5:46 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> > On Thu,  7 Apr 2016 17:33:17 +0200
> > David Marchand <david.marchand@6wind.com> wrote:
> >  
> >> Following discussions with Jan, here is a deprecation notice to prepare for
> >> hotplug and rte_device changes to come in 16.07.
> >>
> >> Signed-off-by: David Marchand <david.marchand@6wind.com>
> >> ---
> >>  doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
> >>  1 file changed, 12 insertions(+)
> >>
> >> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> >> index 98d5529..d749e5d 100644
> >> --- a/doc/guides/rel_notes/deprecation.rst
> >> +++ b/doc/guides/rel_notes/deprecation.rst
> >> @@ -8,6 +8,18 @@ API and ABI deprecation notices are to be posted here.
> >>  Deprecation Notices
> >>  -------------------
> >>
> >> +* The ethdev hotplug API is going to be moved to EAL with a notification
> >> +  mechanism added to crypto and ethdev libraries so that hotplug is now
> >> +  available to both of them. This API will be stripped of the device arguments
> >> +  so that it only cares about hotplugging.
> >> +
> >> +* Structures embodying pci and vdev devices are going to be reworked to
> >> +  integrate new common rte_device / rte_driver objects (see
> >> +  http://dpdk.org/ml/archives/dev/2016-January/031390.html).
> >> +  ethdev and crypto libraries will then only handle those objects so that they
> >> +  do not need to care about the kind of devices that are being used, making it
> >> +  easier to add new buses later.  
> >
> > As a result, the current rte_driver structure will be renamed to
> > rte_module and probably reworked in some way due to its semantics and
> > potential name clash with the new rte_driver struct.  
> 
> If we just introduce some macros like RTE_MODULE_INIT() /
> RTE_MODULE_EXIT(), we don't need a rte_module object at the moment ?
> 

Well, possibly, we don't need it. At least, it might be hidden and not
being a part of the API/ABI. Do you need an ack for this?

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] doc: announce API changes for device objects
  2016-04-07 15:46  0% ` Jan Viktorin
@ 2016-04-07 17:00  0%   ` David Marchand
  2016-04-07 17:09  3%     ` Jan Viktorin
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2016-04-07 17:00 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, Olivier Matz, Thomas Monjalon

On Thu, Apr 7, 2016 at 5:46 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> On Thu,  7 Apr 2016 17:33:17 +0200
> David Marchand <david.marchand@6wind.com> wrote:
>
>> Following discussions with Jan, here is a deprecation notice to prepare for
>> hotplug and rte_device changes to come in 16.07.
>>
>> Signed-off-by: David Marchand <david.marchand@6wind.com>
>> ---
>>  doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>> index 98d5529..d749e5d 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -8,6 +8,18 @@ API and ABI deprecation notices are to be posted here.
>>  Deprecation Notices
>>  -------------------
>>
>> +* The ethdev hotplug API is going to be moved to EAL with a notification
>> +  mechanism added to crypto and ethdev libraries so that hotplug is now
>> +  available to both of them. This API will be stripped of the device arguments
>> +  so that it only cares about hotplugging.
>> +
>> +* Structures embodying pci and vdev devices are going to be reworked to
>> +  integrate new common rte_device / rte_driver objects (see
>> +  http://dpdk.org/ml/archives/dev/2016-January/031390.html).
>> +  ethdev and crypto libraries will then only handle those objects so that they
>> +  do not need to care about the kind of devices that are being used, making it
>> +  easier to add new buses later.
>
> As a result, the current rte_driver structure will be renamed to
> rte_module and probably reworked in some way due to its semantics and
> potential name clash with the new rte_driver struct.

If we just introduce some macros like RTE_MODULE_INIT() /
RTE_MODULE_EXIT(), we don't need a rte_module object at the moment ?

-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v1] doc: fix release notes for 16.04
@ 2016-04-07 16:02  8% John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2016-04-07 16:02 UTC (permalink / raw)
  To: dev; +Cc: thomas.monjalon, John McNamara

Fix grammar, spelling and formatting of DPDK 16.04 release notes.

Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 266 +++++++++++++--------------------
 1 file changed, 104 insertions(+), 162 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index e293960..200053c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -2,39 +2,9 @@ DPDK Release 16.04
 ==================
 
 
-**Read this first**
-
-The text below explains how to update the release notes.
-
-Use proper spelling, capitalization and punctuation in all sections.
-
-Variable and config names should be quoted as fixed width text: ``LIKE_THIS``.
-
-Build the docs and view the output file to ensure the changes are correct::
-
-   make doc-guides-html
-
-   firefox build/doc/html/guides/rel_notes/release_16_04.html
-
-
 New Features
 ------------
 
-This section should contain new features added in this release. Sample format:
-
-* **Add a title in the past tense with a full stop.**
-
-  Add a short 1-2 sentence description in the past tense. The description
-  should be enough to allow someone scanning the release notes to understand
-  the new feature.
-
-  If the feature adds a lot of sub-features you can use a bullet list like this.
-
-  * Added feature foo to do something.
-  * Enhanced feature bar to do something else.
-
-  Refer to the previous release notes for examples.
-
 * **Added function to check primary process state.**
 
   A new function ``rte_eal_primary_proc_alive()`` has been added
@@ -45,141 +15,145 @@ This section should contain new features added in this release. Sample format:
 * **Enabled bulk allocation of mbufs.**
 
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
-  to allocate a bulk of mbufs.
+  to bulk allocate mbufs.
 
 * **Added device link speed capabilities.**
 
-  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
-  allows the application to know the supported speeds of each device.
+  The structure ``rte_eth_dev_info`` now has a ``speed_capa`` bitmap, which
+  allows the application to determine the supported speeds of each device.
 
 * **Added bitmap of link speeds to advertise.**
 
-  Allow defining a set of advertised speeds for auto-negotiation,
+  Added a feature to allow the definition of a set of advertised speeds for auto-negotiation,
   explicitly disabling link auto-negotiation (single speed)
   and full auto-negotiation.
 
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
-  The driver operates variety of ENA adapters through feature negotiation
+  The driver operates for a variety of ENA adapters through feature negotiation
   with the adapter and upgradable commands set.
-  ENA driver handles PCI Physical and Virtual ENA functions.
+  The ENA driver handles PCI Physical and Virtual ENA functions.
 
-* **Restored vmxnet3 Tx data ring.**
+* **Restored vmxnet3 TX data ring.**
 
-  Tx data ring has been shown to improve small pkt forwarding performance
-  on vSphere environment.
+  TX data ring has been shown to improve small packet forwarding performance
+  on the vSphere environment.
 
-* **Added vmxnet3 Tx L4 checksum offload.**
+* **Added vmxnet3 TX L4 checksum offload.**
 
-  Support TCP/UDP checksum offload.
+  Added support for TCP/UDP checksum offload to vmxnet3.
 
 * **Added vmxnet3 TSO support.**
 
+  Added support for TSO to vmxnet3.
+
 * **Added vmxnet3 support for jumbo frames.**
 
   Added support for linking multi-segment buffers together to
   handle Jumbo packets.
 
-* **Virtio 1.0.**
+* **Enabled Virtio 1.0 support.**
 
-  Enabled virtio 1.0 support for virtio pmd driver.
+  Enabled Virtio 1.0 support for Virtio pmd driver.
 
-* **Supported virtio for ARM.**
+* **Supported Virtio for ARM.**
 
-  Enabled virtio support for armv7/v8. Tested for arm64.
-  Virtio for arm support VFIO-noiommu mode only.
-  Virtio can work with other non-x86 arch too like powerpc.
+  Enabled Virtio support for ARMv7/v8. Tested for ARM64.
+  Virtio for ARM supports VFIO-noiommu mode only.
+  Virtio can work with other non-x86 architectures as well, like PowerPC.
 
-* **Supported virtio offload in vhost-user.**
+* **Supported Virtio offload in vhost-user.**
 
-  Add the offload and negotiation of checksum and TSO between vhost-user and
-  vanilla Linux virtio guest.
+  Added the offload and negotiation of checksum and TSO between vhost-user and
+  vanilla Linux Virtio guest.
 
 * **Added vhost-user live migration support.**
 
 * **Added vhost driver.**
 
-  Added virtual PMD that wraps librte_vhost.
+  Added a virtual PMD that wraps ``librte_vhost``.
 
 * **Added multicast promiscuous mode support on VF for ixgbe.**
 
-  Added multicast promiscuous mode support on ixgbe VF driver. So all the VFs
+  Added multicast promiscuous mode support for the ixgbe VF driver so all VFs
   can receive the multicast packets.
 
-  Please note if we want to use this promiscuous mode, we need both PF and VF
-  driver to support it. The reason is this VF feature is configured on PF.
-  If use kernel PF driver + dpdk VF driver, make sure kernel PF driver support
-  VF multicast promiscuous mode. If use dpdk PF + dpdk VF, better make sure PF
-  driver is the same version as VF.
+  Please note if you want to use this promiscuous mode, you need both PF and VF
+  driver to support it. The reason is that this VF feature is configured in the PF.
+  If you use kernel PF driver and the dpdk VF driver, make sure the kernel PF driver supports
+  VF multicast promiscuous mode. If you use dpdk PF and  dpdk VF ensure the PF
+  driver is the same version as the VF.
 
 * **Added support for E-tag on X550.**
 
-  E-tag is defined in 802.1br. Please reference
-  http://www.ieee802.org/1/pages/802.1br.html.
+  E-tag is defined in `802.1BR - Bridge Port Extension <http://www.ieee802.org/1/pages/802.1br.html>`_.
 
-  This feature is for VF, but the settings are on PF. It means
-  the CLIs should be used on PF, but some of their effects will be shown on VF.
-  The forwarding of E-tag packets based on GRP and E-CID_base will have effect
-  on PF. Theoretically the E-tag packets can be forwarded to any pool/queue.
-  But normally we'd like to forward the packets to the pools/queues belonging
-  to the VFs. And E-tag insertion and stripping will have effect on VFs. When
-  VF receives E-tag packets, it should strip the E-tag. When VF transmits
-  packets, it should insert the E-tag. Both can be offloaded.
+  This feature is for the VF, but the settings are on the PF. It means
+  the CLIs should be used on the PF, but some of their effects will be shown on the VF.
+  The forwarding of E-tag packets based on GRP and E-CID_base will have an effect
+  on the PF. Theoretically, the E-tag packets can be forwarded to any pool/queue
+  but normally we'd like to forward the packets to the pools/queues belonging
+  to the VFs. And E-tag insertion and stripping will have an effect on VFs. When
+  a VF receives E-tag packets it should strip the E-tag. When the VF transmits
+  packets, it should insert the E-tag. Both actions can be offloaded.
 
   When we want to use this E-tag support feature, the forwarding should be
-  enabled to forward the packets received by PF to indicated VFs. And insertion
-  and stripping should be enabled for VFs to offload the effort to HW.
+  enabled to forward the packets received by the PF to the indicated VFs. And insertion
+  and stripping should be enabled for VFs to offload the effort to hardware.
+
+  Features added:
 
   * Support E-tag offloading of insertion and stripping.
   * Support Forwarding E-tag packets to pools based on
     GRP and E-CID_base.
 
-* **Added support for VxLAN & NVGRE checksum off-load on X550.**
+* **Added support for VxLAN and NVGRE checksum off-load on X550.**
 
-  * Added support for VxLAN & NVGRE RX/TX checksum off-load on
+  * Added support for VxLAN and NVGRE RX/TX checksum off-load on
     X550. RX/TX checksum off-load is provided on both inner and
     outer IP header and TCP header.
   * Added functions to support VxLAN port configuration. The
     default VxLAN port number is 4789 but this can be updated
     programmatically.
 
-* **Added new X550EM_a devices.**
+* **Added support for new X550EM_a devices.**
 
-  Added new X550EM_a devices and their mac types, X550EM_a and X550EM_a_vf.
-  Updated the code to use the new devices and mac types.
+  Added support for new X550EM_a devices and their MAC types, X550EM_a and X550EM_a_vf.
+  Updated the relevant PMD to use the new devices and MAC types.
 
 * **Added x550em_x V2 device support.**
 
-  Only x550em_x V1 was supported before. Now V2 is supported.
+  Added support for x550em_x V2 device. Only x550em_x V1 was supported before.
   A mask for V1 and V2 is defined and used to support both.
 
 * **Supported link speed auto-negotiation on X550EM_X**
 
-  Normally the auto-negotiation is supported by FW. SW need not care about
-  that. But on x550em_x, FW doesn't support auto-neg. As the ports of x550em_x
-  are 10G, if we connect the port with a peer which is 1G, the link will always
+  Normally the auto-negotiation is supported by firmware and software doesn't care about
+  it. But on x550em_x, firmware doesn't support auto-negotiation. As the ports of x550em_x
+  are 10GbE, if we connect the port with a peer which is 1GbE, the link will always
   be down.
-  We added the support of auto-neg by SW to avoid this link down issue.
+  We added the support for auto-negotiation by software to avoid this link down issue.
 
-* **Added sw-firmware sync on X550EM_a.**
+* **Added software-firmware sync on X550EM_a.**
 
-  Added support for sw-firmware sync for resource sharing.
-  Use the PHY token, shared between sw-fw for PHY access on X550EM_a.
+  Added support for software-firmware sync for resource sharing.
+  Use the PHY token, shared between software-firmware for PHY access on X550EM_a.
 
 * **Updated the i40e base driver.**
 
   The i40e base driver was updated with changes including the
   following:
 
-  * Use Rx control AQ commands to read/write Rx control registers.
+  * Use RX control AQ commands to read/write RX control registers.
   * Add new X722 device IDs, and removed X710 one was never used.
   * Expose registers for HASH/FD input set configuring.
 
 * **Enabled PCI extended tag for i40e.**
 
-  It enabled extended tag by checking and writing corresponding PCI config
-  space bytes, to boost the performance. In the meanwhile, it deprecated the
-  legacy way via reading/writing sysfile supported by kernel module igb_uio.
+  Enabled extended tag for i40e by checking and writing corresponding PCI config
+  space bytes, to boost the performance.
+  The legacy method of reading/writing sysfile supported by kernel module igb_uio
+  is now deprecated.
 
 * **Added i40e support for setting mac addresses.**
 
@@ -197,22 +171,22 @@ This section should contain new features added in this release. Sample format:
 
 * **Added PF reset event reporting in i40e VF driver.**
 
-* **Added fm10k Rx interrupt support.**
+* **Added fm10k RX interrupt support.**
 
-* **Optimized fm10k Tx.**
+* **Optimized fm10k TX.**
 
-  * Free multiple mbufs at a time to reduce freeing mbuf cycles.
+  Optimized fm10k TX by freeing multiple mbufs at a time.
 
-* **Handled error flags in fm10k vector Rx.**
+* **Handled error flags in fm10k vector RX.**
 
-  Parse err flags in Rx desc and set error bits in mbuf with vector instructions.
+  Parse error flags in RX descriptor and set error bits in mbuf with vector instructions.
 
 * **Added fm10k FTAG based forwarding support.**
 
 * **Added mlx5 flow director support.**
 
-  Added flow director support (RTE_FDIR_MODE_PERFECT and
-  RTE_FDIR_MODE_PERFECT_MAC_VLAN).
+  Added flow director support (``RTE_FDIR_MODE_PERFECT`` and
+  ``RTE_FDIR_MODE_PERFECT_MAC_VLAN``).
 
   Only available with Mellanox OFED >= 3.2.
 
@@ -238,7 +212,7 @@ This section should contain new features added in this release. Sample format:
 
 * **Added mlx5 optional packet padding by HW.**
 
-  Added an option to make PCI bus transactions rounded to multiple of a
+  Added an option to make PCI bus transactions rounded to a multiple of a
   cache line size for better alignment.
 
   Only available with Mellanox OFED >= 3.2.
@@ -249,10 +223,10 @@ This section should contain new features added in this release. Sample format:
 
   Only available with Mellanox OFED >= 3.2.
 
-* **Changed szedata2 type of driver from vdev to pdev.**
+* **Changed szedata2 driver type from vdev to pdev.**
 
   Previously szedata2 device had to be added by ``--vdev`` option.
-  Now szedata2 PMD recognises the device automatically during EAL
+  Now szedata2 PMD recognizes the device automatically during EAL
   initialization.
 
 * **Added szedata2 functions for setting link up/down.**
@@ -261,17 +235,17 @@ This section should contain new features added in this release. Sample format:
 
 * **Added af_packet dynamic removal function.**
 
-  Af_packet device can now be detached using API, like other PMD devices.
+  An af_packet device can now be detached using the API, like other PMD devices.
 
 * **Increased number of next hops for LPM IPv4 to 2^24.**
 
-  The next_hop field is extended from 8 bits to 24 bits for IPv4.
+  The ``next_hop`` field has been extended from 8 bits to 24 bits for IPv4.
 
 * **Added support of SNOW 3G (UEA2 and UIA2) for Intel Quick Assist devices.**
 
-  Enabled support for SNOW 3G wireless algorithm for Intel Quick Assist devices.
-  Support for cipher only, hash only is also provided
-  along with alg-chaining operations.
+  Enabled support for the SNOW 3G wireless algorithm for Intel Quick Assist devices.
+  Support for cipher-only and  hash-only is also provided
+  along with algorithm-chaining operations.
 
 * **Added SNOW3G SW PMD.**
 
@@ -281,31 +255,29 @@ This section should contain new features added in this release. Sample format:
 * **Added AES GCM PMD.**
 
   Added new Crypto PMD to support AES-GCM authenticated encryption and
-  authenticated decryption in SW.
+  authenticated decryption in software.
 
 * **Added NULL Crypto PMD**
 
-  Added new Crypto PMD to support null crypto operations in SW.
+  Added new Crypto PMD to support null crypto operations in software.
 
 * **Improved IP Pipeline Application.**
 
   The following features have been added to ip_pipeline application;
 
   * Added CPU utilization measurement and idle cycle rate computation.
-  * Added link idenfication support through existing port-mask option or by
+  * Added link identification support through existing port-mask option or by
     specifying PCI device in every LINK section in the configuration file.
   * Added load balancing support in passthrough pipeline.
 
 * **Added IPsec security gateway example.**
 
-  New application implementing an IPsec Security Gateway.
+  Added a new application implementing an IPsec Security Gateway.
 
 
 Resolved Issues
 ---------------
 
-This section should contain bug fixes added to the relevant sections. Sample format:
-
 * **code/section: Fixed issue in the past tense with a full stop.**
 
   Add a short 1-2 sentence description of the resolved issue in the past tense.
@@ -313,21 +285,17 @@ This section should contain bug fixes added to the relevant sections. Sample for
   Add the entries in alphabetic order in the relevant sections below.
 
 
-EAL
-~~~
-
-
 Drivers
 ~~~~~~~
 
 * **ethdev: Fixed overflow for 100Gbps.**
 
-  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  100Gbps in Mbps (100000) was exceeding the 16-bit max value of ``link_speed``
   in ``rte_eth_link``.
 
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
-  Fixed issue in ethdev library that the structure for setting
+  Fixed issue in ethdev library where the structure for setting
   fdir's mask and flow entry was not consistent in byte ordering.
 
 * **cxgbe: Fixed crash due to incorrect size allocated for RSS table.**
@@ -338,12 +306,12 @@ Drivers
 
 * **cxgbe: Fixed setting wrong device MTU.**
 
-  Fixed an incorrect device MTU being set due to ethernet header and
+  Fixed an incorrect device MTU being set due to the Ethernet header and
   CRC lengths being added twice.
 
 * **ixgbe: Fixed zeroed VF mac address.**
 
-  Resolved an issue where VF mac address is zeroed out in cases where the VF
+  Resolved an issue where the VF MAC address is zeroed out in cases where the VF
   driver is loaded while the PF interface is down.
   The solution is to only set it when we get an ACK from the PF.
 
@@ -370,7 +338,7 @@ Drivers
   It generates a MAC address for each VFs during PF host initialization,
   and keeps the VF MAC address the same among different VF launch.
 
-* **i40e: Fixed failure of reading/writing Rx control registers.**
+* **i40e: Fixed failure of reading/writing RX control registers.**
 
   Fixed i40e issue of failing to read/write rx control registers when
   under stress with traffic, which might result in application launch
@@ -378,14 +346,14 @@ Drivers
 
 * **i40e: Enabled vector driver by default.**
 
-  Previously, vector driver is disabled by default as it cannot fill packet type
-  info for l3fwd to work well. Now there is an option for l3fwd to analysis
-  packet type softly, so enable vector driver by default.
+  Previously, vector driver was disabled by default as it couldn't fill packet type
+  info for l3fwd to work well. Now there is an option for l3fwd to analyze
+  the packet type so the vector driver is enabled by default.
 
 * **i40e: Fixed link info of VF.**
 
-  Previously, the VF's link speed kept as 10G and status always was up.
-  It did not change even the physical link's status changed.
+  Previously, the VF's link speed stayed at 10GbE and status always was up.
+  It did not change even when the physical link's status changed.
   Now this issue is fixed to make VF's link info consistent with physical link.
 
 * **mlx5: Fixed possible crash during initialization.**
@@ -394,7 +362,7 @@ Drivers
 
 * **mlx5: Added port type check.**
 
-  Done to prevent port initialization on non-Ethernet link layers and
+  Added port type check to prevent port initialization on non-Ethernet link layers and
   to report an error.
 
 * **mlx5: Applied VLAN filtering to broadcast and IPv6 multicast flows.**
@@ -407,10 +375,10 @@ Drivers
 
 * **aesni_mb: Fixed wrong return value when creating a device.**
 
-  cryptodev_aesni_mb_init() was returning the device id of the device created,
-  instead of 0 (when success), that rte_eal_vdev_init() expects.
-  This made impossible the creation of more than one aesni_mb device
-  from command line.
+  The ``cryptodev_aesni_mb_init()`` function was returning the device id of the device created,
+  instead of 0 (on success) that ``rte_eal_vdev_init()`` expects.
+  This made it impossible to create more than one aesni_mb device
+  from the command line.
 
 * **qat: Fixed AES GCM decryption.**
 
@@ -424,7 +392,7 @@ Libraries
 * **hash: Fixed CRC32c hash computation for non multiple of 4 bytes sizes.**
 
   Fix crc32c hash functions to return a valid crc32c value for data lengths
-  not multiple of 4 bytes.
+  not a multiple of 4 bytes.
 
 * **hash: Fixed hash library to support multi-process mode.**
 
@@ -440,7 +408,7 @@ Libraries
   ``rte_errno`` to ``EEXIST`` when the object name already exists. This is
   the behavior described in the API documentation in the header file.
   The previous behavior was to return a pointer to the existing object in
-  that case, preventing the caller to know if the object had to be freed
+  that case, preventing the caller from knowing if the object had to be freed
   or not.
 
 * **lpm: Fixed return value when allocating an existing object.**
@@ -449,7 +417,7 @@ Libraries
   ``rte_errno`` to ``EEXIST`` when the object name already exists. This is
   the behavior described in the API documentation in the header file.
   The previous behavior was to return a pointer to the existing object in
-  that case, preventing the caller to know if the object had to be freed
+  that case, preventing the caller from knowing if the object had to be freed
   or not.
 
 * **librte_port: Fixed segmentation fault for ring and ethdev writer nodrop.**
@@ -468,39 +436,19 @@ Examples
 
 * **l3fwd: Fixed using packet type blindly.**
 
-  l3fwd makes use of packet type information without even query if devices or PMDs
-  really set it. For those don't set ptypes, add an option to parse it softly.
+  l3fwd makes use of packet type information without querying if devices or PMDs
+  really set it. For those devices that don't set ptypes, add an option to parse it.
 
 * **examples/vhost: Fixed frequent mbuf allocation failure.**
 
-  vhost-switch often fails to allocate mbuf when dequeue from vring because it
+  The vhost-switch often fails to allocate mbuf when dequeue from vring because it
   wrongly calculates the number of mbufs needed.
 
 
-Other
-~~~~~
-
-
-Known Issues
-------------
-
-This section should contain new known issues in this release. Sample format:
-
-* **Add title in present tense with full stop.**
-
-  Add a short 1-2 sentence description of the known issue in the present
-  tense. Add information on any known workarounds.
-
-
 API Changes
 -----------
 
-This section should contain API changes. Sample format:
-
-* Add a short 1-2 sentence description of the API change. Use fixed width
-  quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
-
-* The ethdev statistics counter imissed is considered to be independent of ierrors.
+* The ethdev statistics counter ``imissed`` is considered to be independent of ``ierrors``.
   All drivers are now counting the missed packets only once, i.e. drivers will
   not increment ierrors anymore for missed packets.
 
@@ -524,13 +472,13 @@ This section should contain API changes. Sample format:
 * A parameter ``vlan_type`` has been added to the function
   ``rte_eth_dev_set_vlan_ether_type``.
 
-* AF_packet device init function is no longer public. Device should be attached
-  with API.
+* The af_packet device init function is no longer public. The device should be attached
+  via the API.
 
 * The LPM ``next_hop`` field is extended from 8 bits to 24 bits for IPv4
   while keeping ABI compatibility.
 
-* A new ``rte_lpm_config`` structure is used so LPM library will allocate
+* A new ``rte_lpm_config`` structure is used so the LPM library will allocate
   exactly the amount of memory which is necessary to hold application’s rules.
   The previous ABI is kept for compatibility.
 
@@ -542,10 +490,6 @@ This section should contain API changes. Sample format:
 ABI Changes
 -----------
 
-* Add a short 1-2 sentence description of the ABI change that was announced in
-  the previous releases and made in this release. Use fixed width quotes for
-  ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
-
 * The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
   from 8-bit to 16-bit.
 
@@ -558,8 +502,6 @@ ABI Changes
 Shared Library Versions
 -----------------------
 
-Update any library version updated in this release and prepend with a ``+`` sign.
-
 The libraries prepended with a plus sign were incremented in this version.
 
 .. code-block:: diff
-- 
2.5.0

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH] doc: announce API changes for device objects
  2016-04-07 15:33  5% [dpdk-dev] [PATCH] doc: announce API changes for device objects David Marchand
@ 2016-04-07 15:46  0% ` Jan Viktorin
  2016-04-07 17:00  0%   ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Jan Viktorin @ 2016-04-07 15:46 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, olivier.matz, thomas.monjalon

On Thu,  7 Apr 2016 17:33:17 +0200
David Marchand <david.marchand@6wind.com> wrote:

> Following discussions with Jan, here is a deprecation notice to prepare for
> hotplug and rte_device changes to come in 16.07.
> 
> Signed-off-by: David Marchand <david.marchand@6wind.com>
> ---
>  doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 98d5529..d749e5d 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -8,6 +8,18 @@ API and ABI deprecation notices are to be posted here.
>  Deprecation Notices
>  -------------------
>  
> +* The ethdev hotplug API is going to be moved to EAL with a notification
> +  mechanism added to crypto and ethdev libraries so that hotplug is now
> +  available to both of them. This API will be stripped of the device arguments
> +  so that it only cares about hotplugging.
> +
> +* Structures embodying pci and vdev devices are going to be reworked to
> +  integrate new common rte_device / rte_driver objects (see
> +  http://dpdk.org/ml/archives/dev/2016-January/031390.html).
> +  ethdev and crypto libraries will then only handle those objects so that they
> +  do not need to care about the kind of devices that are being used, making it
> +  easier to add new buses later.

As a result, the current rte_driver structure will be renamed to
rte_module and probably reworked in some way due to its semantics and
potential name clash with the new rte_driver struct.

Regards
Jan

> +
>  * The EAL function pci_config_space_set is deprecated in release 16.04
>    and will be removed from 16.07.
>    Macros CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] doc: announce API changes for device objects
@ 2016-04-07 15:33  5% David Marchand
  2016-04-07 15:46  0% ` Jan Viktorin
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2016-04-07 15:33 UTC (permalink / raw)
  To: dev; +Cc: viktorin, olivier.matz, thomas.monjalon

Following discussions with Jan, here is a deprecation notice to prepare for
hotplug and rte_device changes to come in 16.07.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 98d5529..d749e5d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,18 @@ API and ABI deprecation notices are to be posted here.
 Deprecation Notices
 -------------------
 
+* The ethdev hotplug API is going to be moved to EAL with a notification
+  mechanism added to crypto and ethdev libraries so that hotplug is now
+  available to both of them. This API will be stripped of the device arguments
+  so that it only cares about hotplugging.
+
+* Structures embodying pci and vdev devices are going to be reworked to
+  integrate new common rte_device / rte_driver objects (see
+  http://dpdk.org/ml/archives/dev/2016-January/031390.html).
+  ethdev and crypto libraries will then only handle those objects so that they
+  do not need to care about the kind of devices that are being used, making it
+  easier to add new buses later.
+
 * The EAL function pci_config_space_set is deprecated in release 16.04
   and will be removed from 16.07.
   Macros CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and
-- 
1.9.1

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] On DPDK ABI policy
  2016-04-07 10:16  5%     ` Marc Sune
@ 2016-04-07 11:51  9%       ` Panu Matilainen
  2016-04-07 21:52  4%         ` Matthew Hall
  2016-04-08  8:47  9%         ` Marc Sune
  2016-04-07 21:48  0%       ` [dpdk-dev] DPDK namespace Matthew Hall
  1 sibling, 2 replies; 200+ results
From: Panu Matilainen @ 2016-04-07 11:51 UTC (permalink / raw)
  To: Marc Sune; +Cc: Thomas Monjalon, dev

[ change of subject since this is about ABI policy, not namespacing ]

On 04/07/2016 01:16 PM, Marc Sune wrote:
>
>
> 2016-04-07 11:33 GMT+02:00 Panu Matilainen <pmatilai@redhat.com
> <mailto:pmatilai@redhat.com>>:
>
>     On 04/07/2016 12:18 PM, Thomas Monjalon wrote:
>
>         Thank you everyone for the feedbacks.
>
>         2016-04-05 15:56, Thomas Monjalon:
>
>             The goal of this email is to get some feedback on how
>             important it is
>             to fix the DPDK namespace.
>
>
>         Everybody agree every symbols must be prefixed. Checking and
>         fixing the
>         namespace consistency will be in the roadmap.
>
>         It seems most of you agree renaming would be a nice improvement
>         but not
>         so important.
>         The main drawback is the induced backporting pain, even if we have
>         some scripts to convert the patches to the old namespace.
>         Note: the backports can be in DPDK itself or in the applications.
>
>             If there is enough agreement that we should do something, I
>             suggest to
>             introduce the "dpdk_" prefix slowly and live with both
>             "rte_" and "dpdk_"
>             during some time.
>             We could start using the new prefix for the new APIs
>             (example: crypto)
>             or when there is a significant API break (example: mempool).
>
>
>         The slow change has been clearly rejected in favor of a complete
>         change
>         in one patch.
>         The timing was also discussed as it could impact the pending
>         patches.
>         So it would be done at the end or the beginning of a release.
>         Marc suggests to do it for 16.04 as the numbering scheme has
>         changed.
>
>
>     Just noting that it cannot be done in 16.04 because the ABI policy
>     requires a deprecation cycle of at least one major release for every
>     breakage. And we're discussing a total 100% breakage of everything
>     here, even if its just a simple rename.
>
>
> I keep not understanding the ABI policy, and particularly why ABI
> changes have to be announced once cycle before _if_ there is already at
> least one ABI change proposed. DPDK applications will have to recompile
> anyway.

The point is to allow API/ABI consumers to assess in advance what sort 
of pains can they expect when moving their applications from one version 
to another. Otherwise all sorts of massive changes could ride the wave 
of whatever "change 16bit struct member to 32bit" trivialities that are 
nevertheless ABI breaks.

There have already been quite a few exceptions to the rule when the ABI 
is already being broken, so its not entirely rigid. Another point that 
migth warrant some tweaking to the policy is the "core" libraries 
depending on each other so an ABI break in any one of them forces 
recompile of everything anyway.

> This aspect of the policy only slows down DPDK development and it

One could also think that slowing down development and forcing people to 
think ahead are not entirely unintentional or unwanted side-effects :)

Look at the latest librte_vhost initiative to remove unnecessarily 
exposed structs to avoid having to deal with ABI breakages all the time: 
the policy is effectively encouraging people into better library design.

> pollutes the repository with commits announcing ABI changes that are
> irrelevant after 2 cycles, as (code) diffs show that already (not
> mentioning NEXT_ABI complexity and extra LOCs).

Fully agreed on NEXT_ABI, I never liked it at all.

> Maintaining LTS releases, and enforcing bug fixing in old LTS first,
> upstreaming bugfixes is to me a much better approach to solve backwards
> compatibility issues.

LTS releases could help the situation somewhat, but then again people 
tend to still want those new fancy things backported (you know, have the 
cake and eat it too) but that can't be done because of ABI breakage, so 
they're forced to run the latest version anyway.

> But this is probably another discussion.

Yup, changed subject to avoid mixing it up with the namespace discussion 
too much.

	- Panu -

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-07  9:33  3%   ` Panu Matilainen
@ 2016-04-07 10:16  5%     ` Marc Sune
  2016-04-07 11:51  9%       ` [dpdk-dev] On DPDK ABI policy Panu Matilainen
  2016-04-07 21:48  0%       ` [dpdk-dev] DPDK namespace Matthew Hall
  0 siblings, 2 replies; 200+ results
From: Marc Sune @ 2016-04-07 10:16 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: Thomas Monjalon, dev, techboard

2016-04-07 11:33 GMT+02:00 Panu Matilainen <pmatilai@redhat.com>:

> On 04/07/2016 12:18 PM, Thomas Monjalon wrote:
>
>> Thank you everyone for the feedbacks.
>>
>> 2016-04-05 15:56, Thomas Monjalon:
>>
>>> The goal of this email is to get some feedback on how important it is
>>> to fix the DPDK namespace.
>>>
>>
>> Everybody agree every symbols must be prefixed. Checking and fixing the
>> namespace consistency will be in the roadmap.
>>
>> It seems most of you agree renaming would be a nice improvement but not
>> so important.
>> The main drawback is the induced backporting pain, even if we have
>> some scripts to convert the patches to the old namespace.
>> Note: the backports can be in DPDK itself or in the applications.
>>
>> If there is enough agreement that we should do something, I suggest to
>>> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
>>> during some time.
>>> We could start using the new prefix for the new APIs (example: crypto)
>>> or when there is a significant API break (example: mempool).
>>>
>>
>> The slow change has been clearly rejected in favor of a complete change
>> in one patch.
>> The timing was also discussed as it could impact the pending patches.
>> So it would be done at the end or the beginning of a release.
>> Marc suggests to do it for 16.04 as the numbering scheme has changed.
>>
>
> Just noting that it cannot be done in 16.04 because the ABI policy
> requires a deprecation cycle of at least one major release for every
> breakage. And we're discussing a total 100% breakage of everything here,
> even if its just a simple rename.


I keep not understanding the ABI policy, and particularly why ABI changes
have to be announced once cycle before _if_ there is already at least one
ABI change proposed. DPDK applications will have to recompile anyway.

This aspect of the policy only slows down DPDK development and it pollutes
the repository with commits announcing ABI changes that are irrelevant
after 2 cycles, as (code) diffs show that already (not mentioning NEXT_ABI
complexity and extra LOCs).

Maintaining LTS releases, and enforcing bug fixing in old LTS first,
upstreaming bugfixes is to me a much better approach to solve backwards
compatibility issues.

But this is probably another discussion.

Marc


>
>         - Panu -
>
>
> There is no strong conclusion at this point because we need to decide
>> wether the renaming deserves to be done or never.
>> I suggest to take the inputs from the technical board.
>>
>> Do not hesitate to comment. Thanks
>>
>>
>

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] DPDK namespace
  @ 2016-04-07  9:33  3%   ` Panu Matilainen
  2016-04-07 10:16  5%     ` Marc Sune
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-04-07  9:33 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: techboard

On 04/07/2016 12:18 PM, Thomas Monjalon wrote:
> Thank you everyone for the feedbacks.
>
> 2016-04-05 15:56, Thomas Monjalon:
>> The goal of this email is to get some feedback on how important it is
>> to fix the DPDK namespace.
>
> Everybody agree every symbols must be prefixed. Checking and fixing the
> namespace consistency will be in the roadmap.
>
> It seems most of you agree renaming would be a nice improvement but not
> so important.
> The main drawback is the induced backporting pain, even if we have
> some scripts to convert the patches to the old namespace.
> Note: the backports can be in DPDK itself or in the applications.
>
>> If there is enough agreement that we should do something, I suggest to
>> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
>> during some time.
>> We could start using the new prefix for the new APIs (example: crypto)
>> or when there is a significant API break (example: mempool).
>
> The slow change has been clearly rejected in favor of a complete change
> in one patch.
> The timing was also discussed as it could impact the pending patches.
> So it would be done at the end or the beginning of a release.
> Marc suggests to do it for 16.04 as the numbering scheme has changed.

Just noting that it cannot be done in 16.04 because the ABI policy 
requires a deprecation cycle of at least one major release for every 
breakage. And we're discussing a total 100% breakage of everything here, 
even if its just a simple rename.

	- Panu -

> There is no strong conclusion at this point because we need to decide
> wether the renaming deserves to be done or never.
> I suggest to take the inputs from the technical board.
>
> Do not hesitate to comment. Thanks
>

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] DPDK namespace
  @ 2016-04-07  8:22  3%           ` Marc
  0 siblings, 0 replies; 200+ results
From: Marc @ 2016-04-07  8:22 UTC (permalink / raw)
  To: Dave Neary
  Cc: Panu Matilainen, Yuanhan Liu, Arnon Warshavsky, Trahe, Fiona,
	Thomas Monjalon, dev

On 6 April 2016 at 22:21, Dave Neary <dneary@redhat.com> wrote:

> Hi,
>
> On 04/06/2016 08:07 AM, Panu Matilainen wrote:
> >> +1: it's a bit weird to keep both, especially for a long while, that
> >> every time we turn a rte_ prefix to dpdk_ prefix, we break applications.
> >> Instead of breaking applications many times, I'd prefer to break once.
> >> Therefore, applications could do a simple global rte_ -> dpdk_
> >> substitute:
> >> it doesn't sound that painful then.
>

+1

Either all types and symbols use dpdk_ or rte_. It probably makes more
sense dpdk_, but to me it is not that important.

If it has to be changed, it might be a good idea to do it in this release,
now that version numbering format also changes.

>
> > I concur. If (and I think that should be a pretty big IF) the prefix is
> > to be changed then its better done in one fast sweep than gradually.
> >
> > Gratuitious (or nearly so) change is always extremely annoying, and the
> > longer it takes the more painful it is. Application developers wont much
> > care what the prefix is as long as its consistent, but if they're forced
> > to track prefix changes across several releases with different libraries
> > moving at different pace, they WILL be calling for bloody murder :)
>
> How about the idea of creating (at switch over time) an optionally
> installable dpdk_compat package that just has a list of #defines for the
> old symbols pointing them at the new symbols? That would also allow
> people with old applications to update DPDK without having to modify
> their applications.
>

You would also have to add all typedefs for type names.

Why bothering? Moving from 2.2 to 16.04 requires recompiling your
application (ABI changes), and is as simple as sed -e 's/rte_/dpdk_/g' in
all the application code base.

Marc


>
> Thanks,
> Dave.
>
> --
> Dave Neary - NFV/SDN Community Strategy
> Open Source and Standards, Red Hat - http://community.redhat.com
> Ph: +1-978-399-2182 / Cell: +1-978-799-3338
>

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor
  2016-04-06  6:53 15% [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor Yuanhan Liu
@ 2016-04-07  7:12  7% ` Panu Matilainen
  2016-04-10  9:58  4%   ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-04-07  7:12 UTC (permalink / raw)
  To: Yuanhan Liu, dev; +Cc: huawei.xie, Thomas Monjalon, Ilya Maximets

On 04/06/2016 09:53 AM, Yuanhan Liu wrote:
> We currently exposed way too many fields (or even structures) than
> necessary. For example, vhost_virtqueue struct should NOT be exposed
> to user at all: application just need to tell the right queue id to
> locate a specific queue, and that's all. Instead, the structure should
> be defined in an internal header file. With that, we could do any changes
> to it we want, without worrying about that we may offense the painful
> ABI rules.
>
> Similar changes could be done to virtio_net struct as well, just exposing
> very few fields that are necessary and moving all others to an internal
> structure.
>
> Huawei then suggested a more radical yet much cleaner one: just exposing
> a virtio_net handle to application, just like the way kernel exposes an
> fd to user for locating a specific file, and exposing some new functions
> to access those old fields, such as flags, virt_qp_nb.
>
> With this change, we're likely to be free from ABI violations forever
> (well, except when we have to extend the virtio_net_device_ops struct).
> For example, following nice cleanup would not be a blocking one then:
>
>      http://dpdk.org/ml/archives/dev/2016-February/033528.html
>
> Suggested-by: Huawei Xie <huawei.xie@intel.com>
> Cc: Ilya Maximets <i.maximets@samsung.com>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> ---
>   doc/guides/rel_notes/deprecation.rst | 7 +++++++
>   1 file changed, 7 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index ad31355..7d16d86 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -40,3 +40,10 @@ Deprecation Notices
>     The existing API will be backward compatible, but there will be new API
>     functions added to facilitate the creation of mempools using an external
>     handler. The 16.07 release will contain these changes.
> +
> +* A librte_vhost public structures refactor is planned for DPDK 16.07
> +  that requires both ABI and API change.
> +  The proposed refactor would expose DPDK vhost dev to applications as
> +  a handle, like the way kernel exposes an fd to user for locating a
> +  specific file, and to keep all major structures internally, so that
> +  we are likely to be free from ABI violations in future.
>

Acked-by: Panu Matilainen <pmatilai@redhat.com>

I applaud the initiative, public structs are by far the worst offender 
when trying to maintain a stable ABI because they're so hard to 
correctly version that hardly anybody besides glibc bothers.

	- Panu -

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-06 12:07  0%       ` Panu Matilainen
  2016-04-06 12:34  0%         ` Ananyev, Konstantin
@ 2016-04-06 14:36  0%         ` Wiles, Keith
    2 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-04-06 14:36 UTC (permalink / raw)
  To: Panu Matilainen, Yuanhan Liu, Arnon Warshavsky
  Cc: Trahe, Fiona, Thomas Monjalon, dev

>On 04/06/2016 08:26 AM, Yuanhan Liu wrote:
>> On Tue, Apr 05, 2016 at 05:31:22PM +0300, Arnon Warshavsky wrote:
>>> On Tue, Apr 5, 2016 at 5:13 PM, Trahe, Fiona <fiona.trahe@intel.com> wrote:
>>>
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
>>>>> Sent: Tuesday, April 05, 2016 2:57 PM
>>>>> To: dev@dpdk.org
>>>>> Subject: [dpdk-dev] DPDK namespace
>>>>>
>>>>> DPDK is going to be more popular in Linux distributions.
>>>>> It means people will have some DPDK files in their /usr/include and some
>>>> DPDK
>>>>> libraries on their system.
>>>>>
>>>>> Let's imagine someone trying to compile an application which needs
>>>>> rte_ethdev.h. He has to figure out that this "rte header" is provided by
>>>> the DPDK.
>>>>> Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
>>>>> Then someone else will try to run a binary without having installed the
>>>> DPDK
>>>>> libraries. The linker will require libethdev.so (no prefix here).
>>>>> StackOverflow will probably have another good answer (among wrong ones):
>>>>> "Hey Sherlock Holmes, have you tried to install the DPDK library?"
>>>>> Followed by an insight: "You know, the DPDK naming is weird..."
>>>>> And we could continue the story with developers having some naming clash
>>>>> because of some identifiers not prefixed at all.
>>>>>
>>>>> The goal of this email is to get some feedback on how important it is to
>>>> fix the
>>>>> DPDK namespace.
>>>>>
>>>>> If there is enough agreement that we should do something, I suggest to
>>>>> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
>>>>> during some time.
>>>>> We could start using the new prefix for the new APIs (example: crypto)
>>>> or when
>>>>> there is a significant API break (example: mempool).
>>>>>
>>>>> Opinions welcome!
>>>> I don't have an opinion on how important it is to fix the namespace,
>>>> though it does seem like a good idea.
>>>> However if it's to be done, in my opinion it should be completed quickly
>>>> or will just cause more confusion.
>>>> So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should
>>>> follow in next release or two, with
>>>> the resulting ABI compatibility handling. Maybe with dual naming handled
>>>> for several releases, but a
>>>> clear end date when all are converted.
>>>> Else there will be many years with a mix of rte_ and dpdk_
>>>>
>>>>
>>>
>>> Googling rte functions or error codes usually takes you to dpdk dev email
>>> archive so I don't think it is that much difficult to figure out where rte
>>> comes from.
>>> Other than that , except for my own refactoring pains when replacing a dpdk
>>> version, I do not see a major reason why not.
>>> If Going for dpdk_ prefix, I agree with the quick death approach.
>>
>> +1: it's a bit weird to keep both, especially for a long while, that
>> every time we turn a rte_ prefix to dpdk_ prefix, we break applications.
>> Instead of breaking applications many times, I'd prefer to break once.
>> Therefore, applications could do a simple global rte_ -> dpdk_ substitute:
>> it doesn't sound that painful then.
>
>I concur. If (and I think that should be a pretty big IF) the prefix is 
>to be changed then its better done in one fast sweep than gradually.
>
>Gratuitious (or nearly so) change is always extremely annoying, and the 
>longer it takes the more painful it is. Application developers wont much 
>care what the prefix is as long as its consistent, but if they're forced 
>to track prefix changes across several releases with different libraries 
>moving at different pace, they WILL be calling for bloody murder :)
>
>As for rte_ being strange for DPDK - yes it is, but it takes like 5 
>minutes to get over it. It would help to have it explained on dpdk.org 
>FAQ: "Due to historical reasons, DPDK libraries are prefixed rte_ 
>instead of dpdk_ because <insert excuse here, probably early project 
>name> and changing it is unnecessarily painful."

As I understand RTE is from the “Run Time Environment” which was the primary set of API’s at the time and it just kept getting propagated :-)

>
>>
>> And here are few more comments:
>>
>> - we should add rte_/dpdk_ prefix to all public structures as well.
>>
>>    I'm thinking we are doing well here. I'm just aware that vhost lib
>>    does a bad job, which is something I proposed to fix in next release.
>
>Yup, all public symbols should be prefixed. What the exact prefix is 
>isn't that important really.
>
>>
>> - If we do the whole change once, I'd suggest to do it ASAP when this
>>    release is over.
>>
>>    It should be a HUGE change that touches a lot of code, if we do it
>>    later, at a stage that a lot of patches for new features have been
>>    made or sent out, all of them need rebase. That'd be painful.
>
>Nod, that's yet another aspect to consider.
>
>So to summarize, I'm not strongly opposed to doing a one-time mass rte_ 
>-> dpdk_ prefix change, but it needs to be one big sweep all at once, or 
>not do it at all. Gradual change is a suicide.
>
>Keeping rte_ is not the end of the world by any means, especially when 
>applied consistently and explained someplace.

To me rte_ is just fine, plus we have to change the structures names and defines names. I am sure we can figure out a script to convert any app for the developer, but why change. The rte_ prefix is something which can be explained and dpdk_ adds one character to type :-)

>
>	- Panu -
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-05 17:58  9% [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07 Harry van Haaren
  2016-04-05 18:45  0% ` Thomas Monjalon
@ 2016-04-06 14:00  0% ` David Harton (dharton)
  1 sibling, 0 replies; 200+ results
From: David Harton (dharton) @ 2016-04-06 14:00 UTC (permalink / raw)
  To: Harry van Haaren, dev; +Cc: maryam.tahhan


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Tuesday, April 05, 2016 1:58 PM
> To: dev@dpdk.org
> Cc: maryam.tahhan@intel.com; Harry van Haaren <harry.van.haaren@intel.com>
> Subject: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
> 
> This patch adds a notice that the API for the xstats functionality will be
> modified in the 16.07 release, with no backwards compatibility planned as
> it would require code duplication in each PMD that supports xstats.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---
>  doc/guides/rel_notes/deprecation.rst | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> index 98d5529..13c3a95 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -54,3 +54,8 @@ Deprecation Notices
>    induce a modification of the rte_mempool structure, plus a
>    modification of the API of rte_mempool_obj_iter(), implying a breakage
>    of the ABI.
> +
> +* ABI change is planned for the xstats API and rte_eth_xstats struct,
> +to
> +  facilitate updating to an API that allows retrieval of values without
> +any
> +  string copies or parsing. No backwards compatibility is planned, as
> +it would
> +  require code duplication in every PMD that supports xstats.
> --
> 2.5.0

Acked-by: David Harton <dharton@cisco.com>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-06 12:14  0%         ` Thomas Monjalon
@ 2016-04-06 13:49  0%           ` David Harton (dharton)
  0 siblings, 0 replies; 200+ results
From: David Harton (dharton) @ 2016-04-06 13:49 UTC (permalink / raw)
  To: Thomas Monjalon, Van Haaren, Harry; +Cc: dev, Tahhan, Maryam, olivier.matz



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, April 06, 2016 8:14 AM
> To: Van Haaren, Harry <harry.van.haaren@intel.com>
> Cc: David Harton (dharton) <dharton@cisco.com>; dev@dpdk.org; Tahhan,
> Maryam <maryam.tahhan@intel.com>; olivier.matz@6wind.com
> Subject: Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
> 
> 2016-04-06 11:16, Van Haaren, Harry:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > The issue we are going to fix is that currently PMDs copy strings
> > > > when retrieving
> > > statistics, which causes unnecessary overhead. The implementation is
> > > not decided yet, but using an int->value mapping seems logical.
> >
> > > I am not sure performance is so much critical when retrieving
> statistics.
> >
> > In the previous discussion David was concerned about performance
> > impact of string copies, are those concerns still present David?
> >
> > > The extended stats can be infinitely extended. So a string
> > > identifier seems a lot more natural.
> >
> > I'm not suggesting that the string identifier is removed totally.
> >
> > > I do not agree to add a new numeric identifier in the API each time
> > > a driver wants to report a specific statistic for debugging purpose.
> >
> > And I agree - the ints are just an index to xstats arrays, no eth-dev
> wide enums here.

Yes, I abandoned the idea of a set of stats ids.  I can see where registration will be problematic and cumbersome to driver developers.

> > The proposal is to make the API more flexible, see example:
> > http://thread.gmane.org/gmane.comp.networking.dpdk.devel/31728/focus=3
> > 2795
> >
> > This more flexible API would allow other types of information about
> > statistics be retrieved too.

I have prototyped this.  If there is interest/acceptance I can work on making an official patch to share back to the community.

Using this method still gives the flexibility the current API desires while giving the user the control to only obtain the counters.  This of course assumes that the counters per device are static but that seems a safe bet.

> 
> OK I think I start to understand.
> 
> > For now, the sent patch announces that the API/ABI may change, and we
> > can discuss details of API as development starts.
> 
> This should not be the normal process.
> It is important to understand what should be the changes to decide of
> announcing or not a deprecation.
> In the case of the mempool reworks, the patch have been sent and discussed
> on the mailing list.
> Given the previous explanations (and knowing you did good job on stats), I
> give my
> Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Thanks for considering this.

Regards,
Dave

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-06 12:07  0%       ` Panu Matilainen
@ 2016-04-06 12:34  0%         ` Ananyev, Konstantin
  2016-04-06 14:36  0%         ` Wiles, Keith
    2 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2016-04-06 12:34 UTC (permalink / raw)
  To: Panu Matilainen, Yuanhan Liu, Arnon Warshavsky
  Cc: Trahe, Fiona, Thomas Monjalon, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Panu Matilainen
> Sent: Wednesday, April 06, 2016 1:08 PM
> To: Yuanhan Liu; Arnon Warshavsky
> Cc: Trahe, Fiona; Thomas Monjalon; dev@dpdk.org
> Subject: Re: [dpdk-dev] DPDK namespace
> 
> On 04/06/2016 08:26 AM, Yuanhan Liu wrote:
> > On Tue, Apr 05, 2016 at 05:31:22PM +0300, Arnon Warshavsky wrote:
> >> On Tue, Apr 5, 2016 at 5:13 PM, Trahe, Fiona <fiona.trahe@intel.com> wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> >>>> Sent: Tuesday, April 05, 2016 2:57 PM
> >>>> To: dev@dpdk.org
> >>>> Subject: [dpdk-dev] DPDK namespace
> >>>>
> >>>> DPDK is going to be more popular in Linux distributions.
> >>>> It means people will have some DPDK files in their /usr/include and some
> >>> DPDK
> >>>> libraries on their system.
> >>>>
> >>>> Let's imagine someone trying to compile an application which needs
> >>>> rte_ethdev.h. He has to figure out that this "rte header" is provided by
> >>> the DPDK.
> >>>> Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
> >>>> Then someone else will try to run a binary without having installed the
> >>> DPDK
> >>>> libraries. The linker will require libethdev.so (no prefix here).
> >>>> StackOverflow will probably have another good answer (among wrong ones):
> >>>> "Hey Sherlock Holmes, have you tried to install the DPDK library?"
> >>>> Followed by an insight: "You know, the DPDK naming is weird..."
> >>>> And we could continue the story with developers having some naming clash
> >>>> because of some identifiers not prefixed at all.
> >>>>
> >>>> The goal of this email is to get some feedback on how important it is to
> >>> fix the
> >>>> DPDK namespace.
> >>>>
> >>>> If there is enough agreement that we should do something, I suggest to
> >>>> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
> >>>> during some time.
> >>>> We could start using the new prefix for the new APIs (example: crypto)
> >>> or when
> >>>> there is a significant API break (example: mempool).
> >>>>
> >>>> Opinions welcome!
> >>> I don't have an opinion on how important it is to fix the namespace,
> >>> though it does seem like a good idea.
> >>> However if it's to be done, in my opinion it should be completed quickly
> >>> or will just cause more confusion.
> >>> So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should
> >>> follow in next release or two, with
> >>> the resulting ABI compatibility handling. Maybe with dual naming handled
> >>> for several releases, but a
> >>> clear end date when all are converted.
> >>> Else there will be many years with a mix of rte_ and dpdk_
> >>>
> >>>
> >>
> >> Googling rte functions or error codes usually takes you to dpdk dev email
> >> archive so I don't think it is that much difficult to figure out where rte
> >> comes from.
> >> Other than that , except for my own refactoring pains when replacing a dpdk
> >> version, I do not see a major reason why not.
> >> If Going for dpdk_ prefix, I agree with the quick death approach.
> >
> > +1: it's a bit weird to keep both, especially for a long while, that
> > every time we turn a rte_ prefix to dpdk_ prefix, we break applications.
> > Instead of breaking applications many times, I'd prefer to break once.
> > Therefore, applications could do a simple global rte_ -> dpdk_ substitute:
> > it doesn't sound that painful then.
> 
> I concur. If (and I think that should be a pretty big IF) the prefix is
> to be changed then its better done in one fast sweep than gradually.
> 
> Gratuitious (or nearly so) change is always extremely annoying, and the
> longer it takes the more painful it is. Application developers wont much
> care what the prefix is as long as its consistent, but if they're forced
> to track prefix changes across several releases with different libraries
> moving at different pace, they WILL be calling for bloody murder :)
> 
> As for rte_ being strange for DPDK - yes it is, but it takes like 5
> minutes to get over it. It would help to have it explained on dpdk.org
> FAQ: "Due to historical reasons, DPDK libraries are prefixed rte_
> instead of dpdk_ because <insert excuse here, probably early project
> name> and changing it is unnecessarily painful."
> 
> >
> > And here are few more comments:
> >
> > - we should add rte_/dpdk_ prefix to all public structures as well.
> >
> >    I'm thinking we are doing well here. I'm just aware that vhost lib
> >    does a bad job, which is something I proposed to fix in next release.
> 
> Yup, all public symbols should be prefixed. What the exact prefix is
> isn't that important really.
> 
> >
> > - If we do the whole change once, I'd suggest to do it ASAP when this
> >    release is over.
> >
> >    It should be a HUGE change that touches a lot of code, if we do it
> >    later, at a stage that a lot of patches for new features have been
> >    made or sent out, all of them need rebase. That'd be painful.
> 
> Nod, that's yet another aspect to consider.
> 
> So to summarize, I'm not strongly opposed to doing a one-time mass rte_
> -> dpdk_ prefix change, but it needs to be one big sweep all at once, or
> not do it at all. Gradual change is a suicide.
> 
> Keeping rte_ is not the end of the world by any means, especially when
> applied consistently and explained someplace.
> 

Yep, I have exactly the same thoughts:
1. Yes, dpdk_'  prefix is a better naming approach than 'rte_',
but for me not that better to overweight all the pain of such big change.
2. If we still decide to do that change - my preference would be to do it in one go. 
I personally don't care that much what the prefix would be, as long as it is consistent
across the whole codebase. 
Konstantin


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-06 11:16  3%       ` Van Haaren, Harry
@ 2016-04-06 12:14  0%         ` Thomas Monjalon
  2016-04-06 13:49  0%           ` David Harton (dharton)
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-06 12:14 UTC (permalink / raw)
  To: Van Haaren, Harry
  Cc: 'David Harton (dharton)', dev, Tahhan, Maryam, olivier.matz

2016-04-06 11:16, Van Haaren, Harry:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > The issue we are going to fix is that currently PMDs copy strings when retrieving
> > statistics, which causes unnecessary overhead. The implementation is not decided yet, but
> > using an int->value mapping seems logical.
> 
> > I am not sure performance is so much critical when retrieving statistics.
> 
> In the previous discussion David was concerned about performance impact
> of string copies, are those concerns still present David?
> 
> > The extended stats can be infinitely extended. So a string identifier seems
> > a lot more natural.
> 
> I'm not suggesting that the string identifier is removed totally.
> 
> > I do not agree to add a new numeric identifier in the API each time a driver
> > wants to report a specific statistic for debugging purpose. 
> 
> And I agree - the ints are just an index to xstats arrays, no eth-dev wide enums here.
> The proposal is to make the API more flexible, see example:
> http://thread.gmane.org/gmane.comp.networking.dpdk.devel/31728/focus=32795
> 
> This more flexible API would allow other types of information about
> statistics be retrieved too.

OK I think I start to understand.

> For now, the sent patch announces that the API/ABI may change, and we can
> discuss details of API as development starts.

This should not be the normal process.
It is important to understand what should be the changes to decide of
announcing or not a deprecation.
In the case of the mempool reworks, the patch have been sent and discussed
on the mailing list.
Given the previous explanations (and knowing you did good job on stats),
I give my
Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-06  5:26  0%     ` Yuanhan Liu
@ 2016-04-06 12:07  0%       ` Panu Matilainen
  2016-04-06 12:34  0%         ` Ananyev, Konstantin
                           ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Panu Matilainen @ 2016-04-06 12:07 UTC (permalink / raw)
  To: Yuanhan Liu, Arnon Warshavsky; +Cc: Trahe, Fiona, Thomas Monjalon, dev

On 04/06/2016 08:26 AM, Yuanhan Liu wrote:
> On Tue, Apr 05, 2016 at 05:31:22PM +0300, Arnon Warshavsky wrote:
>> On Tue, Apr 5, 2016 at 5:13 PM, Trahe, Fiona <fiona.trahe@intel.com> wrote:
>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
>>>> Sent: Tuesday, April 05, 2016 2:57 PM
>>>> To: dev@dpdk.org
>>>> Subject: [dpdk-dev] DPDK namespace
>>>>
>>>> DPDK is going to be more popular in Linux distributions.
>>>> It means people will have some DPDK files in their /usr/include and some
>>> DPDK
>>>> libraries on their system.
>>>>
>>>> Let's imagine someone trying to compile an application which needs
>>>> rte_ethdev.h. He has to figure out that this "rte header" is provided by
>>> the DPDK.
>>>> Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
>>>> Then someone else will try to run a binary without having installed the
>>> DPDK
>>>> libraries. The linker will require libethdev.so (no prefix here).
>>>> StackOverflow will probably have another good answer (among wrong ones):
>>>> "Hey Sherlock Holmes, have you tried to install the DPDK library?"
>>>> Followed by an insight: "You know, the DPDK naming is weird..."
>>>> And we could continue the story with developers having some naming clash
>>>> because of some identifiers not prefixed at all.
>>>>
>>>> The goal of this email is to get some feedback on how important it is to
>>> fix the
>>>> DPDK namespace.
>>>>
>>>> If there is enough agreement that we should do something, I suggest to
>>>> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
>>>> during some time.
>>>> We could start using the new prefix for the new APIs (example: crypto)
>>> or when
>>>> there is a significant API break (example: mempool).
>>>>
>>>> Opinions welcome!
>>> I don't have an opinion on how important it is to fix the namespace,
>>> though it does seem like a good idea.
>>> However if it's to be done, in my opinion it should be completed quickly
>>> or will just cause more confusion.
>>> So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should
>>> follow in next release or two, with
>>> the resulting ABI compatibility handling. Maybe with dual naming handled
>>> for several releases, but a
>>> clear end date when all are converted.
>>> Else there will be many years with a mix of rte_ and dpdk_
>>>
>>>
>>
>> Googling rte functions or error codes usually takes you to dpdk dev email
>> archive so I don't think it is that much difficult to figure out where rte
>> comes from.
>> Other than that , except for my own refactoring pains when replacing a dpdk
>> version, I do not see a major reason why not.
>> If Going for dpdk_ prefix, I agree with the quick death approach.
>
> +1: it's a bit weird to keep both, especially for a long while, that
> every time we turn a rte_ prefix to dpdk_ prefix, we break applications.
> Instead of breaking applications many times, I'd prefer to break once.
> Therefore, applications could do a simple global rte_ -> dpdk_ substitute:
> it doesn't sound that painful then.

I concur. If (and I think that should be a pretty big IF) the prefix is 
to be changed then its better done in one fast sweep than gradually.

Gratuitious (or nearly so) change is always extremely annoying, and the 
longer it takes the more painful it is. Application developers wont much 
care what the prefix is as long as its consistent, but if they're forced 
to track prefix changes across several releases with different libraries 
moving at different pace, they WILL be calling for bloody murder :)

As for rte_ being strange for DPDK - yes it is, but it takes like 5 
minutes to get over it. It would help to have it explained on dpdk.org 
FAQ: "Due to historical reasons, DPDK libraries are prefixed rte_ 
instead of dpdk_ because <insert excuse here, probably early project 
name> and changing it is unnecessarily painful."

>
> And here are few more comments:
>
> - we should add rte_/dpdk_ prefix to all public structures as well.
>
>    I'm thinking we are doing well here. I'm just aware that vhost lib
>    does a bad job, which is something I proposed to fix in next release.

Yup, all public symbols should be prefixed. What the exact prefix is 
isn't that important really.

>
> - If we do the whole change once, I'd suggest to do it ASAP when this
>    release is over.
>
>    It should be a HUGE change that touches a lot of code, if we do it
>    later, at a stage that a lot of patches for new features have been
>    made or sent out, all of them need rebase. That'd be painful.

Nod, that's yet another aspect to consider.

So to summarize, I'm not strongly opposed to doing a one-time mass rte_ 
-> dpdk_ prefix change, but it needs to be one big sweep all at once, or 
not do it at all. Gradual change is a suicide.

Keeping rte_ is not the end of the world by any means, especially when 
applied consistently and explained someplace.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-06  9:22  0%     ` Thomas Monjalon
@ 2016-04-06 11:16  3%       ` Van Haaren, Harry
  2016-04-06 12:14  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Van Haaren, Harry @ 2016-04-06 11:16 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: 'David Harton (dharton)', dev, Tahhan, Maryam, olivier.matz

> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Subject: Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
> > The issue we are going to fix is that currently PMDs copy strings when retrieving
> statistics, which causes unnecessary overhead. The implementation is not decided yet, but
> using an int->value mapping seems logical.

> I am not sure performance is so much critical when retrieving statistics.

In the previous discussion David was concerned about performance impact
of string copies, are those concerns still present David?

> The extended stats can be infinitely extended. So a string identifier seems
> a lot more natural.

I'm not suggesting that the string identifier is removed totally.

> I do not agree to add a new numeric identifier in the API each time a driver
> wants to report a specific statistic for debugging purpose. 

And I agree - the ints are just an index to xstats arrays, no eth-dev wide enums here.
The proposal is to make the API more flexible, see example:
http://thread.gmane.org/gmane.comp.networking.dpdk.devel/31728/focus=32795

This more flexible API would allow other types of information about
statistics be retrieved too.

For now, the sent patch announces that the API/ABI may change, and we can
discuss details of API as development starts.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] Fw: dpdk-armv7-testing - Build # 43 - Failure!
  @ 2016-04-06 10:18  4%   ` Jan Viktorin
  0 siblings, 0 replies; 200+ results
From: Jan Viktorin @ 2016-04-06 10:18 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Adrien Mazarguil

On Wed, 06 Apr 2016 12:05:31 +0200
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:

> Hi Jan,
> 
> 2016-04-06 11:53, Jan Viktorin:
> > Please, see the attached log file.  
> 
> The text attachments are filtered out on the mailing list because
> it is not convenient or impossible to read in the archives.
> Please use inline text, next time. Thanks

I am sorry, didn't notice that. Nobody has pointed to this before.

dpdk-armv7-testing - Build # 44 - Still Failing

See the following log:

[...]
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse_num.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse_num.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse_ipaddr.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse_ipaddr.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse_etheraddr.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse_etheraddr.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse_string.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse_string.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_rdline.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_rdline.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_vt100.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_vt100.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_socket.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_socket.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_cirbuf.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_cirbuf.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  SYMLINK-FILE include/cmdline_parse_portlist.h
ln -nsf `/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/scripts/relpath.sh /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_cmdline/cmdline_parse_portlist.h /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include` /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include
  INSTALL-LIB librte_cmdline.a
cp -f librte_cmdline.a /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/lib
== Build lib/librte_ether
/opt/gcc/br2-arm32-glibc-4.9.x/usr/bin/arm-buildroot-linux-gnueabi-gcc -Wp,-MD,./.rte_ethdev.o.d.tmp -mfloat-abi=softfp -mfloat-abi=softfp -mfloat-abi=softfp -pthread  -march=armv7-a -mtune=cortex-a9 -mfpu=neon -DRTE_MACHINE_CPUFLAG_NEON  -I/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include -include /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/build/include/rte_config.h -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Werror -Wno-error=cast-align   -o rte_ethdev.o -c /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_ether/rte_ethdev.c 
In file included from /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_ether/rte_ethdev.h:186:0,
                 from /var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_ether/rte_ethdev.c:70:
/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_ether/rte_eth_ctrl.h:39:23: fatal error: rte_ether.h: No such file or directory
 #include <rte_ether.h>
                       ^
compilation terminated.
make[3]: *** [rte_ethdev.o] Error 1
make[2]: *** [librte_ether] Error 2
make[1]: *** [lib] Error 2
make: *** [all] Error 2
Build step 'Execute shell' marked build as failure
[WARNINGS] Skipping publisher since build result is FAILURE
Skipped archiving because build is not successful
Email was triggered for: Failure - Any
Sending email for trigger: Failure - Any


-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  9:16  3%           ` Weglicki, MichalX
@ 2016-04-06  9:34  3%             ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-06  9:34 UTC (permalink / raw)
  To: Weglicki, MichalX
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

2016-04-06 09:16, Weglicki, MichalX:
> Hello, 
> 
> Thank you for your answer. 
> 
> I didn't mention that patch is cosmetic, rather naming. 
> 
> But all clear, I somehow missed it 9 months ago, and couldn't find it. 
> 
> Is there any official place where I can find upcoming ABI & API changes, or I have to dig through mailing list? 

Yes, the API and ABI changes are described in the release notes:
	http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst#n471
And the next deprecations are announced in another section:
	http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/deprecation.rst

PS: please answer inline

-----------------
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com] 
> 2016-04-06 08:34, Weglicki, MichalX:
> > Hello, 
> > 
> > I have a question about this patch. 
> > 
> > As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 
> 
> No.
> ETH_LINK_SPEED was used for configuration and reported speed.
> Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
> and the old numerical values are kept for other usages as ETH_SPEED_NUM.
> 
> > Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 
> 
> Yes that's why this change was discussed 9 months ago and announced in the
> previous release notes.
> 
> > It would be great to keep ABI & API stable if possible.
> 
> We try to keep it stable when possible and continue to bring some improvements.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-06  9:02  0%   ` Van Haaren, Harry
@ 2016-04-06  9:22  0%     ` Thomas Monjalon
  2016-04-06 11:16  3%       ` Van Haaren, Harry
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-06  9:22 UTC (permalink / raw)
  To: Van Haaren, Harry
  Cc: 'David Harton (dharton)', dev, Tahhan, Maryam, olivier.matz

2016-04-06 09:02, Van Haaren, Harry:
> + David Harton,
> 
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Subject: Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
> > 2016-04-05 18:58, Harry van Haaren:
> > > +* ABI change is planned for the xstats API
> 
> > Have you already submitted a RFC patch to let us have an opinion on the change?
> > We need, at least, to see the structure changes.
> 
> This API break is to allow changing the API of xstats given the conversation that was on-list, as discussed in this thread:
> 
> http://thread.gmane.org/gmane.comp.networking.dpdk.devel/31728/focus=31903
> 
> The issue we are going to fix is that currently PMDs copy strings when retrieving statistics, which causes unnecessary overhead. The implementation is not decided yet, but using an int->value mapping seems logical.

I am not sure performance is so much critical when retrieving statistics.
The extended stats can be infinitely extended. So a string identifier seems
a lot more natural.
I do not agree to add a new numeric identifier in the API each time a driver
wants to report a specific statistic for debugging purpose.

> The rte_eth_xstats struct size may be modified, and the API to retrieve statistics will be modified.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  8:52  0%         ` Thomas Monjalon
@ 2016-04-06  9:16  3%           ` Weglicki, MichalX
  2016-04-06  9:34  3%             ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Weglicki, MichalX @ 2016-04-06  9:16 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

Hello, 

Thank you for your answer. 

I didn't mention that patch is cosmetic, rather naming. 

But all clear, I somehow missed it 9 months ago, and couldn't find it. 

Is there any official place where I can find upcoming ABI & API changes, or I have to dig through mailing list? 

Thank you in advance. 

Br, 
Michal. 

-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com] 
Sent: Wednesday, April 6, 2016 9:53 AM
To: Weglicki, MichalX <michalx.weglicki@intel.com>
Cc: Marc Sune <marcdevel@gmail.com>; Xu, Qian Q <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>; Gray, Mark D <mark.d.gray@intel.com>
Subject: Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants

2016-04-06 08:34, Weglicki, MichalX:
> Hello, 
> 
> I have a question about this patch. 
> 
> As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

No.
ETH_LINK_SPEED was used for configuration and reported speed.
Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
and the old numerical values are kept for other usages as ETH_SPEED_NUM.

> Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

Yes that's why this change was discussed 9 months ago and announced in the
previous release notes.

> It would be great to keep ABI & API stable if possible.

We try to keep it stable when possible and continue to bring some improvements.

--------------------------------------------------------------
Intel Research and Development Ireland Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263


This e-mail and any attachments may contain confidential material for the sole
use of the intended recipient(s). Any review or distribution by others is
strictly prohibited. If you are not the intended recipient, please contact the
sender and delete all copies.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-05 18:45  0% ` Thomas Monjalon
@ 2016-04-06  9:02  0%   ` Van Haaren, Harry
  2016-04-06  9:22  0%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Van Haaren, Harry @ 2016-04-06  9:02 UTC (permalink / raw)
  To: Thomas Monjalon, 'David Harton (dharton)'; +Cc: dev, Tahhan, Maryam

+ David Harton,

> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Subject: Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
> 2016-04-05 18:58, Harry van Haaren:
> > +* ABI change is planned for the xstats API

> Have you already submitted a RFC patch to let us have an opinion on the change?
> We need, at least, to see the structure changes.

This API break is to allow changing the API of xstats given the conversation that was on-list, as discussed in this thread:

http://thread.gmane.org/gmane.comp.networking.dpdk.devel/31728/focus=31903

The issue we are going to fix is that currently PMDs copy strings when retrieving statistics, which causes unnecessary overhead. The implementation is not decided yet, but using an int->value mapping seems logical.

The rte_eth_xstats struct size may be modified, and the API to retrieve statistics will be modified.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  8:34  2%       ` Weglicki, MichalX
@ 2016-04-06  8:52  0%         ` Thomas Monjalon
  2016-04-06  9:16  3%           ` Weglicki, MichalX
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-06  8:52 UTC (permalink / raw)
  To: Weglicki, MichalX
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

2016-04-06 08:34, Weglicki, MichalX:
> Hello, 
> 
> I have a question about this patch. 
> 
> As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

No.
ETH_LINK_SPEED was used for configuration and reported speed.
Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
and the old numerical values are kept for other usages as ETH_SPEED_NUM.

> Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

Yes that's why this change was discussed 9 months ago and announced in the
previous release notes.

> It would be great to keep ABI & API stable if possible.

We try to keep it stable when possible and continue to bring some improvements.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
  2016-04-05 21:16  4% ` Singh, Jasvinder
@ 2016-04-06  8:51  4%   ` Azarewicz, PiotrX T
  2016-04-07 21:24  4%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Azarewicz, PiotrX T @ 2016-04-06  8:51 UTC (permalink / raw)
  To: Singh, Jasvinder, Zhang, Roy Fan, dev

> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Fan Zhang
> > Sent: Thursday, March 31, 2016 2:29 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [PATCH] doc: announce ABI change for
> > rte_port_source_params structure
> >
> > Several new fields will be added to structure rte_port_source_params
> > for source port enhancement with pcap file reading support.
> >
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> 
> Acked-by: Jasvinder Singh <jasvinder.singh@intel.com>

Acked-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants
  @ 2016-04-06  8:34  2%       ` Weglicki, MichalX
  2016-04-06  8:52  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Weglicki, MichalX @ 2016-04-06  8:34 UTC (permalink / raw)
  To: Marc Sune, Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev,
	Ananyev, Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn,
	Michael J, Gray, Mark D

Hello, 

I have a question about this patch. 

As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

It would be great to keep ABI & API stable if possible. 

Br, 
Michal. 

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
Sent: Saturday, March 26, 2016 1:27 AM
To: Thomas Monjalon <thomas.monjalon@6wind.com>; Xu, Qian Q <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>
Cc: Marc Sune <marcdevel@gmail.com>
Subject: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/ena/ena_ethdev.c              |  2 +-
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 20 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index eb7bbb4..815b53b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1006,20 +1006,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index fad8f2f..473d77f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4dfa7e3..86f25f6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1244,7 +1244,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1254,7 +1254,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1264,14 +1264,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 325c513..1046286 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -504,7 +504,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link *link = &dev->data->dev_link;
 
 	link->link_status = 1;
-	link->link_speed = ETH_LINK_SPEED_10G;
+	link->link_speed = ETH_SPEED_NUM_10G;
 	link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	return 0;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 05126e8..cce9e6f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1386,19 +1386,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1768,7 +1768,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1790,22 +1790,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8158,15 +8158,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 91df13b..295dcd2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2126,7 +2126,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 21a3b8c..a0179d2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2199,17 +2199,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3074,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3095,19 +3095,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5909,15 +5909,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index d93ab7e..1a77c7a 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 80dda85..18ea0f4 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 47aa7e3..dd1ae9e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3f26217..6afa14e 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,7 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2d13f92..bc7d607 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
+#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
+#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
+#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
+#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
+#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
+#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
+#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
+#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.1.4

--------------------------------------------------------------
Intel Research and Development Ireland Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263


This e-mail and any attachments may contain confidential material for the sole
use of the intended recipient(s). Any review or distribution by others is
strictly prohibited. If you are not the intended recipient, please contact the
sender and delete all copies.

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor
@ 2016-04-06  6:53 15% Yuanhan Liu
  2016-04-07  7:12  7% ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Yuanhan Liu @ 2016-04-06  6:53 UTC (permalink / raw)
  To: dev; +Cc: huawei.xie, Thomas Monjalon, Yuanhan Liu, Ilya Maximets

We currently exposed way too many fields (or even structures) than
necessary. For example, vhost_virtqueue struct should NOT be exposed
to user at all: application just need to tell the right queue id to
locate a specific queue, and that's all. Instead, the structure should
be defined in an internal header file. With that, we could do any changes
to it we want, without worrying about that we may offense the painful
ABI rules.

Similar changes could be done to virtio_net struct as well, just exposing
very few fields that are necessary and moving all others to an internal
structure.

Huawei then suggested a more radical yet much cleaner one: just exposing
a virtio_net handle to application, just like the way kernel exposes an
fd to user for locating a specific file, and exposing some new functions
to access those old fields, such as flags, virt_qp_nb.

With this change, we're likely to be free from ABI violations forever
(well, except when we have to extend the virtio_net_device_ops struct).
For example, following nice cleanup would not be a blocking one then:

    http://dpdk.org/ml/archives/dev/2016-February/033528.html

Suggested-by: Huawei Xie <huawei.xie@intel.com>
Cc: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ad31355..7d16d86 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -40,3 +40,10 @@ Deprecation Notices
   The existing API will be backward compatible, but there will be new API
   functions added to facilitate the creation of mempools using an external
   handler. The 16.07 release will contain these changes.
+
+* A librte_vhost public structures refactor is planned for DPDK 16.07
+  that requires both ABI and API change.
+  The proposed refactor would expose DPDK vhost dev to applications as
+  a handle, like the way kernel exposes an fd to user for locating a
+  specific file, and to keep all major structures internally, so that
+  we are likely to be free from ABI violations in future.
-- 
1.9.0

^ permalink raw reply	[relevance 15%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-05 14:31  0%   ` Arnon Warshavsky
@ 2016-04-06  5:26  0%     ` Yuanhan Liu
  2016-04-06 12:07  0%       ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Yuanhan Liu @ 2016-04-06  5:26 UTC (permalink / raw)
  To: Arnon Warshavsky; +Cc: Trahe, Fiona, Thomas Monjalon, dev

On Tue, Apr 05, 2016 at 05:31:22PM +0300, Arnon Warshavsky wrote:
> On Tue, Apr 5, 2016 at 5:13 PM, Trahe, Fiona <fiona.trahe@intel.com> wrote:
> 
> >
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > > Sent: Tuesday, April 05, 2016 2:57 PM
> > > To: dev@dpdk.org
> > > Subject: [dpdk-dev] DPDK namespace
> > >
> > > DPDK is going to be more popular in Linux distributions.
> > > It means people will have some DPDK files in their /usr/include and some
> > DPDK
> > > libraries on their system.
> > >
> > > Let's imagine someone trying to compile an application which needs
> > > rte_ethdev.h. He has to figure out that this "rte header" is provided by
> > the DPDK.
> > > Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
> > > Then someone else will try to run a binary without having installed the
> > DPDK
> > > libraries. The linker will require libethdev.so (no prefix here).
> > > StackOverflow will probably have another good answer (among wrong ones):
> > > "Hey Sherlock Holmes, have you tried to install the DPDK library?"
> > > Followed by an insight: "You know, the DPDK naming is weird..."
> > > And we could continue the story with developers having some naming clash
> > > because of some identifiers not prefixed at all.
> > >
> > > The goal of this email is to get some feedback on how important it is to
> > fix the
> > > DPDK namespace.
> > >
> > > If there is enough agreement that we should do something, I suggest to
> > > introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
> > > during some time.
> > > We could start using the new prefix for the new APIs (example: crypto)
> > or when
> > > there is a significant API break (example: mempool).
> > >
> > > Opinions welcome!
> > I don't have an opinion on how important it is to fix the namespace,
> > though it does seem like a good idea.
> > However if it's to be done, in my opinion it should be completed quickly
> > or will just cause more confusion.
> > So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should
> > follow in next release or two, with
> > the resulting ABI compatibility handling. Maybe with dual naming handled
> > for several releases, but a
> > clear end date when all are converted.
> > Else there will be many years with a mix of rte_ and dpdk_
> >
> >
> 
> Googling rte functions or error codes usually takes you to dpdk dev email
> archive so I don't think it is that much difficult to figure out where rte
> comes from.
> Other than that , except for my own refactoring pains when replacing a dpdk
> version, I do not see a major reason why not.
> If Going for dpdk_ prefix, I agree with the quick death approach.

+1: it's a bit weird to keep both, especially for a long while, that
every time we turn a rte_ prefix to dpdk_ prefix, we break applications.
Instead of breaking applications many times, I'd prefer to break once.
Therefore, applications could do a simple global rte_ -> dpdk_ substitute:
it doesn't sound that painful then.

And here are few more comments:

- we should add rte_/dpdk_ prefix to all public structures as well.

  I'm thinking we are doing well here. I'm just aware that vhost lib
  does a bad job, which is something I proposed to fix in next release.

- If we do the whole change once, I'd suggest to do it ASAP when this
  release is over.

  It should be a HUGE change that touches a lot of code, if we do it
  later, at a stage that a lot of patches for new features have been
  made or sent out, all of them need rebase. That'd be painful.

	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.
@ 2016-04-06  5:11  0% Ilya Maximets
  0 siblings, 0 replies; 200+ results
From: Ilya Maximets @ 2016-04-06  5:11 UTC (permalink / raw)
  To: Flavio Leitner, Yuanhan Liu
  Cc: dev, Sergey Dyasly, Thomas Monjalon, Xie, Huawei

------- Original Message -------
Sender : Flavio Leitner<fbl@sysclose.org>
Date : Apr 06, 2016 07:14 (GMT+03:00)
Title : Re: [RFC] vhost-user public struct refactor (was Re: [dpdk-dev] [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.

On Tue, Apr 05, 2016 at 01:47:33PM +0800, Yuanhan Liu wrote:
> On Fri, Feb 19, 2016 at 03:06:50PM +0800, Yuanhan Liu wrote:
> > On Fri, Feb 19, 2016 at 09:32:41AM +0300, Ilya Maximets wrote:
> > > Array of buf_vector's is just an array for temporary storing information
> > > about available descriptors. It used only locally in virtio_dev_merge_rx()
> > > and there is no reason for that array to be shared.
> > > 
> > > Fix that by allocating local buf_vec inside virtio_dev_merge_rx().
> > > 
> > > Signed-off-by: Ilya Maximets 
> > > ---
> > >  lib/librte_vhost/rte_virtio_net.h |  1 -
> > >  lib/librte_vhost/vhost_rxtx.c     | 45 ++++++++++++++++++++-------------------
> > >  2 files changed, 23 insertions(+), 23 deletions(-)
> > > 
> > > diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
> > > index 10dcb90..ae1e4fb 100644
> > > --- a/lib/librte_vhost/rte_virtio_net.h
> > > +++ b/lib/librte_vhost/rte_virtio_net.h
> > > @@ -91,7 +91,6 @@ struct vhost_virtqueue {
> > >   int kickfd; /**< Currently unused as polling mode is enabled. */
> > >   int enabled;
> > >   uint64_t reserved[16]; /**< Reserve some spaces for future extension. */
> > > - struct buf_vector buf_vec[BUF_VECTOR_MAX]; /**< for scatter RX. */
> > >  } __rte_cache_aligned;
> > 
> > I like this kind of cleanup, however, it breaks ABI.
> 
> So, I was considering to add vhost-user Tx delayed-copy (or zero copy)
> support recently, which comes to yet another ABI violation, as we need
> add a new field to virtio_memory_regions struct to do guest phys addr
> to host phys addr translation. You may ask, however, that why do we need
> expose virtio_memory_regions struct to users at all?
> 
> You are right, we don't have to. And here is the thing: we exposed way
> too many fields (or even structures) than necessary. Say, vhost_virtqueue
> struct should NOT be exposed to user at all: application just need to
> tell the right queue id to locate a specific queue, and that's all.
> The structure should be defined in an internal header file. With that,
> we could do any changes to it we want, without worrying about that we
> may offense the painful ABI rules.
> 
> Similar changes could be done to virtio_net struct as well, just exposing
> very few fields that are necessary and moving all others to an internal
> structure.
> 
> Huawei then suggested a more radical yet much cleaner one: just exposing
> a virtio_net handle to application, just like the way kernel exposes an
> fd to user for locating a specific file. However, it's more than an ABI
> change; it's also an API change: some fields are referenced by applications,
> such as flags, virt_qp_nb. We could expose some new functions to access
> them though.
> 
> I'd vote for this one, as it sounds very clean to me. This would also
> solve the block issue of this patch. Though it would break OVS, I'm thinking
> that'd be okay, as OVS has dependence on DPDK version: what we need to
> do is just to send few patches to OVS, and let it points to next release,
> say DPDK v16.07. Flavio, please correct me if I'm wrong.

> There is a plan to use vHost PMD, so from OVS point of view the virtio
> stuff would be hidden because vhost PMD would look like just as a
> regular ethernet, right?

But we still need to have access to virtqueue_enabe/disable notifications to
work properly. How this will be done if virtqueue will be hidden from user?

Best regards, Ilya Maximets.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.
  2016-04-05  5:47  4%     ` [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local Yuanhan Liu
  2016-04-05  8:37  0%       ` Thomas Monjalon
@ 2016-04-06  4:14  0%       ` Flavio Leitner
  1 sibling, 0 replies; 200+ results
From: Flavio Leitner @ 2016-04-06  4:14 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: Ilya Maximets, dev, Dyasly Sergey, Thomas Monjalon, Xie, Huawei

On Tue, Apr 05, 2016 at 01:47:33PM +0800, Yuanhan Liu wrote:
> On Fri, Feb 19, 2016 at 03:06:50PM +0800, Yuanhan Liu wrote:
> > On Fri, Feb 19, 2016 at 09:32:41AM +0300, Ilya Maximets wrote:
> > > Array of buf_vector's is just an array for temporary storing information
> > > about available descriptors. It used only locally in virtio_dev_merge_rx()
> > > and there is no reason for that array to be shared.
> > > 
> > > Fix that by allocating local buf_vec inside virtio_dev_merge_rx().
> > > 
> > > Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> > > ---
> > >  lib/librte_vhost/rte_virtio_net.h |  1 -
> > >  lib/librte_vhost/vhost_rxtx.c     | 45 ++++++++++++++++++++-------------------
> > >  2 files changed, 23 insertions(+), 23 deletions(-)
> > > 
> > > diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
> > > index 10dcb90..ae1e4fb 100644
> > > --- a/lib/librte_vhost/rte_virtio_net.h
> > > +++ b/lib/librte_vhost/rte_virtio_net.h
> > > @@ -91,7 +91,6 @@ struct vhost_virtqueue {
> > >  	int			kickfd;			/**< Currently unused as polling mode is enabled. */
> > >  	int			enabled;
> > >  	uint64_t		reserved[16];		/**< Reserve some spaces for future extension. */
> > > -	struct buf_vector	buf_vec[BUF_VECTOR_MAX];	/**< for scatter RX. */
> > >  } __rte_cache_aligned;
> > 
> > I like this kind of cleanup, however, it breaks ABI.
> 
> So, I was considering to add vhost-user Tx delayed-copy (or zero copy)
> support recently, which comes to yet another ABI violation, as we need
> add a new field to virtio_memory_regions struct to do guest phys addr
> to host phys addr translation. You may ask, however, that why do we need
> expose virtio_memory_regions struct to users at all?
> 
> You are right, we don't have to. And here is the thing: we exposed way
> too many fields (or even structures) than necessary. Say, vhost_virtqueue
> struct should NOT be exposed to user at all: application just need to
> tell the right queue id to locate a specific queue, and that's all.
> The structure should be defined in an internal header file. With that,
> we could do any changes to it we want, without worrying about that we
> may offense the painful ABI rules.
> 
> Similar changes could be done to virtio_net struct as well, just exposing
> very few fields that are necessary and moving all others to an internal
> structure.
> 
> Huawei then suggested a more radical yet much cleaner one: just exposing
> a virtio_net handle to application, just like the way kernel exposes an
> fd to user for locating a specific file. However, it's more than an ABI
> change; it's also an API change: some fields are referenced by applications,
> such as flags, virt_qp_nb. We could expose some new functions to access
> them though.
> 
> I'd vote for this one, as it sounds very clean to me. This would also
> solve the block issue of this patch. Though it would break OVS, I'm thinking
> that'd be okay, as OVS has dependence on DPDK version: what we need to
> do is just to send few patches to OVS, and let it points to next release,
> say DPDK v16.07. Flavio, please correct me if I'm wrong.

There is a plan to use vHost PMD, so from OVS point of view the virtio
stuff would be hidden because vhost PMD would look like just as a
regular ethernet, right?

I think we are waiting for 16.04 to be released with that so we can
start push changes to OVS as well.

-- 
fbl

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
  2016-03-31 13:29 16% Fan Zhang
  2016-04-05 15:45  7% ` Thomas Monjalon
@ 2016-04-05 21:16  4% ` Singh, Jasvinder
  2016-04-06  8:51  4%   ` Azarewicz, PiotrX T
  1 sibling, 1 reply; 200+ results
From: Singh, Jasvinder @ 2016-04-05 21:16 UTC (permalink / raw)
  To: Zhang, Roy Fan, dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Fan Zhang
> Sent: Thursday, March 31, 2016 2:29 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH] doc: announce ABI change for
> rte_port_source_params structure
> 
> Several new fields will be added to structure rte_port_source_params for
> source port enhancement with pcap file reading support.
> 
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Acked-by: Jasvinder Singh <jasvinder.singh@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
  2016-04-05 17:58  9% [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07 Harry van Haaren
@ 2016-04-05 18:45  0% ` Thomas Monjalon
  2016-04-06  9:02  0%   ` Van Haaren, Harry
  2016-04-06 14:00  0% ` David Harton (dharton)
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-05 18:45 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev, maryam.tahhan

2016-04-05 18:58, Harry van Haaren:
> +* ABI change is planned for the xstats API and rte_eth_xstats struct, to
> +  facilitate updating to an API that allows retrieval of values without any
> +  string copies or parsing. No backwards compatibility is planned, as it would
> +  require code duplication in every PMD that supports xstats.

Have you already submitted a RFC patch to let us have an opinion on the change?
We need, at least, to see the structure changes.
Thanks

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07
@ 2016-04-05 17:58  9% Harry van Haaren
  2016-04-05 18:45  0% ` Thomas Monjalon
  2016-04-06 14:00  0% ` David Harton (dharton)
  0 siblings, 2 replies; 200+ results
From: Harry van Haaren @ 2016-04-05 17:58 UTC (permalink / raw)
  To: dev; +Cc: maryam.tahhan, Harry van Haaren

This patch adds a notice that the API for the xstats
functionality will be modified in the 16.07 release, with
no backwards compatibility planned as it would require
code duplication in each PMD that supports xstats.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 98d5529..13c3a95 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -54,3 +54,8 @@ Deprecation Notices
   induce a modification of the rte_mempool structure, plus a
   modification of the API of rte_mempool_obj_iter(), implying a breakage
   of the ABI.
+
+* ABI change is planned for the xstats API and rte_eth_xstats struct, to
+  facilitate updating to an API that allows retrieval of values without any
+  string copies or parsing. No backwards compatibility is planned, as it would
+  require code duplication in every PMD that supports xstats.
-- 
2.5.0

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
  2016-03-31 13:29 16% Fan Zhang
@ 2016-04-05 15:45  7% ` Thomas Monjalon
  2016-04-05 21:16  4% ` Singh, Jasvinder
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-05 15:45 UTC (permalink / raw)
  To: dev; +Cc: Fan Zhang

2016-03-31 14:29, Fan Zhang:
> Several new fields will be added to structure rte_port_source_params for
> source port enhancement with pcap file reading support.
> 
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Anyone interested or against this ABI break in rte_port?
It will be accepted when having 3 acks without any nack.

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches
  2016-04-05  9:23  9% [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches Lazaros Koromilas
@ 2016-04-05 15:42  4% ` Olivier Matz
  2016-04-08 14:01  4%   ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2016-04-05 15:42 UTC (permalink / raw)
  To: Lazaros Koromilas, dev


On 04/05/2016 11:23 AM, Lazaros Koromilas wrote:
> Deprecation notice for 16.04 for changes targeting release 16.07.
> The changes affect struct rte_mempool, rte_mempool_cache and the
> mempool API.
> 
> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>

Acked-by: Olivier Matz <olivier.matz@6wind.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3] PCI: ABI change request for adding new field in rte_pci_id structure
  @ 2016-04-05 15:31  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-05 15:31 UTC (permalink / raw)
  To: Ziye Yang; +Cc: dev, Bruce Richardson

> > The purpose of this patch is used to add a new field
> > "class" in rte_pci_id structure. The new class field includes
> > class_id, subcalss_id, programming interface of a pci device.
> > With this field, we can identify pci device by its class info,
> > which can be more flexible instead of probing the device by
> > vendor_id OR device_id OR subvendor_id OR subdevice_id.
> > For example, we can probe all nvme devices by class field, which
> > can be quite convenient.
> > 
> > Signed-off-by: Ziye Yang <ziye.yang@intel.com>
> 
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> Acked-by: Helin Zhang <helin.zhang@intel.com>
> Acked-by: Cunming Liang <cunming.liang@intel.com>

Applied, thanks

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07
  2016-04-05 14:08  4%       ` Wiles, Keith
@ 2016-04-05 15:17  4%         ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-05 15:17 UTC (permalink / raw)
  To: Olivier Matz; +Cc: Wiles, Keith, Hunt, David, dev

> >>> Add a deprecation notice for coming changes in mempool for 16.07.
> >> [...]
> >>> +* librte_mempool: new fixes and features will be added in 16.07:
> >>> +  allocation of large mempool in several virtual memory chunks, new API
> >>> +  to populate a mempool, new API to free a mempool, allocation in
> >>> +  anonymous mapping, drop of specific dom0 code. These changes will
> >>> +  induce a modification of the rte_mempool structure, plus a
> >>> +  modification of the API of rte_mempool_obj_iter(), implying a breakage
> >>> +  of the ABI.
> >> Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> >>
> >> Other people involved in the discussion wanting to bring their support?
> >
> >Acked-by: David Hunt<david.hunt@intel.com>
> 
> Acked-by: Keith Wiles <keith.wiles@intel.com>

Applied, thanks

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-05 14:13  3% ` Trahe, Fiona
@ 2016-04-05 14:31  0%   ` Trahe, Fiona
  2016-04-05 14:31  0%   ` Arnon Warshavsky
  1 sibling, 0 replies; 200+ results
From: Trahe, Fiona @ 2016-04-05 14:31 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: Trahe, Fiona



> -----Original Message-----
> From: Trahe, Fiona
> Sent: Tuesday, April 05, 2016 3:13 PM
> To: Thomas Monjalon; dev@dpdk.org
> Cc: Trahe, Fiona
> Subject: RE: [dpdk-dev] DPDK namespace
> 
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > Sent: Tuesday, April 05, 2016 2:57 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] DPDK namespace
> >
> > DPDK is going to be more popular in Linux distributions.
> > It means people will have some DPDK files in their /usr/include and
> > some DPDK libraries on their system.
> >
> > Let's imagine someone trying to compile an application which needs
> > rte_ethdev.h. He has to figure out that this "rte header" is provided by the
> DPDK.
> > Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
> > Then someone else will try to run a binary without having installed
> > the DPDK libraries. The linker will require libethdev.so (no prefix here).
> > StackOverflow will probably have another good answer (among wrong ones):
> > "Hey Sherlock Holmes, have you tried to install the DPDK library?"
> > Followed by an insight: "You know, the DPDK naming is weird..."
> > And we could continue the story with developers having some naming
> > clash because of some identifiers not prefixed at all.
> >
> > The goal of this email is to get some feedback on how important it is
> > to fix the DPDK namespace.
> >
> > If there is enough agreement that we should do something, I suggest to
> > introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
> > during some time.
> > We could start using the new prefix for the new APIs (example: crypto)
> > or when there is a significant API break (example: mempool).
> >
> > Opinions welcome!
> I don't have an opinion on how important it is to fix the namespace, though it
> does seem like a good idea.
> However if it's to be done, in my opinion it should be completed quickly or will
> just cause more confusion.
> So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should follow in
> next release or two, with the resulting ABI compatibility handling. Maybe with
> dual naming handled for several releases, but a clear end date when all are
> converted.
> Else there will be many years with a mix of rte_ and dpdk_

An alternative: Would it not be better to do this as one specific 
namespace-change-only release, e.g. an extra 16.06 release, rather than bundling with functional changes?

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK namespace
  2016-04-05 14:13  3% ` Trahe, Fiona
  2016-04-05 14:31  0%   ` Trahe, Fiona
@ 2016-04-05 14:31  0%   ` Arnon Warshavsky
  2016-04-06  5:26  0%     ` Yuanhan Liu
  1 sibling, 1 reply; 200+ results
From: Arnon Warshavsky @ 2016-04-05 14:31 UTC (permalink / raw)
  To: Trahe, Fiona; +Cc: Thomas Monjalon, dev

On Tue, Apr 5, 2016 at 5:13 PM, Trahe, Fiona <fiona.trahe@intel.com> wrote:

>
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > Sent: Tuesday, April 05, 2016 2:57 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] DPDK namespace
> >
> > DPDK is going to be more popular in Linux distributions.
> > It means people will have some DPDK files in their /usr/include and some
> DPDK
> > libraries on their system.
> >
> > Let's imagine someone trying to compile an application which needs
> > rte_ethdev.h. He has to figure out that this "rte header" is provided by
> the DPDK.
> > Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
> > Then someone else will try to run a binary without having installed the
> DPDK
> > libraries. The linker will require libethdev.so (no prefix here).
> > StackOverflow will probably have another good answer (among wrong ones):
> > "Hey Sherlock Holmes, have you tried to install the DPDK library?"
> > Followed by an insight: "You know, the DPDK naming is weird..."
> > And we could continue the story with developers having some naming clash
> > because of some identifiers not prefixed at all.
> >
> > The goal of this email is to get some feedback on how important it is to
> fix the
> > DPDK namespace.
> >
> > If there is enough agreement that we should do something, I suggest to
> > introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
> > during some time.
> > We could start using the new prefix for the new APIs (example: crypto)
> or when
> > there is a significant API break (example: mempool).
> >
> > Opinions welcome!
> I don't have an opinion on how important it is to fix the namespace,
> though it does seem like a good idea.
> However if it's to be done, in my opinion it should be completed quickly
> or will just cause more confusion.
> So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should
> follow in next release or two, with
> the resulting ABI compatibility handling. Maybe with dual naming handled
> for several releases, but a
> clear end date when all are converted.
> Else there will be many years with a mix of rte_ and dpdk_
>
>

Googling rte functions or error codes usually takes you to dpdk dev email
archive so I don't think it is that much difficult to figure out where rte
comes from.
Other than that , except for my own refactoring pains when replacing a dpdk
version, I do not see a major reason why not.
If Going for dpdk_ prefix, I agree with the quick death approach.

/Arnon

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK namespace
  @ 2016-04-05 14:13  3% ` Trahe, Fiona
  2016-04-05 14:31  0%   ` Trahe, Fiona
  2016-04-05 14:31  0%   ` Arnon Warshavsky
    1 sibling, 2 replies; 200+ results
From: Trahe, Fiona @ 2016-04-05 14:13 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: Trahe, Fiona



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Tuesday, April 05, 2016 2:57 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] DPDK namespace
> 
> DPDK is going to be more popular in Linux distributions.
> It means people will have some DPDK files in their /usr/include and some DPDK
> libraries on their system.
> 
> Let's imagine someone trying to compile an application which needs
> rte_ethdev.h. He has to figure out that this "rte header" is provided by the DPDK.
> Hopefully it will be explained on StackOverflow that RTE stands for DPDK.
> Then someone else will try to run a binary without having installed the DPDK
> libraries. The linker will require libethdev.so (no prefix here).
> StackOverflow will probably have another good answer (among wrong ones):
> "Hey Sherlock Holmes, have you tried to install the DPDK library?"
> Followed by an insight: "You know, the DPDK naming is weird..."
> And we could continue the story with developers having some naming clash
> because of some identifiers not prefixed at all.
> 
> The goal of this email is to get some feedback on how important it is to fix the
> DPDK namespace.
> 
> If there is enough agreement that we should do something, I suggest to
> introduce the "dpdk_" prefix slowly and live with both "rte_" and "dpdk_"
> during some time.
> We could start using the new prefix for the new APIs (example: crypto) or when
> there is a significant API break (example: mempool).
> 
> Opinions welcome!
I don't have an opinion on how important it is to fix the namespace, though it does seem like a good idea. 
However if it's to be done, in my opinion it should be completed quickly or will just cause more confusion.
So if rte_cryptoxxx becomes dpdk_cryptoxxx all other libraries should follow in next release or two, with 
the resulting ABI compatibility handling. Maybe with dual naming handled for several releases, but a 
clear end date when all are converted.
Else there will be many years with a mix of rte_ and dpdk_ 

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07
  2016-04-05  9:27  4%     ` Hunt, David
@ 2016-04-05 14:08  4%       ` Wiles, Keith
  2016-04-05 15:17  4%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2016-04-05 14:08 UTC (permalink / raw)
  To: Hunt, David, Thomas Monjalon, dev; +Cc: Olivier Matz

>
>On 4/4/2016 3:38 PM, Thomas Monjalon wrote:
>> 2016-03-17 10:05, Olivier Matz:
>>> Add a deprecation notice for coming changes in mempool for 16.07.
>> [...]
>>> +* librte_mempool: new fixes and features will be added in 16.07:
>>> +  allocation of large mempool in several virtual memory chunks, new API
>>> +  to populate a mempool, new API to free a mempool, allocation in
>>> +  anonymous mapping, drop of specific dom0 code. These changes will
>>> +  induce a modification of the rte_mempool structure, plus a
>>> +  modification of the API of rte_mempool_obj_iter(), implying a breakage
>>> +  of the ABI.
>> Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
>>
>> Other people involved in the discussion wanting to bring their support?
>
>Acked-by: David Hunt<david.hunt@intel.com>

Acked-by: Keith Wiles <keith.wiles@intel.com>
>
>
>Regards,
>David.
>


Regards,
Keith





^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 14:55  4%       ` Thomas Monjalon
@ 2016-04-05 14:06  4%         ` Wiles, Keith
  0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-04-05 14:06 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Richardson, Bruce, Olivier MATZ

>2016-03-10 13:56, Wiles, Keith:
>> >On Thu, Mar 10, 2016 at 01:37:27PM +0100, Olivier MATZ wrote:
>> >> Hi David,
>> >> 
>> >> On 03/10/2016 12:55 PM, David Hunt wrote:
>> >> > Announce the ABI breakage due to addition of external mempool
>> >> > manager functionality which requires changes to rte_mempool
>> >> > structure.
>> >> > 
>> >> > Signed-off-by: David Hunt <david.hunt@intel.com>
>> >> 
>> >> Acked-by: Olivier Matz <olivier.matz@6wind.com>
>> >> 
>> >Acked-by: Bruce Richardson <bruce.richardson@intel.com>
>> 
>> Asked-by: Keith Wiles <keith.wiles@intel.com>
>
>Is it on purpose, Keith, or a typo? Do you have asked this notice?

Sorry, autocorrect :-(

Acked-by: Keith Wiles <keith.wiles@intel.com>
>
>


Regards,
Keith





^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.
  2016-04-05  8:37  0%       ` Thomas Monjalon
@ 2016-04-05 14:06  0%         ` Yuanhan Liu
  0 siblings, 0 replies; 200+ results
From: Yuanhan Liu @ 2016-04-05 14:06 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Ilya Maximets, Dyasly Sergey, Flavio Leitner, Xie, Huawei

On Tue, Apr 05, 2016 at 10:37:13AM +0200, Thomas Monjalon wrote:
> 2016-04-05 13:47, Yuanhan Liu:
> > So, I was considering to add vhost-user Tx delayed-copy (or zero copy)
> > support recently, which comes to yet another ABI violation, as we need
> > add a new field to virtio_memory_regions struct to do guest phys addr
> > to host phys addr translation. You may ask, however, that why do we need
> > expose virtio_memory_regions struct to users at all?
> > 
> > You are right, we don't have to. And here is the thing: we exposed way
> > too many fields (or even structures) than necessary. Say, vhost_virtqueue
> > struct should NOT be exposed to user at all: application just need to
> > tell the right queue id to locate a specific queue, and that's all.
> > The structure should be defined in an internal header file. With that,
> > we could do any changes to it we want, without worrying about that we
> > may offense the painful ABI rules.
> > 
> > Similar changes could be done to virtio_net struct as well, just exposing
> > very few fields that are necessary and moving all others to an internal
> > structure.
> > 
> > Huawei then suggested a more radical yet much cleaner one: just exposing
> > a virtio_net handle to application, just like the way kernel exposes an
> > fd to user for locating a specific file. However, it's more than an ABI
> > change; it's also an API change: some fields are referenced by applications,
> > such as flags, virt_qp_nb. We could expose some new functions to access
> > them though.
> > 
> > I'd vote for this one, as it sounds very clean to me. This would also
> > solve the block issue of this patch. Though it would break OVS, I'm thinking
> > that'd be okay, as OVS has dependence on DPDK version: what we need to
> > do is just to send few patches to OVS, and let it points to next release,
> > say DPDK v16.07. Flavio, please correct me if I'm wrong.
> > 
> > Thoughts/comments?
> 
> Do you plan to send a deprecation notice to change API in 16.07?

Yes, I planned to, shortly. Before that, I'd ask for comments first.

	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07
  2016-04-04 14:38  4%   ` Thomas Monjalon
@ 2016-04-05  9:27  4%     ` Hunt, David
  2016-04-05 14:08  4%       ` Wiles, Keith
  0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2016-04-05  9:27 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: Olivier Matz


On 4/4/2016 3:38 PM, Thomas Monjalon wrote:
> 2016-03-17 10:05, Olivier Matz:
>> Add a deprecation notice for coming changes in mempool for 16.07.
> [...]
>> +* librte_mempool: new fixes and features will be added in 16.07:
>> +  allocation of large mempool in several virtual memory chunks, new API
>> +  to populate a mempool, new API to free a mempool, allocation in
>> +  anonymous mapping, drop of specific dom0 code. These changes will
>> +  induce a modification of the rte_mempool structure, plus a
>> +  modification of the API of rte_mempool_obj_iter(), implying a breakage
>> +  of the ABI.
> Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
>
> Other people involved in the discussion wanting to bring their support?

Acked-by: David Hunt<david.hunt@intel.com>


Regards,
David.

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches
@ 2016-04-05  9:23  9% Lazaros Koromilas
  2016-04-05 15:42  4% ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Lazaros Koromilas @ 2016-04-05  9:23 UTC (permalink / raw)
  To: dev

Deprecation notice for 16.04 for changes targeting release 16.07.
The changes affect struct rte_mempool, rte_mempool_cache and the
mempool API.

Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
---
 doc/guides/rel_notes/deprecation.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ad31355..6ccabcb 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -40,3 +40,10 @@ Deprecation Notices
   The existing API will be backward compatible, but there will be new API
   functions added to facilitate the creation of mempools using an external
   handler. The 16.07 release will contain these changes.
+
+* ABI change for rte_mempool struct to move the cache-related fields
+  to the more appropriate rte_mempool_cache struct. The mempool API is
+  also changed to enable external cache management that is not tied to EAL
+  threads. Some mempool get and put calls are removed in favor of a more
+  compact API. The ones that remain are backwards compatible and use the
+  per-lcore default cache if available. This change targets release 16.07.
-- 
1.9.1

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.
  2016-04-05  5:47  4%     ` [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local Yuanhan Liu
@ 2016-04-05  8:37  0%       ` Thomas Monjalon
  2016-04-05 14:06  0%         ` Yuanhan Liu
  2016-04-06  4:14  0%       ` Flavio Leitner
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-05  8:37 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, Ilya Maximets, Dyasly Sergey, Flavio Leitner, Xie, Huawei

2016-04-05 13:47, Yuanhan Liu:
> So, I was considering to add vhost-user Tx delayed-copy (or zero copy)
> support recently, which comes to yet another ABI violation, as we need
> add a new field to virtio_memory_regions struct to do guest phys addr
> to host phys addr translation. You may ask, however, that why do we need
> expose virtio_memory_regions struct to users at all?
> 
> You are right, we don't have to. And here is the thing: we exposed way
> too many fields (or even structures) than necessary. Say, vhost_virtqueue
> struct should NOT be exposed to user at all: application just need to
> tell the right queue id to locate a specific queue, and that's all.
> The structure should be defined in an internal header file. With that,
> we could do any changes to it we want, without worrying about that we
> may offense the painful ABI rules.
> 
> Similar changes could be done to virtio_net struct as well, just exposing
> very few fields that are necessary and moving all others to an internal
> structure.
> 
> Huawei then suggested a more radical yet much cleaner one: just exposing
> a virtio_net handle to application, just like the way kernel exposes an
> fd to user for locating a specific file. However, it's more than an ABI
> change; it's also an API change: some fields are referenced by applications,
> such as flags, virt_qp_nb. We could expose some new functions to access
> them though.
> 
> I'd vote for this one, as it sounds very clean to me. This would also
> solve the block issue of this patch. Though it would break OVS, I'm thinking
> that'd be okay, as OVS has dependence on DPDK version: what we need to
> do is just to send few patches to OVS, and let it points to next release,
> say DPDK v16.07. Flavio, please correct me if I'm wrong.
> 
> Thoughts/comments?

Do you plan to send a deprecation notice to change API in 16.07?

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local.
  @ 2016-04-05  5:47  4%     ` Yuanhan Liu
  2016-04-05  8:37  0%       ` Thomas Monjalon
  2016-04-06  4:14  0%       ` Flavio Leitner
  0 siblings, 2 replies; 200+ results
From: Yuanhan Liu @ 2016-04-05  5:47 UTC (permalink / raw)
  To: Ilya Maximets
  Cc: dev, Dyasly Sergey, Thomas Monjalon, Flavio Leitner, Xie, Huawei

On Fri, Feb 19, 2016 at 03:06:50PM +0800, Yuanhan Liu wrote:
> On Fri, Feb 19, 2016 at 09:32:41AM +0300, Ilya Maximets wrote:
> > Array of buf_vector's is just an array for temporary storing information
> > about available descriptors. It used only locally in virtio_dev_merge_rx()
> > and there is no reason for that array to be shared.
> > 
> > Fix that by allocating local buf_vec inside virtio_dev_merge_rx().
> > 
> > Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> > ---
> >  lib/librte_vhost/rte_virtio_net.h |  1 -
> >  lib/librte_vhost/vhost_rxtx.c     | 45 ++++++++++++++++++++-------------------
> >  2 files changed, 23 insertions(+), 23 deletions(-)
> > 
> > diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
> > index 10dcb90..ae1e4fb 100644
> > --- a/lib/librte_vhost/rte_virtio_net.h
> > +++ b/lib/librte_vhost/rte_virtio_net.h
> > @@ -91,7 +91,6 @@ struct vhost_virtqueue {
> >  	int			kickfd;			/**< Currently unused as polling mode is enabled. */
> >  	int			enabled;
> >  	uint64_t		reserved[16];		/**< Reserve some spaces for future extension. */
> > -	struct buf_vector	buf_vec[BUF_VECTOR_MAX];	/**< for scatter RX. */
> >  } __rte_cache_aligned;
> 
> I like this kind of cleanup, however, it breaks ABI.

So, I was considering to add vhost-user Tx delayed-copy (or zero copy)
support recently, which comes to yet another ABI violation, as we need
add a new field to virtio_memory_regions struct to do guest phys addr
to host phys addr translation. You may ask, however, that why do we need
expose virtio_memory_regions struct to users at all?

You are right, we don't have to. And here is the thing: we exposed way
too many fields (or even structures) than necessary. Say, vhost_virtqueue
struct should NOT be exposed to user at all: application just need to
tell the right queue id to locate a specific queue, and that's all.
The structure should be defined in an internal header file. With that,
we could do any changes to it we want, without worrying about that we
may offense the painful ABI rules.

Similar changes could be done to virtio_net struct as well, just exposing
very few fields that are necessary and moving all others to an internal
structure.

Huawei then suggested a more radical yet much cleaner one: just exposing
a virtio_net handle to application, just like the way kernel exposes an
fd to user for locating a specific file. However, it's more than an ABI
change; it's also an API change: some fields are referenced by applications,
such as flags, virt_qp_nb. We could expose some new functions to access
them though.

I'd vote for this one, as it sounds very clean to me. This would also
solve the block issue of this patch. Though it would break OVS, I'm thinking
that'd be okay, as OVS has dependence on DPDK version: what we need to
do is just to send few patches to OVS, and let it points to next release,
say DPDK v16.07. Flavio, please correct me if I'm wrong.

Thoughts/comments?

	--yliu

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 13:56  4%     ` Wiles, Keith
  2016-03-10 14:55  4%       ` Thomas Monjalon
@ 2016-04-04 14:49  4%       ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-04-04 14:49 UTC (permalink / raw)
  To: david.hunt; +Cc: dev, Wiles, Keith, Richardson, Bruce, Olivier MATZ

> >> > Announce the ABI breakage due to addition of external mempool
> >> > manager functionality which requires changes to rte_mempool
> >> > structure.
> >> > 
> >> > Signed-off-by: David Hunt <david.hunt@intel.com>
> >> 
> >> Acked-by: Olivier Matz <olivier.matz@6wind.com>
> >> 
> >Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> 
> Acked-by: John McNamara <john.mcnamara@intel.com>
> Asked-by: Keith Wiles <keith.wiles@intel.com>

Assumed it is an ack.
Applied, thanks

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07
  2016-03-17  9:05 15% ` [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07 Olivier Matz
@ 2016-04-04 14:38  4%   ` Thomas Monjalon
  2016-04-05  9:27  4%     ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-04-04 14:38 UTC (permalink / raw)
  To: dev; +Cc: Olivier Matz

2016-03-17 10:05, Olivier Matz:
> Add a deprecation notice for coming changes in mempool for 16.07.
[...]
> +* librte_mempool: new fixes and features will be added in 16.07:
> +  allocation of large mempool in several virtual memory chunks, new API
> +  to populate a mempool, new API to free a mempool, allocation in
> +  anonymous mapping, drop of specific dom0 code. These changes will
> +  induce a modification of the rte_mempool structure, plus a
> +  modification of the API of rte_mempool_obj_iter(), implying a breakage
> +  of the ABI.

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Other people involved in the discussion wanting to bring their support?

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v14 6/8] ethdev: redesign link speed config
  @ 2016-03-31 22:12  3%       ` Marc Sune
  0 siblings, 0 replies; 200+ results
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                    |  26 ++++----
 doc/guides/rel_notes/deprecation.rst      |   3 -
 doc/guides/rel_notes/release_16_04.rst    |   9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |   1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |   4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |   2 +-
 drivers/net/e1000/em_ethdev.c             | 103 +++++++++++++++---------------
 drivers/net/e1000/igb_ethdev.c            |  95 ++++++++++++++-------------
 drivers/net/i40e/i40e_ethdev.c            |  48 +++++++-------
 drivers/net/i40e/i40e_ethdev_vf.c         |   7 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          |  53 ++++++++-------
 drivers/net/mlx4/mlx4.c                   |   2 +
 drivers/net/mlx5/mlx5_ethdev.c            |   2 +
 drivers/net/mpipe/mpipe_tilegx.c          |   2 +
 drivers/net/null/rte_eth_null.c           |   1 +
 drivers/net/pcap/rte_eth_pcap.c           |   1 +
 drivers/net/ring/rte_eth_ring.c           |   1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |   2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   1 +
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.h             |  31 +++++----
 22 files changed, 213 insertions(+), 185 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 890c5c3..653be09 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -695,9 +688,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1107,13 +1099,20 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index cde314d..bc28d3c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 894278f..3f1ebc1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,16 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	/* IXGBE devices don't support:
+	*    - half duplex (checked afterwards for valid speeds)
+	*    - fixed speed: TODO implement
+	*/
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not supported",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2198,30 +2200,25 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
+		goto error;
+	}
+
+	speed = 0x0;
+	if (*link_speeds == ETH_LINK_SPEED_AUTONEG) {
 		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
-		goto error;
+	} else {
+		if (*link_speeds & ETH_LINK_SPEED_10G)
+			speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (*link_speeds & ETH_LINK_SPEED_1G)
+			speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		if (*link_speeds & ETH_LINK_SPEED_100M)
+			speed |= IXGBE_LINK_SPEED_100_FULL;
 	}
 
 	err = ixgbe_setup_link(hw, speed, link_up);
@@ -3088,7 +3085,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3107,7 +3104,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ed2f488..4f21dbe 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4736,6 +4736,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d7a0eea..beecc63 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -629,6 +629,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 95d533f..bd7a2bb 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,6 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..b88300d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
 #define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
 #define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
 #define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
@@ -278,17 +280,19 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
+#define ETH_LINK_FIXED          0 /**< No autonegotiation. */
+#define ETH_LINK_AUTONEG        1 /**< Autonegotiated. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -802,10 +806,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.1.4

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
@ 2016-03-31 13:29 16% Fan Zhang
  2016-04-05 15:45  7% ` Thomas Monjalon
  2016-04-05 21:16  4% ` Singh, Jasvinder
  0 siblings, 2 replies; 200+ results
From: Fan Zhang @ 2016-03-31 13:29 UTC (permalink / raw)
  To: dev

Several new fields will be added to structure rte_port_source_params for
source port enhancement with pcap file reading support.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

---
 doc/guides/rel_notes/deprecation.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..9b4fc9d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -25,3 +25,8 @@ Deprecation Notices
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
+
+* ABI changes are planned for struct rte_port_source_params in order to
+  support PCAP file reading feature. The release 16.04 contains this ABI
+  change wrapped by RTE_NEXT_ABI macro. Release 16.07 will contain this
+  change, and no backwards compatibility is planned.
-- 
2.5.0

^ permalink raw reply	[relevance 16%]

* [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure
@ 2016-03-31 13:28 16% Fan Zhang
  0 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2016-03-31 13:28 UTC (permalink / raw)
  To: dev

Several new fields will be added to structure rte_port_source_params for
source port enhancement with pcap file reading support.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

---
 doc/guides/rel_notes/deprecation.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..9b4fc9d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -25,3 +25,8 @@ Deprecation Notices
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
+
+* ABI changes are planned for struct rte_port_source_params in order to
+  support PCAP file reading feature. The release 16.04 contains this ABI
+  change wrapped by RTE_NEXT_ABI macro. Release 16.07 will contain this
+  change, and no backwards compatibility is planned.
-- 
2.5.0

^ permalink raw reply	[relevance 16%]

* [dpdk-dev] 16.07 Roadmap
@ 2016-03-31  8:21  2% O'Driscoll, Tim
  0 siblings, 0 replies; 200+ results
From: O'Driscoll, Tim @ 2016-03-31  8:21 UTC (permalink / raw)
  To: dev

As we're nearing the completion of the 16.04 release, I'd like to let the community know our plans for 16.07. It would be good if others are also willing to share their plans so that we can build up a complete picture of what's targeted for 16.07.

These are the features that we're planning to submit:

Vhost/Virtio Performance Loopback Utility: A tool will be provided which will allow virtio/vhost performance testing without the need for NIC traffic.

Virtio Code Refactoring for Rx/TX Split: The Rx and Tx queues will be split as they have different information to maintain apart from the common vring. Other cleanups will be made to make the queues more friendly for optimization.

Virtio Descriptor Index Update: The virtio descriptor index will be optimized for cache2cache transfer in the virtio PMD. The performance increase is expected to be below 10%.

Virtio in Containers: Support will be added for virtio in containers (see http://dpdk.org/ml/archives/dev/2016-February/032786.html). Multi-queue support will also be added.

I40e NSH: This includes: 1. Recognize the Network Services Header packet type; 2. Direct traffic to queues based on service path header and service index (dependent on firmware change so may not make 16.07); 3. Checksum offload.

I40e Floating VEB: Deferred from 16.04. See http://dpdk.org/ml/archives/dev/2016-March/036470.html for details.

Automatic VF Reset From PF (i40e/ixgbe): Currently, when a PF notifies a VF that a reset is required, DPDK just reports this event to the application, which then needs to restart the VF port. A more user-friendly mechanism will be implemented where DPDK will reset the VF port directly. The application will still be notified, but will not need to handle the reset of the VF port.

Software Implementation of the KASUMI Algorithm: Under the cryptodev API, a software implementation of the KASUMI algorithm will be supported. KASUMI is widely used in mobile communications systems.

Bit-Level Support for SNOW 3G: Support for the SNOW 3G algorithm is being added in the 16.04 release. In 16.07, this will be enhanced so that offsets and lengths can be specified in bits instead of bytes (so, you could encrypt 50 bits of a stream starting from the 5th bit for example).

IPsec Sample App Enhancements: Support for IPv6 and Transport Mode will be added to the IPsec sample application that was submitted in 16.04.

XStats Enhancements: Improve the extended NIC stats API to use id value pairs instead of string value pairs. Remap stats registers to use standard interface MIB naming and sizing.

Keep-Alive Enhancements: Improve DPDK keep-alive to use the DPDK alarm/interrupt API instead of using callbacks.

Live Migration for SRIOV: Support for live migration for vhost-user is being added to 16.04. This will be further enhanced to support live migration for SR-IOV by using link bonding to bond an SRIOV interface with a virtio interface.

IP Pipeline Enhancements: This includes: 1. Configure the MAC address in the routing pipeline; 2. Enable RSS per network interface through the configuration file; 3. Streamline the CLI code of the IP pipeline application.

Packet Capture Framework: In 16.04, there was lots of discussion on requirements for tcpdump support in DPDK (see http://dpdk.org/ml/archives/dev/2016-March/035592.html). For 16.07, we plan to submit a packet capture framework which will support hooks for filtering capabilities such as BPF. Our specific use case for this is for low rate packet capture for debug purposes. It should be possible for others to extend the framework to support high rate packet capture if they require that capability.

External Mempool Manager: This was originally submitted for 16.04 but had to be deferred due to ABI changes. See http://dpdk.org/ml/archives/dev/2016-March/035107.html for details.


In addition, there are some features that we're working on now but which we know won't make 16.07, either because time is too tight or because of external dependencies. These include:

QEMU vHost Back-End Reconnect: Currently, if a vswitch is connected to VMs via vhost-user and the vswitch is restarted, then when it comes back up again it cannot reconnect to the existing VMs. To address this, both QEMU and vhost-user need to support client mode (currently only server mode is supported), which implements reconnection messages that allow the vswitch to reconnect to the VMs. Changes are required in QEMU as well as in DPDK, so this change will need to be coordinated with the QEMU community.

Delay Packet Copy in vHost-User Dequeue: It may be possible to increase vhost-user performance by delaying the packet copy until a point where we know for certain whether the copy is required or not. This would avoid copying the packet in cases where it is not definitely required. Further investigation is required to determine how much of a performance gain can be achieved.


Tim

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v13 6/8] ethdev: redesign link speed config
    @ 2016-03-26  1:27  3%     ` Marc Sune
    2 siblings, 0 replies; 200+ results
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                    |  26 ++++----
 doc/guides/rel_notes/deprecation.rst      |   3 -
 doc/guides/rel_notes/release_16_04.rst    |   9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |   1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |   4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |   2 +-
 drivers/net/e1000/em_ethdev.c             | 103 +++++++++++++++---------------
 drivers/net/e1000/igb_ethdev.c            |  95 ++++++++++++++-------------
 drivers/net/i40e/i40e_ethdev.c            |  48 +++++++-------
 drivers/net/i40e/i40e_ethdev_vf.c         |   7 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          |  51 ++++++---------
 drivers/net/mlx4/mlx4.c                   |   2 +
 drivers/net/mlx5/mlx5_ethdev.c            |   2 +
 drivers/net/mpipe/mpipe_tilegx.c          |   2 +
 drivers/net/null/rte_eth_null.c           |   1 +
 drivers/net/pcap/rte_eth_pcap.c           |   1 +
 drivers/net/ring/rte_eth_ring.c           |   1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |   2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   1 +
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.h             |  29 +++++----
 22 files changed, 207 insertions(+), 187 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d5f8c7f..9fb59a2 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1106,13 +1098,20 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dce31db..c9ef417 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a98e8eb..6cc2da0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,16 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	/* IXGBE devices don't support:
+	*    - half duplex (checked afterwards for valid speeds)
+	*    - fixed speed: TODO implement
+	*/
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not supported",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2193,32 +2195,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -3083,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3102,7 +3093,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 59ac423..81528c9 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,6 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d7a0eea..beecc63 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -629,6 +629,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 6afa14e..94d1b2c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -780,6 +780,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..9a1466b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
 #define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
 #define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
 #define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.1.4

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v12 6/8] ethdev: redesign link speed config
  @ 2016-03-25 19:42  3%   ` Thomas Monjalon
    1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---

PLEASE REVIEW CAREFULLY THIS PATCH

 app/test-pmd/cmdline.c                    | 26 ++++----
 doc/guides/rel_notes/deprecation.rst      |  3 -
 doc/guides/rel_notes/release_16_04.rst    |  9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |  1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |  4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  2 +-
 drivers/net/e1000/em_ethdev.c             | 99 +++++++++++++++----------------
 drivers/net/e1000/igb_ethdev.c            | 94 +++++++++++++++--------------
 drivers/net/i40e/i40e_ethdev.c            | 48 +++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  7 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 46 ++++++--------
 drivers/net/mlx4/mlx4.c                   |  2 +
 drivers/net/mpipe/mpipe_tilegx.c          |  2 +
 drivers/net/null/rte_eth_null.c           |  1 +
 drivers/net/pcap/rte_eth_pcap.c           |  1 +
 drivers/net/ring/rte_eth_ring.c           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |  2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  1 +
 examples/ip_pipeline/config_parse.c       |  3 +-
 lib/librte_ether/rte_ethdev.h             | 29 +++++----
 21 files changed, 196 insertions(+), 186 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..af84175 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d5f8c7f..3e26ab0 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1106,8 +1098,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..ced864c 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dce31db..87bc767 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a98e8eb..ff23d7d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2193,32 +2192,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -3083,7 +3071,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3102,7 +3090,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 59ac423..43ac763 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,6 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 6afa14e..94d1b2c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -780,6 +780,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..03d3278 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
 #define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
 #define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
 #define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.7.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] doc: postpone flow director changes planned for cxgbe
@ 2016-03-25 16:29  5% Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-25 16:29 UTC (permalink / raw)
  To: rahul.lakkireddy; +Cc: dev

It will be tried to find a better solution.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index bdbac15..179e30f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -24,4 +24,4 @@ Deprecation Notices
 
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
-  but release 2.3 will.
+  but release 2.3 will. [postponed]
-- 
2.7.0

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches
  2016-03-24 14:35  0%     ` Lazaros Koromilas
  2016-03-24 14:58  0%       ` Venkatesan, Venky
@ 2016-03-24 15:03  0%       ` Wiles, Keith
  1 sibling, 0 replies; 200+ results
From: Wiles, Keith @ 2016-03-24 15:03 UTC (permalink / raw)
  To: Lazaros Koromilas; +Cc: Olivier Matz, dev

>On Mon, Mar 21, 2016 at 3:49 PM, Wiles, Keith <keith.wiles@intel.com> wrote:
>>>Hi Lazaros,
>>>
>>>Thanks for this patch. To me, this is a valuable enhancement.
>>>Please find some comments inline.
>>>
>>>On 03/10/2016 03:44 PM, Lazaros Koromilas wrote:
>>>> The mempool cache is only available to EAL threads as a per-lcore
>>>> resource. Change this so that the user can create and provide their own
>>>> cache on mempool get and put operations. This works with non-EAL threads
>>>> too. This commit introduces new API calls with the 'with_cache' suffix,
>>>> while the current ones default to the per-lcore local cache.
>>>>
>>>> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
>>>> ---
>>>>  lib/librte_mempool/rte_mempool.c |  65 +++++-
>>>>  lib/librte_mempool/rte_mempool.h | 442 ++++++++++++++++++++++++++++++++++++---
>>>>  2 files changed, 467 insertions(+), 40 deletions(-)
>>>>
>>>> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>>>> index f8781e1..cebc2b7 100644
>>>> --- a/lib/librte_mempool/rte_mempool.c
>>>> +++ b/lib/librte_mempool/rte_mempool.c
>>>> @@ -375,6 +375,43 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
>>>>      return usz;
>>>>  }
>>>>
>>>> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>>
>>>I wonder if this wouldn't cause a conflict with Keith's patch
>>>that removes some #ifdefs RTE_MEMPOOL_CACHE_MAX_SIZE.
>>>See: http://www.dpdk.org/dev/patchwork/patch/10492/
>>
>> Hi Lazaros,
>>
>> The patch I submitted keeps the mempool cache structure (pointers and variables) and only allocates the cache if specified by the caller to use a cache. This means to me the caller could fill in the cache pointer and values into the mempool structure to get a cache without a lot of extra code. If we added a set of APIs to fill in these structure variables would that not give you the external cache support. I have not really looked at the patch to verify this will work, but it sure seems like it.
>>
>> So my suggestion the caller can just create a mempool without a cache and then call a set of APIs to fill in his cache values, does that not work?
>>
>> If we can do this it reduces the API and possible the ABI changes to mempool as the new cache create routines and APIs could be in a new file I think, which just updates the mempool structure correctly.
>
>Hi Keith,
>
>The main benefit of having an external cache is to allow mempool users
>(threads) to maintain a local cache even though they don't have a
>valid lcore_id (non-EAL threads). The fact that cache access is done
>by indexing with the lcore_id is what makes it difficult...
>
>What could happen is only have external caches somehow, but that hurts
>the common case where you want an automatic cache.
>Or a cache registration mechanism (overkill?).
>
>So, I'm going to work on the comments and send out a v2 asap. Thanks everyone!

Hi Lazaros,

I look forward seeing the next version as I have some concerns, but I do not think I am seeing the big picture or reason for the change.

Part of my goal with the patch I sent was to remove ifdefs in the code as much as possible, so please try to reduce the ifdefs too.

>
>Lazaros.
>
>>
>>>
>>>As this patch is already acked for 16.07, I think that your v2
>>>could be rebased on top of it to avoid conflicts when Thomas will apply
>>>it.
>>>
>>>By the way, I also encourage you to have a look at other works in
>>>progress in mempool:
>>>http://www.dpdk.org/ml/archives/dev/2016-March/035107.html
>>>http://www.dpdk.org/ml/archives/dev/2016-March/035201.html
>>>
>>>
>>
>> Regards,
>> Keith
>>
>>
>>
>>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches
  2016-03-24 14:35  0%     ` Lazaros Koromilas
@ 2016-03-24 14:58  0%       ` Venkatesan, Venky
  2016-03-24 15:03  0%       ` Wiles, Keith
  1 sibling, 0 replies; 200+ results
From: Venkatesan, Venky @ 2016-03-24 14:58 UTC (permalink / raw)
  To: Lazaros Koromilas, Wiles, Keith; +Cc: Olivier Matz, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Lazaros Koromilas
> Sent: Thursday, March 24, 2016 7:36 AM
> To: Wiles, Keith <keith.wiles@intel.com>
> Cc: Olivier Matz <olivier.matz@6wind.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool
> caches
> 
> On Mon, Mar 21, 2016 at 3:49 PM, Wiles, Keith <keith.wiles@intel.com>
> wrote:
> >>Hi Lazaros,
> >>
> >>Thanks for this patch. To me, this is a valuable enhancement.
> >>Please find some comments inline.
> >>
> >>On 03/10/2016 03:44 PM, Lazaros Koromilas wrote:
> >>> The mempool cache is only available to EAL threads as a per-lcore
> >>> resource. Change this so that the user can create and provide their
> >>> own cache on mempool get and put operations. This works with non-EAL
> >>> threads too. This commit introduces new API calls with the
> >>> 'with_cache' suffix, while the current ones default to the per-lcore local
> cache.
> >>>
> >>> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
> >>> ---
> >>>  lib/librte_mempool/rte_mempool.c |  65 +++++-
> >>> lib/librte_mempool/rte_mempool.h | 442
> >>> ++++++++++++++++++++++++++++++++++++---
> >>>  2 files changed, 467 insertions(+), 40 deletions(-)
> >>>
> >>> diff --git a/lib/librte_mempool/rte_mempool.c
> >>> b/lib/librte_mempool/rte_mempool.c
> >>> index f8781e1..cebc2b7 100644
> >>> --- a/lib/librte_mempool/rte_mempool.c
> >>> +++ b/lib/librte_mempool/rte_mempool.c
> >>> @@ -375,6 +375,43 @@ rte_mempool_xmem_usage(void *vaddr,
> uint32_t elt_num, size_t elt_sz,
> >>>      return usz;
> >>>  }
> >>>
> >>> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> >>
> >>I wonder if this wouldn't cause a conflict with Keith's patch that
> >>removes some #ifdefs RTE_MEMPOOL_CACHE_MAX_SIZE.
> >>See: http://www.dpdk.org/dev/patchwork/patch/10492/
> >
> > Hi Lazaros,
> >
> > The patch I submitted keeps the mempool cache structure (pointers and
> variables) and only allocates the cache if specified by the caller to use a
> cache. This means to me the caller could fill in the cache pointer and values
> into the mempool structure to get a cache without a lot of extra code. If we
> added a set of APIs to fill in these structure variables would that not give you
> the external cache support. I have not really looked at the patch to verify this
> will work, but it sure seems like it.
> >
> > So my suggestion the caller can just create a mempool without a cache and
> then call a set of APIs to fill in his cache values, does that not work?
> >
> > If we can do this it reduces the API and possible the ABI changes to
> mempool as the new cache create routines and APIs could be in a new file I
> think, which just updates the mempool structure correctly.
> 
> Hi Keith,
> 
> The main benefit of having an external cache is to allow mempool users
> (threads) to maintain a local cache even though they don't have a valid
> lcore_id (non-EAL threads). The fact that cache access is done by indexing
> with the lcore_id is what makes it difficult...

Hi Lazaros, 

Alternative suggestion: This could actually be very simply done via creating an EAL API to register and return an lcore_id for a thread wanting to use DPDK services. That way, you could simply create your pthread, call the eal_register_thread() function that assigns an lcore_id to the caller (and internally sets up the per_lcore variable. 

The advantage of doing it this way is that you could extend it to other things other than the mempool that may need an lcore_id setup.

Regards,
-Venky

> 
> What could happen is only have external caches somehow, but that hurts the
> common case where you want an automatic cache.
> Or a cache registration mechanism (overkill?).
> 
> So, I'm going to work on the comments and send out a v2 asap. Thanks
> everyone!
> 
> Lazaros.
> 
> >
> >>
> >>As this patch is already acked for 16.07, I think that your v2 could
> >>be rebased on top of it to avoid conflicts when Thomas will apply it.
> >>
> >>By the way, I also encourage you to have a look at other works in
> >>progress in mempool:
> >>http://www.dpdk.org/ml/archives/dev/2016-March/035107.html
> >>http://www.dpdk.org/ml/archives/dev/2016-March/035201.html
> >>
> >>
> >
> > Regards,
> > Keith
> >
> >
> >
> >

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches
  2016-03-21 13:49  3%   ` Wiles, Keith
@ 2016-03-24 14:35  0%     ` Lazaros Koromilas
  2016-03-24 14:58  0%       ` Venkatesan, Venky
  2016-03-24 15:03  0%       ` Wiles, Keith
  0 siblings, 2 replies; 200+ results
From: Lazaros Koromilas @ 2016-03-24 14:35 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: Olivier Matz, dev

On Mon, Mar 21, 2016 at 3:49 PM, Wiles, Keith <keith.wiles@intel.com> wrote:
>>Hi Lazaros,
>>
>>Thanks for this patch. To me, this is a valuable enhancement.
>>Please find some comments inline.
>>
>>On 03/10/2016 03:44 PM, Lazaros Koromilas wrote:
>>> The mempool cache is only available to EAL threads as a per-lcore
>>> resource. Change this so that the user can create and provide their own
>>> cache on mempool get and put operations. This works with non-EAL threads
>>> too. This commit introduces new API calls with the 'with_cache' suffix,
>>> while the current ones default to the per-lcore local cache.
>>>
>>> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
>>> ---
>>>  lib/librte_mempool/rte_mempool.c |  65 +++++-
>>>  lib/librte_mempool/rte_mempool.h | 442 ++++++++++++++++++++++++++++++++++++---
>>>  2 files changed, 467 insertions(+), 40 deletions(-)
>>>
>>> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>>> index f8781e1..cebc2b7 100644
>>> --- a/lib/librte_mempool/rte_mempool.c
>>> +++ b/lib/librte_mempool/rte_mempool.c
>>> @@ -375,6 +375,43 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
>>>      return usz;
>>>  }
>>>
>>> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>
>>I wonder if this wouldn't cause a conflict with Keith's patch
>>that removes some #ifdefs RTE_MEMPOOL_CACHE_MAX_SIZE.
>>See: http://www.dpdk.org/dev/patchwork/patch/10492/
>
> Hi Lazaros,
>
> The patch I submitted keeps the mempool cache structure (pointers and variables) and only allocates the cache if specified by the caller to use a cache. This means to me the caller could fill in the cache pointer and values into the mempool structure to get a cache without a lot of extra code. If we added a set of APIs to fill in these structure variables would that not give you the external cache support. I have not really looked at the patch to verify this will work, but it sure seems like it.
>
> So my suggestion the caller can just create a mempool without a cache and then call a set of APIs to fill in his cache values, does that not work?
>
> If we can do this it reduces the API and possible the ABI changes to mempool as the new cache create routines and APIs could be in a new file I think, which just updates the mempool structure correctly.

Hi Keith,

The main benefit of having an external cache is to allow mempool users
(threads) to maintain a local cache even though they don't have a
valid lcore_id (non-EAL threads). The fact that cache access is done
by indexing with the lcore_id is what makes it difficult...

What could happen is only have external caches somehow, but that hurts
the common case where you want an automatic cache.
Or a cache registration mechanism (overkill?).

So, I'm going to work on the comments and send out a v2 asap. Thanks everyone!

Lazaros.

>
>>
>>As this patch is already acked for 16.07, I think that your v2
>>could be rebased on top of it to avoid conflicts when Thomas will apply
>>it.
>>
>>By the way, I also encourage you to have a look at other works in
>>progress in mempool:
>>http://www.dpdk.org/ml/archives/dev/2016-March/035107.html
>>http://www.dpdk.org/ml/archives/dev/2016-March/035201.html
>>
>>
>
> Regards,
> Keith
>
>
>
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver
  2016-03-23 13:07  4%       ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Jingjing Wu
  2016-03-23 13:07 19%         ` [dpdk-dev] [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-23 14:46  0%         ` Bruce Richardson
  1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2016-03-23 14:46 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, helin.zhang

On Wed, Mar 23, 2016 at 09:07:03PM +0800, Jingjing Wu wrote:
> v6 changes:
>  - remove ABI announce on rte_eth_ipv4_flow and rte_eth_ipv6_flow in deprecation.
>  - reword commit logs. 
> 
> v5 changes:
>  - remove the reorganizing of struct rte_eth_fdir_flow
>  - remove fdir supporting on Tunnel Id
>  - rebase to latest dpdk/master
> 
> v4 changes:
>  - rebase to latest dpdk-next-net/rel_16_04.
>  - comments on new fields in API structure.
> 
> v3 changes:
>  - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
>  - use AQ rx control register read/write for some registers
>  - remove few useless lines
>  - patch title rewording
> 
> v2 changes:
>  - rebase on dpdk-next-net/rel_16_04
>  - comments rewording.
>  - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
>    avoid ABI breaking.
>  - remove ABI announce in Deprecation.
>  - fix the ethertype setting when program filter in v1 patch set.
> 
> This patch set extends flow director to support filtering by
> additional fields below in i40e driver:
>  - TOS, Protocol and TTL in IP header
>  - single vlan or inner vlan
> 
> 
> Andrey Chilikin (1):
>   i40e: fix VLAN bitmasks for input set
> 
> Jingjing Wu (8):
>   ethdev: extend flow director for input selection
>   i40e: split function for hash and fdir input
>   i40e: remove flex payload from input selection
>   i40e: restore default setting on input set
>   i40e: extend flow director to filter by IP Header
>   testpmd: extend input set related commands
>   i40e: extend flow director to filter by vlan id
>   testpmd: extend flow director commands
>
Patchset applied to dpdk-next-net/rel_16_04.

Thanks,
/Bruce

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v6 1/9] ethdev: extend flow director for input selection
  2016-03-23 13:07  4%       ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Jingjing Wu
@ 2016-03-23 13:07 19%         ` Jingjing Wu
  2016-03-23 14:46  0%         ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson
  1 sibling, 0 replies; 200+ results
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch adds RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field types and extends
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   | 8 --------
 doc/guides/rel_notes/release_16_04.rst | 3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 8 ++++++++
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 252a096..bdbac15 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -22,14 +22,6 @@ Deprecation Notices
 * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
   must be updated to support 100G link and to have a cleaner link speed API.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
-* ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
-  include more fields to be matched against. The release 2.2 does not
-  contain these ABI changes, but release 2.3 will.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9922bcb..6e368f7 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -437,6 +437,9 @@ ABI Changes
 * The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
   from 8-bit to 16-bit.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set.
+
 * The cmdline buffer size has been increase from 256 to 512.
 
 
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 6e2f617..aabd724 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header to match. */
 };
 
 /**
@@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
 };
 
 /**
-- 
2.4.0

^ permalink raw reply	[relevance 19%]

* [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver
  2016-03-21  6:18  4%     ` [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  2016-03-21  6:18 18%       ` [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-23 13:07  4%       ` Jingjing Wu
  2016-03-23 13:07 19%         ` [dpdk-dev] [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-23 14:46  0%         ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson
  1 sibling, 2 replies; 200+ results
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

v6 changes:
 - remove ABI announce on rte_eth_ipv4_flow and rte_eth_ipv6_flow in deprecation.
 - reword commit logs. 

v5 changes:
 - remove the reorganizing of struct rte_eth_fdir_flow
 - remove fdir supporting on Tunnel Id
 - rebase to latest dpdk/master

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - single vlan or inner vlan


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (8):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 100 +++++--
 doc/guides/rel_notes/deprecation.rst        |   8 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +--
 drivers/net/i40e/i40e_ethdev.c              | 393 ++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 100 ++++---
 lib/librte_ether/rte_eth_ctrl.h             |   8 +
 8 files changed, 417 insertions(+), 250 deletions(-)

-- 
2.4.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-23  0:42  0%           ` Wu, Jingjing
@ 2016-03-23  8:45  0%             ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-23  8:45 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev, Zhang, Helin

2016-03-23 00:42, Wu, Jingjing:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-03-21 14:18, Jingjing Wu:
> > > This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> > > RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> > > struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering by
> > > tos, protocol and ttl.
> > [...]
> > > --- a/doc/guides/rel_notes/deprecation.rst
> > > +++ b/doc/guides/rel_notes/deprecation.rst
> > > @@ -22,10 +22,6 @@ Deprecation Notices
> > >  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
> > >    must be updated to support 100G link and to have a cleaner link speed
> > API.
> > >
> > > -* ABI changes are planned for struct rte_eth_fdir_flow in order to
> > > support
> > > -  extend flow director's input set. The release 2.2 does not contain
> > > these ABI
> > > -  changes, but release 2.3 will, and no backwards compatibility is planned.
> > 
> > The changed structures are part of rte_eth_fdir_flow.
> > So this deprecation notice apply to this patch.
> > 
> > >  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow
> > to
> > >    include more fields to be matched against. The release 2.2 does not
> > >    contain these ABI changes, but release 2.3 will.
> > 
> > These are the structures changed in this patch.
> > I think this section must be also removed.
> 
> This deprecation notice is not raised by me. It is raised by rahul.lakkireddy@chelsio.com at commit 954f1545a1ab.
> So, I'm not sure if it is OK for me to remove it in my patch.

It does not matter who raised the notice.
Your patch match with it. Please remove it.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK and HW offloads
  2016-03-22 10:19  0%             ` Bruce Richardson
@ 2016-03-23  2:47  0%               ` Qiu, Michael
  0 siblings, 0 replies; 200+ results
From: Qiu, Michael @ 2016-03-23  2:47 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: Kyle Larose, Thomas Monjalon, Zhang, Helin, Stephen Hemminger, dev

On 3/22/2016 6:20 PM, Richardson, Bruce wrote:
> On Tue, Mar 22, 2016 at 05:50:28AM +0000, Qiu, Michael wrote:
>> On 3/21/2016 11:27 PM, Kyle Larose wrote:
>>> On Mon, Mar 21, 2016 at 10:52 AM, Bruce Richardson
>>> <bruce.richardson@intel.com> wrote:
>>>> On Sun, Mar 20, 2016 at 08:18:57PM +0100, Thomas Monjalon wrote:
>>>>> 2016-03-20 14:17, Zhang, Helin:
>>>>>> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>>>>>>> 2016-03-18 10:16, Stephen Hemminger:
>>>>>>>> Right now, all those offload features are pretty much unusable in a
>>>>>>>> real product without lots and lots of extra codes and huge bug
>>>>>>>> surface. It bothers me enough that I would recommend removing much of the
>>>>>>> filter/offload/ptype stuff from DPDK!
>>>>>>>
>>>>>>> One of the biggest challenge is to think about a good filtering API.
>>>>>>> The offloading has some interaction with the mbuf struct.
>>>>>>>
>>>>>>> I would like to suggest rewriting ethdev API by keeping it as is for some time for
>>>>>>> compatibility while creating a new one. What about the prefix dpdk_netdev_ to
>>>>>>> progressively replace rte_eth_dev?
>>>>>> I totally agree with to add new and generic APIs for user applications. But I don't
>>>>>> think we need to remove all current APIs. Generic APIs may not support all advanced
>>>>>> hardware features, while specific APIs can. Why not support all? One generic APIs for
>>>>>> common users, and others APIs for advanced users.
>>>>> Yes we cannot access to every features of a device through generic API.
>>>>> Until now we were trying to add an ethdev API for every features even if it
>>>>> is used by only one driver.
>>>>> I think we should allow a direct access to the driver by the applications and
>>>>> work on generic API only for common features.
>>>> Definite +1.
>>>> I think that we need to start pushing driver-specific functionality to get exposed
>>>> via a driver's header files. That allow users who want to extract the max
>>>> functionality from a particular NIC to do so via those APIs calls, while not
>>>> polluting the generic ethdev layer.
>>>>
>>> What sort of requirements on ABI/API compatibility would this place on
>>> the drivers? I would hope that it would be treated like any other
>>> public API within DPDK. I don't think this would be too onerous, but
>>> it would require that the drivers be designed to deal with it. (I.e.
>>> don't just expose any old internal driver function).
>> Why not to implement one simple API with variable arguments, just like
>> syscall ioctl() does. And drivers implement it's specific hardware
>> features with a feature bit param, and other needed variable arguments.
>>
>> Thanks,
>> Michael
> A very much dislike that idea. 
> * It makes the code much harder to read as you have to closely examine all the
>   parameters to work out what a function call is actually meant to do.

It's not a big deal, if we have a document.

> * It makes it much harder to see that you have an implicit dependency on a
>   specific device. Having to include a driver specific header file e.g. i40e.h,
>   and call a function named e.g. i40e_do_magic_stuff(), makes it pretty explicit
>   that you have a dependency on i40e-based hardware

Software does not want to bind to specific hardware I think, what about
the transportability?

> * It prevents the compiler from doing type-checking on parameters and informing
>   you of little inconsistencies.

Maybe, we could do self-check for the parameters I think.

>
> For all these reasons, I prefer the device-specific functions option. However,
> at the same time, we also need to ensure we have a reasonable set of generic
> APIs so that the cases where users are forced to drop down to the lower-level
> device-specific primitives are reduced.

For software, it do not care which hardware it is, it only cares about
what ability you have.

Thanks,
Michael

> Regards,
> /Bruce
>
>>>> On the other hand, I don't like the idea of dpdk_netdev. I think we can work
>>>> within the existing rte_eth_dev framework.
>>>>
>>>> /Bruce
>>>>
>>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-22 22:05  0%         ` Thomas Monjalon
@ 2016-03-23  0:42  0%           ` Wu, Jingjing
  2016-03-23  8:45  0%             ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Wu, Jingjing @ 2016-03-23  0:42 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Zhang, Helin

Hi, Thomas

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 23, 2016 6:06 AM
> To: Wu, Jingjing
> Cc: dev@dpdk.org; Zhang, Helin
> Subject: Re: [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for
> input selection
> 
> 2016-03-21 14:18, Jingjing Wu:
> > This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> > RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> > struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering by
> > tos, protocol and ttl.
> [...]
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -22,10 +22,6 @@ Deprecation Notices
> >  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
> >    must be updated to support 100G link and to have a cleaner link speed
> API.
> >
> > -* ABI changes are planned for struct rte_eth_fdir_flow in order to
> > support
> > -  extend flow director's input set. The release 2.2 does not contain
> > these ABI
> > -  changes, but release 2.3 will, and no backwards compatibility is planned.
> 
> The changed structures are part of rte_eth_fdir_flow.
> So this deprecation notice apply to this patch.
> 
> >  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow
> to
> >    include more fields to be matched against. The release 2.2 does not
> >    contain these ABI changes, but release 2.3 will.
> 
> These are the structures changed in this patch.
> I think this section must be also removed.
> 


This deprecation notice is not raised by me. It is raised by rahul.lakkireddy@chelsio.com at commit 954f1545a1ab.
So, I'm not sure if it is OK for me to remove it in my patch.

/Jingjing

> > --- a/doc/guides/rel_notes/release_16_04.rst
> > +++ b/doc/guides/rel_notes/release_16_04.rst
> > @@ -435,6 +435,8 @@ ABI Changes
> >
> >  * The cmdline buffer size has been increase from 256 to 512.
> >
> > +* The ethdev flow director structure ``rte_eth_fdir_flow`` structure
> > +was
> > +  changed. New fields were added to extend flow director's input set.
> 
> For reading ease, it's better to group ethdev changes (before cmdline
> change).

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-21  6:18 18%       ` [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-22 22:05  0%         ` Thomas Monjalon
  2016-03-23  0:42  0%           ` Wu, Jingjing
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-22 22:05 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, helin.zhang

2016-03-21 14:18, Jingjing Wu:
> This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
> by tos, protocol and ttl.
[...]
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -22,10 +22,6 @@ Deprecation Notices
>  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
>    must be updated to support 100G link and to have a cleaner link speed API.
>  
> -* ABI changes are planned for struct rte_eth_fdir_flow in order to support
> -  extend flow director's input set. The release 2.2 does not contain these ABI
> -  changes, but release 2.3 will, and no backwards compatibility is planned.

The changed structures are part of rte_eth_fdir_flow.
So this deprecation notice apply to this patch.

>  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
>    include more fields to be matched against. The release 2.2 does not
>    contain these ABI changes, but release 2.3 will.

These are the structures changed in this patch.
I think this section must be also removed.

> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -435,6 +435,8 @@ ABI Changes
>  
>  * The cmdline buffer size has been increase from 256 to 512.
>  
> +* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
> +  changed. New fields were added to extend flow director's input set.

For reading ease, it's better to group ethdev changes (before cmdline change).

> --- a/lib/librte_ether/rte_eth_ctrl.h
> +++ b/lib/librte_ether/rte_eth_ctrl.h
> @@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
>  	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
>  	RTE_ETH_INPUT_SET_L3_IP6_TC,
>  	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
> +	RTE_ETH_INPUT_SET_L3_IP4_TTL,
> +	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
>  
>  	/* L4 */
>  	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
> @@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
>  struct rte_eth_ipv4_flow {
>  	uint32_t src_ip;      /**< IPv4 source address to match. */
>  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> +	uint8_t  tos;         /**< Type of service to match. */
> +	uint8_t  ttl;         /**< Time to live to match. */
> +	uint8_t  proto;       /**< Protocol, next header to match. */
>  };
>  
>  /**
> @@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
>  struct rte_eth_ipv6_flow {
>  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
>  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> +	uint8_t  tc;             /**< Traffic class to match. */
> +	uint8_t  proto;          /**< Protocol, next header to match. */
> +	uint8_t  hop_limits;     /**< Hop limits to match. */
>  };

This extension of the existing API looks OK.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK and HW offloads
  2016-03-22  5:50  0%           ` Qiu, Michael
@ 2016-03-22 10:19  0%             ` Bruce Richardson
  2016-03-23  2:47  0%               ` Qiu, Michael
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2016-03-22 10:19 UTC (permalink / raw)
  To: Qiu, Michael
  Cc: Kyle Larose, Thomas Monjalon, Zhang, Helin, Stephen Hemminger, dev

On Tue, Mar 22, 2016 at 05:50:28AM +0000, Qiu, Michael wrote:
> On 3/21/2016 11:27 PM, Kyle Larose wrote:
> > On Mon, Mar 21, 2016 at 10:52 AM, Bruce Richardson
> > <bruce.richardson@intel.com> wrote:
> >> On Sun, Mar 20, 2016 at 08:18:57PM +0100, Thomas Monjalon wrote:
> >>> 2016-03-20 14:17, Zhang, Helin:
> >>>> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> >>>>> 2016-03-18 10:16, Stephen Hemminger:
> >>>>>> Right now, all those offload features are pretty much unusable in a
> >>>>>> real product without lots and lots of extra codes and huge bug
> >>>>>> surface. It bothers me enough that I would recommend removing much of the
> >>>>> filter/offload/ptype stuff from DPDK!
> >>>>>
> >>>>> One of the biggest challenge is to think about a good filtering API.
> >>>>> The offloading has some interaction with the mbuf struct.
> >>>>>
> >>>>> I would like to suggest rewriting ethdev API by keeping it as is for some time for
> >>>>> compatibility while creating a new one. What about the prefix dpdk_netdev_ to
> >>>>> progressively replace rte_eth_dev?
> >>>> I totally agree with to add new and generic APIs for user applications. But I don't
> >>>> think we need to remove all current APIs. Generic APIs may not support all advanced
> >>>> hardware features, while specific APIs can. Why not support all? One generic APIs for
> >>>> common users, and others APIs for advanced users.
> >>> Yes we cannot access to every features of a device through generic API.
> >>> Until now we were trying to add an ethdev API for every features even if it
> >>> is used by only one driver.
> >>> I think we should allow a direct access to the driver by the applications and
> >>> work on generic API only for common features.
> >> Definite +1.
> >> I think that we need to start pushing driver-specific functionality to get exposed
> >> via a driver's header files. That allow users who want to extract the max
> >> functionality from a particular NIC to do so via those APIs calls, while not
> >> polluting the generic ethdev layer.
> >>
> > What sort of requirements on ABI/API compatibility would this place on
> > the drivers? I would hope that it would be treated like any other
> > public API within DPDK. I don't think this would be too onerous, but
> > it would require that the drivers be designed to deal with it. (I.e.
> > don't just expose any old internal driver function).
> 
> Why not to implement one simple API with variable arguments, just like
> syscall ioctl() does. And drivers implement it's specific hardware
> features with a feature bit param, and other needed variable arguments.
> 
> Thanks,
> Michael

A very much dislike that idea. 
* It makes the code much harder to read as you have to closely examine all the
  parameters to work out what a function call is actually meant to do.
* It makes it much harder to see that you have an implicit dependency on a
  specific device. Having to include a driver specific header file e.g. i40e.h,
  and call a function named e.g. i40e_do_magic_stuff(), makes it pretty explicit
  that you have a dependency on i40e-based hardware
* It prevents the compiler from doing type-checking on parameters and informing
  you of little inconsistencies.

For all these reasons, I prefer the device-specific functions option. However,
at the same time, we also need to ensure we have a reasonable set of generic
APIs so that the cases where users are forced to drop down to the lower-level
device-specific primitives are reduced.

Regards,
/Bruce

> >> On the other hand, I don't like the idea of dpdk_netdev. I think we can work
> >> within the existing rte_eth_dev framework.
> >>
> >> /Bruce
> >>
> 
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK and HW offloads
  2016-03-21 15:26  3%         ` Kyle Larose
@ 2016-03-22  5:50  0%           ` Qiu, Michael
  2016-03-22 10:19  0%             ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Qiu, Michael @ 2016-03-22  5:50 UTC (permalink / raw)
  To: Kyle Larose, Richardson, Bruce
  Cc: Thomas Monjalon, Zhang, Helin, Stephen Hemminger, dev

On 3/21/2016 11:27 PM, Kyle Larose wrote:
> On Mon, Mar 21, 2016 at 10:52 AM, Bruce Richardson
> <bruce.richardson@intel.com> wrote:
>> On Sun, Mar 20, 2016 at 08:18:57PM +0100, Thomas Monjalon wrote:
>>> 2016-03-20 14:17, Zhang, Helin:
>>>> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>>>>> 2016-03-18 10:16, Stephen Hemminger:
>>>>>> Right now, all those offload features are pretty much unusable in a
>>>>>> real product without lots and lots of extra codes and huge bug
>>>>>> surface. It bothers me enough that I would recommend removing much of the
>>>>> filter/offload/ptype stuff from DPDK!
>>>>>
>>>>> One of the biggest challenge is to think about a good filtering API.
>>>>> The offloading has some interaction with the mbuf struct.
>>>>>
>>>>> I would like to suggest rewriting ethdev API by keeping it as is for some time for
>>>>> compatibility while creating a new one. What about the prefix dpdk_netdev_ to
>>>>> progressively replace rte_eth_dev?
>>>> I totally agree with to add new and generic APIs for user applications. But I don't
>>>> think we need to remove all current APIs. Generic APIs may not support all advanced
>>>> hardware features, while specific APIs can. Why not support all? One generic APIs for
>>>> common users, and others APIs for advanced users.
>>> Yes we cannot access to every features of a device through generic API.
>>> Until now we were trying to add an ethdev API for every features even if it
>>> is used by only one driver.
>>> I think we should allow a direct access to the driver by the applications and
>>> work on generic API only for common features.
>> Definite +1.
>> I think that we need to start pushing driver-specific functionality to get exposed
>> via a driver's header files. That allow users who want to extract the max
>> functionality from a particular NIC to do so via those APIs calls, while not
>> polluting the generic ethdev layer.
>>
> What sort of requirements on ABI/API compatibility would this place on
> the drivers? I would hope that it would be treated like any other
> public API within DPDK. I don't think this would be too onerous, but
> it would require that the drivers be designed to deal with it. (I.e.
> don't just expose any old internal driver function).

Why not to implement one simple API with variable arguments, just like
syscall ioctl() does. And drivers implement it's specific hardware
features with a feature bit param, and other needed variable arguments.

Thanks,
Michael
>> On the other hand, I don't like the idea of dpdk_netdev. I think we can work
>> within the existing rte_eth_dev framework.
>>
>> /Bruce
>>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] DPDK and HW offloads
  @ 2016-03-21 15:26  3%         ` Kyle Larose
  2016-03-22  5:50  0%           ` Qiu, Michael
  0 siblings, 1 reply; 200+ results
From: Kyle Larose @ 2016-03-21 15:26 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Thomas Monjalon, Zhang, Helin, Stephen Hemminger, dev

On Mon, Mar 21, 2016 at 10:52 AM, Bruce Richardson
<bruce.richardson@intel.com> wrote:
> On Sun, Mar 20, 2016 at 08:18:57PM +0100, Thomas Monjalon wrote:
>> 2016-03-20 14:17, Zhang, Helin:
>> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>> > > 2016-03-18 10:16, Stephen Hemminger:
>> > > > Right now, all those offload features are pretty much unusable in a
>> > > > real product without lots and lots of extra codes and huge bug
>> > > > surface. It bothers me enough that I would recommend removing much of the
>> > > filter/offload/ptype stuff from DPDK!
>> > >
>> > > One of the biggest challenge is to think about a good filtering API.
>> > > The offloading has some interaction with the mbuf struct.
>> > >
>> > > I would like to suggest rewriting ethdev API by keeping it as is for some time for
>> > > compatibility while creating a new one. What about the prefix dpdk_netdev_ to
>> > > progressively replace rte_eth_dev?
>> >
>> > I totally agree with to add new and generic APIs for user applications. But I don't
>> > think we need to remove all current APIs. Generic APIs may not support all advanced
>> > hardware features, while specific APIs can. Why not support all? One generic APIs for
>> > common users, and others APIs for advanced users.
>>
>> Yes we cannot access to every features of a device through generic API.
>> Until now we were trying to add an ethdev API for every features even if it
>> is used by only one driver.
>> I think we should allow a direct access to the driver by the applications and
>> work on generic API only for common features.
>
> Definite +1.
> I think that we need to start pushing driver-specific functionality to get exposed
> via a driver's header files. That allow users who want to extract the max
> functionality from a particular NIC to do so via those APIs calls, while not
> polluting the generic ethdev layer.
>

What sort of requirements on ABI/API compatibility would this place on
the drivers? I would hope that it would be treated like any other
public API within DPDK. I don't think this would be too onerous, but
it would require that the drivers be designed to deal with it. (I.e.
don't just expose any old internal driver function).

> On the other hand, I don't like the idea of dpdk_netdev. I think we can work
> within the existing rte_eth_dev framework.
>
> /Bruce
>

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches
  2016-03-21 12:22  4% ` Olivier Matz
@ 2016-03-21 13:49  3%   ` Wiles, Keith
  2016-03-24 14:35  0%     ` Lazaros Koromilas
  0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2016-03-21 13:49 UTC (permalink / raw)
  To: Olivier Matz, Lazaros Koromilas, dev

>Hi Lazaros,
>
>Thanks for this patch. To me, this is a valuable enhancement.
>Please find some comments inline.
>
>On 03/10/2016 03:44 PM, Lazaros Koromilas wrote:
>> The mempool cache is only available to EAL threads as a per-lcore
>> resource. Change this so that the user can create and provide their own
>> cache on mempool get and put operations. This works with non-EAL threads
>> too. This commit introduces new API calls with the 'with_cache' suffix,
>> while the current ones default to the per-lcore local cache.
>> 
>> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
>> ---
>>  lib/librte_mempool/rte_mempool.c |  65 +++++-
>>  lib/librte_mempool/rte_mempool.h | 442 ++++++++++++++++++++++++++++++++++++---
>>  2 files changed, 467 insertions(+), 40 deletions(-)
>> 
>> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>> index f8781e1..cebc2b7 100644
>> --- a/lib/librte_mempool/rte_mempool.c
>> +++ b/lib/librte_mempool/rte_mempool.c
>> @@ -375,6 +375,43 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
>>  	return usz;
>>  }
>>  
>> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>
>I wonder if this wouldn't cause a conflict with Keith's patch
>that removes some #ifdefs RTE_MEMPOOL_CACHE_MAX_SIZE.
>See: http://www.dpdk.org/dev/patchwork/patch/10492/

Hi Lazaros,

The patch I submitted keeps the mempool cache structure (pointers and variables) and only allocates the cache if specified by the caller to use a cache. This means to me the caller could fill in the cache pointer and values into the mempool structure to get a cache without a lot of extra code. If we added a set of APIs to fill in these structure variables would that not give you the external cache support. I have not really looked at the patch to verify this will work, but it sure seems like it.

So my suggestion the caller can just create a mempool without a cache and then call a set of APIs to fill in his cache values, does that not work?

If we can do this it reduces the API and possible the ABI changes to mempool as the new cache create routines and APIs could be in a new file I think, which just updates the mempool structure correctly.

>
>As this patch is already acked for 16.07, I think that your v2
>could be rebased on top of it to avoid conflicts when Thomas will apply
>it.
>
>By the way, I also encourage you to have a look at other works in
>progress in mempool:
>http://www.dpdk.org/ml/archives/dev/2016-March/035107.html
>http://www.dpdk.org/ml/archives/dev/2016-March/035201.html
>
>

Regards,
Keith





^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches
  @ 2016-03-21 12:22  4% ` Olivier Matz
  2016-03-21 13:49  3%   ` Wiles, Keith
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2016-03-21 12:22 UTC (permalink / raw)
  To: Lazaros Koromilas, dev

Hi Lazaros,

Thanks for this patch. To me, this is a valuable enhancement.
Please find some comments inline.

On 03/10/2016 03:44 PM, Lazaros Koromilas wrote:
> The mempool cache is only available to EAL threads as a per-lcore
> resource. Change this so that the user can create and provide their own
> cache on mempool get and put operations. This works with non-EAL threads
> too. This commit introduces new API calls with the 'with_cache' suffix,
> while the current ones default to the per-lcore local cache.
> 
> Signed-off-by: Lazaros Koromilas <l@nofutznetworks.com>
> ---
>  lib/librte_mempool/rte_mempool.c |  65 +++++-
>  lib/librte_mempool/rte_mempool.h | 442 ++++++++++++++++++++++++++++++++++++---
>  2 files changed, 467 insertions(+), 40 deletions(-)
> 
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index f8781e1..cebc2b7 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -375,6 +375,43 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
>  	return usz;
>  }
>  
> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0

I wonder if this wouldn't cause a conflict with Keith's patch
that removes some #ifdefs RTE_MEMPOOL_CACHE_MAX_SIZE.
See: http://www.dpdk.org/dev/patchwork/patch/10492/

As this patch is already acked for 16.07, I think that your v2
could be rebased on top of it to avoid conflicts when Thomas will apply
it.

By the way, I also encourage you to have a look at other works in
progress in mempool:
http://www.dpdk.org/ml/archives/dev/2016-March/035107.html
http://www.dpdk.org/ml/archives/dev/2016-March/035201.html


> +static void
> +mempool_cache_init(struct rte_mempool_cache *cache, uint32_t size)
> +{
> +	cache->size = size;
> +	cache->flushthresh = CALC_CACHE_FLUSHTHRESH(size);
> +	cache->len = 0;
> +}
> +
> +/*
> + * Creates and initializes a cache for objects that are retrieved from and
> + * returned to an underlying mempool. This structure is identical to the
> + * structure included inside struct rte_mempool.
> + */

On top of Keith's patch, this comment may be reworked as the cache
structure is not included in the mempool structure anymore.

nit: I think the imperative form is preferred


> +struct rte_mempool_cache *
> +rte_mempool_cache_create(uint32_t size)
> +{
> +	struct rte_mempool_cache *cache;
> +
> +	if (size > RTE_MEMPOOL_CACHE_MAX_SIZE) {
> +		rte_errno = EINVAL;
> +		return NULL;
> +	}
> +
> +	cache = rte_zmalloc("MEMPOOL_CACHE", sizeof(*cache), RTE_CACHE_LINE_SIZE);
> +	if (cache == NULL) {
> +		RTE_LOG(ERR, MEMPOOL, "Cannot allocate mempool cache!\n");

I would remove the '!'



> @@ -587,10 +624,18 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
>  	mp->elt_size = objsz.elt_size;
>  	mp->header_size = objsz.header_size;
>  	mp->trailer_size = objsz.trailer_size;
> -	mp->cache_size = cache_size;
> -	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
> +	mp->cache_size = cache_size; /* Keep this for backwards compat. */

I'm wondering if this should be kept for compat or if it makes sense
to keep it. The question is: do we want the cache_size to be a parameter
of the mempool or should it be a parameter of the cache?

I think we could remove this field from the mempool structure.


> @@ -673,13 +718,17 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
>  #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>  	unsigned lcore_id;
>  	unsigned count = 0;
> +	unsigned cache_size;
>  	unsigned cache_count;
>  
>  	fprintf(f, "  cache infos:\n");
> -	fprintf(f, "    cache_size=%"PRIu32"\n", mp->cache_size);
>  	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> +		cache_size = mp->local_cache[lcore_id].size;
> +		fprintf(f, "    cache_size[%u]=%"PRIu32"\n",
> +			lcore_id, cache_size);
>  		cache_count = mp->local_cache[lcore_id].len;
> -		fprintf(f, "    cache_count[%u]=%u\n", lcore_id, cache_count);
> +		fprintf(f, "    cache_count[%u]=%"PRIu32"\n",
> +			lcore_id, cache_count);
>  		count += cache_count;

Does it still make sense to dump the content of the cache as some
external caches may exist?

If we want to list all caches, we could imagine a sort of cache
registration before using a cache structure. Example:

   cache = rte_mempool_add_cache()
   rte_mempool_del_cache()

All the caches could be browsed internally using a list.

Thoughts?


> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -95,19 +95,19 @@ struct rte_mempool_debug_stats {
>  } __rte_cache_aligned;
>  #endif
>  
> -#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>  /**
>   * A structure that stores a per-core object cache.
>   */
>  struct rte_mempool_cache {
> -	unsigned len; /**< Cache len */
> +	uint32_t size;        /**< Size of the cache */
> +	uint32_t flushthresh; /**< Threshold before we flush excess elements */
> +	uint32_t len;         /**< Current cache count */
>  	/*
>  	 * Cache is allocated to this size to allow it to overflow in certain
>  	 * cases to avoid needless emptying of cache.
>  	 */
>  	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
>  } __rte_cache_aligned;
> -#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
>  
>  /**
>   * A structure that stores the size of mempool elements.
> @@ -185,8 +185,6 @@ struct rte_mempool {
>  	int flags;                       /**< Flags of the mempool. */
>  	uint32_t size;                   /**< Size of the mempool. */
>  	uint32_t cache_size;             /**< Size of per-lcore local cache. */
> -	uint32_t cache_flushthresh;
> -	/**< Threshold before we flush excess elements. */
>  
>  	uint32_t elt_size;               /**< Size of an element. */
>  	uint32_t header_size;            /**< Size of header (before elt). */

Adding and removing these fields in the structure will break
the ABI. Could you please send a deprecation notice for it for
16.04, in the same model as http://dpdk.org/dev/patchwork/patch/11553/

The process is to get 3 acks for this deprecation notice, but I think
this won't be an issue as there are already several changes scheduled
in mempool that will break the ABI in 16.07, so it's the right time to
do it.



>  /**
> + * Put several objects back in the mempool (multi-producers safe).
> + * Use a user-provided mempool cache.
> + *
> + * @param mp
> + *   A pointer to the mempool structure.
> + * @param obj_table
> + *   A pointer to a table of void * pointers (objects).
> + * @param n
> + *   The number of objects to add in the mempool from the obj_table.
> + * @param cache
> + *   A pointer to a mempool cache structure. May be NULL if not needed.
> + */
> +static inline void __attribute__((always_inline))
> +rte_mempool_mp_put_bulk_with_cache(struct rte_mempool *mp,
> +				   void * const *obj_table, unsigned n,
> +				   struct rte_mempool_cache *cache)
> +{
> +	__mempool_check_cookies(mp, obj_table, n, 0);
> +	__mempool_put_bulk_with_cache(mp, obj_table, n, cache, 1);
> +}
> +
> +/**
> + * Put several objects back in the mempool (NOT multi-producers safe).
> + * Use a user-provided mempool cache.
> + *
> + * @param mp
> + *   A pointer to the mempool structure.
> + * @param obj_table
> + *   A pointer to a table of void * pointers (objects).
> + * @param n
> + *   The number of objects to add in the mempool from obj_table.
> + * @param cache
> + *   A pointer to a mempool cache structure. May be NULL if not needed.
> + */
> +static inline void
> +rte_mempool_sp_put_bulk_with_cache(struct rte_mempool *mp,
> +				   void * const *obj_table, unsigned n,
> +				   struct rte_mempool_cache *cache)
> +{
> +	__mempool_check_cookies(mp, obj_table, n, 0);
> +	__mempool_put_bulk_with_cache(mp, obj_table, n, cache, 0);
> +}
>
> [...]

Many functions are added here. As all of these functions are inline,
what would you think to have instead one new functions that would
match all cases:

static inline void
rte_mempool_generic_put(struct rte_mempool *mp,
		void * const *obj_table, unsigned n,
		struct rte_mempool_cache *cache,
		unsigned flags)

We could then consider the deprecation of some functions. Today,
without your patch, we have for put():

	rte_mempool_mp_put_bulk(mp, obj_table, n)
	rte_mempool_sp_put_bulk(mp, obj_table, n)
	rte_mempool_put_bulk(mp, obj_table, n)
	rte_mempool_mp_put(mp, obj)
	rte_mempool_sp_put(mp, obj)
	rte_mempool_put(mp, obj)

	__mempool_put_bulk(mp, obj_table, n, is_mp)  /* internal */

Maybe we should only keep:

	rte_mempool_put()
	rte_mempool_put_bulk(mp, obj_table, n)
	rte_mempool_generic_put(mp, obj_table, n, cache, flags)

and same for *get().



> +/**
> + * Create a user-owned mempool cache. This can be used by non-EAL threads
> + * to enable caching when they interact with a mempool.

nit: the doxygen format needs a one-line title

> + *
> + * @param size
> + *   The size of the mempool cache. See rte_mempool_create()'s cache_size
> + *   parameter description for more information. The same limits and
> + *   considerations apply here too.
> + */
> +struct rte_mempool_cache *
> +rte_mempool_cache_create(uint32_t size);
> +

I think we should also consider a free() function.

Maybe we should explain a bit more in the help of this function that
a mempool embeds a per-lcore cache by default.

Also, it would be great to have a test in app/test_mempool.c to validate
the feature and have an example of use.

And last thing, this is probably out of scope for now, but I'm
wondering if in the future this external cache could be used to
transparently share a pool (typically a mbuf pool), for instance
in case of a secondary process. Each process would have its own cache,
referencing the same shared mempool structure. This would probably
require to update the ethdev and mbuf API, so it's certainly a quite
large modification. If you have any ideas or plans going in this
direction, I would be interested.


Regards,
Olivier

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-21  6:18  4%     ` [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
@ 2016-03-21  6:18 18%       ` Jingjing Wu
  2016-03-22 22:05  0%         ` Thomas Monjalon
  2016-03-23 13:07  4%       ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Jingjing Wu
  1 sibling, 1 reply; 200+ results
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   | 4 ----
 doc/guides/rel_notes/release_16_04.rst | 2 ++
 lib/librte_ether/rte_eth_ctrl.h        | 8 ++++++++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 252a096..e7a7c7f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -22,10 +22,6 @@ Deprecation Notices
 * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
   must be updated to support 100G link and to have a cleaner link speed API.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 2785b29..5803684 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -435,6 +435,8 @@ ABI Changes
 
 * The cmdline buffer size has been increase from 256 to 512.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 6e2f617..aabd724 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header to match. */
 };
 
 /**
@@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
 };
 
 /**
-- 
2.4.0

^ permalink raw reply	[relevance 18%]

* [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver
  2016-03-10  3:25  4%   ` [dpdk-dev] [PATCH v4 " Jingjing Wu
  2016-03-10  3:25 18%     ` [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
@ 2016-03-21  6:18  4%     ` Jingjing Wu
  2016-03-21  6:18 18%       ` [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-23 13:07  4%       ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Jingjing Wu
  1 sibling, 2 replies; 200+ results
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

v5 changes:
 - remove the reorganizing of struct rte_eth_fdir_flow
 - remove fdir supporting on Tunnel Id
 - rebase to latest dpdk/master

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - single vlan or inner vlan 




Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (8):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 100 +++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   4 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +--
 drivers/net/i40e/i40e_ethdev.c              | 393 ++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 100 ++++---
 lib/librte_ether/rte_eth_ctrl.h             |   8 +
 8 files changed, 416 insertions(+), 246 deletions(-)

-- 
2.4.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07
  2016-03-09 16:19  2% [dpdk-dev] [RFC 00/35] mempool: rework memory allocation Olivier Matz
@ 2016-03-17  9:05 15% ` Olivier Matz
  2016-04-04 14:38  4%   ` Thomas Monjalon
  2016-04-14 10:19  2% ` [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation Olivier Matz
  1 sibling, 1 reply; 200+ results
From: Olivier Matz @ 2016-03-17  9:05 UTC (permalink / raw)
  To: dev

Add a deprecation notice for coming changes in mempool for 16.07.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 252a096..3e8e327 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -33,3 +33,11 @@ Deprecation Notices
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will.
+
+* librte_mempool: new fixes and features will be added in 16.07:
+  allocation of large mempool in several virtual memory chunks, new API
+  to populate a mempool, new API to free a mempool, allocation in
+  anonymous mapping, drop of specific dom0 code. These changes will
+  induce a modification of the rte_mempool structure, plus a
+  modification of the API of rte_mempool_obj_iter(), implying a breakage
+  of the ABI.
-- 
2.1.4

^ permalink raw reply	[relevance 15%]

* Re: [dpdk-dev] [PATCH] vhost: remove lockless enqueue to the virtio ring
  2016-03-16  8:20  0%     ` Xie, Huawei
@ 2016-03-16  8:30  0%       ` Yuanhan Liu
  0 siblings, 0 replies; 200+ results
From: Yuanhan Liu @ 2016-03-16  8:30 UTC (permalink / raw)
  To: Xie, Huawei; +Cc: Thomas Monjalon, dev, ann.zhuangyanying

On Wed, Mar 16, 2016 at 08:20:37AM +0000, Xie, Huawei wrote:
> On 3/15/2016 7:14 AM, Thomas Monjalon wrote:
> > 2016-01-05 07:16, Xie, Huawei:
> >> On 1/5/2016 2:42 PM, Xie, Huawei wrote:
> >>> This patch removes the internal lockless enqueue implmentation.
> >>> DPDK doesn't support receiving/transmitting packets from/to the same
> >>> queue. Vhost PMD wraps vhost device as normal DPDK port. DPDK
> >>> applications normally have their own lock implmentation when enqueue
> >>> packets to the same queue of a port.
> >>>
> >>> The atomic cmpset is a costly operation. This patch should help
> >>> performance a bit.
> >>>
> >>> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
> >> This patch modifies the API's behavior, which is also a trivial ABI
> >> change. In my opinion, application shouldn't rely on previous behavior.
> >> Anyway, i am checking how to declare the ABI change.
> > I guess this patch is now obsolete?
> 
> How about we delay this to next release after more considerations,

I'd suggest so.

> whether we should keep this behavior, and what is the best way for
> concurrency in vhost.

I'm wondering should we do an announcement first, to notify user the
behaviour change?

	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] vhost: remove lockless enqueue to the virtio ring
  2016-03-14 23:13  0%   ` Thomas Monjalon
@ 2016-03-16  8:20  0%     ` Xie, Huawei
  2016-03-16  8:30  0%       ` Yuanhan Liu
  0 siblings, 1 reply; 200+ results
From: Xie, Huawei @ 2016-03-16  8:20 UTC (permalink / raw)
  To: Thomas Monjalon, yuanhan.liu; +Cc: dev, ann.zhuangyanying

On 3/15/2016 7:14 AM, Thomas Monjalon wrote:
> 2016-01-05 07:16, Xie, Huawei:
>> On 1/5/2016 2:42 PM, Xie, Huawei wrote:
>>> This patch removes the internal lockless enqueue implmentation.
>>> DPDK doesn't support receiving/transmitting packets from/to the same
>>> queue. Vhost PMD wraps vhost device as normal DPDK port. DPDK
>>> applications normally have their own lock implmentation when enqueue
>>> packets to the same queue of a port.
>>>
>>> The atomic cmpset is a costly operation. This patch should help
>>> performance a bit.
>>>
>>> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
>> This patch modifies the API's behavior, which is also a trivial ABI
>> change. In my opinion, application shouldn't rely on previous behavior.
>> Anyway, i am checking how to declare the ABI change.
> I guess this patch is now obsolete?

How about we delay this to next release after more considerations,
whether we should keep this behavior, and what is the best way for
concurrency in vhost.



^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] vhost: remove lockless enqueue to the virtio ring
  @ 2016-03-14 23:13  0%   ` Thomas Monjalon
  2016-03-16  8:20  0%     ` Xie, Huawei
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-14 23:13 UTC (permalink / raw)
  To: Xie, Huawei, yuanhan.liu; +Cc: dev, ann.zhuangyanying

2016-01-05 07:16, Xie, Huawei:
> On 1/5/2016 2:42 PM, Xie, Huawei wrote:
> > This patch removes the internal lockless enqueue implmentation.
> > DPDK doesn't support receiving/transmitting packets from/to the same
> > queue. Vhost PMD wraps vhost device as normal DPDK port. DPDK
> > applications normally have their own lock implmentation when enqueue
> > packets to the same queue of a port.
> >
> > The atomic cmpset is a costly operation. This patch should help
> > performance a bit.
> >
> > Signed-off-by: Huawei Xie <huawei.xie@intel.com>
> This patch modifies the API's behavior, which is also a trivial ABI
> change. In my opinion, application shouldn't rely on previous behavior.
> Anyway, i am checking how to declare the ABI change.

I guess this patch is now obsolete?

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-10  2:42  3%   ` [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
@ 2016-03-11 23:02  3%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-11 23:02 UTC (permalink / raw)
  To: Wenzhuo Lu; +Cc: dev

2016-03-10 10:42, Wenzhuo Lu:
> The names of function for tunnel port configuration are not
> accurate. They're tunnel_add/del, better change them to
> tunnel_port_add/del.
> As it may be an ABI change if change the names directly, the
> new functions are added but not remove the old ones. The old
> ones will be removed in the next release after an ABI change
> announcement.

As the API/ABI compatibility is already broken in this release,
I suggest to just rename the functions without keeping the old ones.
Then this patch should be merge with the next one.
I plan do it before applying.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v5 1/2] ethdev: add vlan type for setting ether type
  2016-03-11 16:50  5%       ` [dpdk-dev] [PATCH v5 0/2] i40e setting ether type of VLANs Helin Zhang
@ 2016-03-11 16:50  7%         ` Helin Zhang
  0 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-03-11 16:50 UTC (permalink / raw)
  To: dev

In order to set ether type of VLAN for single VLAN, inner
and outer VLAN, the VLAN type as an input parameter is added
to 'rte_eth_dev_set_vlan_ether_type()'.
In addition, corresponding changes in e1000, ixgbe and i40e
are also added.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 app/test-pmd/cmdline.c                      | 30 +++++++----
 app/test-pmd/config.c                       |  9 ++--
 app/test-pmd/testpmd.h                      |  3 +-
 doc/guides/rel_notes/release_16_04.rst      |  5 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 +---
 drivers/net/e1000/igb_ethdev.c              | 27 +++++++---
 drivers/net/i40e/i40e_ethdev.c              | 79 +++++++++++++++++++++++++++--
 drivers/net/ixgbe/ixgbe_ethdev.c            | 25 +++++++--
 lib/librte_ether/rte_ethdev.c               |  7 +--
 lib/librte_ether/rte_ethdev.h               | 21 ++++++--
 lib/librte_ether/rte_ether_version.map      |  7 +++
 11 files changed, 179 insertions(+), 45 deletions(-)

v5:
 - Removed the versioning mechanism, as ABI broken is already
   there allowed.

v4:
 - Updated the doc of testpmd guide.

v3:
 - Used versioning mechanism to avoid ABI issue.
 - Re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..1eeb8a8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -277,8 +277,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set the VLAN QinQ (extended queue in queue)"
 			" on a port.\n\n"
 
-			"vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
+			"vlan set (inner|outer) tpid (value) (port_id)\n"
+			"    Set the VLAN TPID for Packet Filtering on"
 			" a port\n\n"
 
 			"rx_vlan add (vlan_id|all) (port_id)\n"
@@ -297,10 +297,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Remove a vlan_id, to the set of VLAN identifiers"
 			"filtered for VF(s) from port_id.\n\n"
 
-			"rx_vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
-			" a port\n\n"
-
 			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
 			"(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
 			"   add a tunnel filter of a port.\n\n"
@@ -2747,6 +2743,7 @@ cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
 struct cmd_vlan_offload_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	cmdline_fixed_string_t on;
 	cmdline_fixed_string_t port_id;
@@ -2847,6 +2844,7 @@ cmdline_parse_inst_t cmd_vlan_offload = {
 struct cmd_vlan_tpid_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	uint16_t tp_id;
 	uint8_t port_id;
@@ -2858,8 +2856,17 @@ cmd_vlan_tpid_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	struct cmd_vlan_tpid_result *res = parsed_result;
-	vlan_tpid_set(res->port_id, res->tp_id);
-	return;
+	enum rte_vlan_type vlan_type;
+
+	if (!strcmp(res->vlan_type, "inner"))
+		vlan_type = ETH_VLAN_TYPE_INNER;
+	else if (!strcmp(res->vlan_type, "outer"))
+		vlan_type = ETH_VLAN_TYPE_OUTER;
+	else {
+		printf("Unknown vlan type\n");
+		return;
+	}
+	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
 }
 
 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
@@ -2868,6 +2875,9 @@ cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
 cmdline_parse_token_string_t cmd_vlan_tpid_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 set, "set");
+cmdline_parse_token_string_t cmd_vlan_type =
+	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+				 vlan_type, "inner#outer");
 cmdline_parse_token_string_t cmd_vlan_tpid_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 what, "tpid");
@@ -2881,10 +2891,12 @@ cmdline_parse_token_num_t cmd_vlan_tpid_portid =
 cmdline_parse_inst_t cmd_vlan_tpid = {
 	.f = cmd_vlan_tpid_parsed,
 	.data = NULL,
-	.help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+	.help_str = "set inner|outer tpid tp_id port_id, set the VLAN "
+		    "Ether type",
 	.tokens = {
 		(void *)&cmd_vlan_tpid_vlan,
 		(void *)&cmd_vlan_tpid_set,
+		(void *)&cmd_vlan_type,
 		(void *)&cmd_vlan_tpid_what,
 		(void *)&cmd_vlan_tpid_tpid,
 		(void *)&cmd_vlan_tpid_portid,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..5bb09a5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1821,19 +1821,20 @@ rx_vlan_all_filter_set(portid_t port_id, int on)
 }
 
 void
-vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
 {
 	int diag;
+
 	if (port_id_is_invalid(port_id, ENABLED_WARN))
 		return;
 
-	diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+	diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
 	if (diag == 0)
 		return;
 
-	printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+	printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
 	       "diag=%d\n",
-	       port_id, tp_id, diag);
+	       port_id, vlan_type, tp_id, diag);
 }
 
 void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b618998..0f72ca1 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -508,7 +508,8 @@ void rx_vlan_filter_set(portid_t port_id, int on);
 void rx_vlan_all_filter_set(portid_t port_id, int on);
 int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
 void vlan_extend_set(portid_t port_id, int on);
-void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
+void vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type,
+		   uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
 void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer);
 void tx_vlan_reset(portid_t port_id);
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 7c09fef..077f67b 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -125,6 +125,8 @@ This section should contain new features added in this release. Sample format:
 
   Af_packet device can now be detached using API, like other PMD devices.
 
+* **Added modifying ether type of both single and double VLAN for i40e**
+
 
 Resolved Issues
 ---------------
@@ -256,6 +258,9 @@ This section should contain API changes. Sample format:
 * Af_packet device init function is no longer public. Device should be attached
   with API.
 
+* Add one more parameter for ethdev public interface
+  of ``rte_eth_dev_set_vlan_ether_type``.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..e2b2224 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -498,9 +498,9 @@ Set the VLAN QinQ (extended queue in queue) on for a port::
 vlan set tpid
 ~~~~~~~~~~~~~
 
-Set the outer VLAN TPID for packet filtering on a port::
+Set the inner or outer VLAN TPID for packet filtering on a port::
 
-   testpmd> vlan set tpid (value) (port_id)
+   testpmd> vlan set (inner|outer) tpid (value) (port_id)
 
 .. note::
 
@@ -540,13 +540,6 @@ Remove a VLAN ID, from the set of VLAN identifiers filtered for VF(s) for port I
 
    testpmd> rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)
 
-rx_vlan set tpid
-~~~~~~~~~~~~~~~~
-
-Set the outer VLAN TPID for packet filtering on a port::
-
-   testpmd> rx_vlan set tpid (value) (port_id)
-
 tunnel_filter add
 ~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index f889876..9a34d01 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -126,7 +126,9 @@ static int  eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int eth_igb_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static int eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+				 enum rte_vlan_type vlan_type,
+				 uint16_t tpid_id);
 static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
@@ -2193,15 +2195,28 @@ eth_igb_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
-eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+static int
+eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+		      enum rte_vlan_type vlan_type,
+		      uint16_t tpid)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t reg = ETHER_TYPE_VLAN ;
+	uint32_t reg = ETHER_TYPE_VLAN;
+	int ret = 0;
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		reg |= (tpid << 16);
+		E1000_WRITE_REG(hw, E1000_VET, reg);
+		break;
+	default:
+		ret = -EINVAL;
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 
-	reg |= (tpid << 16);
-	E1000_WRITE_REG(hw, E1000_VET, reg);
+	return ret;
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0c87ec1..7605a68 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -266,6 +266,11 @@
 #define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
 #define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
 
+#define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK  \
+	I40E_MASK(0xFFFF, I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT)
+
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
@@ -292,7 +297,9 @@ static void i40e_dev_info_get(struct rte_eth_dev *dev,
 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
 				uint16_t vlan_id,
 				int on);
-static void i40e_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid);
+static int i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+			      enum rte_vlan_type vlan_type,
+			      uint16_t tpid);
 static void i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
 				      uint16_t queue,
@@ -865,6 +872,20 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	hw->fc.requested_mode = I40E_FC_NONE;
 	i40e_set_fc(hw, &aq_fail, TRUE);
 
+	/* Set the global registers with default ether type value */
+	ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
+	if (ret != I40E_SUCCESS) {
+		PMD_INIT_LOG(ERR, "Failed to set the default outer "
+			     "VLAN ether type");
+		goto err_setup_pf_switch;
+	}
+	ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, ETHER_TYPE_VLAN);
+	if (ret != I40E_SUCCESS) {
+		PMD_INIT_LOG(ERR, "Failed to set the default outer "
+			     "VLAN ether type");
+		goto err_setup_pf_switch;
+	}
+
 	/* PF setup, which includes VSI setup */
 	ret = i40e_pf_setup(pf);
 	if (ret) {
@@ -2312,11 +2333,59 @@ i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 		return i40e_vsi_delete_vlan(vsi, vlan_id);
 }
 
-static void
-i40e_vlan_tpid_set(__rte_unused struct rte_eth_dev *dev,
-		   __rte_unused uint16_t tpid)
+static int
+i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+		   enum rte_vlan_type vlan_type,
+		   uint16_t tpid)
 {
-	PMD_INIT_FUNC_TRACE();
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t reg_r = 0, reg_w = 0;
+	uint16_t reg_id = 0;
+	int ret = 0;
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_OUTER:
+		reg_id = 2;
+		break;
+	case ETH_VLAN_TYPE_INNER:
+		reg_id = 3;
+		break;
+	default:
+		ret = -EINVAL;
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d", vlan_type);
+		return ret;
+	}
+	ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					  &reg_r, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug read from "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		ret = -EIO;
+		return ret;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: "
+		    "0x%08"PRIx64"", reg_id, reg_r);
+
+	reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
+	reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
+	if (reg_r == reg_w) {
+		ret = 0;
+		PMD_DRV_LOG(DEBUG, "No need to write");
+		return ret;
+	}
+
+	ret = i40e_aq_debug_write_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					   reg_w, NULL);
+	if (ret != I40E_SUCCESS) {
+		ret = -EIO;
+		PMD_DRV_LOG(ERR, "Fail to debug write to "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return ret;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
+		    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a9a1583..0dc050d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -178,7 +178,9 @@ static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static int ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+			       enum rte_vlan_type vlan_type,
+			       uint16_t tpid_id);
 static void ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
 		uint16_t queue, bool on);
 static void ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
@@ -1542,14 +1544,27 @@ ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 		ixgbe_vlan_hw_strip_disable(dev, queue);
 }
 
-static void
-ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+static int
+ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+		    enum rte_vlan_type vlan_type,
+		    uint16_t tpid)
 {
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret = 0;
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		/* Only the high 16-bits is valid */
+		IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+		break;
+	default:
+		ret = -EINVAL;
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 
-	/* Only the high 16-bits is valid */
-	IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+	return ret;
 }
 
 void
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..dedb36a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1697,16 +1697,17 @@ rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id, int o
 }
 
 int
-rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tpid)
+rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+				enum rte_vlan_type vlan_type,
+				uint16_t tpid)
 {
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
-	(*dev->dev_ops->vlan_tpid_set)(dev, tpid);
 
-	return 0;
+	return (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, tpid);
 }
 
 int
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..bc3f42e 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -351,6 +351,17 @@ struct rte_eth_rxmode {
 };
 
 /**
+ * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
+ * Note that single VLAN is treated the same as inner VLAN.
+ */
+enum rte_vlan_type {
+	ETH_VLAN_TYPE_UNKNOWN = 0,
+	ETH_VLAN_TYPE_INNER, /**< Single VLAN, or inner VLAN. */
+	ETH_VLAN_TYPE_OUTER, /**< Outer VLAN. */
+	ETH_VLAN_TYPE_MAX,
+};
+
+/**
  * A structure used to configure the Receive Side Scaling (RSS) feature
  * of an Ethernet port.
  * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1076,8 +1087,8 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
 				  int on);
 /**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
 
-typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
-				  uint16_t tpid);
+typedef int (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
+			       enum rte_vlan_type type, uint16_t tpid);
 /**< @internal set the outer VLAN-TPID by an Ethernet device. */
 
 typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
@@ -2346,6 +2357,8 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @vlan_type
+ *   The vlan type.
  * @param tag_type
  *   The Tag Protocol ID
  * @return
@@ -2353,7 +2366,9 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *   - (-ENOSUP) if hardware-assisted VLAN TPID setup is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  */
-int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+				    enum rte_vlan_type vlan_type,
+				    uint16_t tag_type);
 
 /**
  * Set VLAN offload configuration on an Ethernet device
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..6098de5 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_set_vlan_ether_type;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v5 0/2] i40e setting ether type of VLANs
  2016-03-11  8:49  4%     ` [dpdk-dev] [PATCH v4 " Helin Zhang
  2016-03-11  8:49  7%       ` [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type Helin Zhang
@ 2016-03-11 16:50  5%       ` Helin Zhang
  2016-03-11 16:50  7%         ` [dpdk-dev] [PATCH v5 1/2] ethdev: add vlan type for setting ether type Helin Zhang
  1 sibling, 1 reply; 200+ results
From: Helin Zhang @ 2016-03-11 16:50 UTC (permalink / raw)
  To: dev

It adds setting ether type of both single VLAN(inner VLAN) and
outer VLAN for i40e. For ixgbe and e1000/igb, it supports setting
single VLAN(inner VLAN) only, and can be extended in the future.

The patch set was branched off rel_16_04 of repo dpdk-next-net,
on below commit.
commit 5721e6447b5c20208a32c919a509e89d78c3e68d
Author: Robin Jarry <robin.jarry@6wind.com>
Date:   Thu Mar 3 15:27:40 2016 +0100
    mlx4: ensure number of RX queues is a power of 2 

v5:
 - Removed the versioning mechanism, as ABI broken is already
   there allowed.

v4:
 - Updated the doc of testpmd guide.

v3:
 - Used versioning mechanism to avoid ABI issue.
 - Re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.
 - Fixed a i40e overflow issue.

Helin Zhang (2):
  ethdev: add vlan type for setting ether type
  i40e: fix the overflow issue

 app/test-pmd/cmdline.c                      | 30 +++++++----
 app/test-pmd/config.c                       |  9 ++--
 app/test-pmd/testpmd.h                      |  3 +-
 doc/guides/rel_notes/release_16_04.rst      |  5 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 +---
 drivers/net/e1000/igb_ethdev.c              | 27 +++++++---
 drivers/net/i40e/i40e_ethdev.c              | 79 +++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_rxtx.c                |  4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 25 +++++++--
 lib/librte_ether/rte_ethdev.c               |  7 +--
 lib/librte_ether/rte_ethdev.h               | 21 ++++++--
 lib/librte_ether/rte_ether_version.map      |  7 +++
 12 files changed, 181 insertions(+), 47 deletions(-)

-- 
2.5.0

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type
  2016-03-11 14:17  4%             ` Zhang, Helin
@ 2016-03-11 14:20  3%               ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-11 14:20 UTC (permalink / raw)
  To: Zhang, Helin; +Cc: dev

2016-03-11 14:17, Zhang, Helin:
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Friday, March 11, 2016 7:20 PM
> > To: Panu Matilainen; Zhang, Helin
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether
> > type
> > 
> > 2016-03-11 13:19, Panu Matilainen:
> > > On 03/11/2016 10:49 AM, Helin Zhang wrote:
> > > > -int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t
> > > > tag_type);
> > > > +int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
> > > > +				    enum rte_vlan_type vlan_type,
> > > > +				    uint16_t tag_type);
> > > > +int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t
> > > > +tag_type); int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
> > > > +					  enum rte_vlan_type vlan_type,
> > > > +					  uint16_t tag_type);
> > > >
> > > >   /**
> > > >    * Set VLAN offload configuration on an Ethernet device
> > >
> > > Its nice to see people actually trying to be compatible on occasion :)
> > >
> > > However in this case there's not much point in doing so, because
> > > libethdev ABI has already been broken in this cycle:
> > > http://dpdk.org/browse/dpdk/commit/?id=cfd2279ea6299826fe992028f1dffaf
> > > 9fa7e7d0a
> > >
> > > In other words, the compatibility versions can never get invoked
> > > because all software built against libethdev needs to be rebuilt
> > > anyway because of the soname bump. Just drop the compat versions, no
> > > point carrying around something that cannot possibly get used.
> > 
> > Oh yes, you are right.
> > Sorry Helin for having required that extra work.
> > On the good side, you have learnt how to do it ;)
> 
> Yes, as Thomas said, at leat l know how to do that, and the extra work was not too big.
> Thomas, Panu, thank you very much for the great comments!
> 
> Thomas, does that mean I just need to work out a new version and just let the ABI
> changes as is. No ABI annoucenment will be requried? No RTE_NEXT_ABI will be used?

You just need an entry in "API changes" section of the release notes.
You can state that this API change imply an ABI change.
Thanks

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type
  2016-03-11 11:20  0%           ` Thomas Monjalon
@ 2016-03-11 14:17  4%             ` Zhang, Helin
  2016-03-11 14:20  3%               ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Zhang, Helin @ 2016-03-11 14:17 UTC (permalink / raw)
  To: Thomas Monjalon, Panu Matilainen; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 11, 2016 7:20 PM
> To: Panu Matilainen; Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether
> type
> 
> 2016-03-11 13:19, Panu Matilainen:
> > On 03/11/2016 10:49 AM, Helin Zhang wrote:
> > > -int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t
> > > tag_type);
> > > +int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
> > > +				    enum rte_vlan_type vlan_type,
> > > +				    uint16_t tag_type);
> > > +int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t
> > > +tag_type); int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
> > > +					  enum rte_vlan_type vlan_type,
> > > +					  uint16_t tag_type);
> > >
> > >   /**
> > >    * Set VLAN offload configuration on an Ethernet device
> >
> > Its nice to see people actually trying to be compatible on occasion :)
> >
> > However in this case there's not much point in doing so, because
> > libethdev ABI has already been broken in this cycle:
> > http://dpdk.org/browse/dpdk/commit/?id=cfd2279ea6299826fe992028f1dffaf
> > 9fa7e7d0a
> >
> > In other words, the compatibility versions can never get invoked
> > because all software built against libethdev needs to be rebuilt
> > anyway because of the soname bump. Just drop the compat versions, no
> > point carrying around something that cannot possibly get used.
> 
> Oh yes, you are right.
> Sorry Helin for having required that extra work.
> On the good side, you have learnt how to do it ;)

Yes, as Thomas said, at leat l know how to do that, and the extra work was not too big.
Thomas, Panu, thank you very much for the great comments!

Thomas, does that mean I just need to work out a new version and just let the ABI
changes as is. No ABI annoucenment will be requried? No RTE_NEXT_ABI will be used?

Regards,
Helin

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type
  2016-03-11 11:19  3%         ` Panu Matilainen
@ 2016-03-11 11:20  0%           ` Thomas Monjalon
  2016-03-11 14:17  4%             ` Zhang, Helin
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-11 11:20 UTC (permalink / raw)
  To: Panu Matilainen, Helin Zhang; +Cc: dev

2016-03-11 13:19, Panu Matilainen:
> On 03/11/2016 10:49 AM, Helin Zhang wrote:
> > -int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
> > +int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
> > +				    enum rte_vlan_type vlan_type,
> > +				    uint16_t tag_type);
> > +int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tag_type);
> > +int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
> > +					  enum rte_vlan_type vlan_type,
> > +					  uint16_t tag_type);
> >
> >   /**
> >    * Set VLAN offload configuration on an Ethernet device
> 
> Its nice to see people actually trying to be compatible on occasion :)
> 
> However in this case there's not much point in doing so, because 
> libethdev ABI has already been broken in this cycle:
> http://dpdk.org/browse/dpdk/commit/?id=cfd2279ea6299826fe992028f1dffaf9fa7e7d0a
> 
> In other words, the compatibility versions can never get invoked because 
> all software built against libethdev needs to be rebuilt anyway because 
> of the soname bump. Just drop the compat versions, no point carrying 
> around something that cannot possibly get used.

Oh yes, you are right.
Sorry Helin for having required that extra work.
On the good side, you have learnt how to do it ;)

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type
  2016-03-11  8:49  7%       ` [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type Helin Zhang
@ 2016-03-11 11:19  3%         ` Panu Matilainen
  2016-03-11 11:20  0%           ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-11 11:19 UTC (permalink / raw)
  To: Helin Zhang, dev

On 03/11/2016 10:49 AM, Helin Zhang wrote:
> In order to set ether type of VLAN for single VLAN, inner
> and outer VLAN, the VLAN type as an input parameter is added
> to 'rte_eth_dev_set_vlan_ether_type()'.
> In addition, corresponding changes in e1000, ixgbe and i40e
> are also added.
>
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> ---
>   app/test-pmd/cmdline.c                      | 30 +++++++++-----
>   app/test-pmd/config.c                       |  9 +++--
>   app/test-pmd/testpmd.h                      |  3 +-
>   doc/guides/rel_notes/release_16_04.rst      |  4 ++
>   doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 +----
>   drivers/net/e1000/igb_ethdev.c              | 21 +++++++---
>   drivers/net/i40e/i40e_ethdev.c              | 63 +++++++++++++++++++++++++++--
>   drivers/net/ixgbe/ixgbe_ethdev.c            | 19 +++++++--
>   lib/librte_ether/rte_ethdev.c               | 25 +++++++++++-
>   lib/librte_ether/rte_ethdev.h               | 23 ++++++++++-
>   lib/librte_ether/rte_ether_version.map      |  7 ++++
>   11 files changed, 175 insertions(+), 40 deletions(-)
>
> v4:
>   - Updated the doc of testpmd guide.
>
> v3:
>   - Used versioning mechanism to avoid ABI issue.
>   - Re-organized the patch set.
>
> v2:
>   - Used RTE_NEXT_ABI to avoid ABI change issue.
>   - Reworked the announcement of ABI change for release 16.07.
>
[...]
> @@ -1077,7 +1088,7 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
>   /**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
>
>   typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
> -				  uint16_t tpid);
> +				enum rte_vlan_type type, uint16_t tpid);
>   /**< @internal set the outer VLAN-TPID by an Ethernet device. */
>
>   typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
> @@ -2346,6 +2357,8 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
>    *
>    * @param port_id
>    *   The port identifier of the Ethernet device.
> + * @vlan_type
> + *   The vlan type.
>    * @param tag_type
>    *   The Tag Protocol ID
>    * @return
> @@ -2353,7 +2366,13 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
>    *   - (-ENOSUP) if hardware-assisted VLAN TPID setup is not supported.
>    *   - (-ENODEV) if *port_id* invalid.
>    */
> -int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
> +int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
> +				    enum rte_vlan_type vlan_type,
> +				    uint16_t tag_type);
> +int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tag_type);
> +int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
> +					  enum rte_vlan_type vlan_type,
> +					  uint16_t tag_type);
>
>   /**
>    * Set VLAN offload configuration on an Ethernet device

Its nice to see people actually trying to be compatible on occasion :)

However in this case there's not much point in doing so, because 
libethdev ABI has already been broken in this cycle:
http://dpdk.org/browse/dpdk/commit/?id=cfd2279ea6299826fe992028f1dffaf9fa7e7d0a

In other words, the compatibility versions can never get invoked because 
all software built against libethdev needs to be rebuilt anyway because 
of the soname bump. Just drop the compat versions, no point carrying 
around something that cannot possibly get used.

	- Panu -

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type
  2016-03-11  8:49  4%     ` [dpdk-dev] [PATCH v4 " Helin Zhang
@ 2016-03-11  8:49  7%       ` Helin Zhang
  2016-03-11 11:19  3%         ` Panu Matilainen
  2016-03-11 16:50  5%       ` [dpdk-dev] [PATCH v5 0/2] i40e setting ether type of VLANs Helin Zhang
  1 sibling, 1 reply; 200+ results
From: Helin Zhang @ 2016-03-11  8:49 UTC (permalink / raw)
  To: dev

In order to set ether type of VLAN for single VLAN, inner
and outer VLAN, the VLAN type as an input parameter is added
to 'rte_eth_dev_set_vlan_ether_type()'.
In addition, corresponding changes in e1000, ixgbe and i40e
are also added.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 app/test-pmd/cmdline.c                      | 30 +++++++++-----
 app/test-pmd/config.c                       |  9 +++--
 app/test-pmd/testpmd.h                      |  3 +-
 doc/guides/rel_notes/release_16_04.rst      |  4 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 +----
 drivers/net/e1000/igb_ethdev.c              | 21 +++++++---
 drivers/net/i40e/i40e_ethdev.c              | 63 +++++++++++++++++++++++++++--
 drivers/net/ixgbe/ixgbe_ethdev.c            | 19 +++++++--
 lib/librte_ether/rte_ethdev.c               | 25 +++++++++++-
 lib/librte_ether/rte_ethdev.h               | 23 ++++++++++-
 lib/librte_ether/rte_ether_version.map      |  7 ++++
 11 files changed, 175 insertions(+), 40 deletions(-)

v4:
 - Updated the doc of testpmd guide.

v3:
 - Used versioning mechanism to avoid ABI issue.
 - Re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..1eeb8a8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -277,8 +277,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set the VLAN QinQ (extended queue in queue)"
 			" on a port.\n\n"
 
-			"vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
+			"vlan set (inner|outer) tpid (value) (port_id)\n"
+			"    Set the VLAN TPID for Packet Filtering on"
 			" a port\n\n"
 
 			"rx_vlan add (vlan_id|all) (port_id)\n"
@@ -297,10 +297,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Remove a vlan_id, to the set of VLAN identifiers"
 			"filtered for VF(s) from port_id.\n\n"
 
-			"rx_vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
-			" a port\n\n"
-
 			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
 			"(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
 			"   add a tunnel filter of a port.\n\n"
@@ -2747,6 +2743,7 @@ cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
 struct cmd_vlan_offload_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	cmdline_fixed_string_t on;
 	cmdline_fixed_string_t port_id;
@@ -2847,6 +2844,7 @@ cmdline_parse_inst_t cmd_vlan_offload = {
 struct cmd_vlan_tpid_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	uint16_t tp_id;
 	uint8_t port_id;
@@ -2858,8 +2856,17 @@ cmd_vlan_tpid_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	struct cmd_vlan_tpid_result *res = parsed_result;
-	vlan_tpid_set(res->port_id, res->tp_id);
-	return;
+	enum rte_vlan_type vlan_type;
+
+	if (!strcmp(res->vlan_type, "inner"))
+		vlan_type = ETH_VLAN_TYPE_INNER;
+	else if (!strcmp(res->vlan_type, "outer"))
+		vlan_type = ETH_VLAN_TYPE_OUTER;
+	else {
+		printf("Unknown vlan type\n");
+		return;
+	}
+	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
 }
 
 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
@@ -2868,6 +2875,9 @@ cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
 cmdline_parse_token_string_t cmd_vlan_tpid_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 set, "set");
+cmdline_parse_token_string_t cmd_vlan_type =
+	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+				 vlan_type, "inner#outer");
 cmdline_parse_token_string_t cmd_vlan_tpid_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 what, "tpid");
@@ -2881,10 +2891,12 @@ cmdline_parse_token_num_t cmd_vlan_tpid_portid =
 cmdline_parse_inst_t cmd_vlan_tpid = {
 	.f = cmd_vlan_tpid_parsed,
 	.data = NULL,
-	.help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+	.help_str = "set inner|outer tpid tp_id port_id, set the VLAN "
+		    "Ether type",
 	.tokens = {
 		(void *)&cmd_vlan_tpid_vlan,
 		(void *)&cmd_vlan_tpid_set,
+		(void *)&cmd_vlan_type,
 		(void *)&cmd_vlan_tpid_what,
 		(void *)&cmd_vlan_tpid_tpid,
 		(void *)&cmd_vlan_tpid_portid,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..5bb09a5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1821,19 +1821,20 @@ rx_vlan_all_filter_set(portid_t port_id, int on)
 }
 
 void
-vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
 {
 	int diag;
+
 	if (port_id_is_invalid(port_id, ENABLED_WARN))
 		return;
 
-	diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+	diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
 	if (diag == 0)
 		return;
 
-	printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+	printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
 	       "diag=%d\n",
-	       port_id, tp_id, diag);
+	       port_id, vlan_type, tp_id, diag);
 }
 
 void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b618998..0f72ca1 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -508,7 +508,8 @@ void rx_vlan_filter_set(portid_t port_id, int on);
 void rx_vlan_all_filter_set(portid_t port_id, int on);
 int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
 void vlan_extend_set(portid_t port_id, int on);
-void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
+void vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type,
+		   uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
 void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer);
 void tx_vlan_reset(portid_t port_id);
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 7c09fef..c6e5ef0 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -125,6 +125,10 @@ This section should contain new features added in this release. Sample format:
 
   Af_packet device can now be detached using API, like other PMD devices.
 
+* **Added modifying ether type of both single and double VLAN for i40e**
+
+  Versioning mechanism was introduced, to avoid any ABI issue.
+
 
 Resolved Issues
 ---------------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..e2b2224 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -498,9 +498,9 @@ Set the VLAN QinQ (extended queue in queue) on for a port::
 vlan set tpid
 ~~~~~~~~~~~~~
 
-Set the outer VLAN TPID for packet filtering on a port::
+Set the inner or outer VLAN TPID for packet filtering on a port::
 
-   testpmd> vlan set tpid (value) (port_id)
+   testpmd> vlan set (inner|outer) tpid (value) (port_id)
 
 .. note::
 
@@ -540,13 +540,6 @@ Remove a VLAN ID, from the set of VLAN identifiers filtered for VF(s) for port I
 
    testpmd> rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)
 
-rx_vlan set tpid
-~~~~~~~~~~~~~~~~
-
-Set the outer VLAN TPID for packet filtering on a port::
-
-   testpmd> rx_vlan set tpid (value) (port_id)
-
 tunnel_filter add
 ~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index f889876..4549e0a 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -126,7 +126,9 @@ static int  eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int eth_igb_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+				  enum rte_vlan_type vlan_type,
+				  uint16_t tpid_id);
 static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
@@ -2194,14 +2196,23 @@ eth_igb_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+		      enum rte_vlan_type vlan_type,
+		      uint16_t tpid)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t reg = ETHER_TYPE_VLAN ;
+	uint32_t reg = ETHER_TYPE_VLAN;
 
-	reg |= (tpid << 16);
-	E1000_WRITE_REG(hw, E1000_VET, reg);
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		reg |= (tpid << 16);
+		E1000_WRITE_REG(hw, E1000_VET, reg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0c87ec1..e3fc0bc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -266,6 +266,11 @@
 #define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
 #define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
 
+#define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK  \
+	I40E_MASK(0xFFFF, I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT)
+
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
@@ -292,7 +297,9 @@ static void i40e_dev_info_get(struct rte_eth_dev *dev,
 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
 				uint16_t vlan_id,
 				int on);
-static void i40e_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid);
+static void i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+			       enum rte_vlan_type vlan_type,
+			       uint16_t tpid);
 static void i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
 				      uint16_t queue,
@@ -2313,10 +2320,52 @@ i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-i40e_vlan_tpid_set(__rte_unused struct rte_eth_dev *dev,
-		   __rte_unused uint16_t tpid)
+i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+		   enum rte_vlan_type vlan_type,
+		   uint16_t tpid)
 {
-	PMD_INIT_FUNC_TRACE();
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t reg_r = 0, reg_w = 0;
+	uint16_t reg_id = 0;
+	int ret;
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_OUTER:
+		reg_id = 2;
+		break;
+	case ETH_VLAN_TYPE_INNER:
+		reg_id = 3;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d", vlan_type);
+		return;
+	}
+	ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					  &reg_r, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug read from "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: "
+		    "0x%08"PRIx64"", reg_id, reg_r);
+
+	reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
+	reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
+	if (reg_r == reg_w) {
+		PMD_DRV_LOG(DEBUG, "No need to write");
+		return;
+	}
+
+	ret = i40e_aq_debug_write_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					   reg_w, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug write to "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
+		    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
 }
 
 static void
@@ -7332,11 +7381,17 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void
 i40e_hw_init(struct i40e_hw *hw)
 {
+	struct rte_eth_dev *dev = ((struct i40e_adapter *)(hw->back))->eth_dev;
+
 	/* clear the PF Queue Filter control register */
 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, 0);
 
 	/* Disable symmetric hash per port */
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
+
+	/* Set the global registers with default ether type value */
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, ETHER_TYPE_VLAN);
 }
 
 enum i40e_filter_pctype
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a9a1583..ce3ce9f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -178,7 +178,9 @@ static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+				enum rte_vlan_type vlan_type,
+				uint16_t tpid_id);
 static void ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
 		uint16_t queue, bool on);
 static void ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
@@ -1543,13 +1545,22 @@ ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 }
 
 static void
-ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+		    enum rte_vlan_type vlan_type,
+		    uint16_t tpid)
 {
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/* Only the high 16-bits is valid */
-	IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		/* Only the high 16-bits is valid */
+		IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 }
 
 void
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..bb0c3eb 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -65,6 +65,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
+#include <rte_compat.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -1697,17 +1698,37 @@ rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id, int o
 }
 
 int
-rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tpid)
+rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tpid)
 {
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
-	(*dev->dev_ops->vlan_tpid_set)(dev, tpid);
+	(*dev->dev_ops->vlan_tpid_set)(dev, ETH_VLAN_TYPE_INNER, tpid);
 
 	return 0;
 }
+VERSION_SYMBOL(rte_eth_dev_set_vlan_ether_type, _v22, 2.2);
+
+int
+rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
+				      enum rte_vlan_type vlan_type,
+				      uint16_t tpid)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
+	(*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, tpid);
+
+	return 0;
+}
+BIND_DEFAULT_SYMBOL(rte_eth_dev_set_vlan_ether_type, _v1604, 16.04);
+MAP_STATIC_SYMBOL(int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+		  enum rte_vlan_type vlan_type, uint16_t tpid),
+		  rte_eth_dev_set_vlan_ether_type_v1604);
 
 int
 rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..21db144 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -351,6 +351,17 @@ struct rte_eth_rxmode {
 };
 
 /**
+ * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
+ * Note that single VLAN is treated the same as inner VLAN.
+ */
+enum rte_vlan_type {
+	ETH_VLAN_TYPE_UNKNOWN = 0,
+	ETH_VLAN_TYPE_INNER, /**< Single VLAN, or inner VLAN. */
+	ETH_VLAN_TYPE_OUTER, /**< Outer VLAN. */
+	ETH_VLAN_TYPE_MAX,
+};
+
+/**
  * A structure used to configure the Receive Side Scaling (RSS) feature
  * of an Ethernet port.
  * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1077,7 +1088,7 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
 /**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
 
 typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
-				  uint16_t tpid);
+				enum rte_vlan_type type, uint16_t tpid);
 /**< @internal set the outer VLAN-TPID by an Ethernet device. */
 
 typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
@@ -2346,6 +2357,8 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @vlan_type
+ *   The vlan type.
  * @param tag_type
  *   The Tag Protocol ID
  * @return
@@ -2353,7 +2366,13 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *   - (-ENOSUP) if hardware-assisted VLAN TPID setup is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  */
-int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+				    enum rte_vlan_type vlan_type,
+				    uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
+					  enum rte_vlan_type vlan_type,
+					  uint16_t tag_type);
 
 /**
  * Set VLAN offload configuration on an Ethernet device
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..6098de5 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_set_vlan_ether_type;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v4 0/2] i40e setting ether type of VLANs
  2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
  2016-03-10 16:36  7%     ` [dpdk-dev] [PATCH v3 1/2] ethdev: add vlan type for setting ether type Helin Zhang
  2016-03-11  2:36  0%     ` [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs Lu, Wenzhuo
@ 2016-03-11  8:49  4%     ` Helin Zhang
  2016-03-11  8:49  7%       ` [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type Helin Zhang
  2016-03-11 16:50  5%       ` [dpdk-dev] [PATCH v5 0/2] i40e setting ether type of VLANs Helin Zhang
  2 siblings, 2 replies; 200+ results
From: Helin Zhang @ 2016-03-11  8:49 UTC (permalink / raw)
  To: dev

It adds setting ether type of both single VLAN(inner VLAN)
and outer VLAN for i40e. For ixgbe and e1000/igb, it supports
setting single VLAN(inner VLAN) only, and can be extended in
the future.

The patch set was branched off rel_16_04 of repo dpdk-next-net,
on below commit.
commit 5721e6447b5c20208a32c919a509e89d78c3e68d
Author: Robin Jarry <robin.jarry@6wind.com>
Date:   Thu Mar 3 15:27:40 2016 +0100
    mlx4: ensure number of RX queues is a power of 2

v4:
 - Updated the doc of testpmd guide.

v3:
 - Used versioning mechanism to avoid ABI issue.
 - Re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.
 - Fixed a i40e overflow issue.

Helin Zhang (2):
  ethdev: add vlan type for setting ether type
  i40e: fix the overflow issue

 app/test-pmd/cmdline.c                      | 30 +++++++++-----
 app/test-pmd/config.c                       |  9 +++--
 app/test-pmd/testpmd.h                      |  3 +-
 doc/guides/rel_notes/release_16_04.rst      |  4 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 +----
 drivers/net/e1000/igb_ethdev.c              | 21 +++++++---
 drivers/net/i40e/i40e_ethdev.c              | 63 +++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_rxtx.c                |  4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 19 +++++++--
 lib/librte_ether/rte_ethdev.c               | 25 +++++++++++-
 lib/librte_ether/rte_ethdev.h               | 23 ++++++++++-
 lib/librte_ether/rte_ether_version.map      |  7 ++++
 12 files changed, 177 insertions(+), 42 deletions(-)

-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs
  2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
  2016-03-10 16:36  7%     ` [dpdk-dev] [PATCH v3 1/2] ethdev: add vlan type for setting ether type Helin Zhang
@ 2016-03-11  2:36  0%     ` Lu, Wenzhuo
  2016-03-11  8:49  4%     ` [dpdk-dev] [PATCH v4 " Helin Zhang
  2 siblings, 0 replies; 200+ results
From: Lu, Wenzhuo @ 2016-03-11  2:36 UTC (permalink / raw)
  To: Zhang, Helin, dev

Hi,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Helin Zhang
> Sent: Friday, March 11, 2016 12:37 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs
> 
> It adds setting ether type of both single VLAN(inner VLAN) and outer VLAN
> for i40e. For ixgbe and e1000/igb, it supports setting single VLAN(inner VLAN)
> only, and can be extended in the future.
> 
> The patch set was branched off rel_16_04 of repo dpdk-next-net, on below
> commit.
> commit 5cfa5d194a8a45176e70af05719f7e3b136868be
> Author: Zhe Tao <zhe.tao@intel.com>
> Date:   Thu Mar 10 15:26:22 2016 +0000
>     ixgbe: fix ixgbevf RX/TX function assignment
> 
> v3:
>  - Used versioning mechanism to avoid ABI issue.
>  - re-organized the patch set.
> 
> v2:
>  - Used RTE_NEXT_ABI to avoid ABI change issue.
>  - Reworked the announcement of ABI change for release 16.07.
>  - Fixed a i40e overflow issue.
> 
> Helin Zhang (2):
>   ethdev: add vlan type for setting ether type
>   i40e: fix the overflow issue
> 
>  app/test-pmd/cmdline.c                 | 30 +++++++++++-----
>  app/test-pmd/config.c                  |  9 ++---
>  app/test-pmd/testpmd.h                 |  3 +-
>  doc/guides/rel_notes/release_16_04.rst |  4 +++
>  drivers/net/e1000/igb_ethdev.c         | 21 +++++++++---
>  drivers/net/i40e/i40e_ethdev.c         | 63
> +++++++++++++++++++++++++++++++---
>  drivers/net/i40e/i40e_rxtx.c           |  4 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c       | 19 +++++++---
>  lib/librte_ether/rte_ethdev.c          | 25 ++++++++++++--
>  lib/librte_ether/rte_ethdev.h          | 23 +++++++++++--
>  lib/librte_ether/rte_ether_version.map |  7 ++++
>  11 files changed, 175 insertions(+), 33 deletions(-)
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
If you can update the doc/guides/testpmd_app_ug/testpmd_funcs.rst for the CLI change.

> 
> --
> 2.5.0

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4 0/2] add support for buffered tx to ethdev
  2016-03-10 10:57  4% ` [dpdk-dev] [PATCH v3 " Tomasz Kulasek
  2016-03-10 11:31  0%   ` Ananyev, Konstantin
@ 2016-03-10 17:19  4%   ` Tomasz Kulasek
  1 sibling, 0 replies; 200+ results
From: Tomasz Kulasek @ 2016-03-10 17:19 UTC (permalink / raw)
  To: dev

Many sample apps include internal buffering for single-packet-at-a-time
operation. Since this is such a common paradigm, this functionality is
better suited to being implemented in the ethdev API.

The new APIs in the ethdev library are:
* rte_eth_tx_buffer_init - initialize buffer
* rte_eth_tx_buffer - buffer up a single packet for future transmission
* rte_eth_tx_buffer_flush - flush any unsent buffered packets
* rte_eth_tx_buffer_set_err_callback - set up a callback to be called in
  case transmitting a buffered burst fails. By default, we just free the
  unsent packets.

As well as these, an additional reference callbacks are provided, which
frees the packets:

* rte_eth_tx_buffer_drop_callback - silently drop packets (default
  behavior)
* rte_eth_tx_buffer_count_callback - drop and update user-provided counter
  to track the number of dropped packets

Due to the feedback from mailing list, that buffer management facilities
in the user application are more preferable than API simplicity, we decided
to move internal buffer table, as well as callback functions and user data,
from rte_eth_dev/rte_eth_dev_data to the application space.
It prevents ABI breakage and gives some more flexibility in the buffer's
management such as allocation, dynamical size change, reuse buffers on many
ports or after fail, and so on.


The following steps illustrate how tx buffers can be used in application:

1) Initialization

a) Allocate memory for a buffer

   struct rte_eth_dev_tx_buffer *buffer = rte_zmalloc_socket("tx_buffer",
           RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, socket_id);

   RTE_ETH_TX_BUFFER_SIZE(size) macro computes memory required to store
   "size" packets in buffer.

b) Initialize allocated memory and set up default values. Threshold level
   must be lower than or equal to the MAX_PKT_BURST from 1a)

   rte_eth_tx_buffer_init(buffer, threshold);


c) Set error callback (optional)

   rte_eth_tx_buffer_set_err_callback(buffer, callback_fn, userdata);


2) Store packet "pkt" in buffer and send them all to the queue_id on
   port_id when number of packets reaches threshold level set up in 1b)

   rte_eth_tx_buffer(port_id, queue_id, buffer, pkt);


3) Send all stored packets to the queue_id on port_id

   rte_eth_tx_buffer_flush(port_id, queue_id, buffer);


4) Flush buffer and free memory

   rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
   ...
   rte_free(buffer);

v4 changes:
 - added comments
 - chaged names of error callback and user data
 - changed order of function names in map file

v3 changes:
 - error counter removed from tx buffer structure, now default behavior is
   silent drop of unsent packets
 - some names was changed in tx buffer structure to be more descriptive
 - two default calbacks are provided: rte_eth_tx_buffer_drop_callback and
   rte_eth_tx_buffer_count_callback

v2 changes:
 - reworked to use new buffer model
 - buffer data and callbacks are removed from rte_eth_dev/rte_eth_dev_data,
   so this patch doesn't brake an ABI anymore
 - introduced RTE_ETH_TX_BUFFER macro and rte_eth_tx_buffer_init
 - buffers are not attached to the port-queue
 - buffers can be allocated dynamically during application work
 - size of buffer can be changed without port restart

Tomasz Kulasek (2):
  ethdev: add buffered tx api
  examples: rework to use buffered tx

 examples/l2fwd-jobstats/main.c                     |  104 ++++------
 examples/l2fwd-keepalive/main.c                    |  100 ++++------
 examples/l2fwd/main.c                              |  104 ++++------
 examples/l3fwd-acl/main.c                          |   92 ++++-----
 examples/l3fwd-power/main.c                        |   89 ++++-----
 examples/link_status_interrupt/main.c              |  107 ++++------
 .../client_server_mp/mp_client/client.c            |  101 ++++++----
 examples/multi_process/l2fwd_fork/main.c           |   97 ++++-----
 examples/packet_ordering/main.c                    |  122 ++++++++----
 examples/qos_meter/main.c                          |   61 ++----
 lib/librte_ether/rte_ethdev.c                      |   46 +++++
 lib/librte_ether/rte_ethdev.h                      |  206 +++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map             |   10 +
 13 files changed, 697 insertions(+), 542 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 1/2] ethdev: add vlan type for setting ether type
  2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
@ 2016-03-10 16:36  7%     ` Helin Zhang
  2016-03-11  2:36  0%     ` [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs Lu, Wenzhuo
  2016-03-11  8:49  4%     ` [dpdk-dev] [PATCH v4 " Helin Zhang
  2 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-03-10 16:36 UTC (permalink / raw)
  To: dev

In order to set ether type of VLAN for single VLAN, inner
and outer VLAN, the VLAN type as an input parameter is added
to 'rte_eth_dev_set_vlan_ether_type()'.
In addition, corresponding changes in e1000, ixgbe and i40e
are also added.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                 | 30 +++++++++++-----
 app/test-pmd/config.c                  |  9 ++---
 app/test-pmd/testpmd.h                 |  3 +-
 doc/guides/rel_notes/release_16_04.rst |  4 +++
 drivers/net/e1000/igb_ethdev.c         | 21 +++++++++---
 drivers/net/i40e/i40e_ethdev.c         | 63 +++++++++++++++++++++++++++++++---
 drivers/net/ixgbe/ixgbe_ethdev.c       | 19 +++++++---
 lib/librte_ether/rte_ethdev.c          | 25 ++++++++++++--
 lib/librte_ether/rte_ethdev.h          | 23 +++++++++++--
 lib/librte_ether/rte_ether_version.map |  7 ++++
 10 files changed, 173 insertions(+), 31 deletions(-)

v3:
 - Used versioning mechanism to avoid ABI issue.
 - re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..1eeb8a8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -277,8 +277,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set the VLAN QinQ (extended queue in queue)"
 			" on a port.\n\n"
 
-			"vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
+			"vlan set (inner|outer) tpid (value) (port_id)\n"
+			"    Set the VLAN TPID for Packet Filtering on"
 			" a port\n\n"
 
 			"rx_vlan add (vlan_id|all) (port_id)\n"
@@ -297,10 +297,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Remove a vlan_id, to the set of VLAN identifiers"
 			"filtered for VF(s) from port_id.\n\n"
 
-			"rx_vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
-			" a port\n\n"
-
 			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
 			"(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
 			"   add a tunnel filter of a port.\n\n"
@@ -2747,6 +2743,7 @@ cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
 struct cmd_vlan_offload_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	cmdline_fixed_string_t on;
 	cmdline_fixed_string_t port_id;
@@ -2847,6 +2844,7 @@ cmdline_parse_inst_t cmd_vlan_offload = {
 struct cmd_vlan_tpid_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	uint16_t tp_id;
 	uint8_t port_id;
@@ -2858,8 +2856,17 @@ cmd_vlan_tpid_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	struct cmd_vlan_tpid_result *res = parsed_result;
-	vlan_tpid_set(res->port_id, res->tp_id);
-	return;
+	enum rte_vlan_type vlan_type;
+
+	if (!strcmp(res->vlan_type, "inner"))
+		vlan_type = ETH_VLAN_TYPE_INNER;
+	else if (!strcmp(res->vlan_type, "outer"))
+		vlan_type = ETH_VLAN_TYPE_OUTER;
+	else {
+		printf("Unknown vlan type\n");
+		return;
+	}
+	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
 }
 
 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
@@ -2868,6 +2875,9 @@ cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
 cmdline_parse_token_string_t cmd_vlan_tpid_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 set, "set");
+cmdline_parse_token_string_t cmd_vlan_type =
+	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+				 vlan_type, "inner#outer");
 cmdline_parse_token_string_t cmd_vlan_tpid_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 what, "tpid");
@@ -2881,10 +2891,12 @@ cmdline_parse_token_num_t cmd_vlan_tpid_portid =
 cmdline_parse_inst_t cmd_vlan_tpid = {
 	.f = cmd_vlan_tpid_parsed,
 	.data = NULL,
-	.help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+	.help_str = "set inner|outer tpid tp_id port_id, set the VLAN "
+		    "Ether type",
 	.tokens = {
 		(void *)&cmd_vlan_tpid_vlan,
 		(void *)&cmd_vlan_tpid_set,
+		(void *)&cmd_vlan_type,
 		(void *)&cmd_vlan_tpid_what,
 		(void *)&cmd_vlan_tpid_tpid,
 		(void *)&cmd_vlan_tpid_portid,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..5bb09a5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1821,19 +1821,20 @@ rx_vlan_all_filter_set(portid_t port_id, int on)
 }
 
 void
-vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
 {
 	int diag;
+
 	if (port_id_is_invalid(port_id, ENABLED_WARN))
 		return;
 
-	diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+	diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
 	if (diag == 0)
 		return;
 
-	printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+	printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
 	       "diag=%d\n",
-	       port_id, tp_id, diag);
+	       port_id, vlan_type, tp_id, diag);
 }
 
 void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b618998..0f72ca1 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -508,7 +508,8 @@ void rx_vlan_filter_set(portid_t port_id, int on);
 void rx_vlan_all_filter_set(portid_t port_id, int on);
 int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
 void vlan_extend_set(portid_t port_id, int on);
-void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
+void vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type,
+		   uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
 void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer);
 void tx_vlan_reset(portid_t port_id);
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5abf48a..4729019 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -119,6 +119,10 @@ This section should contain new features added in this release. Sample format:
 
   Only available with Mellanox OFED >= 3.2.
 
+* **Added modifying ether type of both single and double VLAN for i40e**
+
+  Macro of RTE_NEXT_ABI was introduced, as ABI change involved.
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 41c107d..36d50c9 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -126,7 +126,9 @@ static int  eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int eth_igb_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+				  enum rte_vlan_type vlan_type,
+				  uint16_t tpid_id);
 static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
@@ -2194,14 +2196,23 @@ eth_igb_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+		      enum rte_vlan_type vlan_type,
+		      uint16_t tpid)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t reg = ETHER_TYPE_VLAN ;
+	uint32_t reg = ETHER_TYPE_VLAN;
 
-	reg |= (tpid << 16);
-	E1000_WRITE_REG(hw, E1000_VET, reg);
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		reg |= (tpid << 16);
+		E1000_WRITE_REG(hw, E1000_VET, reg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0c87ec1..e3fc0bc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -266,6 +266,11 @@
 #define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
 #define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
 
+#define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK  \
+	I40E_MASK(0xFFFF, I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT)
+
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
@@ -292,7 +297,9 @@ static void i40e_dev_info_get(struct rte_eth_dev *dev,
 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
 				uint16_t vlan_id,
 				int on);
-static void i40e_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid);
+static void i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+			       enum rte_vlan_type vlan_type,
+			       uint16_t tpid);
 static void i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
 				      uint16_t queue,
@@ -2313,10 +2320,52 @@ i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-i40e_vlan_tpid_set(__rte_unused struct rte_eth_dev *dev,
-		   __rte_unused uint16_t tpid)
+i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+		   enum rte_vlan_type vlan_type,
+		   uint16_t tpid)
 {
-	PMD_INIT_FUNC_TRACE();
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t reg_r = 0, reg_w = 0;
+	uint16_t reg_id = 0;
+	int ret;
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_OUTER:
+		reg_id = 2;
+		break;
+	case ETH_VLAN_TYPE_INNER:
+		reg_id = 3;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d", vlan_type);
+		return;
+	}
+	ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					  &reg_r, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug read from "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: "
+		    "0x%08"PRIx64"", reg_id, reg_r);
+
+	reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
+	reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
+	if (reg_r == reg_w) {
+		PMD_DRV_LOG(DEBUG, "No need to write");
+		return;
+	}
+
+	ret = i40e_aq_debug_write_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					   reg_w, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug write to "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
+		    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
 }
 
 static void
@@ -7332,11 +7381,17 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void
 i40e_hw_init(struct i40e_hw *hw)
 {
+	struct rte_eth_dev *dev = ((struct i40e_adapter *)(hw->back))->eth_dev;
+
 	/* clear the PF Queue Filter control register */
 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, 0);
 
 	/* Disable symmetric hash per port */
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
+
+	/* Set the global registers with default ether type value */
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, ETHER_TYPE_VLAN);
 }
 
 enum i40e_filter_pctype
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a9a1583..ce3ce9f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -178,7 +178,9 @@ static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+				enum rte_vlan_type vlan_type,
+				uint16_t tpid_id);
 static void ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
 		uint16_t queue, bool on);
 static void ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
@@ -1543,13 +1545,22 @@ ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 }
 
 static void
-ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+		    enum rte_vlan_type vlan_type,
+		    uint16_t tpid)
 {
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/* Only the high 16-bits is valid */
-	IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		/* Only the high 16-bits is valid */
+		IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
 }
 
 void
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..bb0c3eb 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -65,6 +65,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
+#include <rte_compat.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -1697,17 +1698,37 @@ rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id, int o
 }
 
 int
-rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tpid)
+rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tpid)
 {
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
-	(*dev->dev_ops->vlan_tpid_set)(dev, tpid);
+	(*dev->dev_ops->vlan_tpid_set)(dev, ETH_VLAN_TYPE_INNER, tpid);
 
 	return 0;
 }
+VERSION_SYMBOL(rte_eth_dev_set_vlan_ether_type, _v22, 2.2);
+
+int
+rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
+				      enum rte_vlan_type vlan_type,
+				      uint16_t tpid)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
+	(*dev->dev_ops->vlan_tpid_set)(dev, vlan_type, tpid);
+
+	return 0;
+}
+BIND_DEFAULT_SYMBOL(rte_eth_dev_set_vlan_ether_type, _v1604, 16.04);
+MAP_STATIC_SYMBOL(int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+		  enum rte_vlan_type vlan_type, uint16_t tpid),
+		  rte_eth_dev_set_vlan_ether_type_v1604);
 
 int
 rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..21db144 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -351,6 +351,17 @@ struct rte_eth_rxmode {
 };
 
 /**
+ * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
+ * Note that single VLAN is treated the same as inner VLAN.
+ */
+enum rte_vlan_type {
+	ETH_VLAN_TYPE_UNKNOWN = 0,
+	ETH_VLAN_TYPE_INNER, /**< Single VLAN, or inner VLAN. */
+	ETH_VLAN_TYPE_OUTER, /**< Outer VLAN. */
+	ETH_VLAN_TYPE_MAX,
+};
+
+/**
  * A structure used to configure the Receive Side Scaling (RSS) feature
  * of an Ethernet port.
  * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1077,7 +1088,7 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
 /**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
 
 typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
-				  uint16_t tpid);
+				enum rte_vlan_type type, uint16_t tpid);
 /**< @internal set the outer VLAN-TPID by an Ethernet device. */
 
 typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
@@ -2346,6 +2357,8 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @vlan_type
+ *   The vlan type.
  * @param tag_type
  *   The Tag Protocol ID
  * @return
@@ -2353,7 +2366,13 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *   - (-ENOSUP) if hardware-assisted VLAN TPID setup is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  */
-int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+				    enum rte_vlan_type vlan_type,
+				    uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type_v22(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type_v1604(uint8_t port_id,
+					  enum rte_vlan_type vlan_type,
+					  uint16_t tag_type);
 
 /**
  * Set VLAN offload configuration on an Ethernet device
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..6098de5 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_set_vlan_ether_type;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs
  2016-03-07  8:12  4% ` [dpdk-dev] [PATCH v2 0/3] " Helin Zhang
                     ` (2 preceding siblings ...)
  2016-03-07  9:28  0%   ` [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs Thomas Monjalon
@ 2016-03-10 16:36  4%   ` Helin Zhang
  2016-03-10 16:36  7%     ` [dpdk-dev] [PATCH v3 1/2] ethdev: add vlan type for setting ether type Helin Zhang
                       ` (2 more replies)
  3 siblings, 3 replies; 200+ results
From: Helin Zhang @ 2016-03-10 16:36 UTC (permalink / raw)
  To: dev

It adds setting ether type of both single VLAN(inner VLAN) and
outer VLAN for i40e. For ixgbe and e1000/igb, it supports setting
single VLAN(inner VLAN) only, and can be extended in the future.

The patch set was branched off rel_16_04 of repo dpdk-next-net,
on below commit.
commit 5cfa5d194a8a45176e70af05719f7e3b136868be
Author: Zhe Tao <zhe.tao@intel.com>
Date:   Thu Mar 10 15:26:22 2016 +0000
    ixgbe: fix ixgbevf RX/TX function assignment

v3:
 - Used versioning mechanism to avoid ABI issue.
 - re-organized the patch set.

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.
 - Fixed a i40e overflow issue.

Helin Zhang (2):
  ethdev: add vlan type for setting ether type
  i40e: fix the overflow issue

 app/test-pmd/cmdline.c                 | 30 +++++++++++-----
 app/test-pmd/config.c                  |  9 ++---
 app/test-pmd/testpmd.h                 |  3 +-
 doc/guides/rel_notes/release_16_04.rst |  4 +++
 drivers/net/e1000/igb_ethdev.c         | 21 +++++++++---
 drivers/net/i40e/i40e_ethdev.c         | 63 +++++++++++++++++++++++++++++++---
 drivers/net/i40e/i40e_rxtx.c           |  4 +--
 drivers/net/ixgbe/ixgbe_ethdev.c       | 19 +++++++---
 lib/librte_ether/rte_ethdev.c          | 25 ++++++++++++--
 lib/librte_ether/rte_ethdev.h          | 23 +++++++++++--
 lib/librte_ether/rte_ether_version.map |  7 ++++
 11 files changed, 175 insertions(+), 33 deletions(-)

-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 11:55  7% [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice David Hunt
  2016-03-10 12:37  4% ` Olivier MATZ
@ 2016-03-10 16:23  4% ` Mcnamara, John
  1 sibling, 0 replies; 200+ results
From: Mcnamara, John @ 2016-03-10 16:23 UTC (permalink / raw)
  To: Hunt, David, dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Hunt
> Sent: Thursday, March 10, 2016 11:56 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
> 
> Announce the ABI breakage due to addition of external mempool manager
> functionality which requires changes to rte_mempool structure.
> 
> Signed-off-by: David Hunt <david.hunt@intel.com>

Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 0/2] add support for buffered tx to ethdev
  2016-03-10 11:31  0%   ` Ananyev, Konstantin
@ 2016-03-10 16:01  0%     ` Jastrzebski, MichalX K
  0 siblings, 0 replies; 200+ results
From: Jastrzebski, MichalX K @ 2016-03-10 16:01 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ananyev,
> Konstantin
> Sent: Thursday, March 10, 2016 12:32 PM
> To: Kulasek, TomaszX <tomaszx.kulasek@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 0/2] add support for buffered tx to
> ethdev
> 
> > Many sample apps include internal buffering for single-packet-at-a-time
> > operation. Since this is such a common paradigm, this functionality is
> > better suited to being implemented in the ethdev API.
> >
> > The new APIs in the ethdev library are:
> > * rte_eth_tx_buffer_init - initialize buffer
> > * rte_eth_tx_buffer - buffer up a single packet for future transmission
> > * rte_eth_tx_buffer_flush - flush any unsent buffered packets
> > * rte_eth_tx_buffer_set_err_callback - set up a callback to be called in
> >   case transmitting a buffered burst fails. By default, we just free the
> >   unsent packets.
> >
> > As well as these, an additional reference callbacks are provided, which
> > frees the packets:
> >
> > * rte_eth_tx_buffer_drop_callback - silently drop packets (default
> >   behavior)
> > * rte_eth_tx_buffer_count_callback - drop and update user-provided
> counter
> >   to track the number of dropped packets
> >
> > Due to the feedback from mailing list, that buffer management facilities
> > in the user application are more preferable than API simplicity, we
> decided
> > to move internal buffer table, as well as callback functions and user data,
> > from rte_eth_dev/rte_eth_dev_data to the application space.
> > It prevents ABI breakage and gives some more flexibility in the buffer's
> > management such as allocation, dynamical size change, reuse buffers on
> many
> > ports or after fail, and so on.
> >
> >
> > The following steps illustrate how tx buffers can be used in application:
> >
> > 1) Initialization
> >
> > a) Allocate memory for a buffer
> >
> >    struct rte_eth_dev_tx_buffer *buffer = rte_zmalloc_socket("tx_buffer",
> >            RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, socket_id);
> >
> >    RTE_ETH_TX_BUFFER_SIZE(size) macro computes memory required to
> store
> >    "size" packets in buffer.
> >
> > b) Initialize allocated memory and set up default values. Threshold level
> >    must be lower than or equal to the MAX_PKT_BURST from 1a)
> >
> >    rte_eth_tx_buffer_init(buffer, threshold);
> >
> >
> > c) Set error callback (optional)
> >
> >    rte_eth_tx_buffer_set_err_callback(buffer, callback_fn, userdata);
> >
> >
> > 2) Store packet "pkt" in buffer and send them all to the queue_id on
> >    port_id when number of packets reaches threshold level set up in 1b)
> >
> >    rte_eth_tx_buffer(port_id, queue_id, buffer, pkt);
> >
> >
> > 3) Send all stored packets to the queue_id on port_id
> >
> >    rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
> >
> >
> > 4) Flush buffer and free memory
> >
> >    rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
> >    ...
> >    rte_free(buffer);
> >
> > v3 changes:
> >  - error counter removed from tx buffer structure, now default behavior is
> >    silent drop of unsent packets
> >  - some names was changed in tx buffer structure to be more descriptive
> >  - two default calbacks are provided: rte_eth_tx_buffer_drop_callback and
> >    rte_eth_tx_buffer_count_callback
> >
> > v2 changes:
> >  - reworked to use new buffer model
> >  - buffer data and callbacks are removed from
> rte_eth_dev/rte_eth_dev_data,
> >    so this patch doesn't brake an ABI anymore
> >  - introduced RTE_ETH_TX_BUFFER macro and rte_eth_tx_buffer_init
> >  - buffers are not attached to the port-queue
> >  - buffers can be allocated dynamically during application work
> >  - size of buffer can be changed without port restart
> >
> > Tomasz Kulasek (2):
> >   ethdev: add buffered tx api
> >   examples: rework to use buffered tx
> >
> >  examples/l2fwd-jobstats/main.c                     |  104 ++++------
> >  examples/l2fwd-keepalive/main.c                    |  100 ++++------
> >  examples/l2fwd/main.c                              |  104 ++++------
> >  examples/l3fwd-acl/main.c                          |   92 ++++-----
> >  examples/l3fwd-power/main.c                        |   89 ++++-----
> >  examples/link_status_interrupt/main.c              |  107 ++++------
> >  .../client_server_mp/mp_client/client.c            |  101 ++++++----
> >  examples/multi_process/l2fwd_fork/main.c           |   97 ++++-----
> >  examples/packet_ordering/main.c                    |  122 ++++++++----
> >  examples/qos_meter/main.c                          |   61 ++----
> >  lib/librte_ether/rte_ethdev.c                      |   46 +++++
> >  lib/librte_ether/rte_ethdev.h                      |  205 +++++++++++++++++++-
> >  lib/librte_ether/rte_ether_version.map             |   10 +
> >  13 files changed, 696 insertions(+), 542 deletions(-)
> >
> > --
> 
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 
> > 1.7.9.5

Hi Thomas,
Could You write please does this patch meet Your requirements and 
does it have a green light to be applied?

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 13:56  4%     ` Wiles, Keith
@ 2016-03-10 14:55  4%       ` Thomas Monjalon
  2016-04-05 14:06  4%         ` Wiles, Keith
  2016-04-04 14:49  4%       ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-10 14:55 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dev

2016-03-10 13:56, Wiles, Keith:
> >On Thu, Mar 10, 2016 at 01:37:27PM +0100, Olivier MATZ wrote:
> >> Hi David,
> >> 
> >> On 03/10/2016 12:55 PM, David Hunt wrote:
> >> > Announce the ABI breakage due to addition of external mempool
> >> > manager functionality which requires changes to rte_mempool
> >> > structure.
> >> > 
> >> > Signed-off-by: David Hunt <david.hunt@intel.com>
> >> 
> >> Acked-by: Olivier Matz <olivier.matz@6wind.com>
> >> 
> >Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> 
> Asked-by: Keith Wiles <keith.wiles@intel.com>

Is it on purpose, Keith, or a typo? Do you have asked this notice?

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 13:15  4%   ` Bruce Richardson
@ 2016-03-10 13:56  4%     ` Wiles, Keith
  2016-03-10 14:55  4%       ` Thomas Monjalon
  2016-04-04 14:49  4%       ` Thomas Monjalon
  0 siblings, 2 replies; 200+ results
From: Wiles, Keith @ 2016-03-10 13:56 UTC (permalink / raw)
  To: Richardson, Bruce, Olivier MATZ; +Cc: dev

>On Thu, Mar 10, 2016 at 01:37:27PM +0100, Olivier MATZ wrote:
>> Hi David,
>> 
>> On 03/10/2016 12:55 PM, David Hunt wrote:
>> > Announce the ABI breakage due to addition of external mempool
>> > manager functionality which requires changes to rte_mempool
>> > structure.
>> > 
>> > Signed-off-by: David Hunt <david.hunt@intel.com>
>> 
>> Acked-by: Olivier Matz <olivier.matz@6wind.com>
>> 
>Acked-by: Bruce Richardson <bruce.richardson@intel.com>

Asked-by: Keith Wiles <keith.wiles@intel.com>
>
>/Bruce
>


Regards,
Keith





^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data
  2016-03-10  0:00  0% ` Thomas Monjalon
@ 2016-03-10 13:37  0%   ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-10 13:37 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On 3/10/2016 12:00 AM, Thomas Monjalon wrote:
> 2016-02-17 14:20, Ferruh Yigit:
>> This is to provide abstraction and reduce global variable access.
>>
>> Global variable rte_eth_devices kept exported to not break ABI.
>>
>> Bonding driver not selected on purpose, just it seems it is using 
>> rte_eth_devices heavily.
>>
>> There are a few more usage in drivers but they left as it is because they
>> are in fast path code.
> 
> What is the benefit of these functions if you do not plan to remove the
> global variables later?
> 
- Better discipline to abstract, function call can be costly than direct
access, but I believe this is no problem outside of the fast path.
- Helper functions for common tasks, like get private data by port.

> Anyway this discussion targets the release 16.07.
> 
There is no urgency for these.

Thanks,
ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 12:37  4% ` Olivier MATZ
@ 2016-03-10 13:15  4%   ` Bruce Richardson
  2016-03-10 13:56  4%     ` Wiles, Keith
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2016-03-10 13:15 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

On Thu, Mar 10, 2016 at 01:37:27PM +0100, Olivier MATZ wrote:
> Hi David,
> 
> On 03/10/2016 12:55 PM, David Hunt wrote:
> > Announce the ABI breakage due to addition of external mempool
> > manager functionality which requires changes to rte_mempool
> > structure.
> > 
> > Signed-off-by: David Hunt <david.hunt@intel.com>
> 
> Acked-by: Olivier Matz <olivier.matz@6wind.com>
> 
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

/Bruce

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option
  2016-03-10 10:53 31% [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Panu Matilainen
  2016-03-10 10:53 19% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
  2016-03-10 10:53 15% ` [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check Panu Matilainen
@ 2016-03-10 12:52  7% ` Ferruh Yigit
  2 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-10 12:52 UTC (permalink / raw)
  To: Panu Matilainen, dev

On 3/10/2016 10:53 AM, Panu Matilainen wrote:
> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
> ---
>  doc/guides/contributing/versioning.rst |  4 +++-
>  scripts/validate-abi.sh                | 13 ++++++++++---
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
> index ae10a98..33b03a1 100644
> --- a/doc/guides/contributing/versioning.rst
> +++ b/doc/guides/contributing/versioning.rst
> @@ -469,11 +469,13 @@ utilities which can be installed via a package manager. For example::
>  
>  The syntax of the ``validate-abi.sh`` utility is::
>  
> -   ./scripts/validate-abi.sh <REV1> <REV2> <TARGET>
> +   ./scripts/validate-abi.sh [-j[N]] <REV1> <REV2> <TARGET>
>  
>  Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
>  https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
>  on the local repo and target is the usual DPDK compilation target.
> +The optional -j[N] switch enables parallel building with at most
> +N simultaneous jobs, ie the same as -j option of ``make``.
>  
>  For example:
>  
> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
> index c36ad61..f094582 100755
> --- a/scripts/validate-abi.sh
> +++ b/scripts/validate-abi.sh
> @@ -27,13 +27,20 @@
>  #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>  #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  
> +case "$1" in
> +    -j*)
> +        MAKEJOBS="$1"
> +        shift
> +        ;;
> +esac
> +
>  TAG1=$1
>  TAG2=$2
>  TARGET=$3
>  ABI_DIR=`mktemp -d -p /tmp ABI.XXXXXX`
>  
>  usage() {
> -	echo "$0 <REV1> <REV2> <TARGET>"
> +	echo "$0 [-j[N]] <REV1> <REV2> <TARGET>"
>  }
>  
>  log() {
> @@ -183,7 +190,7 @@ log "INFO" "Configuring DPDK $TAG1"
>  make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
>  
>  log "INFO" "Building DPDK $TAG1. This might take a moment"
> -make O=$TARGET > $VERBOSE 2>&1
> +make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
>  
>  if [ $? -ne 0 ]
>  then
> @@ -214,7 +221,7 @@ log "INFO" "Configuring DPDK $TAG2"
>  make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
>  
>  log "INFO" "Building DPDK $TAG2. This might take a moment"
> -make O=$TARGET > $VERBOSE 2>&1
> +make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
>  
>  if [ $? -ne 0 ]
>  then
> 

This is something good to have.

I also found following is also working, not sure if need to document in
script:
"MAKEFLAGS="-j32" ./validate-abi.sh X Y Z"

And was just thinking if needs to address "-j N" usage (space after -j),
it is your call. Other than this,

Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 12:39  4%         ` Panu Matilainen
@ 2016-03-10 12:47  4%           ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-10 12:47 UTC (permalink / raw)
  To: Panu Matilainen, dev

On 3/10/2016 12:39 PM, Panu Matilainen wrote:
> On 03/10/2016 02:34 PM, Ferruh Yigit wrote:
>> On 3/10/2016 12:29 PM, Panu Matilainen wrote:
>>> On 03/10/2016 02:22 PM, Ferruh Yigit wrote:
>>>> On 3/10/2016 10:53 AM, Panu Matilainen wrote:
>>>>> When doing multiple runs of validate-abi.sh, the git status check
>>>>> will more often than not unnecessarily fail with "Working directory not
>>>>> clean" error because of the compat_result and compile target directories
>>>>> from the previous run. Filter out the self-generated directories
>>>>> when checking.
>>>>>
>>>>> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
>>>>> ---
>>>>>    scripts/validate-abi.sh | 3 +--
>>>>>    1 file changed, 1 insertion(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
>>>>> index ea60639..a21f883 100755
>>>>> --- a/scripts/validate-abi.sh
>>>>> +++ b/scripts/validate-abi.sh
>>>>> @@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
>>>>>    log "INFO" ""
>>>>>
>>>>>    # Check to make sure we have a clean tree
>>>>> -git status | grep -q clean
>>>>> -if [ $? -ne 0 ]
>>>>> +if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
>>>>>    then
>>>>>    	log "WARN" "Working directory not clean, aborting"
>>>>>    	cleanup_and_exit 1
>>>>>
>>>> Hi Panu,
>>>>
>>>> This check catches untracked files too, does it makes sense to limit
>>>> error only to modified files (local or staged)?
>>>
>>> I did ponder about that, untracked files seem mostly harmless in this
>>> picture but erred on the side of caution.
>>>
>> This is something prevents me running script from working tree, and
>> forces to create a new clone.
> 
> Hmm, what untracked files you typically have in your working tree then?
> 

cscope.out, various sym links, perf.data, and some more J, I want to
keep in working directory.

>>>>
>>>> This also prevents specific "compat_reports" folder check.
>>>>
>>>> And of course mentioned change requires "git clean -fd" removed, or
>>>> replaced with "make clean"
>>>
>>> Sorry, I dont understand you mean by these two comments.
>>>
>> If untracked files accepted by script, "compat_reports" exclusion is no
>> more required, and "git clean -fd" needs to removed from script.
> 
> Ah, sure. Thanks for clarifying.
> 
> 	- Panu -
> 
>>
>> Regards,
>> ferruh
>>
> 

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 12:34  4%       ` Ferruh Yigit
@ 2016-03-10 12:39  4%         ` Panu Matilainen
  2016-03-10 12:47  4%           ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-10 12:39 UTC (permalink / raw)
  To: Ferruh Yigit, dev

On 03/10/2016 02:34 PM, Ferruh Yigit wrote:
> On 3/10/2016 12:29 PM, Panu Matilainen wrote:
>> On 03/10/2016 02:22 PM, Ferruh Yigit wrote:
>>> On 3/10/2016 10:53 AM, Panu Matilainen wrote:
>>>> When doing multiple runs of validate-abi.sh, the git status check
>>>> will more often than not unnecessarily fail with "Working directory not
>>>> clean" error because of the compat_result and compile target directories
>>>> from the previous run. Filter out the self-generated directories
>>>> when checking.
>>>>
>>>> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
>>>> ---
>>>>    scripts/validate-abi.sh | 3 +--
>>>>    1 file changed, 1 insertion(+), 2 deletions(-)
>>>>
>>>> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
>>>> index ea60639..a21f883 100755
>>>> --- a/scripts/validate-abi.sh
>>>> +++ b/scripts/validate-abi.sh
>>>> @@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
>>>>    log "INFO" ""
>>>>
>>>>    # Check to make sure we have a clean tree
>>>> -git status | grep -q clean
>>>> -if [ $? -ne 0 ]
>>>> +if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
>>>>    then
>>>>    	log "WARN" "Working directory not clean, aborting"
>>>>    	cleanup_and_exit 1
>>>>
>>> Hi Panu,
>>>
>>> This check catches untracked files too, does it makes sense to limit
>>> error only to modified files (local or staged)?
>>
>> I did ponder about that, untracked files seem mostly harmless in this
>> picture but erred on the side of caution.
>>
> This is something prevents me running script from working tree, and
> forces to create a new clone.

Hmm, what untracked files you typically have in your working tree then?

>>>
>>> This also prevents specific "compat_reports" folder check.
>>>
>>> And of course mentioned change requires "git clean -fd" removed, or
>>> replaced with "make clean"
>>
>> Sorry, I dont understand you mean by these two comments.
>>
> If untracked files accepted by script, "compat_reports" exclusion is no
> more required, and "git clean -fd" needs to removed from script.

Ah, sure. Thanks for clarifying.

	- Panu -

>
> Regards,
> ferruh
>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
  2016-03-10 11:55  7% [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice David Hunt
@ 2016-03-10 12:37  4% ` Olivier MATZ
  2016-03-10 13:15  4%   ` Bruce Richardson
  2016-03-10 16:23  4% ` Mcnamara, John
  1 sibling, 1 reply; 200+ results
From: Olivier MATZ @ 2016-03-10 12:37 UTC (permalink / raw)
  To: David Hunt, dev

Hi David,

On 03/10/2016 12:55 PM, David Hunt wrote:
> Announce the ABI breakage due to addition of external mempool
> manager functionality which requires changes to rte_mempool
> structure.
> 
> Signed-off-by: David Hunt <david.hunt@intel.com>

Acked-by: Olivier Matz <olivier.matz@6wind.com>

Please note we need not 2 more acks for this kind of deprecation
notices.

Thanks,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh
  2016-03-10 12:25  4%   ` Ferruh Yigit
@ 2016-03-10 12:36  4%     ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-10 12:36 UTC (permalink / raw)
  To: Ferruh Yigit, dev

On 03/10/2016 02:25 PM, Ferruh Yigit wrote:
> On 3/10/2016 10:53 AM, Panu Matilainen wrote:
>> The defconfig_* files are templates which are not supposed to be
>> edited, and doing so tends to leave unwanted cruft behind. Edit
>> the "working copy" config instead, which is the intended DPDK way.
>>
>> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
>> ---
>>   scripts/validate-abi.sh | 18 +++++++++---------
>>   1 file changed, 9 insertions(+), 9 deletions(-)
>>
>> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
>> index f094582..ea60639 100755
>> --- a/scripts/validate-abi.sh
>> +++ b/scripts/validate-abi.sh
>> @@ -90,11 +90,11 @@ cleanup_and_exit() {
>>   # Make sure we configure SHARED libraries
>>   # Also turn off IGB and KNI as those require kernel headers to build
>>   fixup_config() {
>> -	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
>> -	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
>> -	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
>> -	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
>> -	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" config/defconfig_$TARGET
>> +	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $TARGET/.config
>> +	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $TARGET/.config
>> +	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $TARGET/.config
>> +	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $TARGET/.config
>> +	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $TARGET/.config
>>   }
>>
> Since working .config copy updated, is there a benefit to save and
> restore the original .config file (if exists)?

Maybe, but it already is being modified and not restored, so that 
behavior is not new in this patch.

> And is "git reset --hard" still required in the script?

Perhaps not, strictly speaking. It does ensure there are no other 
artifacts left around though.

	- Panu -

> Thanks,
> ferruh
>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 12:29  4%     ` Panu Matilainen
@ 2016-03-10 12:34  4%       ` Ferruh Yigit
  2016-03-10 12:39  4%         ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2016-03-10 12:34 UTC (permalink / raw)
  To: Panu Matilainen, dev

On 3/10/2016 12:29 PM, Panu Matilainen wrote:
> On 03/10/2016 02:22 PM, Ferruh Yigit wrote:
>> On 3/10/2016 10:53 AM, Panu Matilainen wrote:
>>> When doing multiple runs of validate-abi.sh, the git status check
>>> will more often than not unnecessarily fail with "Working directory not
>>> clean" error because of the compat_result and compile target directories
>>> from the previous run. Filter out the self-generated directories
>>> when checking.
>>>
>>> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
>>> ---
>>>   scripts/validate-abi.sh | 3 +--
>>>   1 file changed, 1 insertion(+), 2 deletions(-)
>>>
>>> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
>>> index ea60639..a21f883 100755
>>> --- a/scripts/validate-abi.sh
>>> +++ b/scripts/validate-abi.sh
>>> @@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
>>>   log "INFO" ""
>>>
>>>   # Check to make sure we have a clean tree
>>> -git status | grep -q clean
>>> -if [ $? -ne 0 ]
>>> +if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
>>>   then
>>>   	log "WARN" "Working directory not clean, aborting"
>>>   	cleanup_and_exit 1
>>>
>> Hi Panu,
>>
>> This check catches untracked files too, does it makes sense to limit
>> error only to modified files (local or staged)?
> 
> I did ponder about that, untracked files seem mostly harmless in this 
> picture but erred on the side of caution.
> 
This is something prevents me running script from working tree, and
forces to create a new clone.

>>
>> This also prevents specific "compat_reports" folder check.
>>
>> And of course mentioned change requires "git clean -fd" removed, or
>> replaced with "make clean"
> 
> Sorry, I dont understand you mean by these two comments.
> 
If untracked files accepted by script, "compat_reports" exclusion is no
more required, and "git clean -fd" needs to removed from script.

Regards,
ferruh

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 12:22  4%   ` Ferruh Yigit
@ 2016-03-10 12:29  4%     ` Panu Matilainen
  2016-03-10 12:34  4%       ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-10 12:29 UTC (permalink / raw)
  To: Ferruh Yigit, dev

On 03/10/2016 02:22 PM, Ferruh Yigit wrote:
> On 3/10/2016 10:53 AM, Panu Matilainen wrote:
>> When doing multiple runs of validate-abi.sh, the git status check
>> will more often than not unnecessarily fail with "Working directory not
>> clean" error because of the compat_result and compile target directories
>> from the previous run. Filter out the self-generated directories
>> when checking.
>>
>> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
>> ---
>>   scripts/validate-abi.sh | 3 +--
>>   1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
>> index ea60639..a21f883 100755
>> --- a/scripts/validate-abi.sh
>> +++ b/scripts/validate-abi.sh
>> @@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
>>   log "INFO" ""
>>
>>   # Check to make sure we have a clean tree
>> -git status | grep -q clean
>> -if [ $? -ne 0 ]
>> +if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
>>   then
>>   	log "WARN" "Working directory not clean, aborting"
>>   	cleanup_and_exit 1
>>
> Hi Panu,
>
> This check catches untracked files too, does it makes sense to limit
> error only to modified files (local or staged)?

I did ponder about that, untracked files seem mostly harmless in this 
picture but erred on the side of caution.

>
> This also prevents specific "compat_reports" folder check.
>
> And of course mentioned change requires "git clean -fd" removed, or
> replaced with "make clean"

Sorry, I dont understand you mean by these two comments.

	- Panu -

> Thanks,
> ferruh
>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh
  2016-03-10 10:53 19% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
@ 2016-03-10 12:25  4%   ` Ferruh Yigit
  2016-03-10 12:36  4%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2016-03-10 12:25 UTC (permalink / raw)
  To: Panu Matilainen, dev

On 3/10/2016 10:53 AM, Panu Matilainen wrote:
> The defconfig_* files are templates which are not supposed to be
> edited, and doing so tends to leave unwanted cruft behind. Edit
> the "working copy" config instead, which is the intended DPDK way.
> 
> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
> ---
>  scripts/validate-abi.sh | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
> index f094582..ea60639 100755
> --- a/scripts/validate-abi.sh
> +++ b/scripts/validate-abi.sh
> @@ -90,11 +90,11 @@ cleanup_and_exit() {
>  # Make sure we configure SHARED libraries
>  # Also turn off IGB and KNI as those require kernel headers to build
>  fixup_config() {
> -	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
> -	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
> -	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
> -	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
> -	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" config/defconfig_$TARGET
> +	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $TARGET/.config
> +	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $TARGET/.config
> +	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $TARGET/.config
> +	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $TARGET/.config
> +	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $TARGET/.config
>  }
>  
Since working .config copy updated, is there a benefit to save and
restore the original .config file (if exists)?

And is "git reset --hard" still required in the script?

Thanks,
ferruh

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 10:53 15% ` [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check Panu Matilainen
@ 2016-03-10 12:22  4%   ` Ferruh Yigit
  2016-03-10 12:29  4%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2016-03-10 12:22 UTC (permalink / raw)
  To: Panu Matilainen, dev

On 3/10/2016 10:53 AM, Panu Matilainen wrote:
> When doing multiple runs of validate-abi.sh, the git status check
> will more often than not unnecessarily fail with "Working directory not
> clean" error because of the compat_result and compile target directories
> from the previous run. Filter out the self-generated directories
> when checking.
> 
> Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
> ---
>  scripts/validate-abi.sh | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
> index ea60639..a21f883 100755
> --- a/scripts/validate-abi.sh
> +++ b/scripts/validate-abi.sh
> @@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
>  log "INFO" ""
>  
>  # Check to make sure we have a clean tree
> -git status | grep -q clean
> -if [ $? -ne 0 ]
> +if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
>  then
>  	log "WARN" "Working directory not clean, aborting"
>  	cleanup_and_exit 1
> 
Hi Panu,

This check catches untracked files too, does it makes sense to limit
error only to modified files (local or staged)?

This also prevents specific "compat_reports" folder check.

And of course mentioned change requires "git clean -fd" removed, or
replaced with "make clean"

Thanks,
ferruh

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice
@ 2016-03-10 11:55  7% David Hunt
  2016-03-10 12:37  4% ` Olivier MATZ
  2016-03-10 16:23  4% ` Mcnamara, John
  0 siblings, 2 replies; 200+ results
From: David Hunt @ 2016-03-10 11:55 UTC (permalink / raw)
  To: dev

Announce the ABI breakage due to addition of external mempool
manager functionality which requires changes to rte_mempool
structure.

Signed-off-by: David Hunt <david.hunt@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9930b5a..263e652 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -39,3 +39,13 @@ Deprecation Notices
   and table action handlers will be updated:
   the pipeline parameter will be added, the packets mask parameter will be
   either removed (for input port action handler) or made input-only.
+
+* librte_mempool: The rte_mempool struct will be changed in 16.07 to
+  facilitate the new external mempool manager functionality.
+  The ring element will be replaced with a more generic 'pool' opaque pointer
+  to allow new mempool handlers to use their own user-defined mempool
+  layout. Also newly added to rte_mempool is a handler index.
+  The existing API will be backward compatible, but there will be new API
+  functions added to facilitate the creation of mempools using an external
+  handler. The 16.07 release will contain these changes.
+
-- 
2.5.0

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v3 0/2] add support for buffered tx to ethdev
  2016-03-10 10:57  4% ` [dpdk-dev] [PATCH v3 " Tomasz Kulasek
@ 2016-03-10 11:31  0%   ` Ananyev, Konstantin
  2016-03-10 16:01  0%     ` Jastrzebski, MichalX K
  2016-03-10 17:19  4%   ` [dpdk-dev] [PATCH v4 " Tomasz Kulasek
  1 sibling, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2016-03-10 11:31 UTC (permalink / raw)
  To: Kulasek, TomaszX, dev

> Many sample apps include internal buffering for single-packet-at-a-time
> operation. Since this is such a common paradigm, this functionality is
> better suited to being implemented in the ethdev API.
> 
> The new APIs in the ethdev library are:
> * rte_eth_tx_buffer_init - initialize buffer
> * rte_eth_tx_buffer - buffer up a single packet for future transmission
> * rte_eth_tx_buffer_flush - flush any unsent buffered packets
> * rte_eth_tx_buffer_set_err_callback - set up a callback to be called in
>   case transmitting a buffered burst fails. By default, we just free the
>   unsent packets.
> 
> As well as these, an additional reference callbacks are provided, which
> frees the packets:
> 
> * rte_eth_tx_buffer_drop_callback - silently drop packets (default
>   behavior)
> * rte_eth_tx_buffer_count_callback - drop and update user-provided counter
>   to track the number of dropped packets
> 
> Due to the feedback from mailing list, that buffer management facilities
> in the user application are more preferable than API simplicity, we decided
> to move internal buffer table, as well as callback functions and user data,
> from rte_eth_dev/rte_eth_dev_data to the application space.
> It prevents ABI breakage and gives some more flexibility in the buffer's
> management such as allocation, dynamical size change, reuse buffers on many
> ports or after fail, and so on.
> 
> 
> The following steps illustrate how tx buffers can be used in application:
> 
> 1) Initialization
> 
> a) Allocate memory for a buffer
> 
>    struct rte_eth_dev_tx_buffer *buffer = rte_zmalloc_socket("tx_buffer",
>            RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, socket_id);
> 
>    RTE_ETH_TX_BUFFER_SIZE(size) macro computes memory required to store
>    "size" packets in buffer.
> 
> b) Initialize allocated memory and set up default values. Threshold level
>    must be lower than or equal to the MAX_PKT_BURST from 1a)
> 
>    rte_eth_tx_buffer_init(buffer, threshold);
> 
> 
> c) Set error callback (optional)
> 
>    rte_eth_tx_buffer_set_err_callback(buffer, callback_fn, userdata);
> 
> 
> 2) Store packet "pkt" in buffer and send them all to the queue_id on
>    port_id when number of packets reaches threshold level set up in 1b)
> 
>    rte_eth_tx_buffer(port_id, queue_id, buffer, pkt);
> 
> 
> 3) Send all stored packets to the queue_id on port_id
> 
>    rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
> 
> 
> 4) Flush buffer and free memory
> 
>    rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
>    ...
>    rte_free(buffer);
> 
> v3 changes:
>  - error counter removed from tx buffer structure, now default behavior is
>    silent drop of unsent packets
>  - some names was changed in tx buffer structure to be more descriptive
>  - two default calbacks are provided: rte_eth_tx_buffer_drop_callback and
>    rte_eth_tx_buffer_count_callback
> 
> v2 changes:
>  - reworked to use new buffer model
>  - buffer data and callbacks are removed from rte_eth_dev/rte_eth_dev_data,
>    so this patch doesn't brake an ABI anymore
>  - introduced RTE_ETH_TX_BUFFER macro and rte_eth_tx_buffer_init
>  - buffers are not attached to the port-queue
>  - buffers can be allocated dynamically during application work
>  - size of buffer can be changed without port restart
> 
> Tomasz Kulasek (2):
>   ethdev: add buffered tx api
>   examples: rework to use buffered tx
> 
>  examples/l2fwd-jobstats/main.c                     |  104 ++++------
>  examples/l2fwd-keepalive/main.c                    |  100 ++++------
>  examples/l2fwd/main.c                              |  104 ++++------
>  examples/l3fwd-acl/main.c                          |   92 ++++-----
>  examples/l3fwd-power/main.c                        |   89 ++++-----
>  examples/link_status_interrupt/main.c              |  107 ++++------
>  .../client_server_mp/mp_client/client.c            |  101 ++++++----
>  examples/multi_process/l2fwd_fork/main.c           |   97 ++++-----
>  examples/packet_ordering/main.c                    |  122 ++++++++----
>  examples/qos_meter/main.c                          |   61 ++----
>  lib/librte_ether/rte_ethdev.c                      |   46 +++++
>  lib/librte_ether/rte_ethdev.h                      |  205 +++++++++++++++++++-
>  lib/librte_ether/rte_ether_version.map             |   10 +
>  13 files changed, 696 insertions(+), 542 deletions(-)
> 
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> 1.7.9.5

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3 0/2] add support for buffered tx to ethdev
  @ 2016-03-10 10:57  4% ` Tomasz Kulasek
  2016-03-10 11:31  0%   ` Ananyev, Konstantin
  2016-03-10 17:19  4%   ` [dpdk-dev] [PATCH v4 " Tomasz Kulasek
  0 siblings, 2 replies; 200+ results
From: Tomasz Kulasek @ 2016-03-10 10:57 UTC (permalink / raw)
  To: dev

Many sample apps include internal buffering for single-packet-at-a-time
operation. Since this is such a common paradigm, this functionality is
better suited to being implemented in the ethdev API.

The new APIs in the ethdev library are:
* rte_eth_tx_buffer_init - initialize buffer
* rte_eth_tx_buffer - buffer up a single packet for future transmission
* rte_eth_tx_buffer_flush - flush any unsent buffered packets
* rte_eth_tx_buffer_set_err_callback - set up a callback to be called in
  case transmitting a buffered burst fails. By default, we just free the
  unsent packets.

As well as these, an additional reference callbacks are provided, which
frees the packets:

* rte_eth_tx_buffer_drop_callback - silently drop packets (default
  behavior)
* rte_eth_tx_buffer_count_callback - drop and update user-provided counter
  to track the number of dropped packets

Due to the feedback from mailing list, that buffer management facilities
in the user application are more preferable than API simplicity, we decided
to move internal buffer table, as well as callback functions and user data,
from rte_eth_dev/rte_eth_dev_data to the application space.
It prevents ABI breakage and gives some more flexibility in the buffer's
management such as allocation, dynamical size change, reuse buffers on many
ports or after fail, and so on.


The following steps illustrate how tx buffers can be used in application:

1) Initialization

a) Allocate memory for a buffer

   struct rte_eth_dev_tx_buffer *buffer = rte_zmalloc_socket("tx_buffer",
           RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, socket_id);

   RTE_ETH_TX_BUFFER_SIZE(size) macro computes memory required to store
   "size" packets in buffer.

b) Initialize allocated memory and set up default values. Threshold level
   must be lower than or equal to the MAX_PKT_BURST from 1a)

   rte_eth_tx_buffer_init(buffer, threshold);


c) Set error callback (optional)

   rte_eth_tx_buffer_set_err_callback(buffer, callback_fn, userdata);


2) Store packet "pkt" in buffer and send them all to the queue_id on
   port_id when number of packets reaches threshold level set up in 1b)

   rte_eth_tx_buffer(port_id, queue_id, buffer, pkt);


3) Send all stored packets to the queue_id on port_id

   rte_eth_tx_buffer_flush(port_id, queue_id, buffer);


4) Flush buffer and free memory

   rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
   ...
   rte_free(buffer);

v3 changes:
 - error counter removed from tx buffer structure, now default behavior is
   silent drop of unsent packets
 - some names was changed in tx buffer structure to be more descriptive
 - two default calbacks are provided: rte_eth_tx_buffer_drop_callback and
   rte_eth_tx_buffer_count_callback

v2 changes:
 - reworked to use new buffer model
 - buffer data and callbacks are removed from rte_eth_dev/rte_eth_dev_data,
   so this patch doesn't brake an ABI anymore
 - introduced RTE_ETH_TX_BUFFER macro and rte_eth_tx_buffer_init
 - buffers are not attached to the port-queue
 - buffers can be allocated dynamically during application work
 - size of buffer can be changed without port restart

Tomasz Kulasek (2):
  ethdev: add buffered tx api
  examples: rework to use buffered tx

 examples/l2fwd-jobstats/main.c                     |  104 ++++------
 examples/l2fwd-keepalive/main.c                    |  100 ++++------
 examples/l2fwd/main.c                              |  104 ++++------
 examples/l3fwd-acl/main.c                          |   92 ++++-----
 examples/l3fwd-power/main.c                        |   89 ++++-----
 examples/link_status_interrupt/main.c              |  107 ++++------
 .../client_server_mp/mp_client/client.c            |  101 ++++++----
 examples/multi_process/l2fwd_fork/main.c           |   97 ++++-----
 examples/packet_ordering/main.c                    |  122 ++++++++----
 examples/qos_meter/main.c                          |   61 ++----
 lib/librte_ether/rte_ethdev.c                      |   46 +++++
 lib/librte_ether/rte_ethdev.h                      |  205 +++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map             |   10 +
 13 files changed, 696 insertions(+), 542 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check
  2016-03-10 10:53 31% [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Panu Matilainen
  2016-03-10 10:53 19% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
@ 2016-03-10 10:53 15% ` Panu Matilainen
  2016-03-10 12:22  4%   ` Ferruh Yigit
  2016-03-10 12:52  7% ` [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Ferruh Yigit
  2 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-10 10:53 UTC (permalink / raw)
  To: dev

When doing multiple runs of validate-abi.sh, the git status check
will more often than not unnecessarily fail with "Working directory not
clean" error because of the compat_result and compile target directories
from the previous run. Filter out the self-generated directories
when checking.

Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
---
 scripts/validate-abi.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index ea60639..a21f883 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -163,8 +163,7 @@ log "INFO" "against DPDK DSOs built from version $TAG2."
 log "INFO" ""
 
 # Check to make sure we have a clean tree
-git status | grep -q clean
-if [ $? -ne 0 ]
+if [ $(git status --porcelain | grep -vE "($TARGET|compat_reports)" | wc -l)  -ne 0 ]
 then
 	log "WARN" "Working directory not clean, aborting"
 	cleanup_and_exit 1
-- 
2.5.0

^ permalink raw reply	[relevance 15%]

* [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh
  2016-03-10 10:53 31% [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Panu Matilainen
@ 2016-03-10 10:53 19% ` Panu Matilainen
  2016-03-10 12:25  4%   ` Ferruh Yigit
  2016-03-10 10:53 15% ` [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check Panu Matilainen
  2016-03-10 12:52  7% ` [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Ferruh Yigit
  2 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-10 10:53 UTC (permalink / raw)
  To: dev

The defconfig_* files are templates which are not supposed to be
edited, and doing so tends to leave unwanted cruft behind. Edit
the "working copy" config instead, which is the intended DPDK way.

Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
---
 scripts/validate-abi.sh | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index f094582..ea60639 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -90,11 +90,11 @@ cleanup_and_exit() {
 # Make sure we configure SHARED libraries
 # Also turn off IGB and KNI as those require kernel headers to build
 fixup_config() {
-	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
-	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
-	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
-	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
-	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" config/defconfig_$TARGET
+	sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $TARGET/.config
+	sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $TARGET/.config
+	sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $TARGET/.config
+	sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $TARGET/.config
+	sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $TARGET/.config
 }
 
 ###########################################
@@ -177,8 +177,6 @@ log "INFO" "Checking out version $TAG1 of the dpdk"
 # Move to the old version of the tree
 git checkout $HASH1
 
-fixup_config
-
 # Checking abi compliance relies on using the dwarf information in
 # The shared objects.  Thats only included in the DSO's if we build
 # with -g
@@ -189,6 +187,8 @@ export EXTRA_LDFLAGS="$EXTRA_LDFLAGS -g"
 log "INFO" "Configuring DPDK $TAG1"
 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
 
+fixup_config
+
 log "INFO" "Building DPDK $TAG1. This might take a moment"
 make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
 
@@ -214,12 +214,12 @@ git reset --hard
 log "INFO" "Checking out version $TAG2 of the dpdk"
 git checkout $HASH2
 
-fixup_config
-
 # Now configure the build
 log "INFO" "Configuring DPDK $TAG2"
 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
 
+fixup_config
+
 log "INFO" "Building DPDK $TAG2. This might take a moment"
 make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
 
-- 
2.5.0

^ permalink raw reply	[relevance 19%]

* [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option
@ 2016-03-10 10:53 31% Panu Matilainen
  2016-03-10 10:53 19% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Panu Matilainen @ 2016-03-10 10:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
---
 doc/guides/contributing/versioning.rst |  4 +++-
 scripts/validate-abi.sh                | 13 ++++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index ae10a98..33b03a1 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -469,11 +469,13 @@ utilities which can be installed via a package manager. For example::
 
 The syntax of the ``validate-abi.sh`` utility is::
 
-   ./scripts/validate-abi.sh <REV1> <REV2> <TARGET>
+   ./scripts/validate-abi.sh [-j[N]] <REV1> <REV2> <TARGET>
 
 Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
 https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
 on the local repo and target is the usual DPDK compilation target.
+The optional -j[N] switch enables parallel building with at most
+N simultaneous jobs, ie the same as -j option of ``make``.
 
 For example:
 
diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index c36ad61..f094582 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -27,13 +27,20 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+case "$1" in
+    -j*)
+        MAKEJOBS="$1"
+        shift
+        ;;
+esac
+
 TAG1=$1
 TAG2=$2
 TARGET=$3
 ABI_DIR=`mktemp -d -p /tmp ABI.XXXXXX`
 
 usage() {
-	echo "$0 <REV1> <REV2> <TARGET>"
+	echo "$0 [-j[N]] <REV1> <REV2> <TARGET>"
 }
 
 log() {
@@ -183,7 +190,7 @@ log "INFO" "Configuring DPDK $TAG1"
 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
 
 log "INFO" "Building DPDK $TAG1. This might take a moment"
-make O=$TARGET > $VERBOSE 2>&1
+make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
 
 if [ $? -ne 0 ]
 then
@@ -214,7 +221,7 @@ log "INFO" "Configuring DPDK $TAG2"
 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
 
 log "INFO" "Building DPDK $TAG2. This might take a moment"
-make O=$TARGET > $VERBOSE 2>&1
+make $MAKEJOBS O=$TARGET > $VERBOSE 2>&1
 
 if [ $? -ne 0 ]
 then
-- 
2.5.0

^ permalink raw reply	[relevance 31%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-10  0:04  0%     ` Thomas Monjalon
@ 2016-03-10  6:31  0%       ` Vincent JARDIN
  0 siblings, 0 replies; 200+ results
From: Vincent JARDIN @ 2016-03-10  6:31 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Avi Kivity, dev

Le 10 mars 2016 01:06, "Thomas Monjalon" <thomas.monjalon@6wind.com> a
écrit :
>
> 2016-03-02 23:35, Thomas Monjalon:
> > 2016-03-02 12:21, Thomas Monjalon:
> > > 2016-03-02 11:47, Vincent JARDIN:
> > > > Le 02/03/2016 09:27, Panu Matilainen a écrit :
> > > > >>> I'd like to see these be merged.
> > > > >>>
> > > > >>> Jay
> > > > >>
> > > > >> The code is really not ready. I am okay with cooperative
development
> > > > >> but the current code needs to go into a staging type tree.
> > > > >> No compatibility, no ABI guarantees, more of an RFC.
> > > > >> Don't want vendors building products with it then screaming when
it
> > > > >> gets rebuilt/reworked/scrapped.
> > > > >>
> > > > >
> > > > > Exactly.
> > > >
> > > > +1 too
> > > >
> > > > We need to build on this innovation while there is a path for kernel
> > > > mainstream. The logic of using a staging is a good one.
> > > >
> > > > Thomas,
> > > >
> > > > can we open a staging folder into the DPDK like it is done into the
kernel?
> > >
> > > It's possible to create a staging directory if everybody agree.
> > > It is important to state in a README file or in the doc/ that
> > > there will be no guarantee (no stable ABI, no validation and can be
dropped)
> > > and that it is a work in progress, a suggestion to discuss with the
kernel
> > > community.
> > >
> > > The kernel modules must clearly target an upstream integration.
> >
> > Actually the examples directory has been used as a staging for ethtool
and
> > lthread. We also have the crypto API which is still experimental.
> > So I think we must decide among these 3 solutions:
> >       - no special directory, just mark and document an experimental
state
> >       - put only kcp/kdp in the staging directory

I do prefer this option.

> >       - put kcp/kdp in staging and move other experimental libs here
>
> Any opinion? Are we targetting upstream work without any DPDK staging?
>
> Please let's make clear the status of these patches.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-10  3:25  4%   ` [dpdk-dev] [PATCH v4 " Jingjing Wu
@ 2016-03-10  3:25 18%     ` Jingjing Wu
  2016-03-21  6:18  4%     ` [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  1 sibling, 0 replies; 200+ results
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  4 ----
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 27 +++++++++++++++------------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..7fa8639 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,10 +20,6 @@ Deprecation Notices
   tables (512 queues).
   It should be integrated in release 2.3.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5abf48a..87ec402 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -238,6 +238,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index e2ac686..5b2a6ed 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

^ permalink raw reply	[relevance 18%]

* [dpdk-dev] [PATCH v4 00/12] extend flow director fields in i40e driver
  2016-03-09  5:42  4% ` [dpdk-dev] [PATCH v3 00/12] extend flow director " Jingjing Wu
  2016-03-09  5:42 18%   ` [dpdk-dev] [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
  2016-03-09  6:18  0%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
@ 2016-03-10  3:25  4%   ` Jingjing Wu
  2016-03-10  3:25 18%     ` [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
  2016-03-21  6:18  4%     ` [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  2 siblings, 2 replies; 200+ results
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan 


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (11):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  librte_ether: extend flow director struct
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend flow director commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 403 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 8 files changed, 570 insertions(+), 271 deletions(-)

-- 
2.4.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v8 1/4] lib/ether: optimize struct rte_eth_tunnel_filter_conf
  @ 2016-03-10  3:05 13%     ` Jingjing Wu
  0 siblings, 0 replies; 200+ results
From: Jingjing Wu @ 2016-03-10  3:05 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: dev

From: Xutao Sun <xutao.sun@intel.com>

Change the fields of outer_mac and inner_mac in struct
rte_eth_tunnel_filter_conf from pointer to struct in order to
keep the code's readability.

Signed-off-by: Xutao Sun <xutao.sun@intel.com>
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
 app/test-pmd/cmdline.c                 |  6 ++++--
 doc/guides/rel_notes/deprecation.rst   |  5 -----
 doc/guides/rel_notes/release_16_04.rst |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
 lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
 5 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 81ba2bd..5104301 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6628,8 +6628,10 @@ cmd_tunnel_filter_parsed(void *parsed_result,
 	struct rte_eth_tunnel_filter_conf tunnel_filter_conf;
 	int ret = 0;
 
-	tunnel_filter_conf.outer_mac = &res->outer_mac;
-	tunnel_filter_conf.inner_mac = &res->inner_mac;
+	rte_memcpy(&tunnel_filter_conf.outer_mac, &res->outer_mac,
+			ETHER_ADDR_LEN);
+	rte_memcpy(&tunnel_filter_conf.inner_mac, &res->inner_mac,
+			ETHER_ADDR_LEN);
 	tunnel_filter_conf.inner_vlan = res->inner_vlan;
 
 	if (res->ip_value.family == AF_INET) {
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f033bbc..a2017f1 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -34,10 +34,5 @@ Deprecation Notices
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will.
 
-* ABI changes are planned for rte_eth_tunnel_filter_conf. Change the fields
-  of outer_mac and inner_mac from pointer to struct in order to keep the
-  code's readability. The release 2.2 does not contain these ABI changes, but
-  release 2.3 will, and no backwards compatibility is planned.
-
 * The scheduler statistics structure will change to allow keeping track of
   RED actions.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index aa9eabc..3211747 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -162,6 +162,10 @@ This section should contain API changes. Sample format:
   handlers are updated: the pipeline parameter is added,
   the packets mask parameter has been either removed or made input-only.
 
+* The ``outer_mac`` and ``inner_mac`` fields in structure
+  ``rte_eth_tunnel_filter_conf`` are changed from pointer to struct in order
+  to keep code's readability.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7e68c61..127ed72 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5839,10 +5839,10 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
 	}
 	pfilter = cld_filter;
 
-	(void)rte_memcpy(&pfilter->outer_mac, tunnel_filter->outer_mac,
-			sizeof(struct ether_addr));
-	(void)rte_memcpy(&pfilter->inner_mac, tunnel_filter->inner_mac,
-			sizeof(struct ether_addr));
+	(void)rte_memcpy(&pfilter->outer_mac, &tunnel_filter->outer_mac,
+			ETHER_ADDR_LEN);
+	(void)rte_memcpy(&pfilter->inner_mac, &tunnel_filter->inner_mac,
+			ETHER_ADDR_LEN);
 
 	pfilter->inner_vlan = tunnel_filter->inner_vlan;
 	if (tunnel_filter->ip_type == RTE_TUNNEL_IPTYPE_IPV4) {
@@ -6142,13 +6142,13 @@ i40e_tunnel_filter_param_check(struct i40e_pf *pf,
 	}
 
 	if ((filter->filter_type & ETH_TUNNEL_FILTER_OMAC) &&
-		(is_zero_ether_addr(filter->outer_mac))) {
+		(is_zero_ether_addr(&filter->outer_mac))) {
 		PMD_DRV_LOG(ERR, "Cannot add NULL outer MAC address");
 		return -EINVAL;
 	}
 
 	if ((filter->filter_type & ETH_TUNNEL_FILTER_IMAC) &&
-		(is_zero_ether_addr(filter->inner_mac))) {
+		(is_zero_ether_addr(&filter->inner_mac))) {
 		PMD_DRV_LOG(ERR, "Cannot add NULL inner MAC address");
 		return -EINVAL;
 	}
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index d433e0b..736cfc1 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -280,8 +280,8 @@ enum rte_tunnel_iptype {
  * Tunneling Packet filter configuration.
  */
 struct rte_eth_tunnel_filter_conf {
-	struct ether_addr *outer_mac;  /**< Outer MAC address filter. */
-	struct ether_addr *inner_mac;  /**< Inner MAC address filter. */
+	struct ether_addr outer_mac;  /**< Outer MAC address filter. */
+	struct ether_addr inner_mac;  /**< Inner MAC address filter. */
 	uint16_t inner_vlan;           /**< Inner VLAN filter. */
 	enum rte_tunnel_iptype ip_type; /**< IP address type. */
 	union {
-- 
2.4.0

^ permalink raw reply	[relevance 13%]

* [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load
  2016-03-10  2:42  3% ` [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
  2016-03-10  2:42  3%   ` [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
@ 2016-03-10  2:42  7%   ` Wenzhuo Lu
  1 sibling, 0 replies; 200+ results
From: Wenzhuo Lu @ 2016-03-10  2:42 UTC (permalink / raw)
  To: dev

The patch add VxLAN & NVGRE TX checksum off-load. When the flag of
outer IP header checksum offload is set, we'll set the context
descriptor to enable this checksum off-load.

Also update release note for VxLAN & NVGRE checksum off-load support
and ABI change.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 14 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  4 +++
 drivers/net/ixgbe/ixgbe_rxtx.c         | 56 +++++++++++++++++++++++++++-------
 drivers/net/ixgbe/ixgbe_rxtx.h         |  6 +++-
 4 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 8273817..efb7d87 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,15 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added support for VxLAN & NVGRE checksum off-load on X550.**
+
+  * Added support for VxLAN & NVGRE RX/TX checksum off-load on
+    X550. RX/TX checksum off-load is provided on both inner and
+    outer IP header and TCP header.
+  * Added functions to support VxLAN port configuration. The
+    default VxLAN port number is 4789 but this can be updated
+    programmatically.
+
 
 Resolved Issues
 ---------------
@@ -113,6 +122,11 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* New API ``rte_eth_dev_udp_tunnel_port_add`` has been introduced to replace
+  ``rte_eth_dev_udp_tunnel_add``.
+
+* New API ``rte_eth_dev_udp_tunnel_port_delete`` has been introduced to replace
+  ``rte_eth_dev_udp_tunnel_delete``.
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4722ea4..71606fb 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2811,6 +2811,10 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		DEV_TX_OFFLOAD_SCTP_CKSUM  |
 		DEV_TX_OFFLOAD_TCP_TSO;
 
+	if (hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x)
+		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
 			.pthresh = IXGBE_DEFAULT_RX_PTHRESH,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 6b913ee..c2c71de 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -85,7 +85,8 @@
 		PKT_TX_VLAN_PKT |		 \
 		PKT_TX_IP_CKSUM |		 \
 		PKT_TX_L4_MASK |		 \
-		PKT_TX_TCP_SEG)
+		PKT_TX_TCP_SEG |		 \
+		PKT_TX_OUTER_IP_CKSUM)
 
 static inline struct rte_mbuf *
 rte_rxmbuf_alloc(struct rte_mempool *mp)
@@ -364,9 +365,11 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
 	uint32_t ctx_idx;
 	uint32_t vlan_macip_lens;
 	union ixgbe_tx_offload tx_offload_mask;
+	uint32_t seqnum_seed = 0;
 
 	ctx_idx = txq->ctx_curr;
-	tx_offload_mask.data = 0;
+	tx_offload_mask.data[0] = 0;
+	tx_offload_mask.data[1] = 0;
 	type_tucmd_mlhl = 0;
 
 	/* Specify which HW CTX to upload. */
@@ -430,18 +433,35 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
 		}
 	}
 
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM) {
+		tx_offload_mask.outer_l2_len |= ~0;
+		tx_offload_mask.outer_l3_len |= ~0;
+		tx_offload_mask.l2_len |= ~0;
+		seqnum_seed |= tx_offload.outer_l3_len
+			       << IXGBE_ADVTXD_OUTER_IPLEN;
+		seqnum_seed |= tx_offload.l2_len
+			       << IXGBE_ADVTXD_TUNNEL_LEN;
+	}
+
 	txq->ctx_cache[ctx_idx].flags = ol_flags;
-	txq->ctx_cache[ctx_idx].tx_offload.data  =
-		tx_offload_mask.data & tx_offload.data;
+	txq->ctx_cache[ctx_idx].tx_offload.data[0]  =
+		tx_offload_mask.data[0] & tx_offload.data[0];
+	txq->ctx_cache[ctx_idx].tx_offload.data[1]  =
+		tx_offload_mask.data[1] & tx_offload.data[1];
 	txq->ctx_cache[ctx_idx].tx_offload_mask    = tx_offload_mask;
 
 	ctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);
 	vlan_macip_lens = tx_offload.l3_len;
-	vlan_macip_lens |= (tx_offload.l2_len << IXGBE_ADVTXD_MACLEN_SHIFT);
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+		vlan_macip_lens |= (tx_offload.outer_l2_len <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
+	else
+		vlan_macip_lens |= (tx_offload.l2_len <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
 	vlan_macip_lens |= ((uint32_t)tx_offload.vlan_tci << IXGBE_ADVTXD_VLAN_SHIFT);
 	ctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);
 	ctx_txd->mss_l4len_idx   = rte_cpu_to_le_32(mss_l4len_idx);
-	ctx_txd->seqnum_seed     = 0;
+	ctx_txd->seqnum_seed     = seqnum_seed;
 }
 
 /*
@@ -454,16 +474,24 @@ what_advctx_update(struct ixgbe_tx_queue *txq, uint64_t flags,
 {
 	/* If match with the current used context */
 	if (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&
-		(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==
-		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[0] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[0]
+		 & tx_offload.data[0])) &&
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[1] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[1]
+		 & tx_offload.data[1])))) {
 			return txq->ctx_curr;
 	}
 
 	/* What if match with the next context  */
 	txq->ctx_curr ^= 1;
 	if (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&
-		(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==
-		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[0] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[0]
+		 & tx_offload.data[0])) &&
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[1] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[1]
+		 & tx_offload.data[1])))) {
 			return txq->ctx_curr;
 	}
 
@@ -492,6 +520,8 @@ tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags)
 		cmdtype |= IXGBE_ADVTXD_DCMD_VLE;
 	if (ol_flags & PKT_TX_TCP_SEG)
 		cmdtype |= IXGBE_ADVTXD_DCMD_TSE;
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+		cmdtype |= (1 << IXGBE_ADVTXD_OUTERIPCS_SHIFT);
 	return cmdtype;
 }
 
@@ -588,8 +618,10 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	uint64_t tx_ol_req;
 	uint32_t ctx = 0;
 	uint32_t new_ctx;
-	union ixgbe_tx_offload tx_offload = {0};
+	union ixgbe_tx_offload tx_offload;
 
+	tx_offload.data[0] = 0;
+	tx_offload.data[1] = 0;
 	txq = tx_queue;
 	sw_ring = txq->sw_ring;
 	txr     = txq->tx_ring;
@@ -623,6 +655,8 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			tx_offload.l4_len = tx_pkt->l4_len;
 			tx_offload.vlan_tci = tx_pkt->vlan_tci;
 			tx_offload.tso_segsz = tx_pkt->tso_segsz;
+			tx_offload.outer_l2_len = tx_pkt->outer_l2_len;
+			tx_offload.outer_l3_len = tx_pkt->outer_l3_len;
 
 			/* If new context need be built or reuse the exist ctx. */
 			ctx = what_advctx_update(txq, tx_ol_req,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 475a800..c15f9fa 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -163,7 +163,7 @@ enum ixgbe_advctx_num {
 
 /** Offload features */
 union ixgbe_tx_offload {
-	uint64_t data;
+	uint64_t data[2];
 	struct {
 		uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
 		uint64_t l3_len:9; /**< L3 (IP) Header Length. */
@@ -171,6 +171,10 @@ union ixgbe_tx_offload {
 		uint64_t tso_segsz:16; /**< TCP TSO segment size */
 		uint64_t vlan_tci:16;
 		/**< VLAN Tag Control Identifier (CPU order). */
+
+		/* fields for TX offloading of tunnels */
+		uint64_t outer_l3_len:8; /**< Outer L3 (IP) Hdr Length. */
+		uint64_t outer_l2_len:8; /**< Outer L2 (MAC) Hdr Length. */
 	};
 };
 
-- 
1.9.3

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-10  2:42  3% ` [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
@ 2016-03-10  2:42  3%   ` Wenzhuo Lu
  2016-03-11 23:02  3%     ` Thomas Monjalon
  2016-03-10  2:42  7%   ` [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
  1 sibling, 1 reply; 200+ results
From: Wenzhuo Lu @ 2016-03-10  2:42 UTC (permalink / raw)
  To: dev

The names of function for tunnel port configuration are not
accurate. They're tunnel_add/del, better change them to
tunnel_port_add/del.
As it may be an ABI change if change the names directly, the
new functions are added but not remove the old ones. The old
ones will be removed in the next release after an ABI change
announcement.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 app/test-pmd/cmdline.c                 |  6 +++--
 examples/tep_termination/vxlan_setup.c |  2 +-
 lib/librte_ether/rte_ethdev.c          | 45 ++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 42 +++++++++++++++++++++++++++----
 lib/librte_ether/rte_ether_version.map |  7 ++++++
 5 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..0fae655 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6782,9 +6782,11 @@ cmd_tunnel_udp_config_parsed(void *parsed_result,
 		tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
 
 	if (!strcmp(res->what, "add"))
-		ret = rte_eth_dev_udp_tunnel_add(res->port_id, &tunnel_udp);
+		ret = rte_eth_dev_udp_tunnel_port_add(res->port_id,
+						      &tunnel_udp);
 	else
-		ret = rte_eth_dev_udp_tunnel_delete(res->port_id, &tunnel_udp);
+		ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id,
+							 &tunnel_udp);
 
 	if (ret < 0)
 		printf("udp tunneling add error: (%s)\n", strerror(-ret));
diff --git a/examples/tep_termination/vxlan_setup.c b/examples/tep_termination/vxlan_setup.c
index 51ad133..8836603 100644
--- a/examples/tep_termination/vxlan_setup.c
+++ b/examples/tep_termination/vxlan_setup.c
@@ -191,7 +191,7 @@ vxlan_port_init(uint8_t port, struct rte_mempool *mbuf_pool)
 	/* Configure UDP port for UDP tunneling */
 	tunnel_udp.udp_port = udp_port;
 	tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
-	retval = rte_eth_dev_udp_tunnel_add(port, &tunnel_udp);
+	retval = rte_eth_dev_udp_tunnel_port_add(port, &tunnel_udp);
 	if (retval < 0)
 		return retval;
 	rte_eth_macaddr_get(port, &ports_eth_addr[port]);
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..937b348 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1949,6 +1949,28 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,
 }
 
 int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	if (udp_tunnel == NULL) {
+		RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+		return -EINVAL;
+	}
+
+	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
+		RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
+	return (*dev->dev_ops->udp_tunnel_port_add)(dev, udp_tunnel);
+}
+
+int
 rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 			      struct rte_eth_udp_tunnel *udp_tunnel)
 {
@@ -1972,6 +1994,29 @@ rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 }
 
 int
+rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
+				   struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (udp_tunnel == NULL) {
+		RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+		return -EINVAL;
+	}
+
+	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
+		RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP);
+	return (*dev->dev_ops->udp_tunnel_port_del)(dev, udp_tunnel);
+}
+
+int
 rte_eth_led_on(uint8_t port_id)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..511df82 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -738,10 +738,14 @@ struct rte_fdir_conf {
 
 /**
  * UDP tunneling configuration.
+ * Used to config the UDP port for a type of tunnel.
+ * NICs need the UDP port to identify the tunnel type.
+ * Normally a type of tunnel has a default UDP port, this structure can be used
+ * in case if the users want to change or support more UDP port.
  */
 struct rte_eth_udp_tunnel {
-	uint16_t udp_port;
-	uint8_t prot_type;
+	uint16_t udp_port; /**< UDP port used for the tunnel. */
+	uint8_t prot_type; /**< Tunnel type. Defined in rte_eth_tunnel_type. */
 };
 
 /**
@@ -1261,6 +1265,14 @@ typedef int (*eth_set_eeprom_t)(struct rte_eth_dev *dev,
 				struct rte_dev_eeprom_info *info);
 /**< @internal Program eeprom data  */
 
+typedef int (*eth_udp_tunnel_port_add_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Add tunneling UDP port */
+
+typedef int (*eth_udp_tunnel_port_del_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Delete tunneling UDP port */
+
 #ifdef RTE_NIC_BYPASS
 
 enum {
@@ -1443,6 +1455,10 @@ struct eth_dev_ops {
 	eth_timesync_read_time timesync_read_time;
 	/** Set the device clock time. */
 	eth_timesync_write_time timesync_write_time;
+	/** Add UDP tunnel port. */
+	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
+	/** Del UDP tunnel port. */
+	eth_udp_tunnel_port_del_t udp_tunnel_port_del;
 };
 
 /**
@@ -3387,8 +3403,11 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
 			      struct rte_eth_rss_conf *rss_conf);
 
  /**
- * Add UDP tunneling port of an Ethernet device for filtering a specific
- * tunneling packet by UDP port number.
+ * Add UDP tunneling port for a specific type of tunnel.
+ * The packets with this UDP port will be identified as this type of tunnel.
+ * Before enabling any offloading function for a tunnel, users can call this API
+ * to change or add more UDP port for the tunnel. So the offloading function
+ * can take effect on the packets with the sepcific UDP port.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
@@ -3401,11 +3420,20 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
  *   - (-ENOTSUP) if hardware doesn't support tunnel type.
  */
 int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
+/* Deprecated.  @see rte_eth_dev_udp_tunnel_port_add. */
+__rte_deprecated int
 rte_eth_dev_udp_tunnel_add(uint8_t port_id,
 			   struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
- * Detete UDP tunneling port configuration of Ethernet device
+ * Delete UDP tunneling port a specific type of tunnel.
+ * The packets with this UDP port will not be identified as this type of tunnel
+ * any more.
+ * Before enabling any offloading function for a tunnel, users can call this API
+ * to delete a UDP port for the tunnel. So the offloading function will not take
+ * effect on the packets with the sepcific UDP port.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
@@ -3418,6 +3446,10 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,
  *   - (-ENOTSUP) if hardware doesn't support tunnel type.
  */
 int
+rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
+				   struct rte_eth_udp_tunnel *tunnel_udp);
+/* Deprecated.  @see rte_eth_dev_udp_tunnel_port_delete. */
+__rte_deprecated int
 rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 			      struct rte_eth_udp_tunnel *tunnel_udp);
 
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..1b28e75 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_udp_tunnel_port_add;
+	rte_eth_dev_udp_tunnel_port_delete;
+}DPDK_2.2;
-- 
1.9.3

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550
      2016-03-09  3:35  3% ` [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
@ 2016-03-10  2:42  3% ` Wenzhuo Lu
  2016-03-10  2:42  3%   ` [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
  2016-03-10  2:42  7%   ` [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
  2 siblings, 2 replies; 200+ results
From: Wenzhuo Lu @ 2016-03-10  2:42 UTC (permalink / raw)
  To: dev

This patch set add the VxLAN & NVGRE checksum off-load support.
Both RX and TX checksum off-load can be used for VxLAN & NVGRE.
And the VxLAN port can be set, it's implemented in this patch
set either.

v2:
- Update release note.

v3:
- Update RX/TX offload capability.
- Reuse PKT_RX_EIP_CKSUM_BAD but not add a new one.
- Correct the tunnel len for TX, and remove the useless out_l2_len.
- Don't set the tunnel type for TX, and remove the unused ol_flag_nvgre.

v4:
- Fix the issue that not setting the MAC length correctly.

v5:
- Change the behavior of VxLAN port add/del to make it align with i40e.

v6:
- Fix x86_64-native-linuxapp-gcc-shared compile error.

v7:
- Change the return value from hardcode to macro.

v8:
- Add more comments for tunnel port add/del.
- Add ABI change announce.

v9:
- Explain more for tunnel port add/del.
- Change the release number in rte_ether_version.map.

Wenzhuo Lu (5):
  lib/librte_ether: change function name of tunnel port config
  i40e: rename the tunnel port config functions
  ixgbe: support UDP tunnel port config
  ixgbe: support VxLAN &  NVGRE RX checksum off-load
  ixgbe: support VxLAN &  NVGRE TX checksum off-load

 app/test-pmd/cmdline.c                 |   6 +-
 doc/guides/rel_notes/release_16_04.rst |  14 ++++
 drivers/net/i40e/i40e_ethdev.c         |  22 +++---
 drivers/net/ixgbe/ixgbe_ethdev.c       | 131 +++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_rxtx.c         |  67 ++++++++++++++---
 drivers/net/ixgbe/ixgbe_rxtx.h         |   6 +-
 examples/tep_termination/vxlan_setup.c |   2 +-
 lib/librte_ether/rte_ethdev.c          |  45 +++++++++++
 lib/librte_ether/rte_ethdev.h          |  43 +++++++++--
 lib/librte_ether/rte_ether_version.map |   7 ++
 lib/librte_mbuf/rte_mbuf.c             |   2 +-
 lib/librte_mbuf/rte_mbuf.h             |   2 +-
 12 files changed, 314 insertions(+), 33 deletions(-)

-- 
1.9.3

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v7 01/11] ethdev: add API to query packet type filling info
  @ 2016-03-09 19:31  4%   ` Jianfeng Tan
  0 siblings, 0 replies; 200+ results
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given already started device or its pmd rx burst
function has already been decided).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  8 ++++++++
 4 files changed, 64 insertions(+)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index aa9eabc..376ece5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -162,6 +162,9 @@ This section should contain API changes. Sample format:
   handlers are updated: the pipeline parameter is added,
   the packets mask parameter has been either removed or made input-only.
 
+* A new API ``rte_eth_dev_get_ptype_info`` is added to query what packet types
+  can be filled by given already started device.
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 5c2b416..d828dcf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index d53e362..e0d2232 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of an Ethernet device. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,29 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @note
+ *   Better to invoke this API after the device is already started or rx burst
+ *   function is decided, to obtain concise ptype information.
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			       uint32_t *ptypes, int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..a12784c 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,11 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_get_ptype_info;
+
+	local: *;
+} DPDK_2.2;
-- 
2.1.4

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-03-10  0:40  3%       ` Lu, Wenzhuo
  0 siblings, 0 replies; 200+ results
From: Lu, Wenzhuo @ 2016-03-10  0:40 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,


> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 9, 2016 5:49 PM
> To: Lu, Wenzhuo
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name
> of tunnel port config
> 
> 2016-03-09 11:35, Wenzhuo Lu:
> > +       uint16_t udp_port; /**< UDP port used for the tunnel. */
> > +       uint8_t prot_type; /**< Tunnel type. */
> 
> Is 42 a valid tunnel type?
> Please reference where to find the constants.
> Think as a user who won't read your datasheet.
OK. Let me add more. Honestly, I want to change " uint8_t prot_type " to " enum rte_eth_tunnel_type  prot_type". But seems it's a ABI change, so I don't do that. 

> 
> [...]
> >   /**
> > - * Add UDP tunneling port of an Ethernet device for filtering a
> > specific
> > - * tunneling packet by UDP port number.
> > + * Add UDP tunneling port for a specific type of tunnel.
> > + * The packets with this UDP port will be parsed as this type of tunnel.
> 
> We progress.
> What will be parsed? What will be the action? checksum? decapsulation?
Let me explain more.

> 
> [...]
> >  int
> > +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> > +                               struct rte_eth_udp_tunnel
> > +*tunnel_udp);
> > +/* Below is deprecated. Replaced by rte_eth_dev_udp_tunnel_port_add.
> > +*/ int
> >  rte_eth_dev_udp_tunnel_add(uint8_t port_id,
> >                            struct rte_eth_udp_tunnel *tunnel_udp);
> 
> Better. Please make a doxygen comment with @see.
> We still need a __rte_deprecated attribute on the function.
Let me try to find some reference.

> 
> > --- a/lib/librte_ether/rte_ether_version.map
> > +++ b/lib/librte_ether/rte_ether_version.map
> > @@ -117,3 +117,10 @@ DPDK_2.2 {
> >
> >         local: *;
> >  };
> > +
> > +DPDK_2.3 {
> > +       global:
> > +
> > +       rte_eth_dev_udp_tunnel_port_add;
> > +       rte_eth_dev_udp_tunnel_port_delete;
> > +}DPDK_2.2;
> 
> Please rename 2.3 to 16.04.
Will correct it. Thanks.
> 

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  @ 2016-03-10  0:04  0%     ` Thomas Monjalon
  2016-03-10  6:31  0%       ` Vincent JARDIN
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-10  0:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Avi Kivity, dev

2016-03-02 23:35, Thomas Monjalon:
> 2016-03-02 12:21, Thomas Monjalon:
> > 2016-03-02 11:47, Vincent JARDIN:
> > > Le 02/03/2016 09:27, Panu Matilainen a écrit :
> > > >>> I'd like to see these be merged.
> > > >>>
> > > >>> Jay
> > > >>
> > > >> The code is really not ready. I am okay with cooperative development
> > > >> but the current code needs to go into a staging type tree.
> > > >> No compatibility, no ABI guarantees, more of an RFC.
> > > >> Don't want vendors building products with it then screaming when it
> > > >> gets rebuilt/reworked/scrapped.
> > > >>
> > > >
> > > > Exactly.
> > > 
> > > +1 too
> > > 
> > > We need to build on this innovation while there is a path for kernel 
> > > mainstream. The logic of using a staging is a good one.
> > > 
> > > Thomas,
> > > 
> > > can we open a staging folder into the DPDK like it is done into the kernel?
> > 
> > It's possible to create a staging directory if everybody agree.
> > It is important to state in a README file or in the doc/ that
> > there will be no guarantee (no stable ABI, no validation and can be dropped)
> > and that it is a work in progress, a suggestion to discuss with the kernel
> > community.
> > 
> > The kernel modules must clearly target an upstream integration.
> 
> Actually the examples directory has been used as a staging for ethtool and
> lthread. We also have the crypto API which is still experimental.
> So I think we must decide among these 3 solutions:
> 	- no special directory, just mark and document an experimental state
> 	- put only kcp/kdp in the staging directory
> 	- put kcp/kdp in staging and move other experimental libs here

Any opinion? Are we targetting upstream work without any DPDK staging?

Please let's make clear the status of these patches.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data
  @ 2016-03-10  0:00  0% ` Thomas Monjalon
  2016-03-10 13:37  0%   ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-10  0:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev

2016-02-17 14:20, Ferruh Yigit:
> This is to provide abstraction and reduce global variable access.
> 
> Global variable rte_eth_devices kept exported to not break ABI.
> 
> Bonding driver not selected on purpose, just it seems it is using 
> rte_eth_devices heavily.
> 
> There are a few more usage in drivers but they left as it is because they
> are in fast path code.

What is the benefit of these functions if you do not plan to remove the
global variables later?

Anyway this discussion targets the release 16.07.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09 16:31  4%             ` Olivier MATZ
@ 2016-03-09 16:39  4%               ` Hunt, David
  0 siblings, 0 replies; 200+ results
From: Hunt, David @ 2016-03-09 16:39 UTC (permalink / raw)
  To: Olivier MATZ, Panu Matilainen, dev

Hi Olivier,

On 3/9/2016 4:31 PM, Olivier MATZ wrote:
> Hi David,
>
> On 03/09/2016 05:28 PM, Hunt, David wrote:
>
>> Sure, v4 will remove the NEXT_ABI patch , and replace it with just the
>> ABI break announcement for 16.07. For anyone who what's to try out the
>> patch, they can always get it from patchwork, but not as part 16.04.
> I think it's better to have the deprecation notice in a separate
> mail, outside of the patch series, so Thomas can just apply this
> one and let the series pending for 16.07.
>
> Thanks,
> Olivier

Yes, sure, makes perfect sense.

Thanks,
David.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09 16:28  7%           ` Hunt, David
@ 2016-03-09 16:31  4%             ` Olivier MATZ
  2016-03-09 16:39  4%               ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2016-03-09 16:31 UTC (permalink / raw)
  To: Hunt, David, Panu Matilainen, dev

Hi David,

On 03/09/2016 05:28 PM, Hunt, David wrote:
>> Sorry, maybe I wasn't very clear in my previous messages. For me, the
>> NEXT_ABI is not the proper solution because, as Panu stated, it makes
>> the patch hard to read. My understanding of NEXT_ABI is that it should
>> only be used if the changes are small enough. Duplicating the code with
>> a big #ifdef NEXT_ABI is not an option to me either.
>>
>> So that's why the deprecation notice should be used instead. But in this
>> case, it means that this patch won't be present in 16.04, but will be
>> added in 16.07.
>>
> Sure, v4 will remove the NEXT_ABI patch , and replace it with just the
> ABI break announcement for 16.07. For anyone who what's to try out the
> patch, they can always get it from patchwork, but not as part 16.04.

I think it's better to have the deprecation notice in a separate
mail, outside of the patch series, so Thomas can just apply this
one and let the series pending for 16.07.

Thanks,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09 14:59  4%         ` Olivier MATZ
@ 2016-03-09 16:28  7%           ` Hunt, David
  2016-03-09 16:31  4%             ` Olivier MATZ
  0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2016-03-09 16:28 UTC (permalink / raw)
  To: Olivier MATZ, Panu Matilainen, dev

Hi Olivier,

On 3/9/2016 2:59 PM, Olivier MATZ wrote:
> Hi David,
>
> On 03/09/2016 12:30 PM, Hunt, David wrote:
>> Hi Panu,
>>
>> On 3/9/2016 10:46 AM, Panu Matilainen wrote:
>>> On 03/09/2016 11:50 AM, David Hunt wrote:
>>>> This patch is for those people who want to be easily able to switch
>>>> between the new mempool layout and the old. Change the value of
>>>> RTE_NEXT_ABI in common_base config file
>>> I guess the idea here is to document how to switch between the ABIs
>>> but to me this reads as if this patch is supposed to change the value
>>> in common_base. Of course there's  no such change included (nor should
>>> there be) here, but the description could use some fine-tuning perhaps.
>>>
>> You're right, I'll clarify the comments. v4 due soon.
>>
>>>> v3: Updated to take re-work of file layouts into consideration
>>>>
>>>> v2: Kept all the NEXT_ABI defs to this patch so as to make the
>>>> previous patches easier to read, and also to imake it clear what
>>>> code is necessary to keep ABI compatibility when NEXT_ABI is
>>>> disabled.
>>> Maybe its just me, but:
>>> I can see why NEXT_ABI is in a separate patch for review purposes but
>>> for final commit this split doesn't seem right to me. In any case its
>>> quite a large change for NEXT_ABI.
>>>
>> The patch basically re-introduces the old (pre-mempool) code as the
>> refactoring of the code would have made the NEXT_ABI additions totally
>> unreadable. I think this way is the lesser of two evils.
>>
>>> In any case, you should add a deprecation notice for the oncoming ABI
>>> break in 16.07.
>>>
>> Sure, I'll add that in v4.
> Sorry, maybe I wasn't very clear in my previous messages. For me, the
> NEXT_ABI is not the proper solution because, as Panu stated, it makes
> the patch hard to read. My understanding of NEXT_ABI is that it should
> only be used if the changes are small enough. Duplicating the code with
> a big #ifdef NEXT_ABI is not an option to me either.
>
> So that's why the deprecation notice should be used instead. But in this
> case, it means that this patch won't be present in 16.04, but will be
> added in 16.07.
>
> Regards,
> Olivier

Sure, v4 will remove the NEXT_ABI patch , and replace it with just the 
ABI break announcement for 16.07. For anyone who what's to try out the 
patch, they can always get it from patchwork, but not as part 16.04.

Thanks,
David.

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [RFC 00/35] mempool: rework memory allocation
@ 2016-03-09 16:19  2% Olivier Matz
  2016-03-17  9:05 15% ` [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07 Olivier Matz
  2016-04-14 10:19  2% ` [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation Olivier Matz
  0 siblings, 2 replies; 200+ results
From: Olivier Matz @ 2016-03-09 16:19 UTC (permalink / raw)
  To: dev

This series is a rework of mempool. For those who don't want to read
all the cover letter, here is a sumary:

- it is not possible to allocate large mempools if there is not enough
  contiguous memory, this series solves this issue
- introduce new APIs with less arguments: "create, populate, obj_init"
- allow to free a mempool
- split code in smaller functions, will ease the introduction of ext_handler
- remove test-pmd anonymous mempool creation
- remove most of dom0-specific mempool code
- opens the door for a eal_memory rework: we probably don't need large
  contiguous memory area anymore, working with pages would work.

This will clearly break the ABI, but as there are already 2 other changes that
will break it for 16.07, the target for this series is 16.07. I plan to send a
deprecation notice for 16.04 soon.

The API stays almost the same, no modification is needed in examples app
or in test-pmd. Only kni and mellanox drivers are slightly modified.

Description of the initial issue
--------------------------------

The allocation of mbuf pool can fail even if there is enough memory.
The problem is related to the way the memory is allocated and used in
dpdk. It is particularly annoying with mbuf pools, but it can also fail
in other use cases allocating a large amount of memory.

- rte_malloc() allocates physically contiguous memory, which is needed
  for mempools, but useless most of the time.

  Allocating a large physically contiguous zone is often impossible
  because the system provide hugepages which may not be contiguous.

- rte_mempool_create() (and therefore rte_pktmbuf_pool_create())
  requires a physically contiguous zone.

- rte_mempool_xmem_create() does not solve the issue as it still
  needs the memory to be virtually contiguous, and there is no
  way in dpdk to allocate a virtually contiguous memory that is
  not also physically contiguous.

How to reproduce the issue
--------------------------

- start the dpdk with some 2MB hugepages (it can also occur with 1GB)
- allocate a large mempool
- even if there is enough memory, the allocation can fail

Example:

  git clone http://dpdk.org/git/dpdk
  cd dpdk
  make config T=x86_64-native-linuxapp-gcc
  make -j32
  mkdir -p /mnt/huge
  mount -t hugetlbfs nodev /mnt/huge
  echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

  # we try to allocate a mempool whose size is ~450MB, it fails
  ./build/app/testpmd -l 2,4 -- --total-num-mbufs=200000 -i

The EAL logs "EAL: Virtual area found at..." shows that there are
several zones, but all smaller than 450MB.

Workarounds:

- Use 1GB hugepages: it sometimes work, but for very large
  pools (millions of mbufs) there is the same issue. Moreover,
  it would consume 1GB memory at least which can be a lot
  in some cases.

- Reboot the machine or allocate hugepages at boot time: this increases
  the chances to have more contiguous memory, but does not completely
  solve the issue

Solutions
---------

Below is a list of proposed solutions. I implemented a quick and dirty
PoC of solution 1, but it's not working in all conditions and it's
really an ugly hack.  This series implement the solution 4 which looks
the best to me, knowing it does not prevent to do more enhancements
in dpdk memory in the future (solution 3 for instance).

Solution 1: in application
--------------------------

- allocate several hugepages using rte_malloc() or rte_memzone_reserve()
  (only keeping complete hugepages)
- parse memsegs and /proc/maps to check which files mmaps these pages
- mmap the files in a contiguous virtual area
- use rte_mempool_xmem_create()

Cons:

- 1a. parsing the memsegs of rte config in the application does not
  use a public API, and can be broken if internal dpdk code changes
- 1b. some memory is lost due to malloc headers. Also, if the memory is
  very fragmented (ex: all 2MB pages are physically separated), it does
  not work at all because we cannot get any complete page. It is not
  possible to use a lower level allocator since commit fafcc11985a.
- 1c. we cannot use rte_pktmbuf_pool_create(), so we need to use mempool
  api and do a part of the job manually
- 1d. it breaks secondary processes as the virtual addresses won't be
  mmap'd at the same place in secondary process
- 1e. it only fixes the issue for the mbuf pool of the application,
  internal pools in dpdk libraries are not modified
- 1f. this is a pure linux solution (rte_map files)
- 1g. The application has to be aware of RTE_EAL_SINGLE_SEGMENTS option
  that changes the way hugepages are mapped. By the way, it's strange
  to have such a compile-time option, we should probably have only
  one behavior that works all the time.

Solution 2: in dpdk memory allocator
------------------------------------

- do the same than solution 1 in a new function rte_malloc_non_contig():
  allocate several chunks and mmap them in a contiguous virtual memory
- a flag has to be added in malloc header to do the proper cleanup in
  rte_free() (free all the chunks, munmap the memory)
- introduce a new rte_mem_get_physmap(*physmap,addr, len) that returns
  the virt2phys mapping of a virtual area in dpdk
- add a mempool flag MEMPOOL_F_NON_PHYS_CONTIG to use
  rte_malloc_non_contig() to allocate the area storing the objects

Cons:

- 2a. same than 1b: it breaks secondary processes if the mempool flag is
  used.
- 2b. same as 1d: some memory is lost due to malloc headers, and it
  cannot work if memory is too fragmented.
- 2c. rte_malloc_virt2phy() cannot be used on these zones. It would
  return the physical address of the first page. It would be better to
  return an error in this case.
- 2d. need to check how to implement this on bsd (TBD)

Solution 3: in dpdk eal memory
------------------------------

- Rework the way hugepages are mmap'd in dpdk: instead of having several
  rte_map* files, just mmap one file per node. It may drastically
  simplify EAL memory management in dpdk.
- An API should be added to retrieve the physical mapping of a virtual
  area (ex: rte_mem_get_physmap(*physmap, addr, len))
- rte_malloc() and rte_memzone_reserve() won't allocate physically
  contiguous memory anymore (TBD)
- Update mempool to always use the rte_mempool_xmem_create() version

Cons:

- 3a. lot of rework in eal memory, it will induce some behavior changes
  and maybe api changes
- 3b. possible conflicts with xen_dom0 mempool

Solution 4: in mempool
----------------------

- Introduce a new API to fill a mempool with zones that are not
  virtually contiguous. It requires to add new functions to create and
  populate a mempool. Example (TBD):

  - rte_mempool_create_empty(name, n, elt_size, cache_size, priv_size)
  - rte_mempool_populate(mp, addr, len): add virtual memory for objects
  - rte_mempool_mempool_obj_iter(mp, obj_cb, arg): call a cb for each object

- update rte_mempool_create() to allocate objects in several memory
  chunks by default if there is no large enough physically contiguous
  memory.

Tests done
----------

Compilation
~~~~~~~~~~~

The following targets:

 x86_64-native-linuxapp-gcc
 i686-native-linuxapp-gcc
 x86_x32-native-linuxapp-gcc
 x86_64-native-linuxapp-clang

Libraries ith and without debug, in static and shared mode + examples.

autotests
~~~~~~~~~

cd /root/dpdk.org
make config T=x86_64-native-linuxapp-gcc O=x86_64-native-linuxapp-gcc
make -j4 O=x86_64-native-linuxapp-gcc EXTRA_CFLAGS="-g -O0"
modprobe uio_pci_generic
python tools/dpdk_nic_bind.py -b uio_pci_generic 0000:03:00.0
python tools/dpdk_nic_bind.py -b uio_pci_generic 0000:08:00.0
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

./x86_64-native-linuxapp-gcc/app/test -l 0,2,4 -n 4
  memory_autotest       OK
  memzone_autotest      OK
  ring_autotest         OK
  ring_perf_autotest    OK
  mempool_autotest      OK
  mempool_perf_autotest OK

same with --no-huge
  memory_autotest       OK
  memzone_autotest      KO  (was already KO)
  mempool_autotest      OK
  mempool_perf_autotest OK
  ring_autotest         OK
  ring_perf_autotest    OK

test-pmd
~~~~~~~~

# now starts fine, was failing before if mempool was too fragmented
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -- -i --port-topology=chained

# still ok
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 -- -i --port-topology=chained --mp-anon
set fwd txonly
start
stop

# fail, but was failing before too. The problem is because the physical
# addresses are not properly set when using --no-huge. The mempool phys addr
# are now correct, but the zones allocated through memzone_reserve() are
# still wrong. This could be fixed in a future series.
./x86_64-native-linuxapp-gcc/app/testpmd -l 0,2,4 -n 4 -m 256 --no-huge -- -i ---port-topology=chained
set fwd txonly
start
stop

Tests not done (for now)
------------------------

- mellanox driver (it is slightly modified)
- kni (it is slightly modified)
- compilation and test with freebsd
- compilation and test with xen
- compilation and test on other archs


Olivier Matz (35):
  mempool: fix comments and style
  mempool: replace elt_size by total_elt_size
  mempool: uninline function to check cookies
  mempool: use sizeof to get the size of header and trailer
  mempool: rename mempool_obj_ctor_t as mempool_obj_cb_t
  mempool: update library version
  mempool: list objects when added in the mempool
  mempool: remove const attribute in mempool_walk
  mempool: use the list to iterate the mempool elements
  eal: introduce RTE_DECONST macro
  mempool: use the list to audit all elements
  mempool: use the list to initialize mempool objects
  mempool: create the internal ring in a specific function
  mempool: store physaddr in mempool objects
  mempool: remove MEMPOOL_IS_CONTIG()
  mempool: store memory chunks in a list
  mempool: new function to iterate the memory chunks
  mempool: simplify xmem_usage
  mempool: introduce a free callback for memory chunks
  mempool: make page size optional when getting xmem size
  mempool: default allocation in several memory chunks
  eal: lock memory when using no-huge
  mempool: support no-hugepage mode
  mempool: replace mempool physaddr by a memzone pointer
  mempool: introduce a function to free a mempool
  mempool: introduce a function to create an empty mempool
  eal/xen: return machine address without knowing memseg id
  mempool: rework support of xen dom0
  mempool: create the internal ring when populating
  mempool: populate a mempool with anonymous memory
  test-pmd: remove specific anon mempool code
  mempool: make mempool populate and free api public
  mem: avoid memzone/mempool/ring name truncation
  mempool: new flag when phys contig mem is not needed
  mempool: update copyright

 app/test-pmd/Makefile                        |    4 -
 app/test-pmd/mempool_anon.c                  |  201 -----
 app/test-pmd/mempool_osdep.h                 |   54 --
 app/test-pmd/testpmd.c                       |   17 +-
 app/test/test_mempool.c                      |   21 +-
 doc/guides/rel_notes/release_16_04.rst       |    2 +-
 drivers/net/mlx4/mlx4.c                      |   71 +-
 drivers/net/mlx5/mlx5_rxq.c                  |    9 +-
 drivers/net/mlx5/mlx5_rxtx.c                 |   62 +-
 drivers/net/mlx5/mlx5_rxtx.h                 |    2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.h        |    2 +-
 drivers/net/xenvirt/rte_mempool_gntalloc.c   |    4 +-
 lib/librte_eal/common/eal_common_log.c       |    2 +-
 lib/librte_eal/common/eal_common_memzone.c   |   10 +-
 lib/librte_eal/common/include/rte_common.h   |    9 +
 lib/librte_eal/common/include/rte_memory.h   |   11 +-
 lib/librte_eal/linuxapp/eal/eal_memory.c     |    2 +-
 lib/librte_eal/linuxapp/eal/eal_xen_memory.c |   17 +-
 lib/librte_kni/rte_kni.c                     |   12 +-
 lib/librte_mempool/Makefile                  |    5 +-
 lib/librte_mempool/rte_dom0_mempool.c        |  133 ----
 lib/librte_mempool/rte_mempool.c             | 1031 +++++++++++++++++---------
 lib/librte_mempool/rte_mempool.h             |  590 +++++++--------
 lib/librte_mempool/rte_mempool_version.map   |   18 +-
 lib/librte_ring/rte_ring.c                   |   16 +-
 25 files changed, 1121 insertions(+), 1184 deletions(-)
 delete mode 100644 app/test-pmd/mempool_anon.c
 delete mode 100644 app/test-pmd/mempool_osdep.h
 delete mode 100644 lib/librte_mempool/rte_dom0_mempool.c

-- 
2.1.4

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH] doc: fix API change in release note
  2016-03-09 11:59 13% [dpdk-dev] [PATCH] doc: fix API change in release note Jingjing Wu
@ 2016-03-09 16:15  0% ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-09 16:15 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

2016-03-09 19:59, Jingjing Wu:
> Move the structure ``rte_eth_fdir_masks`` change announcement from ABI
> to API in release note.
> 
> Fixes: 1409f127d7f1 (ethdev: fix byte order consistency of flow director)
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>

Applied, thanks

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs
  2016-03-07  9:28  0%   ` [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs Thomas Monjalon
@ 2016-03-09 15:20  0%     ` Zhang, Helin
  0 siblings, 0 replies; 200+ results
From: Zhang, Helin @ 2016-03-09 15:20 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Monday, March 7, 2016 5:29 PM
> To: Zhang, Helin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs
> 
> 2016-03-07 16:12, Helin Zhang:
> > The patch set was branched off rel_16_04 of repo dpdk-next-net, on
> > below commit.
> >  - commit 4ac366ba647909c3b71818f9be9db86ba5e871da
> >      nfp: fix non-x86 build
> 
> Currently, changes on ethdev are directly applied on dpdk.git.
Won't it be reviewed by Bruce, and applied on his maintainer branch first?

> 
> > v2:
> >  - Used RTE_NEXT_ABI to avoid ABI change issue.
> 
> RTE_NEXT_ABI must be used only when it is really too difficult to keep the
> compatibility with librte_compat.
> Here you are just adding a parameter to some functions, so you should try
> versionning the functions with the help of macros in librte_compat.
Let me think it a little bit more. I don't think I have understood that
versioning quite well.

> 
> About the API change, you want to be able to insert a QinQ inner-vlan, right?
No, I just want to configure the ether type of vlan the hardware can recognize,
but not to insert a vlan.

> The current comment of rte_eth_dev_set_vlan_ether_type is:
>  * Set the Outer VLAN Ether Type by an Ethernet device, it can be inserted to
>  * the VLAN Header. This is a register setup available on some Intel NIC, not
>  * but all, please check the data sheet for availability.
Yes, I agree with you the comments should be reworked.

> 
> 2 comments:
> - you haven't changed "Outer VLAN" so the API description is wrong
> - it is announced as something Intel-specific
> 
> About the new enum:
> + * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
> + * Note that most of time single VLAN is treated the same as inner VLAN.
> 
> You cannot say "most of time" in an API.
Accepted.

> 
> More generally, I am not convinced by the current VLAN API that you are
> extending.
> Why this function is not merged with rte_eth_dev_set_vlan_pvid?
No, they are different. I am trying to configure the hardware recognized
ether type of both inner and outer vlan, but not to configure the vlan itself.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] ethdev: bump library version
  2016-03-09 15:09  0% ` [dpdk-dev] [PATCH 1/2] ethdev: " Nélio Laranjeiro
@ 2016-03-09 15:16  0%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-09 15:16 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

> > There was an ABI change and more are coming in the release 16.04.
> > 
> > Fixes: a9963a86b2e1 ("ethdev: increase RETA entry size")
> > 
> > Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> 
> Series Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

Applied

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] ethdev: bump library version
  2016-03-09 14:14  8% [dpdk-dev] [PATCH 1/2] ethdev: bump library version Thomas Monjalon
  2016-03-09 14:14  8% ` [dpdk-dev] [PATCH 2/2] cmdline: " Thomas Monjalon
@ 2016-03-09 15:09  0% ` Nélio Laranjeiro
  2016-03-09 15:16  0%   ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Nélio Laranjeiro @ 2016-03-09 15:09 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Wed, Mar 09, 2016 at 03:14:07PM +0100, Thomas Monjalon wrote:
> There was an ABI change and more are coming in the release 16.04.
> 
> Fixes: a9963a86b2e1 ("ethdev: increase RETA entry size")
> 
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> ---
>  doc/guides/rel_notes/release_16_04.rst | 5 ++++-
>  lib/librte_ether/Makefile              | 2 +-
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index 96f144e..8101f4c 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -148,6 +148,9 @@ ABI Changes
>  * The fields in ethdev structure ``rte_eth_fdir_masks`` were changed
>    to be in big endian.
>  
> +* The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
> +  from 8-bit to 16-bit.
> +
>  
>  Shared Library Versions
>  -----------------------
> @@ -158,7 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
>  
>  .. code-block:: diff
>  
> -     libethdev.so.2
> +   + libethdev.so.3
>       librte_acl.so.2
>       librte_cfgfile.so.2
>       librte_cmdline.so.1
> diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
> index 3e81a0e..e810284 100644
> --- a/lib/librte_ether/Makefile
> +++ b/lib/librte_ether/Makefile
> @@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
>  
>  EXPORT_MAP := rte_ether_version.map
>  
> -LIBABIVER := 2
> +LIBABIVER := 3
>  
>  SRCS-y += rte_ethdev.c
>  
> -- 
> 2.7.0
> 

Series Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09 11:30  4%       ` Hunt, David
@ 2016-03-09 14:59  4%         ` Olivier MATZ
  2016-03-09 16:28  7%           ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2016-03-09 14:59 UTC (permalink / raw)
  To: Hunt, David, Panu Matilainen, dev

Hi David,

On 03/09/2016 12:30 PM, Hunt, David wrote:
> Hi Panu,
> 
> On 3/9/2016 10:46 AM, Panu Matilainen wrote:
>> On 03/09/2016 11:50 AM, David Hunt wrote:
>>> This patch is for those people who want to be easily able to switch
>>> between the new mempool layout and the old. Change the value of
>>> RTE_NEXT_ABI in common_base config file
>>
>> I guess the idea here is to document how to switch between the ABIs
>> but to me this reads as if this patch is supposed to change the value
>> in common_base. Of course there's  no such change included (nor should
>> there be) here, but the description could use some fine-tuning perhaps.
>>
> 
> You're right, I'll clarify the comments. v4 due soon.
> 
>>>
>>> v3: Updated to take re-work of file layouts into consideration
>>>
>>> v2: Kept all the NEXT_ABI defs to this patch so as to make the
>>> previous patches easier to read, and also to imake it clear what
>>> code is necessary to keep ABI compatibility when NEXT_ABI is
>>> disabled.
>>
>> Maybe its just me, but:
>> I can see why NEXT_ABI is in a separate patch for review purposes but
>> for final commit this split doesn't seem right to me. In any case its
>> quite a large change for NEXT_ABI.
>>
> 
> The patch basically re-introduces the old (pre-mempool) code as the
> refactoring of the code would have made the NEXT_ABI additions totally
> unreadable. I think this way is the lesser of two evils.
> 
>> In any case, you should add a deprecation notice for the oncoming ABI
>> break in 16.07.
>>
> 
> Sure, I'll add that in v4.

Sorry, maybe I wasn't very clear in my previous messages. For me, the
NEXT_ABI is not the proper solution because, as Panu stated, it makes
the patch hard to read. My understanding of NEXT_ABI is that it should
only be used if the changes are small enough. Duplicating the code with
a big #ifdef NEXT_ABI is not an option to me either.

So that's why the deprecation notice should be used instead. But in this
case, it means that this patch won't be present in 16.04, but will be
added in 16.07.

Regards,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  2016-03-08  2:44  0%         ` Yuanhan Liu
@ 2016-03-09 14:44  0%           ` Tan, Jianfeng
  0 siblings, 0 replies; 200+ results
From: Tan, Jianfeng @ 2016-03-09 14:44 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: nakajima.yoshihiro, mst, dev, p.fedin, ann.zhuangyanying

Hi,

On 3/8/2016 10:44 AM, Yuanhan Liu wrote:
> On Tue, Mar 08, 2016 at 09:55:10AM +0800, Tan, Jianfeng wrote:
>> Hi Yuanhan,
>>
>> On 3/7/2016 9:13 PM, Yuanhan Liu wrote:
>>> CC'ed EAL hugepage maintainer, which is something you should do when
>>> send a patch.
>> Thanks for doing this.
>>
>>> On Fri, Feb 05, 2016 at 07:20:24PM +0800, Jianfeng Tan wrote:
>>>> Originally, there're two cons in using hugepage: a. needs root
>>>> privilege to touch /proc/self/pagemap, which is a premise to
>>>> alllocate physically contiguous memseg; b. possibly too many
>>>> hugepage file are created, especially used with 2M hugepage.
>>>>
>>>> For virtual devices, they don't care about physical-contiguity
>>>> of allocated hugepages at all. Option --single-file is to
>>>> provide a way to allocate all hugepages into single mem-backed
>>>> file.
>>>>
>>>> Known issue:
>>>> a. single-file option relys on kernel to allocate numa-affinitive
>>>> memory.
>>>> b. possible ABI break, originally, --no-huge uses anonymous memory
>>>> instead of file-backed way to create memory.
>>>>
>>>> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
>>>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>>> ...
>>>> @@ -956,6 +961,16 @@ eal_check_common_options(struct internal_config *internal_cfg)
>>>>   			"be specified together with --"OPT_NO_HUGE"\n");
>>>>   		return -1;
>>>>   	}
>>>> +	if (internal_cfg->single_file && internal_cfg->force_sockets == 1) {
>>>> +		RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE" cannot "
>>>> +			"be specified together with --"OPT_SOCKET_MEM"\n");
>>>> +		return -1;
>>>> +	}
>>>> +	if (internal_cfg->single_file && internal_cfg->hugepage_unlink) {
>>>> +		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
>>>> +			"be specified together with --"OPT_SINGLE_FILE"\n");
>>>> +		return -1;
>>>> +	}
>>> The two limitation doesn't make sense to me.
>> For the force_sockets option, my original thought on --single-file option
>> is, we don't sort those pages (require root/cap_sys_admin) and even don't
>> look up numa information because it may contain both sockets' memory.
>>
>> For the hugepage_unlink option, those hugepage files get closed in the end
>> of memory initialization, if we even unlink those hugepage files, so we
>> cannot share those with other processes (say backend).
> Yeah, I know how the two limitations come, from your implementation. I
> was just wondering if they both are __truly__ the limitations. I mean,
> can we get rid of them somehow?
>
> For --socket-mem option, if we can't handle it well, or if we could
> ignore the socket_id for allocated huge page, yes, the limitation is
> a true one.

To make it work with --socket-mem option, we need to call 
mbind()/set_mempolicy(), which leads to including "LDFLAGS += -lnuma" a 
mandatory line in mk file. Don't know if it's  acceptable to bring in 
dependency on libnuma.so?


>
> But for the second option, no, we should be able to co-work it with
> well. One extra action is you should not invoke "close(fd)" for those
> huge page files. And then you can get all the informations as I stated
> in a reply to your 2nd patch.

As discussed yesterday, I think there's a open files limitation for each 
process, if we keep those FDs open, it will bring failure to those 
existing programs. If others treat it as a problem?
...
>>> BTW, since we already have SINGLE_FILE_SEGMENTS (config) option, adding
>>> another option --single-file looks really confusing to me.
>>>
>>> To me, maybe you could base the SINGLE_FILE_SEGMENTS option, and add
>>> another option, say --no-sort (I confess this name sucks, but you get
>>> my point). With that, we could make sure to create as least huge page
>>> files as possible, to fit your case.
>> This is a great advice. So how do you think of --converged, or
>> --no-scattered-mem, or any better idea?
> TBH, none of them looks great to me, either. But I have no better
> options. Well, --no-phys-continuity looks like the best option to
> me so far :)

I'd like to make it a little more concise, how about --no-phys-contig? 
In addition, Yuanhan thinks there's still no literal meaning that just 
create one file for each hugetlbfs (or socket). But from my side, 
there's an indirect meaning, because if no need to promise 
physically-contig, then no need to create hugepages one by one. Anyone 
can give your option here? Thanks.

Thanks,
Jianfeng

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH 2/2] cmdline: bump library version
  2016-03-09 14:14  8% [dpdk-dev] [PATCH 1/2] ethdev: bump library version Thomas Monjalon
@ 2016-03-09 14:14  8% ` Thomas Monjalon
  2016-03-09 15:09  0% ` [dpdk-dev] [PATCH 1/2] ethdev: " Nélio Laranjeiro
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-09 14:14 UTC (permalink / raw)
  To: nelio.laranjeiro, olivier.matz; +Cc: dev

There was an ABI change in the release 16.04.

Fixes: fb76dd26a31d ("cmdline: increase command line buffer")

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 doc/guides/rel_notes/release_16_04.rst | 4 +++-
 lib/librte_cmdline/Makefile            | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 8101f4c..621da29 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -151,6 +151,8 @@ ABI Changes
 * The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
   from 8-bit to 16-bit.
 
+* The cmdline buffer size has been increase from 256 to 512.
+
 
 Shared Library Versions
 -----------------------
@@ -164,7 +166,7 @@ The libraries prepended with a plus sign were incremented in this version.
    + libethdev.so.3
      librte_acl.so.2
      librte_cfgfile.so.2
-     librte_cmdline.so.1
+   + librte_cmdline.so.2
      librte_distributor.so.1
      librte_eal.so.2
      librte_hash.so.2
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index 719dff6..7d2d148 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -38,7 +38,7 @@ CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
 
 EXPORT_MAP := rte_cmdline_version.map
 
-LIBABIVER := 1
+LIBABIVER := 2
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := cmdline.c
-- 
2.7.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH 1/2] ethdev: bump library version
@ 2016-03-09 14:14  8% Thomas Monjalon
  2016-03-09 14:14  8% ` [dpdk-dev] [PATCH 2/2] cmdline: " Thomas Monjalon
  2016-03-09 15:09  0% ` [dpdk-dev] [PATCH 1/2] ethdev: " Nélio Laranjeiro
  0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2016-03-09 14:14 UTC (permalink / raw)
  To: nelio.laranjeiro, olivier.matz; +Cc: dev

There was an ABI change and more are coming in the release 16.04.

Fixes: a9963a86b2e1 ("ethdev: increase RETA entry size")

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 doc/guides/rel_notes/release_16_04.rst | 5 ++++-
 lib/librte_ether/Makefile              | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 96f144e..8101f4c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -148,6 +148,9 @@ ABI Changes
 * The fields in ethdev structure ``rte_eth_fdir_masks`` were changed
   to be in big endian.
 
+* The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
+  from 8-bit to 16-bit.
+
 
 Shared Library Versions
 -----------------------
@@ -158,7 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
 
 .. code-block:: diff
 
-     libethdev.so.2
+   + libethdev.so.3
      librte_acl.so.2
      librte_cfgfile.so.2
      librte_cmdline.so.1
diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index 3e81a0e..e810284 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_ether_version.map
 
-LIBABIVER := 2
+LIBABIVER := 3
 
 SRCS-y += rte_ethdev.c
 
-- 
2.7.0

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH v4] lpm: extended ipv4 next_hop field
  @ 2016-03-09 13:39  3%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-09 13:39 UTC (permalink / raw)
  To: Michal Jastrzebski; +Cc: dev

2016-03-09 13:40, Michal Jastrzebski:
> -     librte_lpm.so.2
> +     +librte_lpm.so.3
[...]
> -LIBABIVER := 2
> +LIBABIVER := 3

The LIBABIVER should be updated only when removing some symbols.
Here the ABI compatibility is preserved.

>  int
>  rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
> -uint8_t *next_hop);
> +uint32_t *next_hop);

The indent may be fixed here.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] doc: fix API change in release note
@ 2016-03-09 11:59 13% Jingjing Wu
  2016-03-09 16:15  0% ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jingjing Wu @ 2016-03-09 11:59 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: dev

Move the structure ``rte_eth_fdir_masks`` change announcement from ABI
to API in release note.

Fixes: 1409f127d7f1 (ethdev: fix byte order consistency of flow director)
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 96f144e..4c86660 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -137,6 +137,9 @@ This section should contain API changes. Sample format:
 * Add a short 1-2 sentence description of the API change. Use fixed width
   quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The fields in ethdev structure ``rte_eth_fdir_masks`` were changed
+  to be in big endian.
+
 
 ABI Changes
 -----------
@@ -145,9 +148,6 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
-* The fields in ethdev structure ``rte_eth_fdir_masks`` were changed
-  to be in big endian.
-
 
 Shared Library Versions
 -----------------------
-- 
2.4.0

^ permalink raw reply	[relevance 13%]

* [dpdk-dev] [PATCH v5 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder
  @ 2016-03-09 11:41  1%   ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-09 11:41 UTC (permalink / raw)
  To: dev

With KCP, examples/ethtool/lib/ethtool has two users, to prevent code
dublication, moving library from examples folder into lib/ folder.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---

v4, v5:
* No update
---
 config/common_base                         |   5 +
 config/common_linuxapp                     |   1 +
 doc/api/doxy-api-index.md                  |   3 +-
 doc/api/doxy-api.conf                      |   1 +
 doc/api/examples.dox                       |   5 +-
 doc/guides/prog_guide/ethtool_lib.rst      |  62 ++
 doc/guides/prog_guide/index.rst            |   3 +-
 doc/guides/rel_notes/release_16_04.rst     |   1 +
 doc/guides/sample_app_ug/ethtool.rst       |  36 +-
 examples/ethtool/Makefile                  |  24 +-
 examples/ethtool/ethapp.c                  | 873 +++++++++++++++++++++++++++++
 examples/ethtool/ethapp.h                  |  41 ++
 examples/ethtool/ethtool-app/Makefile      |  54 --
 examples/ethtool/ethtool-app/ethapp.c      | 873 -----------------------------
 examples/ethtool/ethtool-app/ethapp.h      |  41 --
 examples/ethtool/ethtool-app/main.c        | 305 ----------
 examples/ethtool/lib/Makefile              |  57 --
 examples/ethtool/lib/rte_ethtool.c         | 423 --------------
 examples/ethtool/lib/rte_ethtool.h         | 410 --------------
 examples/ethtool/main.c                    | 305 ++++++++++
 lib/Makefile                               |   1 +
 lib/librte_ethtool/Makefile                |  57 ++
 lib/librte_ethtool/rte_ethtool.c           | 423 ++++++++++++++
 lib/librte_ethtool/rte_ethtool.h           | 413 ++++++++++++++
 lib/librte_ethtool/rte_ethtool_version.map |  28 +
 mk/rte.app.mk                              |   1 +
 26 files changed, 2237 insertions(+), 2209 deletions(-)
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst
 create mode 100644 examples/ethtool/ethapp.c
 create mode 100644 examples/ethtool/ethapp.h
 delete mode 100644 examples/ethtool/ethtool-app/Makefile
 delete mode 100644 examples/ethtool/ethtool-app/ethapp.c
 delete mode 100644 examples/ethtool/ethtool-app/ethapp.h
 delete mode 100644 examples/ethtool/ethtool-app/main.c
 delete mode 100644 examples/ethtool/lib/Makefile
 delete mode 100644 examples/ethtool/lib/rte_ethtool.c
 delete mode 100644 examples/ethtool/lib/rte_ethtool.h
 create mode 100644 examples/ethtool/main.c
 create mode 100644 lib/librte_ethtool/Makefile
 create mode 100644 lib/librte_ethtool/rte_ethtool.c
 create mode 100644 lib/librte_ethtool/rte_ethtool.h
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

diff --git a/config/common_base b/config/common_base
index c73f71a..70343ae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -485,6 +485,11 @@ CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
 CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=n
+
+#
 # Compile vhost library
 # fuse-devel is needed to run vhost-cuse.
 # fuse-devel enables user space char driver development
diff --git a/config/common_linuxapp b/config/common_linuxapp
index ffbe260..6d42070 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -39,6 +39,7 @@ CONFIG_RTE_EAL_IGB_UIO=y
 CONFIG_RTE_EAL_VFIO=y
 CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
+CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
 CONFIG_RTE_LIBRTE_POWER=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 7a91001..4cdd3f5 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -149,4 +149,5 @@ There are many libraries, so their headers may be grouped by topics:
   [common]             (@ref rte_common.h),
   [ABI compat]         (@ref rte_compat.h),
   [keepalive]          (@ref rte_keepalive.h),
-  [version]            (@ref rte_version.h)
+  [version]            (@ref rte_version.h),
+  [ethtool]            (@ref rte_ethtool.h),
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 57e8b5d..c5b8615 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -41,6 +41,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cryptodev \
                           lib/librte_distributor \
                           lib/librte_ether \
+                          lib/librte_ethtool \
                           lib/librte_hash \
                           lib/librte_ip_frag \
                           lib/librte_ivshmem \
diff --git a/doc/api/examples.dox b/doc/api/examples.dox
index 200af0b..8763d77 100644
--- a/doc/api/examples.dox
+++ b/doc/api/examples.dox
@@ -8,9 +8,8 @@
 @example distributor/main.c
 @example dpdk_qat/crypto.c
 @example dpdk_qat/main.c
-@example ethtool/ethtool-app/ethapp.c
-@example ethtool/ethtool-app/main.c
-@example ethtool/lib/rte_ethtool.c
+@example ethtool/ethapp.c
+@example ethtool/main.c
 @example exception_path/main.c
 @example helloworld/main.c
 @example ip_fragmentation/main.c
diff --git a/doc/guides/prog_guide/ethtool_lib.rst b/doc/guides/prog_guide/ethtool_lib.rst
new file mode 100644
index 0000000..e161cd0
--- /dev/null
+++ b/doc/guides/prog_guide/ethtool_lib.rst
@@ -0,0 +1,62 @@
+..  BSD LICENSE
+    Copyright(c) 2016 Intel Corporation. All rights reserved.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+    * Neither the name of Intel Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+.. _Ethtool_Library:
+
+Ethtool Library
+===============
+
+Ethtool interface
+-----------------
+
+The Ethtool interface is built as a separate library, and implements
+the following functions:
+
+- ``rte_ethtool_get_drvinfo()``
+- ``rte_ethtool_get_regs_len()``
+- ``rte_ethtool_get_regs()``
+- ``rte_ethtool_get_link()``
+- ``rte_ethtool_get_eeprom_len()``
+- ``rte_ethtool_get_eeprom()``
+- ``rte_ethtool_set_eeprom()``
+- ``rte_ethtool_get_pauseparam()``
+- ``rte_ethtool_set_pauseparam()``
+- ``rte_ethtool_net_open()``
+- ``rte_ethtool_net_stop()``
+- ``rte_ethtool_net_get_mac_addr()``
+- ``rte_ethtool_net_set_mac_addr()``
+- ``rte_ethtool_net_validate_addr()``
+- ``rte_ethtool_net_change_mtu()``
+- ``rte_ethtool_net_get_stats64()``
+- ``rte_ethtool_net_vlan_rx_add_vid()``
+- ``rte_ethtool_net_vlan_rx_kill_vid()``
+- ``rte_ethtool_net_set_rx_mode()``
+- ``rte_ethtool_get_ringparam()``
+- ``rte_ethtool_set_ringparam()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index a9404fb..98f4aca 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,7 @@ Programmer's Guide
     packet_distrib_lib
     reorder_lib
     ip_fragment_reassembly_lib
+    ethtool_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 96f144e..a07c292 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -164,6 +164,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cmdline.so.1
      librte_distributor.so.1
      librte_eal.so.2
+   + librte_ethtool.so.1
      librte_hash.so.2
      librte_ip_frag.so.1
      librte_ivshmem.so.1
diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst
index 4d1697e..65240ae 100644
--- a/doc/guides/sample_app_ug/ethtool.rst
+++ b/doc/guides/sample_app_ug/ethtool.rst
@@ -1,6 +1,6 @@
 
 ..  BSD LICENSE
-    Copyright(c) 2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ The only available options are the standard ones for the EAL:
 
 .. code-block:: console
 
-    ./ethtool-app/ethtool-app/${RTE_TARGET}/ethtool [EAL options]
+    ./${RTE_TARGET}/ethtool [EAL options]
 
 Refer to the *DPDK Getting Started Guide* for general information on
 running applications and the Environment Abstraction Layer (EAL)
@@ -128,33 +128,5 @@ Ethtool Shell
 The foreground part of the Ethtool sample is a console-based
 interface that accepts commands as described in `using the
 application`_. Individual call-back functions handle the detail
-associated with each command, which make use of the functions
-defined in the `Ethtool interface`_ to the DPDK functions.
-
-Ethtool interface
------------------
-
-The Ethtool interface is built as a separate library, and implements
-the following functions:
-
-- ``rte_ethtool_get_drvinfo()``
-- ``rte_ethtool_get_regs_len()``
-- ``rte_ethtool_get_regs()``
-- ``rte_ethtool_get_link()``
-- ``rte_ethtool_get_eeprom_len()``
-- ``rte_ethtool_get_eeprom()``
-- ``rte_ethtool_set_eeprom()``
-- ``rte_ethtool_get_pauseparam()``
-- ``rte_ethtool_set_pauseparam()``
-- ``rte_ethtool_net_open()``
-- ``rte_ethtool_net_stop()``
-- ``rte_ethtool_net_get_mac_addr()``
-- ``rte_ethtool_net_set_mac_addr()``
-- ``rte_ethtool_net_validate_addr()``
-- ``rte_ethtool_net_change_mtu()``
-- ``rte_ethtool_net_get_stats64()``
-- ``rte_ethtool_net_vlan_rx_add_vid()``
-- ``rte_ethtool_net_vlan_rx_kill_vid()``
-- ``rte_ethtool_net_set_rx_mode()``
-- ``rte_ethtool_get_ringparam()``
-- ``rte_ethtool_set_ringparam()``
+associated with each command, which make use of librte_ethtool
+library.
diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile
index 995cd25..23a6ffd 100644
--- a/examples/ethtool/Makefile
+++ b/examples/ethtool/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -33,17 +33,23 @@ ifeq ($(RTE_SDK),)
 $(error "Please define RTE_SDK environment variable")
 endif
 
-# Default target, can be overwritten by command line or environment
+# Default target, can be overridden by command line or environment
 RTE_TARGET ?= x86_64-native-linuxapp-gcc
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(info This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-else
+# binary name
+APP = ethtool
+
+# all source are stored in SRCS-y
+SRCS-y := main.c ethapp.c
+
+#CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
+#LDLIBS += -lrte_ethtool
 
-DIRS-y += lib ethtool-app
-endif
 
-include $(RTE_SDK)/mk/rte.extsubdir.mk
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/ethtool/ethapp.c b/examples/ethtool/ethapp.c
new file mode 100644
index 0000000..fca602b
--- /dev/null
+++ b/examples/ethtool/ethapp.c
@@ -0,0 +1,873 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_parse_etheraddr.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include "rte_ethtool.h"
+#include "ethapp.h"
+
+#define EEPROM_DUMP_CHUNKSIZE 1024
+
+
+struct pcmd_get_params {
+	cmdline_fixed_string_t cmd;
+};
+struct pcmd_int_params {
+	cmdline_fixed_string_t cmd;
+	uint16_t port;
+};
+struct pcmd_intstr_params {
+	cmdline_fixed_string_t cmd;
+	uint16_t port;
+	cmdline_fixed_string_t opt;
+};
+struct pcmd_intmac_params {
+	cmdline_fixed_string_t cmd;
+	uint16_t port;
+	struct ether_addr mac;
+};
+struct pcmd_str_params {
+	cmdline_fixed_string_t cmd;
+	cmdline_fixed_string_t opt;
+};
+struct pcmd_vlan_params {
+	cmdline_fixed_string_t cmd;
+	uint16_t port;
+	cmdline_fixed_string_t mode;
+	uint16_t vid;
+};
+struct pcmd_intintint_params {
+	cmdline_fixed_string_t cmd;
+	uint16_t port;
+	uint16_t tx;
+	uint16_t rx;
+};
+
+
+/* Parameter-less commands */
+cmdline_parse_token_string_t pcmd_quit_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "quit");
+cmdline_parse_token_string_t pcmd_stats_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "stats");
+cmdline_parse_token_string_t pcmd_drvinfo_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "drvinfo");
+cmdline_parse_token_string_t pcmd_link_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "link");
+
+/* Commands taking just port id */
+cmdline_parse_token_string_t pcmd_open_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "open");
+cmdline_parse_token_string_t pcmd_stop_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "stop");
+cmdline_parse_token_string_t pcmd_rxmode_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode");
+cmdline_parse_token_string_t pcmd_portstats_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats");
+cmdline_parse_token_num_t pcmd_int_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16);
+
+/* Commands taking port id and string */
+cmdline_parse_token_string_t pcmd_eeprom_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "eeprom");
+cmdline_parse_token_string_t pcmd_mtu_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "mtu");
+cmdline_parse_token_string_t pcmd_regs_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "regs");
+
+cmdline_parse_token_num_t pcmd_intstr_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
+cmdline_parse_token_string_t pcmd_intstr_token_opt =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL);
+
+/* Commands taking port id and a MAC address string */
+cmdline_parse_token_string_t pcmd_macaddr_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "macaddr");
+cmdline_parse_token_num_t pcmd_intmac_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16);
+cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac =
+	TOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac);
+
+/* Command taking just a MAC address */
+cmdline_parse_token_string_t pcmd_validate_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "validate");
+
+
+/* Commands taking port id and two integers */
+cmdline_parse_token_string_t pcmd_ringparam_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd,
+		"ringparam");
+cmdline_parse_token_num_t pcmd_intintint_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16);
+cmdline_parse_token_num_t pcmd_intintint_token_tx =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16);
+cmdline_parse_token_num_t pcmd_intintint_token_rx =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16);
+
+
+/* Pause commands */
+cmdline_parse_token_string_t pcmd_pause_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "pause");
+cmdline_parse_token_num_t pcmd_pause_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
+cmdline_parse_token_string_t pcmd_pause_token_opt =
+	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params,
+		opt, "all#tx#rx#none");
+
+/* VLAN commands */
+cmdline_parse_token_string_t pcmd_vlan_token_cmd =
+	TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, "vlan");
+cmdline_parse_token_num_t pcmd_vlan_token_port =
+	TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16);
+cmdline_parse_token_string_t pcmd_vlan_token_mode =
+	TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, "add#del");
+cmdline_parse_token_num_t pcmd_vlan_token_vid =
+	TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16);
+
+
+static void
+pcmd_quit_callback(__rte_unused void *ptr_params,
+	struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	cmdline_quit(ctx);
+}
+
+
+static void
+pcmd_drvinfo_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct ethtool_drvinfo info;
+	int id_port;
+
+	for (id_port = 0; id_port < rte_eth_dev_count(); id_port++) {
+		if (rte_ethtool_get_drvinfo(id_port, &info)) {
+			printf("Error getting info for port %i\n", id_port);
+			return;
+		}
+		printf("Port %i driver: %s (ver: %s)\n",
+			id_port, info.driver, info.version
+		      );
+	}
+}
+
+
+static void
+pcmd_link_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	int num_ports = rte_eth_dev_count();
+	int id_port, stat_port;
+
+	for (id_port = 0; id_port < num_ports; id_port++) {
+		if (!rte_eth_dev_is_valid_port(id_port))
+			continue;
+		stat_port = rte_ethtool_get_link(id_port);
+		switch (stat_port) {
+		case 0:
+			printf("Port %i: Down\n", id_port);
+			break;
+		case 1:
+			printf("Port %i: Up\n", id_port);
+			break;
+		default:
+			printf("Port %i: Error getting link status\n",
+				id_port
+				);
+			break;
+		}
+	}
+	printf("\n");
+}
+
+
+static void
+pcmd_regs_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_intstr_params *params = ptr_params;
+	int len_regs;
+	struct ethtool_regs regs;
+	unsigned char *buf_data;
+	FILE *fp_regs;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	len_regs = rte_ethtool_get_regs_len(params->port);
+	if (len_regs > 0) {
+		printf("Port %i: %i bytes\n", params->port, len_regs);
+		buf_data = malloc(len_regs);
+		if (buf_data == NULL) {
+			printf("Error allocating %i bytes for buffer\n",
+				len_regs);
+			return;
+		}
+		if (!rte_ethtool_get_regs(params->port, &regs, buf_data)) {
+			fp_regs = fopen(params->opt, "wb");
+			if (fp_regs == NULL) {
+				printf("Error opening '%s' for writing\n",
+					params->opt);
+			} else {
+				if ((int)fwrite(buf_data,
+						1, len_regs,
+						fp_regs) != len_regs)
+					printf("Error writing '%s'\n",
+						params->opt);
+				fclose(fp_regs);
+			}
+		}
+		free(buf_data);
+	} else if (len_regs == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error getting registers\n", params->port);
+}
+
+
+static void
+pcmd_eeprom_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_intstr_params *params = ptr_params;
+	struct ethtool_eeprom info_eeprom;
+	int len_eeprom;
+	int pos_eeprom;
+	int stat;
+	unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
+	FILE *fp_eeprom;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	len_eeprom = rte_ethtool_get_eeprom_len(params->port);
+	if (len_eeprom > 0) {
+		fp_eeprom = fopen(params->opt, "wb");
+		if (fp_eeprom == NULL) {
+			printf("Error opening '%s' for writing\n",
+				params->opt);
+			return;
+		}
+		printf("Total EEPROM length: %i bytes\n", len_eeprom);
+		info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
+		for (pos_eeprom = 0;
+				pos_eeprom < len_eeprom;
+				pos_eeprom += EEPROM_DUMP_CHUNKSIZE) {
+			info_eeprom.offset = pos_eeprom;
+			if (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom)
+				info_eeprom.len = len_eeprom - pos_eeprom;
+			else
+				info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
+			stat = rte_ethtool_get_eeprom(
+				params->port, &info_eeprom, bytes_eeprom
+				);
+			if (stat != 0) {
+				printf("EEPROM read error %i\n", stat);
+				break;
+			}
+			if (fwrite(bytes_eeprom,
+					1, info_eeprom.len,
+					fp_eeprom) != info_eeprom.len) {
+				printf("Error writing '%s'\n", params->opt);
+				break;
+			}
+		}
+		fclose(fp_eeprom);
+	} else if (len_eeprom == 0)
+		printf("Port %i: Device does not have EEPROM\n", params->port);
+	else if (len_eeprom == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error getting EEPROM\n", params->port);
+}
+
+
+static void
+pcmd_pause_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	void *ptr_data)
+{
+	struct pcmd_intstr_params *params = ptr_params;
+	struct ethtool_pauseparam info;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	if (ptr_data != NULL) {
+		stat = rte_ethtool_get_pauseparam(params->port, &info);
+	} else {
+		memset(&info, 0, sizeof(info));
+		if (strcasecmp("all", params->opt) == 0) {
+			info.tx_pause = 1;
+			info.rx_pause = 1;
+		} else if (strcasecmp("tx", params->opt) == 0) {
+			info.tx_pause = 1;
+			info.rx_pause = 0;
+		} else if (strcasecmp("rx", params->opt) == 0) {
+			info.tx_pause = 0;
+			info.rx_pause = 1;
+		} else {
+			info.tx_pause = 0;
+			info.rx_pause = 0;
+		}
+		/* Assume auto-negotiation wanted */
+		info.autoneg = 1;
+		stat = rte_ethtool_set_pauseparam(params->port, &info);
+	}
+	if (stat == 0) {
+		if (info.rx_pause && info.tx_pause)
+			printf("Port %i: Tx & Rx Paused\n", params->port);
+		else if (info.rx_pause)
+			printf("Port %i: Rx Paused\n", params->port);
+		else if (info.tx_pause)
+			printf("Port %i: Tx Paused\n", params->port);
+		else
+			printf("Port %i: Tx & Rx not paused\n", params->port);
+	} else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error %i\n", params->port, stat);
+}
+
+
+static void
+pcmd_open_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_int_params *params = ptr_params;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	lock_port(params->port);
+	stat = rte_ethtool_net_open(params->port);
+	mark_port_active(params->port);
+	unlock_port(params->port);
+	if (stat == 0)
+		return;
+	else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error opening device\n", params->port);
+}
+
+static void
+pcmd_stop_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_int_params *params = ptr_params;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	lock_port(params->port);
+	stat = rte_ethtool_net_stop(params->port);
+	mark_port_inactive(params->port);
+	unlock_port(params->port);
+	if (stat == 0)
+		return;
+	else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error stopping device\n", params->port);
+}
+
+
+static void
+pcmd_rxmode_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_intstr_params *params = ptr_params;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	stat = rte_ethtool_net_set_rx_mode(params->port);
+	if (stat == 0)
+		return;
+	else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error setting rx mode\n", params->port);
+}
+
+
+static void
+pcmd_macaddr_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	void *ptr_data)
+{
+	struct pcmd_intmac_params *params = ptr_params;
+	struct ether_addr mac_addr;
+	int stat;
+
+	stat = 0;
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	if (ptr_data != NULL) {
+		lock_port(params->port);
+		stat = rte_ethtool_net_set_mac_addr(params->port,
+			&params->mac);
+		mark_port_newmac(params->port);
+		unlock_port(params->port);
+		if (stat == 0) {
+			printf("MAC address changed\n");
+			return;
+		}
+	} else {
+		stat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr);
+		if (stat == 0) {
+			printf(
+				"Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+				params->port,
+				mac_addr.addr_bytes[0],
+				mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2],
+				mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4],
+				mac_addr.addr_bytes[5]);
+			return;
+		}
+	}
+
+	printf("Port %i: Error %s\n", params->port,
+	       strerror(-stat));
+}
+
+static void
+pcmd_mtu_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_intstr_params *params = ptr_params;
+	int stat;
+	int new_mtu;
+	char *ptr_parse_end;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	new_mtu = atoi(params->opt);
+	new_mtu = strtoul(params->opt, &ptr_parse_end, 10);
+	if (*ptr_parse_end != '\0' ||
+			new_mtu < ETHER_MIN_MTU ||
+			new_mtu > ETHER_MAX_JUMBO_FRAME_LEN) {
+		printf("Port %i: Invalid MTU value\n", params->port);
+		return;
+	}
+	stat = rte_ethtool_net_change_mtu(params->port, new_mtu);
+	if (stat == 0)
+		printf("Port %i: MTU set to %i\n", params->port, new_mtu);
+	else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error setting MTU\n", params->port);
+}
+
+
+
+static void pcmd_portstats_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_int_params *params = ptr_params;
+	struct rte_eth_stats stat_info;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	stat = rte_ethtool_net_get_stats64(params->port, &stat_info);
+	if (stat == 0) {
+		/* Most of rte_eth_stats is deprecated.. */
+		printf("Port %i stats\n", params->port);
+		printf("   In: %" PRIu64 " (%" PRIu64 " bytes)\n"
+			"  Out: %"PRIu64" (%"PRIu64 " bytes)\n"
+			"  Err: %"PRIu64"\n",
+			stat_info.ipackets,
+			stat_info.ibytes,
+			stat_info.opackets,
+			stat_info.obytes,
+			stat_info.ierrors+stat_info.oerrors
+		      );
+	} else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error fetching statistics\n", params->port);
+}
+
+static void pcmd_ringparam_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	void *ptr_data)
+{
+	struct pcmd_intintint_params *params = ptr_params;
+	struct ethtool_ringparam ring_data;
+	struct ethtool_ringparam ring_params;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	if (ptr_data == NULL) {
+		stat = rte_ethtool_get_ringparam(params->port, &ring_data);
+		if (stat == 0) {
+			printf("Port %i ring parameters\n"
+				"  Rx Pending: %i (%i max)\n"
+				"  Tx Pending: %i (%i max)\n",
+				params->port,
+				ring_data.rx_pending,
+				ring_data.rx_max_pending,
+				ring_data.tx_pending,
+				ring_data.tx_max_pending);
+		}
+	} else {
+		if (params->tx < 1 || params->rx < 1) {
+			printf("Error: Invalid parameters\n");
+			return;
+		}
+		memset(&ring_params, 0, sizeof(struct ethtool_ringparam));
+		ring_params.tx_pending = params->tx;
+		ring_params.rx_pending = params->rx;
+		lock_port(params->port);
+		stat = rte_ethtool_set_ringparam(params->port, &ring_params);
+		unlock_port(params->port);
+	}
+	if (stat == 0)
+		return;
+	else if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else
+		printf("Port %i: Error fetching statistics\n", params->port);
+}
+
+static void pcmd_validate_callback(void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_intmac_params *params = ptr_params;
+
+	if (rte_ethtool_net_validate_addr(0, &params->mac))
+		printf("Address is unicast\n");
+	else
+		printf("Address is not unicast\n");
+}
+
+
+static void pcmd_vlan_callback(__rte_unused void *ptr_params,
+	__rte_unused struct cmdline *ctx,
+	__rte_unused void *ptr_data)
+{
+	struct pcmd_vlan_params *params = ptr_params;
+	int stat;
+
+	if (!rte_eth_dev_is_valid_port(params->port)) {
+		printf("Error: Invalid port number %i\n", params->port);
+		return;
+	}
+	stat = 0;
+
+	if (strcasecmp("add", params->mode) == 0) {
+		stat = rte_ethtool_net_vlan_rx_add_vid(
+			params->port, params->vid
+			);
+		if (stat == 0)
+			printf("VLAN vid %i added\n", params->vid);
+
+	} else if (strcasecmp("del", params->mode) == 0) {
+		stat = rte_ethtool_net_vlan_rx_kill_vid(
+			params->port, params->vid
+			);
+		if (stat == 0)
+			printf("VLAN vid %i removed\n", params->vid);
+	} else {
+		/* Should not happen! */
+		printf("Error: Bad mode %s\n", params->mode);
+	}
+	if (stat == -ENOTSUP)
+		printf("Port %i: Operation not supported\n", params->port);
+	else if (stat == -ENOSYS)
+		printf("Port %i: VLAN filtering disabled\n", params->port);
+	else if (stat != 0)
+		printf("Port %i: Error changing VLAN setup (code %i)\n",
+			params->port, -stat);
+}
+
+
+cmdline_parse_inst_t pcmd_quit = {
+	.f = pcmd_quit_callback,
+	.data = NULL,
+	.help_str = "quit\n     Exit program",
+	.tokens = {(void *)&pcmd_quit_token_cmd, NULL},
+};
+cmdline_parse_inst_t pcmd_drvinfo = {
+	.f = pcmd_drvinfo_callback,
+	.data = NULL,
+	.help_str = "drvinfo\n     Print driver info",
+	.tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},
+};
+cmdline_parse_inst_t pcmd_link = {
+	.f = pcmd_link_callback,
+	.data = NULL,
+	.help_str = "link\n     Print port link states",
+	.tokens = {(void *)&pcmd_link_token_cmd, NULL},
+};
+cmdline_parse_inst_t pcmd_regs = {
+	.f = pcmd_regs_callback,
+	.data = NULL,
+	.help_str = "regs <port_id> <filename>\n"
+		"     Dump port register(s) to file",
+	.tokens = {
+		(void *)&pcmd_regs_token_cmd,
+		(void *)&pcmd_intstr_token_port,
+		(void *)&pcmd_intstr_token_opt,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_eeprom = {
+	.f = pcmd_eeprom_callback,
+	.data = NULL,
+	.help_str = "eeprom <port_id> <filename>\n    Dump EEPROM to file",
+	.tokens = {
+		(void *)&pcmd_eeprom_token_cmd,
+		(void *)&pcmd_intstr_token_port,
+		(void *)&pcmd_intstr_token_opt,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_pause_noopt = {
+	.f = pcmd_pause_callback,
+	.data = (void *)0x01,
+	.help_str = "pause <port_id>\n     Print port pause state",
+	.tokens = {
+		(void *)&pcmd_pause_token_cmd,
+		(void *)&pcmd_pause_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_pause = {
+	.f = pcmd_pause_callback,
+	.data = NULL,
+	.help_str =
+		"pause <port_id> <all|tx|rx|none>\n     Pause/unpause port",
+	.tokens = {
+		(void *)&pcmd_pause_token_cmd,
+		(void *)&pcmd_pause_token_port,
+		(void *)&pcmd_pause_token_opt,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_open = {
+	.f = pcmd_open_callback,
+	.data = NULL,
+	.help_str = "open <port_id>\n     Open port",
+	.tokens = {
+		(void *)&pcmd_open_token_cmd,
+		(void *)&pcmd_int_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_stop = {
+	.f = pcmd_stop_callback,
+	.data = NULL,
+	.help_str = "stop <port_id>\n     Stop port",
+	.tokens = {
+		(void *)&pcmd_stop_token_cmd,
+		(void *)&pcmd_int_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_rxmode = {
+	.f = pcmd_rxmode_callback,
+	.data = NULL,
+	.help_str = "rxmode <port_id>\n     Toggle port Rx mode",
+	.tokens = {
+		(void *)&pcmd_rxmode_token_cmd,
+		(void *)&pcmd_int_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_macaddr_get = {
+	.f = pcmd_macaddr_callback,
+	.data = NULL,
+	.help_str = "macaddr <port_id>\n"
+		"     Get MAC address",
+	.tokens = {
+		(void *)&pcmd_macaddr_token_cmd,
+		(void *)&pcmd_intstr_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_macaddr = {
+	.f = pcmd_macaddr_callback,
+	.data = (void *)0x01,
+	.help_str =
+		"macaddr <port_id> <mac_addr>\n"
+		"     Set MAC address",
+	.tokens = {
+		(void *)&pcmd_macaddr_token_cmd,
+		(void *)&pcmd_intmac_token_port,
+		(void *)&pcmd_intmac_token_mac,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_mtu = {
+	.f = pcmd_mtu_callback,
+	.data = NULL,
+	.help_str = "mtu <port_id> <mtu_value>\n"
+		"     Change MTU",
+	.tokens = {
+		(void *)&pcmd_mtu_token_cmd,
+		(void *)&pcmd_intstr_token_port,
+		(void *)&pcmd_intstr_token_opt,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_portstats = {
+	.f = pcmd_portstats_callback,
+	.data = NULL,
+	.help_str = "portstats <port_id>\n"
+		"     Print port eth statistics",
+	.tokens = {
+		(void *)&pcmd_portstats_token_cmd,
+		(void *)&pcmd_int_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_ringparam = {
+	.f = pcmd_ringparam_callback,
+	.data = NULL,
+	.help_str = "ringparam <port_id>\n"
+		"     Print ring parameters",
+	.tokens = {
+		(void *)&pcmd_ringparam_token_cmd,
+		(void *)&pcmd_intintint_token_port,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_ringparam_set = {
+	.f = pcmd_ringparam_callback,
+	.data = (void *)1,
+	.help_str = "ringparam <port_id> <tx_param> <rx_param>\n"
+		"     Set ring parameters",
+	.tokens = {
+		(void *)&pcmd_ringparam_token_cmd,
+		(void *)&pcmd_intintint_token_port,
+		(void *)&pcmd_intintint_token_tx,
+		(void *)&pcmd_intintint_token_rx,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_validate = {
+	.f = pcmd_validate_callback,
+	.data = NULL,
+	.help_str = "validate <mac_addr>\n"
+		"     Check that MAC address is valid unicast address",
+	.tokens = {
+		(void *)&pcmd_validate_token_cmd,
+		(void *)&pcmd_intmac_token_mac,
+		NULL
+	},
+};
+cmdline_parse_inst_t pcmd_vlan = {
+	.f = pcmd_vlan_callback,
+	.data = NULL,
+	.help_str = "vlan <port_id> <add|del> <vlan_id>\n"
+		"     Add/remove VLAN id",
+	.tokens = {
+		(void *)&pcmd_vlan_token_cmd,
+		(void *)&pcmd_vlan_token_port,
+		(void *)&pcmd_vlan_token_mode,
+		(void *)&pcmd_vlan_token_vid,
+		NULL
+	},
+};
+
+
+cmdline_parse_ctx_t list_prompt_commands[] = {
+	(cmdline_parse_inst_t *)&pcmd_drvinfo,
+	(cmdline_parse_inst_t *)&pcmd_eeprom,
+	(cmdline_parse_inst_t *)&pcmd_link,
+	(cmdline_parse_inst_t *)&pcmd_macaddr_get,
+	(cmdline_parse_inst_t *)&pcmd_macaddr,
+	(cmdline_parse_inst_t *)&pcmd_mtu,
+	(cmdline_parse_inst_t *)&pcmd_open,
+	(cmdline_parse_inst_t *)&pcmd_pause_noopt,
+	(cmdline_parse_inst_t *)&pcmd_pause,
+	(cmdline_parse_inst_t *)&pcmd_portstats,
+	(cmdline_parse_inst_t *)&pcmd_regs,
+	(cmdline_parse_inst_t *)&pcmd_ringparam,
+	(cmdline_parse_inst_t *)&pcmd_ringparam_set,
+	(cmdline_parse_inst_t *)&pcmd_rxmode,
+	(cmdline_parse_inst_t *)&pcmd_stop,
+	(cmdline_parse_inst_t *)&pcmd_validate,
+	(cmdline_parse_inst_t *)&pcmd_vlan,
+	(cmdline_parse_inst_t *)&pcmd_quit,
+	NULL
+};
+
+
+void ethapp_main(void)
+{
+	struct cmdline *ctx_cmdline;
+
+	ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
+	cmdline_interact(ctx_cmdline);
+	cmdline_stdin_exit(ctx_cmdline);
+}
diff --git a/examples/ethtool/ethapp.h b/examples/ethtool/ethapp.h
new file mode 100644
index 0000000..bd48c7c
--- /dev/null
+++ b/examples/ethtool/ethapp.h
@@ -0,0 +1,41 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+void ethapp_main(void);
+void print_stats(void);
+void lock_port(int idx_port);
+void unlock_port(int idx_port);
+void mark_port_inactive(int idx_port);
+void mark_port_active(int idx_port);
+void mark_port_newmac(int idx_port);
diff --git a/examples/ethtool/ethtool-app/Makefile b/examples/ethtool/ethtool-app/Makefile
deleted file mode 100644
index 09c66ad..0000000
--- a/examples/ethtool/ethtool-app/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overridden by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-# binary name
-APP = ethtool
-
-# all source are stored in SRCS-y
-SRCS-y := main.c ethapp.c
-
-CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
-CFLAGS += $(WERROR_FLAGS)
-
-LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
-LDLIBS += -lrte_ethtool
-
-
-include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethtool-app/ethapp.c
deleted file mode 100644
index 2ed4796..0000000
--- a/examples/ethtool/ethtool-app/ethapp.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-#include <cmdline_parse_etheraddr.h>
-#include <cmdline_socket.h>
-#include <cmdline.h>
-
-#include "rte_ethtool.h"
-#include "ethapp.h"
-
-#define EEPROM_DUMP_CHUNKSIZE 1024
-
-
-struct pcmd_get_params {
-	cmdline_fixed_string_t cmd;
-};
-struct pcmd_int_params {
-	cmdline_fixed_string_t cmd;
-	uint16_t port;
-};
-struct pcmd_intstr_params {
-	cmdline_fixed_string_t cmd;
-	uint16_t port;
-	cmdline_fixed_string_t opt;
-};
-struct pcmd_intmac_params {
-	cmdline_fixed_string_t cmd;
-	uint16_t port;
-	struct ether_addr mac;
-};
-struct pcmd_str_params {
-	cmdline_fixed_string_t cmd;
-	cmdline_fixed_string_t opt;
-};
-struct pcmd_vlan_params {
-	cmdline_fixed_string_t cmd;
-	uint16_t port;
-	cmdline_fixed_string_t mode;
-	uint16_t vid;
-};
-struct pcmd_intintint_params {
-	cmdline_fixed_string_t cmd;
-	uint16_t port;
-	uint16_t tx;
-	uint16_t rx;
-};
-
-
-/* Parameter-less commands */
-cmdline_parse_token_string_t pcmd_quit_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "quit");
-cmdline_parse_token_string_t pcmd_stats_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "stats");
-cmdline_parse_token_string_t pcmd_drvinfo_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "drvinfo");
-cmdline_parse_token_string_t pcmd_link_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "link");
-
-/* Commands taking just port id */
-cmdline_parse_token_string_t pcmd_open_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "open");
-cmdline_parse_token_string_t pcmd_stop_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "stop");
-cmdline_parse_token_string_t pcmd_rxmode_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode");
-cmdline_parse_token_string_t pcmd_portstats_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats");
-cmdline_parse_token_num_t pcmd_int_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16);
-
-/* Commands taking port id and string */
-cmdline_parse_token_string_t pcmd_eeprom_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "eeprom");
-cmdline_parse_token_string_t pcmd_mtu_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "mtu");
-cmdline_parse_token_string_t pcmd_regs_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "regs");
-
-cmdline_parse_token_num_t pcmd_intstr_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
-cmdline_parse_token_string_t pcmd_intstr_token_opt =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL);
-
-/* Commands taking port id and a MAC address string */
-cmdline_parse_token_string_t pcmd_macaddr_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "macaddr");
-cmdline_parse_token_num_t pcmd_intmac_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16);
-cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac =
-	TOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac);
-
-/* Command taking just a MAC address */
-cmdline_parse_token_string_t pcmd_validate_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "validate");
-
-
-/* Commands taking port id and two integers */
-cmdline_parse_token_string_t pcmd_ringparam_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd,
-		"ringparam");
-cmdline_parse_token_num_t pcmd_intintint_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16);
-cmdline_parse_token_num_t pcmd_intintint_token_tx =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16);
-cmdline_parse_token_num_t pcmd_intintint_token_rx =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16);
-
-
-/* Pause commands */
-cmdline_parse_token_string_t pcmd_pause_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "pause");
-cmdline_parse_token_num_t pcmd_pause_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
-cmdline_parse_token_string_t pcmd_pause_token_opt =
-	TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params,
-		opt, "all#tx#rx#none");
-
-/* VLAN commands */
-cmdline_parse_token_string_t pcmd_vlan_token_cmd =
-	TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, "vlan");
-cmdline_parse_token_num_t pcmd_vlan_token_port =
-	TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16);
-cmdline_parse_token_string_t pcmd_vlan_token_mode =
-	TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, "add#del");
-cmdline_parse_token_num_t pcmd_vlan_token_vid =
-	TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16);
-
-
-static void
-pcmd_quit_callback(__rte_unused void *ptr_params,
-	struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	cmdline_quit(ctx);
-}
-
-
-static void
-pcmd_drvinfo_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct ethtool_drvinfo info;
-	int id_port;
-
-	for (id_port = 0; id_port < rte_eth_dev_count(); id_port++) {
-		if (rte_ethtool_get_drvinfo(id_port, &info)) {
-			printf("Error getting info for port %i\n", id_port);
-			return;
-		}
-		printf("Port %i driver: %s (ver: %s)\n",
-			id_port, info.driver, info.version
-		      );
-	}
-}
-
-
-static void
-pcmd_link_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	int num_ports = rte_eth_dev_count();
-	int id_port, stat_port;
-
-	for (id_port = 0; id_port < num_ports; id_port++) {
-		if (!rte_eth_dev_is_valid_port(id_port))
-			continue;
-		stat_port = rte_ethtool_get_link(id_port);
-		switch (stat_port) {
-		case 0:
-			printf("Port %i: Down\n", id_port);
-			break;
-		case 1:
-			printf("Port %i: Up\n", id_port);
-			break;
-		default:
-			printf("Port %i: Error getting link status\n",
-				id_port
-				);
-			break;
-		}
-	}
-	printf("\n");
-}
-
-
-static void
-pcmd_regs_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_intstr_params *params = ptr_params;
-	int len_regs;
-	struct ethtool_regs regs;
-	unsigned char *buf_data;
-	FILE *fp_regs;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	len_regs = rte_ethtool_get_regs_len(params->port);
-	if (len_regs > 0) {
-		printf("Port %i: %i bytes\n", params->port, len_regs);
-		buf_data = malloc(len_regs);
-		if (buf_data == NULL) {
-			printf("Error allocating %i bytes for buffer\n",
-				len_regs);
-			return;
-		}
-		if (!rte_ethtool_get_regs(params->port, &regs, buf_data)) {
-			fp_regs = fopen(params->opt, "wb");
-			if (fp_regs == NULL) {
-				printf("Error opening '%s' for writing\n",
-					params->opt);
-			} else {
-				if ((int)fwrite(buf_data,
-						1, len_regs,
-						fp_regs) != len_regs)
-					printf("Error writing '%s'\n",
-						params->opt);
-				fclose(fp_regs);
-			}
-		}
-		free(buf_data);
-	} else if (len_regs == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error getting registers\n", params->port);
-}
-
-
-static void
-pcmd_eeprom_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_intstr_params *params = ptr_params;
-	struct ethtool_eeprom info_eeprom;
-	int len_eeprom;
-	int pos_eeprom;
-	int stat;
-	unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
-	FILE *fp_eeprom;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	len_eeprom = rte_ethtool_get_eeprom_len(params->port);
-	if (len_eeprom > 0) {
-		fp_eeprom = fopen(params->opt, "wb");
-		if (fp_eeprom == NULL) {
-			printf("Error opening '%s' for writing\n",
-				params->opt);
-			return;
-		}
-		printf("Total EEPROM length: %i bytes\n", len_eeprom);
-		info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
-		for (pos_eeprom = 0;
-				pos_eeprom < len_eeprom;
-				pos_eeprom += EEPROM_DUMP_CHUNKSIZE) {
-			info_eeprom.offset = pos_eeprom;
-			if (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom)
-				info_eeprom.len = len_eeprom - pos_eeprom;
-			else
-				info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
-			stat = rte_ethtool_get_eeprom(
-				params->port, &info_eeprom, bytes_eeprom
-				);
-			if (stat != 0) {
-				printf("EEPROM read error %i\n", stat);
-				break;
-			}
-			if (fwrite(bytes_eeprom,
-					1, info_eeprom.len,
-					fp_eeprom) != info_eeprom.len) {
-				printf("Error writing '%s'\n", params->opt);
-				break;
-			}
-		}
-		fclose(fp_eeprom);
-	} else if (len_eeprom == 0)
-		printf("Port %i: Device does not have EEPROM\n", params->port);
-	else if (len_eeprom == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error getting EEPROM\n", params->port);
-}
-
-
-static void
-pcmd_pause_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	void *ptr_data)
-{
-	struct pcmd_intstr_params *params = ptr_params;
-	struct ethtool_pauseparam info;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	if (ptr_data != NULL) {
-		stat = rte_ethtool_get_pauseparam(params->port, &info);
-	} else {
-		memset(&info, 0, sizeof(info));
-		if (strcasecmp("all", params->opt) == 0) {
-			info.tx_pause = 1;
-			info.rx_pause = 1;
-		} else if (strcasecmp("tx", params->opt) == 0) {
-			info.tx_pause = 1;
-			info.rx_pause = 0;
-		} else if (strcasecmp("rx", params->opt) == 0) {
-			info.tx_pause = 0;
-			info.rx_pause = 1;
-		} else {
-			info.tx_pause = 0;
-			info.rx_pause = 0;
-		}
-		/* Assume auto-negotiation wanted */
-		info.autoneg = 1;
-		stat = rte_ethtool_set_pauseparam(params->port, &info);
-	}
-	if (stat == 0) {
-		if (info.rx_pause && info.tx_pause)
-			printf("Port %i: Tx & Rx Paused\n", params->port);
-		else if (info.rx_pause)
-			printf("Port %i: Rx Paused\n", params->port);
-		else if (info.tx_pause)
-			printf("Port %i: Tx Paused\n", params->port);
-		else
-			printf("Port %i: Tx & Rx not paused\n", params->port);
-	} else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error %i\n", params->port, stat);
-}
-
-
-static void
-pcmd_open_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_int_params *params = ptr_params;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	lock_port(params->port);
-	stat = rte_ethtool_net_open(params->port);
-	mark_port_active(params->port);
-	unlock_port(params->port);
-	if (stat == 0)
-		return;
-	else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error opening device\n", params->port);
-}
-
-static void
-pcmd_stop_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_int_params *params = ptr_params;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	lock_port(params->port);
-	stat = rte_ethtool_net_stop(params->port);
-	mark_port_inactive(params->port);
-	unlock_port(params->port);
-	if (stat == 0)
-		return;
-	else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error stopping device\n", params->port);
-}
-
-
-static void
-pcmd_rxmode_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_intstr_params *params = ptr_params;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	stat = rte_ethtool_net_set_rx_mode(params->port);
-	if (stat == 0)
-		return;
-	else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error setting rx mode\n", params->port);
-}
-
-
-static void
-pcmd_macaddr_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	void *ptr_data)
-{
-	struct pcmd_intmac_params *params = ptr_params;
-	struct ether_addr mac_addr;
-	int stat;
-
-	stat = 0;
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	if (ptr_data != NULL) {
-		lock_port(params->port);
-		stat = rte_ethtool_net_set_mac_addr(params->port,
-			&params->mac);
-		mark_port_newmac(params->port);
-		unlock_port(params->port);
-		if (stat == 0) {
-			printf("MAC address changed\n");
-			return;
-		}
-	} else {
-		stat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr);
-		if (stat == 0) {
-			printf(
-				"Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-				params->port,
-				mac_addr.addr_bytes[0],
-				mac_addr.addr_bytes[1],
-				mac_addr.addr_bytes[2],
-				mac_addr.addr_bytes[3],
-				mac_addr.addr_bytes[4],
-				mac_addr.addr_bytes[5]);
-			return;
-		}
-	}
-
-	printf("Port %i: Error %s\n", params->port,
-	       strerror(-stat));
-}
-
-static void
-pcmd_mtu_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_intstr_params *params = ptr_params;
-	int stat;
-	int new_mtu;
-	char *ptr_parse_end;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	new_mtu = atoi(params->opt);
-	new_mtu = strtoul(params->opt, &ptr_parse_end, 10);
-	if (*ptr_parse_end != '\0' ||
-			new_mtu < ETHER_MIN_MTU ||
-			new_mtu > ETHER_MAX_JUMBO_FRAME_LEN) {
-		printf("Port %i: Invalid MTU value\n", params->port);
-		return;
-	}
-	stat = rte_ethtool_net_change_mtu(params->port, new_mtu);
-	if (stat == 0)
-		printf("Port %i: MTU set to %i\n", params->port, new_mtu);
-	else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error setting MTU\n", params->port);
-}
-
-
-
-static void pcmd_portstats_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_int_params *params = ptr_params;
-	struct rte_eth_stats stat_info;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	stat = rte_ethtool_net_get_stats64(params->port, &stat_info);
-	if (stat == 0) {
-		/* Most of rte_eth_stats is deprecated.. */
-		printf("Port %i stats\n", params->port);
-		printf("   In: %" PRIu64 " (%" PRIu64 " bytes)\n"
-			"  Out: %"PRIu64" (%"PRIu64 " bytes)\n"
-			"  Err: %"PRIu64"\n",
-			stat_info.ipackets,
-			stat_info.ibytes,
-			stat_info.opackets,
-			stat_info.obytes,
-			stat_info.ierrors+stat_info.oerrors
-		      );
-	} else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error fetching statistics\n", params->port);
-}
-
-static void pcmd_ringparam_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	void *ptr_data)
-{
-	struct pcmd_intintint_params *params = ptr_params;
-	struct ethtool_ringparam ring_data;
-	struct ethtool_ringparam ring_params;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	if (ptr_data == NULL) {
-		stat = rte_ethtool_get_ringparam(params->port, &ring_data);
-		if (stat == 0) {
-			printf("Port %i ring parameters\n"
-				"  Rx Pending: %i (%i max)\n"
-				"  Tx Pending: %i (%i max)\n",
-				params->port,
-				ring_data.rx_pending,
-				ring_data.rx_max_pending,
-				ring_data.tx_pending,
-				ring_data.tx_max_pending);
-		}
-	} else {
-		if (params->tx < 1 || params->rx < 1) {
-			printf("Error: Invalid parameters\n");
-			return;
-		}
-		memset(&ring_params, 0, sizeof(struct ethtool_ringparam));
-		ring_params.tx_pending = params->tx;
-		ring_params.rx_pending = params->rx;
-		lock_port(params->port);
-		stat = rte_ethtool_set_ringparam(params->port, &ring_params);
-		unlock_port(params->port);
-	}
-	if (stat == 0)
-		return;
-	else if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else
-		printf("Port %i: Error fetching statistics\n", params->port);
-}
-
-static void pcmd_validate_callback(void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_intmac_params *params = ptr_params;
-
-	if (rte_ethtool_net_validate_addr(0, &params->mac))
-		printf("Address is unicast\n");
-	else
-		printf("Address is not unicast\n");
-}
-
-
-static void pcmd_vlan_callback(__rte_unused void *ptr_params,
-	__rte_unused struct cmdline *ctx,
-	__rte_unused void *ptr_data)
-{
-	struct pcmd_vlan_params *params = ptr_params;
-	int stat;
-
-	if (!rte_eth_dev_is_valid_port(params->port)) {
-		printf("Error: Invalid port number %i\n", params->port);
-		return;
-	}
-	stat = 0;
-
-	if (strcasecmp("add", params->mode) == 0) {
-		stat = rte_ethtool_net_vlan_rx_add_vid(
-			params->port, params->vid
-			);
-		if (stat == 0)
-			printf("VLAN vid %i added\n", params->vid);
-
-	} else if (strcasecmp("del", params->mode) == 0) {
-		stat = rte_ethtool_net_vlan_rx_kill_vid(
-			params->port, params->vid
-			);
-		if (stat == 0)
-			printf("VLAN vid %i removed\n", params->vid);
-	} else {
-		/* Should not happen! */
-		printf("Error: Bad mode %s\n", params->mode);
-	}
-	if (stat == -ENOTSUP)
-		printf("Port %i: Operation not supported\n", params->port);
-	else if (stat == -ENOSYS)
-		printf("Port %i: VLAN filtering disabled\n", params->port);
-	else if (stat != 0)
-		printf("Port %i: Error changing VLAN setup (code %i)\n",
-			params->port, -stat);
-}
-
-
-cmdline_parse_inst_t pcmd_quit = {
-	.f = pcmd_quit_callback,
-	.data = NULL,
-	.help_str = "quit\n     Exit program",
-	.tokens = {(void *)&pcmd_quit_token_cmd, NULL},
-};
-cmdline_parse_inst_t pcmd_drvinfo = {
-	.f = pcmd_drvinfo_callback,
-	.data = NULL,
-	.help_str = "drvinfo\n     Print driver info",
-	.tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},
-};
-cmdline_parse_inst_t pcmd_link = {
-	.f = pcmd_link_callback,
-	.data = NULL,
-	.help_str = "link\n     Print port link states",
-	.tokens = {(void *)&pcmd_link_token_cmd, NULL},
-};
-cmdline_parse_inst_t pcmd_regs = {
-	.f = pcmd_regs_callback,
-	.data = NULL,
-	.help_str = "regs <port_id> <filename>\n"
-		"     Dump port register(s) to file",
-	.tokens = {
-		(void *)&pcmd_regs_token_cmd,
-		(void *)&pcmd_intstr_token_port,
-		(void *)&pcmd_intstr_token_opt,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_eeprom = {
-	.f = pcmd_eeprom_callback,
-	.data = NULL,
-	.help_str = "eeprom <port_id> <filename>\n    Dump EEPROM to file",
-	.tokens = {
-		(void *)&pcmd_eeprom_token_cmd,
-		(void *)&pcmd_intstr_token_port,
-		(void *)&pcmd_intstr_token_opt,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_pause_noopt = {
-	.f = pcmd_pause_callback,
-	.data = (void *)0x01,
-	.help_str = "pause <port_id>\n     Print port pause state",
-	.tokens = {
-		(void *)&pcmd_pause_token_cmd,
-		(void *)&pcmd_pause_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_pause = {
-	.f = pcmd_pause_callback,
-	.data = NULL,
-	.help_str =
-		"pause <port_id> <all|tx|rx|none>\n     Pause/unpause port",
-	.tokens = {
-		(void *)&pcmd_pause_token_cmd,
-		(void *)&pcmd_pause_token_port,
-		(void *)&pcmd_pause_token_opt,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_open = {
-	.f = pcmd_open_callback,
-	.data = NULL,
-	.help_str = "open <port_id>\n     Open port",
-	.tokens = {
-		(void *)&pcmd_open_token_cmd,
-		(void *)&pcmd_int_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_stop = {
-	.f = pcmd_stop_callback,
-	.data = NULL,
-	.help_str = "stop <port_id>\n     Stop port",
-	.tokens = {
-		(void *)&pcmd_stop_token_cmd,
-		(void *)&pcmd_int_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_rxmode = {
-	.f = pcmd_rxmode_callback,
-	.data = NULL,
-	.help_str = "rxmode <port_id>\n     Toggle port Rx mode",
-	.tokens = {
-		(void *)&pcmd_rxmode_token_cmd,
-		(void *)&pcmd_int_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_macaddr_get = {
-	.f = pcmd_macaddr_callback,
-	.data = NULL,
-	.help_str = "macaddr <port_id>\n"
-		"     Get MAC address",
-	.tokens = {
-		(void *)&pcmd_macaddr_token_cmd,
-		(void *)&pcmd_intstr_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_macaddr = {
-	.f = pcmd_macaddr_callback,
-	.data = (void *)0x01,
-	.help_str =
-		"macaddr <port_id> <mac_addr>\n"
-		"     Set MAC address",
-	.tokens = {
-		(void *)&pcmd_macaddr_token_cmd,
-		(void *)&pcmd_intmac_token_port,
-		(void *)&pcmd_intmac_token_mac,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_mtu = {
-	.f = pcmd_mtu_callback,
-	.data = NULL,
-	.help_str = "mtu <port_id> <mtu_value>\n"
-		"     Change MTU",
-	.tokens = {
-		(void *)&pcmd_mtu_token_cmd,
-		(void *)&pcmd_intstr_token_port,
-		(void *)&pcmd_intstr_token_opt,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_portstats = {
-	.f = pcmd_portstats_callback,
-	.data = NULL,
-	.help_str = "portstats <port_id>\n"
-		"     Print port eth statistics",
-	.tokens = {
-		(void *)&pcmd_portstats_token_cmd,
-		(void *)&pcmd_int_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_ringparam = {
-	.f = pcmd_ringparam_callback,
-	.data = NULL,
-	.help_str = "ringparam <port_id>\n"
-		"     Print ring parameters",
-	.tokens = {
-		(void *)&pcmd_ringparam_token_cmd,
-		(void *)&pcmd_intintint_token_port,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_ringparam_set = {
-	.f = pcmd_ringparam_callback,
-	.data = (void *)1,
-	.help_str = "ringparam <port_id> <tx_param> <rx_param>\n"
-		"     Set ring parameters",
-	.tokens = {
-		(void *)&pcmd_ringparam_token_cmd,
-		(void *)&pcmd_intintint_token_port,
-		(void *)&pcmd_intintint_token_tx,
-		(void *)&pcmd_intintint_token_rx,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_validate = {
-	.f = pcmd_validate_callback,
-	.data = NULL,
-	.help_str = "validate <mac_addr>\n"
-		"     Check that MAC address is valid unicast address",
-	.tokens = {
-		(void *)&pcmd_validate_token_cmd,
-		(void *)&pcmd_intmac_token_mac,
-		NULL
-	},
-};
-cmdline_parse_inst_t pcmd_vlan = {
-	.f = pcmd_vlan_callback,
-	.data = NULL,
-	.help_str = "vlan <port_id> <add|del> <vlan_id>\n"
-		"     Add/remove VLAN id",
-	.tokens = {
-		(void *)&pcmd_vlan_token_cmd,
-		(void *)&pcmd_vlan_token_port,
-		(void *)&pcmd_vlan_token_mode,
-		(void *)&pcmd_vlan_token_vid,
-		NULL
-	},
-};
-
-
-cmdline_parse_ctx_t list_prompt_commands[] = {
-	(cmdline_parse_inst_t *)&pcmd_drvinfo,
-	(cmdline_parse_inst_t *)&pcmd_eeprom,
-	(cmdline_parse_inst_t *)&pcmd_link,
-	(cmdline_parse_inst_t *)&pcmd_macaddr_get,
-	(cmdline_parse_inst_t *)&pcmd_macaddr,
-	(cmdline_parse_inst_t *)&pcmd_mtu,
-	(cmdline_parse_inst_t *)&pcmd_open,
-	(cmdline_parse_inst_t *)&pcmd_pause_noopt,
-	(cmdline_parse_inst_t *)&pcmd_pause,
-	(cmdline_parse_inst_t *)&pcmd_portstats,
-	(cmdline_parse_inst_t *)&pcmd_regs,
-	(cmdline_parse_inst_t *)&pcmd_ringparam,
-	(cmdline_parse_inst_t *)&pcmd_ringparam_set,
-	(cmdline_parse_inst_t *)&pcmd_rxmode,
-	(cmdline_parse_inst_t *)&pcmd_stop,
-	(cmdline_parse_inst_t *)&pcmd_validate,
-	(cmdline_parse_inst_t *)&pcmd_vlan,
-	(cmdline_parse_inst_t *)&pcmd_quit,
-	NULL
-};
-
-
-void ethapp_main(void)
-{
-	struct cmdline *ctx_cmdline;
-
-	ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
-	cmdline_interact(ctx_cmdline);
-	cmdline_stdin_exit(ctx_cmdline);
-}
diff --git a/examples/ethtool/ethtool-app/ethapp.h b/examples/ethtool/ethtool-app/ethapp.h
deleted file mode 100644
index ba438ee..0000000
--- a/examples/ethtool/ethtool-app/ethapp.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-void ethapp_main(void);
-void print_stats(void);
-void lock_port(int idx_port);
-void unlock_port(int idx_port);
-void mark_port_inactive(int idx_port);
-void mark_port_active(int idx_port);
-void mark_port_newmac(int idx_port);
diff --git a/examples/ethtool/ethtool-app/main.c b/examples/ethtool/ethtool-app/main.c
deleted file mode 100644
index 2c655d8..0000000
--- a/examples/ethtool/ethtool-app/main.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_spinlock.h>
-#include <rte_eal.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_memory.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-
-#include "ethapp.h"
-
-#define MAX_PORTS RTE_MAX_ETHPORTS
-#define MAX_BURST_LENGTH 32
-#define PORT_RX_QUEUE_SIZE 128
-#define PORT_TX_QUEUE_SIZE 256
-#define PKTPOOL_EXTRA_SIZE 512
-#define PKTPOOL_CACHE 32
-
-
-struct txq_port {
-	uint16_t cnt_unsent;
-	struct rte_mbuf *buf_frames[MAX_BURST_LENGTH];
-};
-
-struct app_port {
-	struct ether_addr mac_addr;
-	struct txq_port txq;
-	rte_spinlock_t lock;
-	int port_active;
-	int port_dirty;
-	int idx_port;
-	struct rte_mempool *pkt_pool;
-};
-
-struct app_config {
-	struct app_port ports[MAX_PORTS];
-	int cnt_ports;
-	int exit_now;
-};
-
-
-struct app_config app_cfg;
-
-
-void lock_port(int idx_port)
-{
-	struct app_port *ptr_port = &app_cfg.ports[idx_port];
-
-	rte_spinlock_lock(&ptr_port->lock);
-}
-
-void unlock_port(int idx_port)
-{
-	struct app_port *ptr_port = &app_cfg.ports[idx_port];
-
-	rte_spinlock_unlock(&ptr_port->lock);
-}
-
-void mark_port_active(int idx_port)
-{
-	struct app_port *ptr_port = &app_cfg.ports[idx_port];
-
-	ptr_port->port_active = 1;
-}
-
-void mark_port_inactive(int idx_port)
-{
-	struct app_port *ptr_port = &app_cfg.ports[idx_port];
-
-	ptr_port->port_active = 0;
-}
-
-void mark_port_newmac(int idx_port)
-{
-	struct app_port *ptr_port = &app_cfg.ports[idx_port];
-
-	ptr_port->port_dirty = 1;
-}
-
-static void setup_ports(struct app_config *app_cfg, int cnt_ports)
-{
-	int idx_port;
-	int size_pktpool;
-	struct rte_eth_conf cfg_port;
-	struct rte_eth_dev_info dev_info;
-	char str_name[16];
-
-	memset(&cfg_port, 0, sizeof(cfg_port));
-	cfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;
-
-	for (idx_port = 0; idx_port < cnt_ports; idx_port++) {
-		struct app_port *ptr_port = &app_cfg->ports[idx_port];
-
-		rte_eth_dev_info_get(idx_port, &dev_info);
-		size_pktpool = dev_info.rx_desc_lim.nb_max +
-			dev_info.tx_desc_lim.nb_max + PKTPOOL_EXTRA_SIZE;
-
-		snprintf(str_name, 16, "pkt_pool%i", idx_port);
-		ptr_port->pkt_pool = rte_pktmbuf_pool_create(
-			str_name,
-			size_pktpool, PKTPOOL_CACHE,
-			0,
-			RTE_MBUF_DEFAULT_BUF_SIZE,
-			rte_socket_id()
-			);
-		if (ptr_port->pkt_pool == NULL)
-			rte_exit(EXIT_FAILURE,
-				"rte_pktmbuf_pool_create failed"
-				);
-
-		printf("Init port %i..\n", idx_port);
-		ptr_port->port_active = 1;
-		ptr_port->port_dirty = 0;
-		ptr_port->idx_port = idx_port;
-
-		if (rte_eth_dev_configure(idx_port, 1, 1, &cfg_port) < 0)
-			rte_exit(EXIT_FAILURE,
-				 "rte_eth_dev_configure failed");
-		if (rte_eth_rx_queue_setup(
-			    idx_port, 0, PORT_RX_QUEUE_SIZE,
-			    rte_eth_dev_socket_id(idx_port), NULL,
-			    ptr_port->pkt_pool) < 0)
-			rte_exit(EXIT_FAILURE,
-				 "rte_eth_rx_queue_setup failed"
-				);
-		if (rte_eth_tx_queue_setup(
-			    idx_port, 0, PORT_TX_QUEUE_SIZE,
-			    rte_eth_dev_socket_id(idx_port), NULL) < 0)
-			rte_exit(EXIT_FAILURE,
-				 "rte_eth_tx_queue_setup failed"
-				);
-		if (rte_eth_dev_start(idx_port) < 0)
-			rte_exit(EXIT_FAILURE,
-				 "%s:%i: rte_eth_dev_start failed",
-				 __FILE__, __LINE__
-				);
-		rte_eth_promiscuous_enable(idx_port);
-		rte_eth_macaddr_get(idx_port, &ptr_port->mac_addr);
-		rte_spinlock_init(&ptr_port->lock);
-	}
-}
-
-static void process_frame(struct app_port *ptr_port,
-	struct rte_mbuf *ptr_frame)
-{
-	struct ether_hdr *ptr_mac_hdr;
-
-	ptr_mac_hdr = rte_pktmbuf_mtod(ptr_frame, struct ether_hdr *);
-	ether_addr_copy(&ptr_mac_hdr->s_addr, &ptr_mac_hdr->d_addr);
-	ether_addr_copy(&ptr_port->mac_addr, &ptr_mac_hdr->s_addr);
-}
-
-static int slave_main(__attribute__((unused)) void *ptr_data)
-{
-	struct app_port *ptr_port;
-	struct rte_mbuf *ptr_frame;
-	struct txq_port *txq;
-
-	uint16_t cnt_recv_frames;
-	uint16_t idx_frame;
-	uint16_t cnt_sent;
-	uint16_t idx_port;
-	uint16_t lock_result;
-
-	while (app_cfg.exit_now == 0) {
-		for (idx_port = 0; idx_port < app_cfg.cnt_ports; idx_port++) {
-			/* Check that port is active and unlocked */
-			ptr_port = &app_cfg.ports[idx_port];
-			lock_result = rte_spinlock_trylock(&ptr_port->lock);
-			if (lock_result == 0)
-				continue;
-			if (ptr_port->port_active == 0) {
-				rte_spinlock_unlock(&ptr_port->lock);
-				continue;
-			}
-			txq = &ptr_port->txq;
-
-			/* MAC address was updated */
-			if (ptr_port->port_dirty == 1) {
-				rte_eth_macaddr_get(ptr_port->idx_port,
-					&ptr_port->mac_addr);
-				ptr_port->port_dirty = 0;
-			}
-
-			/* Incoming frames */
-			cnt_recv_frames = rte_eth_rx_burst(
-				ptr_port->idx_port, 0,
-				&txq->buf_frames[txq->cnt_unsent],
-				RTE_DIM(txq->buf_frames) - txq->cnt_unsent
-				);
-			if (cnt_recv_frames > 0) {
-				for (idx_frame = 0;
-					idx_frame < cnt_recv_frames;
-					idx_frame++) {
-					ptr_frame = txq->buf_frames[
-						idx_frame + txq->cnt_unsent];
-					process_frame(ptr_port, ptr_frame);
-				}
-				txq->cnt_unsent += cnt_recv_frames;
-			}
-
-			/* Outgoing frames */
-			if (txq->cnt_unsent > 0) {
-				cnt_sent = rte_eth_tx_burst(
-					ptr_port->idx_port, 0,
-					txq->buf_frames,
-					txq->cnt_unsent
-					);
-				/* Shuffle up unsent frame pointers */
-				for (idx_frame = cnt_sent;
-					idx_frame < txq->cnt_unsent;
-					idx_frame++)
-					txq->buf_frames[idx_frame - cnt_sent] =
-						txq->buf_frames[idx_frame];
-				txq->cnt_unsent -= cnt_sent;
-			}
-			rte_spinlock_unlock(&ptr_port->lock);
-		} /* end for( idx_port ) */
-	} /* end for(;;) */
-
-	return 0;
-}
-
-int main(int argc, char **argv)
-{
-	int cnt_args_parsed;
-	uint32_t id_core;
-	uint32_t cnt_ports;
-
-	/* Init runtime enviornment */
-	cnt_args_parsed = rte_eal_init(argc, argv);
-	if (cnt_args_parsed < 0)
-		rte_exit(EXIT_FAILURE, "rte_eal_init(): Failed");
-
-	cnt_ports = rte_eth_dev_count();
-	printf("Number of NICs: %i\n", cnt_ports);
-	if (cnt_ports == 0)
-		rte_exit(EXIT_FAILURE, "No available NIC ports!\n");
-	if (cnt_ports > MAX_PORTS) {
-		printf("Info: Using only %i of %i ports\n",
-			cnt_ports, MAX_PORTS
-			);
-		cnt_ports = MAX_PORTS;
-	}
-
-	setup_ports(&app_cfg, cnt_ports);
-
-	app_cfg.exit_now = 0;
-	app_cfg.cnt_ports = cnt_ports;
-
-	if (rte_lcore_count() < 2)
-		rte_exit(EXIT_FAILURE, "No available slave core!\n");
-	/* Assume there is an available slave.. */
-	id_core = rte_lcore_id();
-	id_core = rte_get_next_lcore(id_core, 1, 1);
-	rte_eal_remote_launch(slave_main, NULL, id_core);
-
-	ethapp_main();
-
-	app_cfg.exit_now = 1;
-	RTE_LCORE_FOREACH_SLAVE(id_core) {
-		if (rte_eal_wait_lcore(id_core) < 0)
-			return -1;
-	}
-
-	return 0;
-}
diff --git a/examples/ethtool/lib/Makefile b/examples/ethtool/lib/Makefile
deleted file mode 100644
index d7ee955..0000000
--- a/examples/ethtool/lib/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overwritten by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(error This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-endif
-
-# library name
-LIB = librte_ethtool.a
-
-LIBABIVER := 1
-
-# all source are stored in SRC-Y
-SRCS-y := rte_ethtool.c
-
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-
-include $(RTE_SDK)/mk/rte.extlib.mk
diff --git a/examples/ethtool/lib/rte_ethtool.c b/examples/ethtool/lib/rte_ethtool.c
deleted file mode 100644
index 42e05f1..0000000
--- a/examples/ethtool/lib/rte_ethtool.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <rte_version.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include "rte_ethtool.h"
-
-#define PKTPOOL_SIZE 512
-#define PKTPOOL_CACHE 32
-
-
-int
-rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
-{
-	struct rte_eth_dev_info dev_info;
-	int n;
-
-	if (drvinfo == NULL)
-		return -EINVAL;
-
-	if (!rte_eth_dev_is_valid_port(port_id))
-		return -ENODEV;
-
-	memset(&dev_info, 0, sizeof(dev_info));
-	rte_eth_dev_info_get(port_id, &dev_info);
-
-	snprintf(drvinfo->driver, sizeof(drvinfo->driver), "%s",
-		dev_info.driver_name);
-	snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
-		rte_version());
-	snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
-		"%04x:%02x:%02x.%x",
-		dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,
-		dev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function);
-
-	n = rte_eth_dev_get_reg_length(port_id);
-	if (n > 0)
-		drvinfo->regdump_len = n;
-	else
-		drvinfo->regdump_len = 0;
-
-	n = rte_eth_dev_get_eeprom_length(port_id);
-	if (n > 0)
-		drvinfo->eedump_len = n;
-	else
-		drvinfo->eedump_len = 0;
-
-	drvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
-	drvinfo->testinfo_len = 0;
-
-	return 0;
-}
-
-int
-rte_ethtool_get_regs_len(uint8_t port_id)
-{
-	int count_regs;
-
-	count_regs = rte_eth_dev_get_reg_length(port_id);
-	if (count_regs > 0)
-		return count_regs * sizeof(uint32_t);
-	return count_regs;
-}
-
-int
-rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs, void *data)
-{
-	struct rte_dev_reg_info reg_info;
-	int status;
-
-	if (regs == NULL || data == NULL)
-		return -EINVAL;
-
-	reg_info.data = data;
-	reg_info.length = 0;
-
-	status = rte_eth_dev_get_reg_info(port_id, &reg_info);
-	if (status)
-		return status;
-	regs->version = reg_info.version;
-
-	return 0;
-}
-
-int
-rte_ethtool_get_link(uint8_t port_id)
-{
-	struct rte_eth_link link;
-
-	if (!rte_eth_dev_is_valid_port(port_id))
-		return -ENODEV;
-	rte_eth_link_get(port_id, &link);
-	return link.link_status;
-}
-
-int
-rte_ethtool_get_eeprom_len(uint8_t port_id)
-{
-	return rte_eth_dev_get_eeprom_length(port_id);
-}
-
-int
-rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-	void *words)
-{
-	struct rte_dev_eeprom_info eeprom_info;
-	int status;
-
-	if (eeprom == NULL || words == NULL)
-		return -EINVAL;
-
-	eeprom_info.offset = eeprom->offset;
-	eeprom_info.length = eeprom->len;
-	eeprom_info.data = words;
-
-	status = rte_eth_dev_get_eeprom(port_id, &eeprom_info);
-	if (status)
-		return status;
-
-	eeprom->magic = eeprom_info.magic;
-
-	return 0;
-}
-
-int
-rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-	void *words)
-{
-	struct rte_dev_eeprom_info eeprom_info;
-	int status;
-
-	if (eeprom == NULL || words == NULL || eeprom->offset >= eeprom->len)
-		return -EINVAL;
-
-	eeprom_info.offset = eeprom->offset;
-	eeprom_info.length = eeprom->len;
-	eeprom_info.data = words;
-
-	status = rte_eth_dev_set_eeprom(port_id, &eeprom_info);
-	if (status)
-		return status;
-
-	eeprom->magic = eeprom_info.magic;
-
-	return 0;
-}
-
-int
-rte_ethtool_get_pauseparam(uint8_t port_id,
-	struct ethtool_pauseparam *pause_param)
-{
-	struct rte_eth_fc_conf fc_conf;
-	int status;
-
-	if (pause_param == NULL)
-		return -EINVAL;
-
-	status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
-	if (status)
-		return status;
-
-	pause_param->tx_pause = 0;
-	pause_param->rx_pause = 0;
-	switch (fc_conf.mode) {
-	case RTE_FC_RX_PAUSE:
-		pause_param->rx_pause = 1;
-		break;
-	case RTE_FC_TX_PAUSE:
-		pause_param->tx_pause = 1;
-		break;
-	case RTE_FC_FULL:
-		pause_param->rx_pause = 1;
-		pause_param->tx_pause = 1;
-	default:
-		/* dummy block to avoid compiler warning */
-		break;
-	}
-	pause_param->autoneg = (uint32_t)fc_conf.autoneg;
-
-	return 0;
-}
-
-int
-rte_ethtool_set_pauseparam(uint8_t port_id,
-	struct ethtool_pauseparam *pause_param)
-{
-	struct rte_eth_fc_conf fc_conf;
-	int status;
-
-	if (pause_param == NULL)
-		return -EINVAL;
-
-	/*
-	 * Read device flow control parameter first since
-	 * ethtool set_pauseparam op doesn't have all the information.
-	 * as defined in struct rte_eth_fc_conf.
-	 * This API requires the device to support both
-	 * rte_eth_dev_flow_ctrl_get and rte_eth_dev_flow_ctrl_set, otherwise
-	 * return -ENOTSUP
-	 */
-	status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
-	if (status)
-		return status;
-
-	fc_conf.autoneg = (uint8_t)pause_param->autoneg;
-
-	if (pause_param->tx_pause) {
-		if (pause_param->rx_pause)
-			fc_conf.mode = RTE_FC_FULL;
-		else
-			fc_conf.mode = RTE_FC_TX_PAUSE;
-	} else {
-		if (pause_param->rx_pause)
-			fc_conf.mode = RTE_FC_RX_PAUSE;
-		else
-			fc_conf.mode = RTE_FC_NONE;
-	}
-
-	status = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf);
-	if (status)
-		return status;
-
-	return 0;
-}
-
-int
-rte_ethtool_net_open(uint8_t port_id)
-{
-	rte_eth_dev_stop(port_id);
-
-	return rte_eth_dev_start(port_id);
-}
-
-int
-rte_ethtool_net_stop(uint8_t port_id)
-{
-	if (!rte_eth_dev_is_valid_port(port_id))
-		return -ENODEV;
-	rte_eth_dev_stop(port_id);
-
-	return 0;
-}
-
-int
-rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)
-{
-	if (!rte_eth_dev_is_valid_port(port_id))
-		return -ENODEV;
-	if (addr == NULL)
-		return -EINVAL;
-	rte_eth_macaddr_get(port_id, addr);
-
-	return 0;
-}
-
-int
-rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)
-{
-	if (addr == NULL)
-		return -EINVAL;
-	return rte_eth_dev_default_mac_addr_set(port_id, addr);
-}
-
-int
-rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,
-	struct ether_addr *addr)
-{
-	if (addr == NULL)
-		return -EINVAL;
-	return is_valid_assigned_ether_addr(addr);
-}
-
-int
-rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)
-{
-	if (mtu < 0 || mtu > UINT16_MAX)
-		return -EINVAL;
-	return rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);
-}
-
-int
-rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)
-{
-	if (stats == NULL)
-		return -EINVAL;
-	return rte_eth_stats_get(port_id, stats);
-}
-
-int
-rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)
-{
-	return rte_eth_dev_vlan_filter(port_id, vid, 1);
-}
-
-int
-rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
-{
-	return rte_eth_dev_vlan_filter(port_id, vid, 0);
-}
-
-/*
- * The set_rx_mode provides driver-specific rx mode setting.
- * This implementation implements rx mode setting based upon
- * ixgbe/igb drivers. Further improvement is to provide a
- * callback op field over struct rte_eth_dev::dev_ops so each
- * driver can register device-specific implementation
- */
-int
-rte_ethtool_net_set_rx_mode(uint8_t port_id)
-{
-	uint16_t num_vfs;
-	struct rte_eth_dev_info dev_info;
-	uint16_t vf;
-
-	memset(&dev_info, 0, sizeof(dev_info));
-	rte_eth_dev_info_get(port_id, &dev_info);
-	num_vfs = dev_info.max_vfs;
-
-	/* Set VF vf_rx_mode, VF unsupport status is discard */
-	for (vf = 0; vf < num_vfs; vf++)
-		rte_eth_dev_set_vf_rxmode(port_id, vf,
-			ETH_VMDQ_ACCEPT_UNTAG, 0);
-
-	/* Enable Rx vlan filter, VF unspport status is discard */
-	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
-
-	return 0;
-}
-
-
-int
-rte_ethtool_get_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param)
-{
-	struct rte_eth_dev_info dev_info;
-	struct rte_eth_rxq_info rx_qinfo;
-	struct rte_eth_txq_info tx_qinfo;
-	int stat;
-
-	if (ring_param == NULL)
-		return -EINVAL;
-
-	rte_eth_dev_info_get(port_id, &dev_info);
-
-	stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
-	if (stat != 0)
-		return stat;
-
-	stat = rte_eth_tx_queue_info_get(port_id, 0, &tx_qinfo);
-	if (stat != 0)
-		return stat;
-
-	memset(ring_param, 0, sizeof(*ring_param));
-	ring_param->rx_pending = rx_qinfo.nb_desc;
-	ring_param->rx_max_pending = dev_info.rx_desc_lim.nb_max;
-	ring_param->tx_pending = tx_qinfo.nb_desc;
-	ring_param->tx_max_pending = dev_info.tx_desc_lim.nb_max;
-
-	return 0;
-}
-
-
-int
-rte_ethtool_set_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param)
-{
-	struct rte_eth_rxq_info rx_qinfo;
-	int stat;
-
-	if (ring_param == NULL)
-		return -EINVAL;
-
-	stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
-	if (stat != 0)
-		return stat;
-
-	rte_eth_dev_stop(port_id);
-
-	stat = rte_eth_tx_queue_setup(port_id, 0, ring_param->tx_pending,
-		rte_socket_id(), NULL);
-	if (stat != 0)
-		return stat;
-
-	stat = rte_eth_rx_queue_setup(port_id, 0, ring_param->rx_pending,
-		rte_socket_id(), NULL, rx_qinfo.mp);
-	if (stat != 0)
-		return stat;
-
-	return rte_eth_dev_start(port_id);
-}
diff --git a/examples/ethtool/lib/rte_ethtool.h b/examples/ethtool/lib/rte_ethtool.h
deleted file mode 100644
index 2e79d45..0000000
--- a/examples/ethtool/lib/rte_ethtool.h
+++ /dev/null
@@ -1,410 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_ETHTOOL_H_
-#define _RTE_ETHTOOL_H_
-
-/*
- * This new interface is designed to provide a user-space shim layer for
- * Ethtool and Netdevice op API.
- *
- * rte_ethtool_get_driver:          ethtool_ops::get_driverinfo
- * rte_ethtool_get_link:            ethtool_ops::get_link
- * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len
- * rte_ethtool_get_regs:            ethtool_ops::get_regs
- * rte_ethtool_get_eeprom_len:      ethtool_ops::get_eeprom_len
- * rte_ethtool_get_eeprom:          ethtool_ops::get_eeprom
- * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom
- * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam
- * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam
- *
- * rte_ethtool_net_open:            net_device_ops::ndo_open
- * rte_ethtool_net_stop:            net_device_ops::ndo_stop
- * rte_ethtool_net_set_mac_addr:    net_device_ops::ndo_set_mac_address
- * rte_ethtool_net_validate_addr:   net_device_ops::ndo_validate_addr
- * rte_ethtool_net_change_mtu:      net_device_ops::rte_net_change_mtu
- * rte_ethtool_net_get_stats64:     net_device_ops::ndo_get_stats64
- * rte_ethtool_net_vlan_rx_add_vid  net_device_ops::ndo_vlan_rx_add_vid
- * rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid
- * rte_ethtool_net_set_rx_mode      net_device_ops::ndo_set_rx_mode
- *
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <rte_ethdev.h>
-#include <linux/ethtool.h>
-
-/**
- * Retrieve the Ethernet device driver information according to
- * attributes described by ethtool data structure, ethtool_drvinfo.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param drvinfo
- *   A pointer to get driver information
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port_id* invalid.
- */
-int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo);
-
-/**
- * Retrieve the Ethernet device register length in bytes.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *   - (> 0) # of device registers (in bytes) available for dump
- *   - (0) no registers available for dump.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_regs_len(uint8_t port_id);
-
-/**
- * Retrieve the Ethernet device register information according to
- * attributes described by ethtool data structure, ethtool_regs
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param reg
- *   A pointer to ethtool_regs that has register information
- * @param data
- *   A pointer to a buffer that is used to retrieve device register content
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
-			    void *data);
-
-/**
- * Retrieve the Ethernet device link status
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *   - (1) if link up.
- *   - (0) if link down.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_link(uint8_t port_id);
-
-/**
- * Retrieve the Ethernet device EEPROM size
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *	 - (> 0) device EEPROM size in bytes
- *   - (0) device has NO EEPROM
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_eeprom_len(uint8_t port_id);
-
-/**
- * Retrieve EEPROM content based upon eeprom range described in ethtool
- * data structure, ethtool_eeprom
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
- * @param words
- *	 A buffer that holds data read from eeprom
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
-
-/**
- * Setting EEPROM content based upon eeprom range described in ethtool
- * data structure, ethtool_eeprom
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
- * @param words
- *	 A buffer that holds data to be written into eeprom
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
-
-/**
- * Retrieve the Ethernet device pause frame configuration according to
- * parameter attributes desribed by ethtool data structure,
- * ethtool_pauseparam.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param pause_param
- *	 The pointer of ethtool_coalesce that gets pause frame
- *	 configuration parameters
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_get_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *pause_param);
-
-/**
- * Setting the Ethernet device pause frame configuration according to
- * parameter attributes desribed by ethtool data structure, ethtool_pauseparam.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param pause_param
- *	 The pointer of ethtool_coalesce that gets ring configuration parameters
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_set_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *param);
-
-/**
- * Start the Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_open(uint8_t port_id);
-
-/**
- * Stop the Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port_id* invalid.
- */
-int rte_ethtool_net_stop(uint8_t port_id);
-
-/**
- * Get the Ethernet device MAC address.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param addr
- *	 MAC address of the Ethernet device.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port_id* invalid.
- */
-int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
-
-/**
- * Setting the Ethernet device MAC address.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param addr
- *	 The new MAC addr.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
-
-/**
- * Validate if the provided MAC address is valid unicast address
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param addr
- *	 A pointer to a buffer (6-byte, 48bit) for the target MAC address
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
-
-/**
- * Setting the Ethernet device maximum Tx unit.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param mtu
- *	 New MTU
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
-
-/**
- * Retrieve the Ethernet device traffic statistics
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param stats
- *	 A pointer to struct rte_eth_stats for statistics parameters
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if parameters invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
-
-/**
- * Update the Ethernet device VLAN filter with new vid
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param vid
- *	 A new VLAN id
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
-
-/**
- * Remove VLAN id from Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param vid
- *	 A new VLAN id
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);
-
-/**
- * Setting the Ethernet device rx mode.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- */
-int rte_ethtool_net_set_rx_mode(uint8_t port_id);
-
-/**
- * Getting ring paramaters for Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param ring_param
- *   Pointer to struct ethrool_ringparam to receive parameters.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- * @note
- *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam
- *   are used, and the function only gets parameters for queue 0.
- */
-int rte_ethtool_get_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
-
-/**
- * Setting ring paramaters for Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param ring_param
- *   Pointer to struct ethrool_ringparam with parameters to set.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
- * @note
- *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam
- *   are used, and the function only sets parameters for queue 0.
- */
-int rte_ethtool_set_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_ETHTOOL_H_ */
diff --git a/examples/ethtool/main.c b/examples/ethtool/main.c
new file mode 100644
index 0000000..2c655d8
--- /dev/null
+++ b/examples/ethtool/main.c
@@ -0,0 +1,305 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rte_common.h>
+#include <rte_spinlock.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+
+#include "ethapp.h"
+
+#define MAX_PORTS RTE_MAX_ETHPORTS
+#define MAX_BURST_LENGTH 32
+#define PORT_RX_QUEUE_SIZE 128
+#define PORT_TX_QUEUE_SIZE 256
+#define PKTPOOL_EXTRA_SIZE 512
+#define PKTPOOL_CACHE 32
+
+
+struct txq_port {
+	uint16_t cnt_unsent;
+	struct rte_mbuf *buf_frames[MAX_BURST_LENGTH];
+};
+
+struct app_port {
+	struct ether_addr mac_addr;
+	struct txq_port txq;
+	rte_spinlock_t lock;
+	int port_active;
+	int port_dirty;
+	int idx_port;
+	struct rte_mempool *pkt_pool;
+};
+
+struct app_config {
+	struct app_port ports[MAX_PORTS];
+	int cnt_ports;
+	int exit_now;
+};
+
+
+struct app_config app_cfg;
+
+
+void lock_port(int idx_port)
+{
+	struct app_port *ptr_port = &app_cfg.ports[idx_port];
+
+	rte_spinlock_lock(&ptr_port->lock);
+}
+
+void unlock_port(int idx_port)
+{
+	struct app_port *ptr_port = &app_cfg.ports[idx_port];
+
+	rte_spinlock_unlock(&ptr_port->lock);
+}
+
+void mark_port_active(int idx_port)
+{
+	struct app_port *ptr_port = &app_cfg.ports[idx_port];
+
+	ptr_port->port_active = 1;
+}
+
+void mark_port_inactive(int idx_port)
+{
+	struct app_port *ptr_port = &app_cfg.ports[idx_port];
+
+	ptr_port->port_active = 0;
+}
+
+void mark_port_newmac(int idx_port)
+{
+	struct app_port *ptr_port = &app_cfg.ports[idx_port];
+
+	ptr_port->port_dirty = 1;
+}
+
+static void setup_ports(struct app_config *app_cfg, int cnt_ports)
+{
+	int idx_port;
+	int size_pktpool;
+	struct rte_eth_conf cfg_port;
+	struct rte_eth_dev_info dev_info;
+	char str_name[16];
+
+	memset(&cfg_port, 0, sizeof(cfg_port));
+	cfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;
+
+	for (idx_port = 0; idx_port < cnt_ports; idx_port++) {
+		struct app_port *ptr_port = &app_cfg->ports[idx_port];
+
+		rte_eth_dev_info_get(idx_port, &dev_info);
+		size_pktpool = dev_info.rx_desc_lim.nb_max +
+			dev_info.tx_desc_lim.nb_max + PKTPOOL_EXTRA_SIZE;
+
+		snprintf(str_name, 16, "pkt_pool%i", idx_port);
+		ptr_port->pkt_pool = rte_pktmbuf_pool_create(
+			str_name,
+			size_pktpool, PKTPOOL_CACHE,
+			0,
+			RTE_MBUF_DEFAULT_BUF_SIZE,
+			rte_socket_id()
+			);
+		if (ptr_port->pkt_pool == NULL)
+			rte_exit(EXIT_FAILURE,
+				"rte_pktmbuf_pool_create failed"
+				);
+
+		printf("Init port %i..\n", idx_port);
+		ptr_port->port_active = 1;
+		ptr_port->port_dirty = 0;
+		ptr_port->idx_port = idx_port;
+
+		if (rte_eth_dev_configure(idx_port, 1, 1, &cfg_port) < 0)
+			rte_exit(EXIT_FAILURE,
+				 "rte_eth_dev_configure failed");
+		if (rte_eth_rx_queue_setup(
+			    idx_port, 0, PORT_RX_QUEUE_SIZE,
+			    rte_eth_dev_socket_id(idx_port), NULL,
+			    ptr_port->pkt_pool) < 0)
+			rte_exit(EXIT_FAILURE,
+				 "rte_eth_rx_queue_setup failed"
+				);
+		if (rte_eth_tx_queue_setup(
+			    idx_port, 0, PORT_TX_QUEUE_SIZE,
+			    rte_eth_dev_socket_id(idx_port), NULL) < 0)
+			rte_exit(EXIT_FAILURE,
+				 "rte_eth_tx_queue_setup failed"
+				);
+		if (rte_eth_dev_start(idx_port) < 0)
+			rte_exit(EXIT_FAILURE,
+				 "%s:%i: rte_eth_dev_start failed",
+				 __FILE__, __LINE__
+				);
+		rte_eth_promiscuous_enable(idx_port);
+		rte_eth_macaddr_get(idx_port, &ptr_port->mac_addr);
+		rte_spinlock_init(&ptr_port->lock);
+	}
+}
+
+static void process_frame(struct app_port *ptr_port,
+	struct rte_mbuf *ptr_frame)
+{
+	struct ether_hdr *ptr_mac_hdr;
+
+	ptr_mac_hdr = rte_pktmbuf_mtod(ptr_frame, struct ether_hdr *);
+	ether_addr_copy(&ptr_mac_hdr->s_addr, &ptr_mac_hdr->d_addr);
+	ether_addr_copy(&ptr_port->mac_addr, &ptr_mac_hdr->s_addr);
+}
+
+static int slave_main(__attribute__((unused)) void *ptr_data)
+{
+	struct app_port *ptr_port;
+	struct rte_mbuf *ptr_frame;
+	struct txq_port *txq;
+
+	uint16_t cnt_recv_frames;
+	uint16_t idx_frame;
+	uint16_t cnt_sent;
+	uint16_t idx_port;
+	uint16_t lock_result;
+
+	while (app_cfg.exit_now == 0) {
+		for (idx_port = 0; idx_port < app_cfg.cnt_ports; idx_port++) {
+			/* Check that port is active and unlocked */
+			ptr_port = &app_cfg.ports[idx_port];
+			lock_result = rte_spinlock_trylock(&ptr_port->lock);
+			if (lock_result == 0)
+				continue;
+			if (ptr_port->port_active == 0) {
+				rte_spinlock_unlock(&ptr_port->lock);
+				continue;
+			}
+			txq = &ptr_port->txq;
+
+			/* MAC address was updated */
+			if (ptr_port->port_dirty == 1) {
+				rte_eth_macaddr_get(ptr_port->idx_port,
+					&ptr_port->mac_addr);
+				ptr_port->port_dirty = 0;
+			}
+
+			/* Incoming frames */
+			cnt_recv_frames = rte_eth_rx_burst(
+				ptr_port->idx_port, 0,
+				&txq->buf_frames[txq->cnt_unsent],
+				RTE_DIM(txq->buf_frames) - txq->cnt_unsent
+				);
+			if (cnt_recv_frames > 0) {
+				for (idx_frame = 0;
+					idx_frame < cnt_recv_frames;
+					idx_frame++) {
+					ptr_frame = txq->buf_frames[
+						idx_frame + txq->cnt_unsent];
+					process_frame(ptr_port, ptr_frame);
+				}
+				txq->cnt_unsent += cnt_recv_frames;
+			}
+
+			/* Outgoing frames */
+			if (txq->cnt_unsent > 0) {
+				cnt_sent = rte_eth_tx_burst(
+					ptr_port->idx_port, 0,
+					txq->buf_frames,
+					txq->cnt_unsent
+					);
+				/* Shuffle up unsent frame pointers */
+				for (idx_frame = cnt_sent;
+					idx_frame < txq->cnt_unsent;
+					idx_frame++)
+					txq->buf_frames[idx_frame - cnt_sent] =
+						txq->buf_frames[idx_frame];
+				txq->cnt_unsent -= cnt_sent;
+			}
+			rte_spinlock_unlock(&ptr_port->lock);
+		} /* end for( idx_port ) */
+	} /* end for(;;) */
+
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	int cnt_args_parsed;
+	uint32_t id_core;
+	uint32_t cnt_ports;
+
+	/* Init runtime enviornment */
+	cnt_args_parsed = rte_eal_init(argc, argv);
+	if (cnt_args_parsed < 0)
+		rte_exit(EXIT_FAILURE, "rte_eal_init(): Failed");
+
+	cnt_ports = rte_eth_dev_count();
+	printf("Number of NICs: %i\n", cnt_ports);
+	if (cnt_ports == 0)
+		rte_exit(EXIT_FAILURE, "No available NIC ports!\n");
+	if (cnt_ports > MAX_PORTS) {
+		printf("Info: Using only %i of %i ports\n",
+			cnt_ports, MAX_PORTS
+			);
+		cnt_ports = MAX_PORTS;
+	}
+
+	setup_ports(&app_cfg, cnt_ports);
+
+	app_cfg.exit_now = 0;
+	app_cfg.cnt_ports = cnt_ports;
+
+	if (rte_lcore_count() < 2)
+		rte_exit(EXIT_FAILURE, "No available slave core!\n");
+	/* Assume there is an available slave.. */
+	id_core = rte_lcore_id();
+	id_core = rte_get_next_lcore(id_core, 1, 1);
+	rte_eal_remote_launch(slave_main, NULL, id_core);
+
+	ethapp_main();
+
+	app_cfg.exit_now = 1;
+	RTE_LCORE_FOREACH_SLAVE(id_core) {
+		if (rte_eal_wait_lcore(id_core) < 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/lib/Makefile b/lib/Makefile
index 6840f87..57b66c6 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -58,6 +58,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PORT) += librte_port
 DIRS-$(CONFIG_RTE_LIBRTE_TABLE) += librte_table
 DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline
 DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
+DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_ethtool/Makefile b/lib/librte_ethtool/Makefile
new file mode 100644
index 0000000..8be7105
--- /dev/null
+++ b/lib/librte_ethtool/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_ethtool.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ethtool_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRC-Y
+SRCS-y := rte_ethtool.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_ethtool.h
+
+# this lib depends upon:
+DEPDIRS-y += lib/librte_eal lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ethtool/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
new file mode 100644
index 0000000..d9c5408
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool.c
@@ -0,0 +1,423 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include "rte_ethtool.h"
+
+#define PKTPOOL_SIZE 512
+#define PKTPOOL_CACHE 32
+
+
+int
+rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
+{
+	struct rte_eth_dev_info dev_info;
+	int n;
+
+	if (drvinfo == NULL)
+		return -EINVAL;
+
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	memset(&dev_info, 0, sizeof(dev_info));
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	snprintf(drvinfo->driver, sizeof(drvinfo->driver), "%s",
+		dev_info.driver_name);
+	snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
+		rte_version());
+	snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
+		"%04x:%02x:%02x.%x",
+		dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,
+		dev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function);
+
+	n = rte_eth_dev_get_reg_length(port_id);
+	if (n > 0)
+		drvinfo->regdump_len = n;
+	else
+		drvinfo->regdump_len = 0;
+
+	n = rte_eth_dev_get_eeprom_length(port_id);
+	if (n > 0)
+		drvinfo->eedump_len = n;
+	else
+		drvinfo->eedump_len = 0;
+
+	drvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
+	drvinfo->testinfo_len = 0;
+
+	return 0;
+}
+
+int
+rte_ethtool_get_regs_len(uint8_t port_id)
+{
+	int count_regs;
+
+	count_regs = rte_eth_dev_get_reg_length(port_id);
+	if (count_regs > 0)
+		return count_regs * sizeof(uint32_t);
+	return count_regs;
+}
+
+int
+rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs, void *data)
+{
+	struct rte_dev_reg_info reg_info;
+	int status;
+
+	if (regs == NULL || data == NULL)
+		return -EINVAL;
+
+	reg_info.data = data;
+	reg_info.length = 0;
+
+	status = rte_eth_dev_get_reg_info(port_id, &reg_info);
+	if (status)
+		return status;
+	regs->version = reg_info.version;
+
+	return 0;
+}
+
+int
+rte_ethtool_get_link(uint8_t port_id)
+{
+	struct rte_eth_link link;
+
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+	rte_eth_link_get(port_id, &link);
+	return link.link_status;
+}
+
+int
+rte_ethtool_get_eeprom_len(uint8_t port_id)
+{
+	return rte_eth_dev_get_eeprom_length(port_id);
+}
+
+int
+rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
+	void *words)
+{
+	struct rte_dev_eeprom_info eeprom_info;
+	int status;
+
+	if (eeprom == NULL || words == NULL)
+		return -EINVAL;
+
+	eeprom_info.offset = eeprom->offset;
+	eeprom_info.length = eeprom->len;
+	eeprom_info.data = words;
+
+	status = rte_eth_dev_get_eeprom(port_id, &eeprom_info);
+	if (status)
+		return status;
+
+	eeprom->magic = eeprom_info.magic;
+
+	return 0;
+}
+
+int
+rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
+	void *words)
+{
+	struct rte_dev_eeprom_info eeprom_info;
+	int status;
+
+	if (eeprom == NULL || words == NULL || eeprom->offset >= eeprom->len)
+		return -EINVAL;
+
+	eeprom_info.offset = eeprom->offset;
+	eeprom_info.length = eeprom->len;
+	eeprom_info.data = words;
+
+	status = rte_eth_dev_set_eeprom(port_id, &eeprom_info);
+	if (status)
+		return status;
+
+	eeprom->magic = eeprom_info.magic;
+
+	return 0;
+}
+
+int
+rte_ethtool_get_pauseparam(uint8_t port_id,
+	struct ethtool_pauseparam *pause_param)
+{
+	struct rte_eth_fc_conf fc_conf;
+	int status;
+
+	if (pause_param == NULL)
+		return -EINVAL;
+
+	status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+	if (status)
+		return status;
+
+	pause_param->tx_pause = 0;
+	pause_param->rx_pause = 0;
+	switch (fc_conf.mode) {
+	case RTE_FC_RX_PAUSE:
+		pause_param->rx_pause = 1;
+		break;
+	case RTE_FC_TX_PAUSE:
+		pause_param->tx_pause = 1;
+		break;
+	case RTE_FC_FULL:
+		pause_param->rx_pause = 1;
+		pause_param->tx_pause = 1;
+	default:
+		/* dummy block to avoid compiler warning */
+		break;
+	}
+	pause_param->autoneg = (uint32_t)fc_conf.autoneg;
+
+	return 0;
+}
+
+int
+rte_ethtool_set_pauseparam(uint8_t port_id,
+	struct ethtool_pauseparam *pause_param)
+{
+	struct rte_eth_fc_conf fc_conf;
+	int status;
+
+	if (pause_param == NULL)
+		return -EINVAL;
+
+	/*
+	 * Read device flow control parameter first since
+	 * ethtool set_pauseparam op doesn't have all the information.
+	 * as defined in struct rte_eth_fc_conf.
+	 * This API requires the device to support both
+	 * rte_eth_dev_flow_ctrl_get and rte_eth_dev_flow_ctrl_set, otherwise
+	 * return -ENOTSUP
+	 */
+	status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+	if (status)
+		return status;
+
+	fc_conf.autoneg = (uint8_t)pause_param->autoneg;
+
+	if (pause_param->tx_pause) {
+		if (pause_param->rx_pause)
+			fc_conf.mode = RTE_FC_FULL;
+		else
+			fc_conf.mode = RTE_FC_TX_PAUSE;
+	} else {
+		if (pause_param->rx_pause)
+			fc_conf.mode = RTE_FC_RX_PAUSE;
+		else
+			fc_conf.mode = RTE_FC_NONE;
+	}
+
+	status = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf);
+	if (status)
+		return status;
+
+	return 0;
+}
+
+int
+rte_ethtool_net_open(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+
+	return rte_eth_dev_start(port_id);
+}
+
+int
+rte_ethtool_net_stop(uint8_t port_id)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+	rte_eth_dev_stop(port_id);
+
+	return 0;
+}
+
+int
+rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+	if (addr == NULL)
+		return -EINVAL;
+	rte_eth_macaddr_get(port_id, addr);
+
+	return 0;
+}
+
+int
+rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)
+{
+	if (addr == NULL)
+		return -EINVAL;
+	return rte_eth_dev_default_mac_addr_set(port_id, addr);
+}
+
+int
+rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,
+	struct ether_addr *addr)
+{
+	if (addr == NULL)
+		return -EINVAL;
+	return is_valid_assigned_ether_addr(addr);
+}
+
+int
+rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)
+{
+	if (mtu < 0 || mtu > UINT16_MAX)
+		return -EINVAL;
+	return rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);
+}
+
+int
+rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)
+{
+	if (stats == NULL)
+		return -EINVAL;
+	return rte_eth_stats_get(port_id, stats);
+}
+
+int
+rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)
+{
+	return rte_eth_dev_vlan_filter(port_id, vid, 1);
+}
+
+int
+rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
+{
+	return rte_eth_dev_vlan_filter(port_id, vid, 0);
+}
+
+/*
+ * The set_rx_mode provides driver-specific rx mode setting.
+ * This implementation implements rx mode setting based upon
+ * ixgbe/igb drivers. Further improvement is to provide a
+ * callback op field over struct rte_eth_dev::dev_ops so each
+ * driver can register device-specific implementation
+ */
+int
+rte_ethtool_net_set_rx_mode(uint8_t port_id)
+{
+	uint16_t num_vfs;
+	struct rte_eth_dev_info dev_info;
+	uint16_t vf;
+
+	memset(&dev_info, 0, sizeof(dev_info));
+	rte_eth_dev_info_get(port_id, &dev_info);
+	num_vfs = dev_info.max_vfs;
+
+	/* Set VF vf_rx_mode, VF unsupport status is discard */
+	for (vf = 0; vf < num_vfs; vf++)
+		rte_eth_dev_set_vf_rxmode(port_id, vf,
+			ETH_VMDQ_ACCEPT_UNTAG, 0);
+
+	/* Enable Rx vlan filter, VF unspport status is discard */
+	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
+
+	return 0;
+}
+
+
+int
+rte_ethtool_get_ringparam(uint8_t port_id,
+	struct ethtool_ringparam *ring_param)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_rxq_info rx_qinfo;
+	struct rte_eth_txq_info tx_qinfo;
+	int stat;
+
+	if (ring_param == NULL)
+		return -EINVAL;
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
+	if (stat != 0)
+		return stat;
+
+	stat = rte_eth_tx_queue_info_get(port_id, 0, &tx_qinfo);
+	if (stat != 0)
+		return stat;
+
+	memset(ring_param, 0, sizeof(*ring_param));
+	ring_param->rx_pending = rx_qinfo.nb_desc;
+	ring_param->rx_max_pending = dev_info.rx_desc_lim.nb_max;
+	ring_param->tx_pending = tx_qinfo.nb_desc;
+	ring_param->tx_max_pending = dev_info.tx_desc_lim.nb_max;
+
+	return 0;
+}
+
+
+int
+rte_ethtool_set_ringparam(uint8_t port_id,
+	struct ethtool_ringparam *ring_param)
+{
+	struct rte_eth_rxq_info rx_qinfo;
+	int stat;
+
+	if (ring_param == NULL)
+		return -EINVAL;
+
+	stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
+	if (stat != 0)
+		return stat;
+
+	rte_eth_dev_stop(port_id);
+
+	stat = rte_eth_tx_queue_setup(port_id, 0, ring_param->tx_pending,
+		rte_socket_id(), NULL);
+	if (stat != 0)
+		return stat;
+
+	stat = rte_eth_rx_queue_setup(port_id, 0, ring_param->rx_pending,
+		rte_socket_id(), NULL, rx_qinfo.mp);
+	if (stat != 0)
+		return stat;
+
+	return rte_eth_dev_start(port_id);
+}
diff --git a/lib/librte_ethtool/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
new file mode 100644
index 0000000..c60f7bb
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool.h
@@ -0,0 +1,413 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_ETHTOOL_H_
+#define _RTE_ETHTOOL_H_
+
+/**
+ * @file
+ *
+ * This new interface is designed to provide a user-space shim layer for
+ * Ethtool and Netdevice op API.
+ *
+ * rte_ethtool_get_drvinfo:         ethtool_ops::get_driverinfo \n
+ * rte_ethtool_get_link:            ethtool_ops::get_link \n
+ * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len \n
+ * rte_ethtool_get_regs:            ethtool_ops::get_regs \n
+ * rte_ethtool_get_eeprom_len:      ethtool_ops::get_eeprom_len \n
+ * rte_ethtool_get_eeprom:          ethtool_ops::get_eeprom \n
+ * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom \n
+ * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam \n
+ * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam \n
+ * rte_ethtool_get_ringparam:       ethtool_ops::set_ringparam \n
+ * rte_ethtool_set_ringparam:       ethtool_ops::set_ringparam \n
+ *
+ * rte_ethtool_net_open:            net_device_ops::ndo_open \n
+ * rte_ethtool_net_stop:            net_device_ops::ndo_stop \n
+ * rte_ethtool_net_set_mac_addr:    net_device_ops::ndo_set_mac_address \n
+ * rte_ethtool_net_validate_addr:   net_device_ops::ndo_validate_addr \n
+ * rte_ethtool_net_change_mtu:      net_device_ops::rte_net_change_mtu \n
+ * rte_ethtool_net_get_stats64:     net_device_ops::ndo_get_stats64 \n
+ * rte_ethtool_net_vlan_rx_add_vid  net_device_ops::ndo_vlan_rx_add_vid \n
+ * rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid \n
+ * rte_ethtool_net_set_rx_mode      net_device_ops::ndo_set_rx_mode \n
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rte_ethdev.h>
+#include <linux/ethtool.h>
+
+/**
+ * Retrieve the Ethernet device driver information according to
+ * attributes described by ethtool data structure, ethtool_drvinfo.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param drvinfo
+ *   A pointer to get driver information
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo);
+
+/**
+ * Retrieve the Ethernet device register length in bytes.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (> 0) # of device registers (in bytes) available for dump
+ *   - (0) no registers available for dump.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_regs_len(uint8_t port_id);
+
+/**
+ * Retrieve the Ethernet device register information according to
+ * attributes described by ethtool data structure, ethtool_regs
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param regs
+ *   A pointer to ethtool_regs that has register information
+ * @param data
+ *   A pointer to a buffer that is used to retrieve device register content
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
+		void *data);
+
+/**
+ * Retrieve the Ethernet device link status
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (1) if link up.
+ *   - (0) if link down.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_link(uint8_t port_id);
+
+/**
+ * Retrieve the Ethernet device EEPROM size
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (> 0) device EEPROM size in bytes
+ *   - (0) device has NO EEPROM
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_eeprom_len(uint8_t port_id);
+
+/**
+ * Retrieve EEPROM content based upon eeprom range described in ethtool
+ * data structure, ethtool_eeprom
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param eeprom
+ *   The pointer of ethtool_eeprom that provides eeprom range
+ * @param words
+ *   A buffer that holds data read from eeprom
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
+		void *words);
+
+/**
+ * Setting EEPROM content based upon eeprom range described in ethtool
+ * data structure, ethtool_eeprom
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param eeprom
+ *   The pointer of ethtool_eeprom that provides eeprom range
+ * @param words
+ *   A buffer that holds data to be written into eeprom
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
+		void *words);
+
+/**
+ * Retrieve the Ethernet device pause frame configuration according to
+ * parameter attributes desribed by ethtool data structure,
+ * ethtool_pauseparam.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param pause_param
+ *   The pointer of ethtool_coalesce that gets pause frame
+ *   configuration parameters
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_pauseparam(uint8_t port_id,
+		struct ethtool_pauseparam *pause_param);
+
+/**
+ * Setting the Ethernet device pause frame configuration according to
+ * parameter attributes desribed by ethtool data structure, ethtool_pauseparam.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param param
+ *   The pointer of ethtool_coalesce that gets ring configuration parameters
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_set_pauseparam(uint8_t port_id,
+		struct ethtool_pauseparam *param);
+
+/**
+ * Start the Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_open(uint8_t port_id);
+
+/**
+ * Stop the Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_ethtool_net_stop(uint8_t port_id);
+
+/**
+ * Get the Ethernet device MAC address.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *   MAC address of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Setting the Ethernet device MAC address.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *   The new MAC addr.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Validate if the provided MAC address is valid unicast address
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *   A pointer to a buffer (6-byte, 48bit) for the target MAC address
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Setting the Ethernet device maximum Tx unit.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param mtu
+ *   New MTU
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
+
+/**
+ * Retrieve the Ethernet device traffic statistics
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param stats
+ *   A pointer to struct rte_eth_stats for statistics parameters
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if parameters invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
+
+/**
+ * Update the Ethernet device VLAN filter with new vid
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param vid
+ *   A new VLAN id
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
+
+/**
+ * Remove VLAN id from Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param vid
+ *   A new VLAN id
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);
+
+/**
+ * Setting the Ethernet device rx mode.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_set_rx_mode(uint8_t port_id);
+
+/**
+ * Getting ring paramaters for Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ring_param
+ *   Pointer to struct ethrool_ringparam to receive parameters.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ * @note
+ *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam
+ *   are used, and the function only gets parameters for queue 0.
+ */
+int rte_ethtool_get_ringparam(uint8_t port_id,
+		struct ethtool_ringparam *ring_param);
+
+/**
+ * Setting ring paramaters for Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ring_param
+ *   Pointer to struct ethrool_ringparam with parameters to set.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ * @note
+ *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam
+ *   are used, and the function only sets parameters for queue 0.
+ */
+int rte_ethtool_set_ringparam(uint8_t port_id,
+		struct ethtool_ringparam *ring_param);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETHTOOL_H_ */
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
new file mode 100644
index 0000000..34183b8
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,28 @@
+DPDK_16.04 {
+	global:
+
+	rte_ethtool_get_drvinfo;
+	rte_ethtool_get_link;
+	rte_ethtool_get_regs_len;
+	rte_ethtool_get_regs;
+	rte_ethtool_get_eeprom_len;
+	rte_ethtool_get_eeprom;
+	rte_ethtool_set_eeprom;
+	rte_ethtool_get_pauseparam;
+	rte_ethtool_set_pauseparam;
+	rte_ethtool_get_ringparam;
+	rte_ethtool_set_ringparam;
+
+	rte_ethtool_net_open;
+	rte_ethtool_net_stop;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_set_mac_addr;
+	rte_ethtool_net_validate_addr;
+	rte_ethtool_net_change_mtu;
+	rte_ethtool_net_get_stats64;
+	rte_ethtool_net_vlan_rx_add_vid;
+	rte_ethtool_net_vlan_rx_kill_vid;
+	rte_ethtool_net_set_rx_mode;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index daac09f..d94da7a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -113,6 +113,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF_OFFLOAD)   += -lrte_mbuf_offload
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        += -lrte_ip_frag
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lethdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
-- 
2.5.0

^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09 10:46  7%     ` Panu Matilainen
@ 2016-03-09 11:30  4%       ` Hunt, David
  2016-03-09 14:59  4%         ` Olivier MATZ
  0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2016-03-09 11:30 UTC (permalink / raw)
  To: Panu Matilainen, dev

Hi Panu,

On 3/9/2016 10:46 AM, Panu Matilainen wrote:
> On 03/09/2016 11:50 AM, David Hunt wrote:
>> This patch is for those people who want to be easily able to switch
>> between the new mempool layout and the old. Change the value of
>> RTE_NEXT_ABI in common_base config file
>
> I guess the idea here is to document how to switch between the ABIs 
> but to me this reads as if this patch is supposed to change the value 
> in common_base. Of course there's  no such change included (nor should 
> there be) here, but the description could use some fine-tuning perhaps.
>

You're right, I'll clarify the comments. v4 due soon.

>>
>> v3: Updated to take re-work of file layouts into consideration
>>
>> v2: Kept all the NEXT_ABI defs to this patch so as to make the
>> previous patches easier to read, and also to imake it clear what
>> code is necessary to keep ABI compatibility when NEXT_ABI is
>> disabled.
>
> Maybe its just me, but:
> I can see why NEXT_ABI is in a separate patch for review purposes but 
> for final commit this split doesn't seem right to me. In any case its 
> quite a large change for NEXT_ABI.
>

The patch basically re-introduces the old (pre-mempool) code as the 
refactoring of the code would have made the NEXT_ABI additions totally 
unreadable. I think this way is the lesser of two evils.

> In any case, you should add a deprecation notice for the oncoming ABI 
> break in 16.07.
>

Sure, I'll add that in v4.


>     - Panu -
>
Thanks for the comments,
Regards,
David.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09  9:50  4%   ` [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages David Hunt
@ 2016-03-09 10:46  7%     ` Panu Matilainen
  2016-03-09 11:30  4%       ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-09 10:46 UTC (permalink / raw)
  To: David Hunt, dev

On 03/09/2016 11:50 AM, David Hunt wrote:
> This patch is for those people who want to be easily able to switch
> between the new mempool layout and the old. Change the value of
> RTE_NEXT_ABI in common_base config file

I guess the idea here is to document how to switch between the ABIs but 
to me this reads as if this patch is supposed to change the value in 
common_base. Of course there's  no such change included (nor should 
there be) here, but the description could use some fine-tuning perhaps.

>
> v3: Updated to take re-work of file layouts into consideration
>
> v2: Kept all the NEXT_ABI defs to this patch so as to make the
> previous patches easier to read, and also to imake it clear what
> code is necessary to keep ABI compatibility when NEXT_ABI is
> disabled.

Maybe its just me, but:
I can see why NEXT_ABI is in a separate patch for review purposes but 
for final commit this split doesn't seem right to me. In any case its 
quite a large change for NEXT_ABI.

In any case, you should add a deprecation notice for the oncoming ABI 
break in 16.07.

	- Panu -

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages
  2016-03-09  9:50  3% ` [dpdk-dev] [PATCH v3 0/4] " David Hunt
@ 2016-03-09  9:50  4%   ` David Hunt
  2016-03-09 10:46  7%     ` Panu Matilainen
  2016-04-14 13:57  2%   ` [dpdk-dev] [PATCH v4 0/3] external mempool manager Olivier Matz
  1 sibling, 1 reply; 200+ results
From: David Hunt @ 2016-03-09  9:50 UTC (permalink / raw)
  To: dev

This patch is for those people who want to be easily able to switch
between the new mempool layout and the old. Change the value of
RTE_NEXT_ABI in common_base config file

v3: Updated to take re-work of file layouts into consideration

v2: Kept all the NEXT_ABI defs to this patch so as to make the
previous patches easier to read, and also to imake it clear what
code is necessary to keep ABI compatibility when NEXT_ABI is
disabled.

Signed-off-by: David Hunt <david.hunt@intel.com>
---
 app/test/Makefile                |   2 +
 app/test/test_mempool_perf.c     |   3 +
 lib/librte_mbuf/rte_mbuf.c       |   7 ++
 lib/librte_mempool/Makefile      |   2 +
 lib/librte_mempool/rte_mempool.c | 245 ++++++++++++++++++++++++++++++++++++++-
 lib/librte_mempool/rte_mempool.h |  59 +++++++++-
 6 files changed, 315 insertions(+), 3 deletions(-)

diff --git a/app/test/Makefile b/app/test/Makefile
index 9a2f75f..8fcf0c2 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -74,7 +74,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_TIMER) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_TIMER) += test_timer_racecond.c
 
 SRCS-y += test_mempool.c
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
 SRCS-y += test_ext_mempool.c
+endif
 SRCS-y += test_mempool_perf.c
 
 SRCS-y += test_mbuf.c
diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
index 091c1df..ca69e49 100644
--- a/app/test/test_mempool_perf.c
+++ b/app/test/test_mempool_perf.c
@@ -161,6 +161,9 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg)
 							   n_get_bulk);
 				if (unlikely(ret < 0)) {
 					rte_mempool_dump(stdout, mp);
+#ifndef RTE_NEXT_ABI
+					rte_ring_dump(stdout, mp->ring);
+#endif
 					/* in this case, objects are lost... */
 					return -1;
 				}
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 42b0cd1..967d987 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -167,6 +167,7 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
 	mbp_priv.mbuf_data_room_size = data_room_size;
 	mbp_priv.mbuf_priv_size = priv_size;
 
+#ifdef RTE_NEXT_ABI
 #ifdef RTE_MEMPOOL_HANDLER_EXT
 	return rte_mempool_create_ext(name, n, elt_size,
 		cache_size, sizeof(struct rte_pktmbuf_pool_private),
@@ -179,6 +180,12 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
 		rte_pktmbuf_pool_init, &mbp_priv, rte_pktmbuf_init, NULL,
 		socket_id, 0);
 #endif
+#else
+	return rte_mempool_create(name, n, elt_size,
+		cache_size, sizeof(struct rte_pktmbuf_pool_private),
+		rte_pktmbuf_pool_init, &mbp_priv, rte_pktmbuf_init, NULL,
+		socket_id, 0);
+#endif
 }
 
 /* do some sanity checks on a mbuf: panic if it fails */
diff --git a/lib/librte_mempool/Makefile b/lib/librte_mempool/Makefile
index a32c89e..a27eef9 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -42,8 +42,10 @@ LIBABIVER := 1
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool.c
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_handler.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_default.c
+endif
 
 ifeq ($(CONFIG_RTE_LIBRTE_XEN_DOM0),y)
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_dom0_mempool.c
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 7342a7f..e77ef47 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -59,7 +59,10 @@
 #include <rte_spinlock.h>
 
 #include "rte_mempool.h"
+#ifdef RTE_NEXT_ABI
 #include "rte_mempool_handler.h"
+#endif
+
 
 TAILQ_HEAD(rte_mempool_list, rte_tailq_entry);
 
@@ -150,7 +153,11 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, uint32_t obj_idx,
 		obj_init(mp, obj_init_arg, obj, obj_idx);
 
 	/* enqueue in ring */
+#ifdef RTE_NEXT_ABI
 	rte_mempool_ext_put_bulk(mp, &obj, 1);
+#else
+	rte_ring_mp_enqueue_bulk(mp->ring, &obj, 1);
+#endif
 }
 
 uint32_t
@@ -420,6 +427,7 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
 					       MEMPOOL_PG_SHIFT_MAX);
 }
 
+#ifdef RTE_NEXT_ABI
 /*
  * Common mempool create function.
  * Create the mempool over already allocated chunk of memory.
@@ -711,6 +719,229 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 
 	return mp;
 }
+#else
+/*
+ * Create the mempool over already allocated chunk of memory.
+ * That external memory buffer can consists of physically disjoint pages.
+ * Setting vaddr to NULL, makes mempool to fallback to original behaviour
+ * and allocate space for mempool and it's elements as one big chunk of
+ * physically continuos memory.
+ * */
+struct rte_mempool *
+rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
+		unsigned cache_size, unsigned private_data_size,
+		rte_mempool_ctor_t *mp_init, void *mp_init_arg,
+		rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
+		int socket_id, unsigned flags, void *vaddr,
+		const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift)
+{
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	char rg_name[RTE_RING_NAMESIZE];
+	struct rte_mempool_list *mempool_list;
+	struct rte_mempool *mp = NULL;
+	struct rte_tailq_entry *te;
+	struct rte_ring *r;
+	const struct rte_memzone *mz;
+	size_t mempool_size;
+	int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY;
+	int rg_flags = 0;
+	void *obj;
+	struct rte_mempool_objsz objsz;
+	void *startaddr;
+	int page_size = getpagesize();
+
+	/* compilation-time checks */
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#endif
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
+			  RTE_CACHE_LINE_MASK) != 0);
+	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, stats) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#endif
+
+	mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
+
+	/* asked cache too big */
+	if (cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE ||
+	    CALC_CACHE_FLUSHTHRESH(cache_size) > n) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* check that we have both VA and PA */
+	if (vaddr != NULL && paddr == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* Check that pg_num and pg_shift parameters are valid. */
+	if (pg_num < RTE_DIM(mp->elt_pa) || pg_shift > MEMPOOL_PG_SHIFT_MAX) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* "no cache align" imply "no spread" */
+	if (flags & MEMPOOL_F_NO_CACHE_ALIGN)
+		flags |= MEMPOOL_F_NO_SPREAD;
+
+	/* ring flags */
+	if (flags & MEMPOOL_F_SP_PUT)
+		rg_flags |= RING_F_SP_ENQ;
+	if (flags & MEMPOOL_F_SC_GET)
+		rg_flags |= RING_F_SC_DEQ;
+
+	/* calculate mempool object sizes. */
+	if (!rte_mempool_calc_obj_size(elt_size, flags, &objsz)) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	rte_rwlock_write_lock(RTE_EAL_MEMPOOL_RWLOCK);
+
+	/* allocate the ring that will be used to store objects */
+	/* Ring functions will return appropriate errors if we are
+	 * running as a secondary process etc., so no checks made
+	 * in this function for that condition */
+	snprintf(rg_name, sizeof(rg_name), RTE_MEMPOOL_MZ_FORMAT, name);
+	r = rte_ring_create(rg_name, rte_align32pow2(n+1), socket_id, rg_flags);
+	if (r == NULL)
+		goto exit;
+
+	/*
+	 * reserve a memory zone for this mempool: private data is
+	 * cache-aligned
+	 */
+	private_data_size = (private_data_size +
+		RTE_MEMPOOL_ALIGN_MASK) & (~RTE_MEMPOOL_ALIGN_MASK);
+
+	if (!rte_eal_has_hugepages()) {
+		/*
+		 * expand private data size to a whole page, so that the
+		 * first pool element will start on a new standard page
+		 */
+		int head = sizeof(struct rte_mempool);
+		int new_size = (private_data_size + head) % page_size;
+
+		if (new_size)
+			private_data_size += page_size - new_size;
+	}
+
+	/* try to allocate tailq entry */
+	te = rte_zmalloc("MEMPOOL_TAILQ_ENTRY", sizeof(*te), 0);
+	if (te == NULL) {
+		RTE_LOG(ERR, MEMPOOL, "Cannot allocate tailq entry!\n");
+		goto exit;
+	}
+
+	/*
+	 * If user provided an external memory buffer, then use it to
+	 * store mempool objects. Otherwise reserve a memzone that is large
+	 * enough to hold mempool header and metadata plus mempool objects.
+	 */
+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
+	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
+	if (vaddr == NULL)
+		mempool_size += (size_t)objsz.total_size * n;
+
+	if (!rte_eal_has_hugepages()) {
+		/*
+		 * we want the memory pool to start on a page boundary,
+		 * because pool elements crossing page boundaries would
+		 * result in discontiguous physical addresses
+		 */
+		mempool_size += page_size;
+	}
+
+	snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_MZ_FORMAT, name);
+
+	mz = rte_memzone_reserve(mz_name, mempool_size, socket_id, mz_flags);
+
+	/*
+	 * no more memory: in this case we loose previously reserved
+	 * space for the ring as we cannot free it
+	 */
+	if (mz == NULL) {
+		rte_free(te);
+		goto exit;
+	}
+
+	if (rte_eal_has_hugepages()) {
+		startaddr = (void *)mz->addr;
+	} else {
+		/* align memory pool start address on a page boundary */
+		unsigned long addr = (unsigned long)mz->addr;
+
+		if (addr & (page_size - 1)) {
+			addr += page_size;
+			addr &= ~(page_size - 1);
+		}
+		startaddr = (void *)addr;
+	}
+
+	/* init the mempool structure */
+	mp = startaddr;
+	memset(mp, 0, sizeof(*mp));
+	snprintf(mp->name, sizeof(mp->name), "%s", name);
+	mp->phys_addr = mz->phys_addr;
+	mp->ring = r;
+	mp->size = n;
+	mp->flags = flags;
+	mp->elt_size = objsz.elt_size;
+	mp->header_size = objsz.header_size;
+	mp->trailer_size = objsz.trailer_size;
+	mp->cache_size = cache_size;
+	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
+	mp->private_data_size = private_data_size;
+
+	/* calculate address of the first element for continuous mempool. */
+	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
+		private_data_size;
+	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
+
+	/* populate address translation fields. */
+	mp->pg_num = pg_num;
+	mp->pg_shift = pg_shift;
+	mp->pg_mask = RTE_LEN2MASK(mp->pg_shift, typeof(mp->pg_mask));
+
+	/* mempool elements allocated together with mempool */
+	if (vaddr == NULL) {
+		mp->elt_va_start = (uintptr_t)obj;
+		mp->elt_pa[0] = mp->phys_addr +
+			(mp->elt_va_start - (uintptr_t)mp);
+
+	/* mempool elements in a separate chunk of memory. */
+	} else {
+		mp->elt_va_start = (uintptr_t)vaddr;
+		memcpy(mp->elt_pa, paddr, sizeof(mp->elt_pa[0]) * pg_num);
+	}
+
+	mp->elt_va_end = mp->elt_va_start;
+
+	/* call the initializer */
+	if (mp_init)
+		mp_init(mp, mp_init_arg);
+
+	mempool_populate(mp, n, 1, obj_init, obj_init_arg);
+
+	te->data = (void *) mp;
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+	TAILQ_INSERT_TAIL(mempool_list, te, next);
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+exit:
+	rte_rwlock_write_unlock(RTE_EAL_MEMPOOL_RWLOCK);
+
+	return mp;
+}
+#endif
 
 /* Return the number of entries in the mempool */
 unsigned
@@ -718,7 +949,11 @@ rte_mempool_count(const struct rte_mempool *mp)
 {
 	unsigned count;
 
+#ifdef RTE_NEXT_ABI
 	count = rte_mempool_ext_get_count(mp);
+#else
+	count = rte_ring_count(mp->ring);
+#endif
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	{
@@ -874,6 +1109,9 @@ rte_mempool_dump(FILE *f, const struct rte_mempool *mp)
 
 	fprintf(f, "mempool <%s>@%p\n", mp->name, mp);
 	fprintf(f, "  flags=%x\n", mp->flags);
+#ifndef RTE_NEXT_ABI
+	fprintf(f, "  ring=<%s>@%p\n", mp->ring->name, mp->ring);
+#endif
 	fprintf(f, "  phys_addr=0x%" PRIx64 "\n", mp->phys_addr);
 	fprintf(f, "  size=%"PRIu32"\n", mp->size);
 	fprintf(f, "  header_size=%"PRIu32"\n", mp->header_size);
@@ -896,7 +1134,11 @@ rte_mempool_dump(FILE *f, const struct rte_mempool *mp)
 			mp->size);
 
 	cache_count = rte_mempool_dump_cache(f, mp);
+#ifdef RTE_NEXT_ABI
 	common_count = rte_mempool_ext_get_count(mp);
+#else
+	common_count = rte_ring_count(mp->ring);
+#endif
 	if ((cache_count + common_count) > mp->size)
 		common_count = mp->size - cache_count;
 	fprintf(f, "  common_pool_count=%u\n", common_count);
@@ -991,7 +1233,7 @@ void rte_mempool_walk(void (*func)(const struct rte_mempool *, void *),
 	rte_rwlock_read_unlock(RTE_EAL_MEMPOOL_RWLOCK);
 }
 
-
+#ifdef RTE_NEXT_ABI
 /* create the mempool using an external mempool manager */
 struct rte_mempool *
 rte_mempool_create_ext(const char *name, unsigned n, unsigned elt_size,
@@ -1017,3 +1259,4 @@ rte_mempool_create_ext(const char *name, unsigned n, unsigned elt_size,
 
 
 }
+#endif
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index f987d8a..4b14b80 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -175,6 +175,7 @@ struct rte_mempool_objtlr {
 #endif
 };
 
+#ifdef RTE_NEXT_ABI
 /* Handler functions for external mempool support */
 typedef void *(*rte_mempool_alloc_t)(struct rte_mempool *mp,
 		const char *name, unsigned n, int socket_id, unsigned flags);
@@ -256,12 +257,16 @@ rte_mempool_ext_get_count(const struct rte_mempool *mp);
  */
 int
 rte_mempool_ext_free(struct rte_mempool *mp);
+#endif
 
 /**
  * The RTE mempool structure.
  */
 struct rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
+#ifndef RTE_NEXT_ABI
+	struct rte_ring *ring;           /**< Ring to store objects. */
+#endif
 	phys_addr_t phys_addr;           /**< Phys. addr. of mempool struct. */
 	int flags;                       /**< Flags of the mempool. */
 	uint32_t size;                   /**< Size of the mempool. */
@@ -275,6 +280,7 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
+#ifdef RTE_NEXT_ABI
 	/* Common pool data structure pointer */
 	void *pool;
 
@@ -286,6 +292,7 @@ struct rte_mempool {
 	 * directly would not be valid for secondary processes.
 	 */
 	int16_t handler_idx;
+#endif
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/** Per-lcore local cache. */
@@ -316,8 +323,9 @@ struct rte_mempool {
 #define MEMPOOL_F_NO_CACHE_ALIGN 0x0002 /**< Do not align objs on cache lines.*/
 #define MEMPOOL_F_SP_PUT         0x0004 /**< Default put is "single-producer".*/
 #define MEMPOOL_F_SC_GET         0x0008 /**< Default get is "single-consumer".*/
+#ifdef RTE_NEXT_ABI
 #define MEMPOOL_F_INT_HANDLER    0x0020 /**< Using internal mempool handler */
-
+#endif
 
 /**
  * @internal When debug is enabled, store some statistics.
@@ -847,7 +855,12 @@ void rte_mempool_dump(FILE *f, const struct rte_mempool *mp);
  */
 static inline void __attribute__((always_inline))
 __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
-		    unsigned n, __rte_unused int is_mp)
+#ifdef RTE_NEXT_ABI
+		unsigned n, __rte_unused int is_mp)
+#else
+		unsigned n, int is_mp)
+#endif
+
 {
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	struct rte_mempool_cache *cache;
@@ -887,9 +900,15 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 
 	cache->len += n;
 
+#ifdef RTE_NEXT_ABI
 	if (unlikely(cache->len >= flushthresh)) {
 		rte_mempool_ext_put_bulk(mp, &cache->objs[cache_size],
 				cache->len - cache_size);
+#else
+	if (cache->len >= flushthresh) {
+		rte_ring_mp_enqueue_bulk(mp->ring, &cache->objs[cache_size],
+				cache->len - cache_size);
+#endif
 		cache->len = cache_size;
 		/*
 		 * Increment stats counter to tell us how many pool puts
@@ -903,10 +922,28 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 ring_enqueue:
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
+#ifdef RTE_NEXT_ABI
 	/* Increment stats counter to tell us how many pool puts happened */
 	__MEMPOOL_STAT_ADD(mp, put_pool, n);
 
 	rte_mempool_ext_put_bulk(mp, obj_table, n);
+#else
+	/* push remaining objects in ring */
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	if (is_mp) {
+		if (rte_ring_mp_enqueue_bulk(mp->ring, obj_table, n) < 0)
+			rte_panic("cannot put objects in mempool\n");
+	} else {
+		if (rte_ring_sp_enqueue_bulk(mp->ring, obj_table, n) < 0)
+			rte_panic("cannot put objects in mempool\n");
+	}
+#else
+	if (is_mp)
+		rte_ring_mp_enqueue_bulk(mp->ring, obj_table, n);
+	else
+		rte_ring_sp_enqueue_bulk(mp->ring, obj_table, n);
+#endif
+#endif
 }
 
 
@@ -1030,7 +1067,11 @@ rte_mempool_put(struct rte_mempool *mp, void *obj)
  */
 static inline int __attribute__((always_inline))
 __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
+#ifdef RTE_NEXT_ABI
 		   unsigned n, __attribute__((unused))int is_mc)
+#else
+		   unsigned n, int is_mc)
+#endif
 {
 	int ret;
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
@@ -1054,8 +1095,13 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 		uint32_t req = n + (cache_size - cache->len);
 
 		/* How many do we require i.e. number to fill the cache + the request */
+#ifdef RTE_NEXT_ABI
 		ret = rte_mempool_ext_get_bulk(mp,
 			&cache->objs[cache->len], req);
+#else
+		ret = rte_ring_mc_dequeue_bulk(mp->ring,
+			&cache->objs[cache->len], req);
+#endif
 		if (unlikely(ret < 0)) {
 			/*
 			 * In the offchance that we are buffer constrained,
@@ -1083,7 +1129,14 @@ ring_dequeue:
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 	/* get remaining objects from ring */
+#ifdef RTE_NEXT_ABI
 	ret = rte_mempool_ext_get_bulk(mp, obj_table, n);
+#else
+	if (is_mc)
+		ret = rte_ring_mc_dequeue_bulk(mp->ring, obj_table, n);
+	else
+		ret = rte_ring_sc_dequeue_bulk(mp->ring, obj_table, n);
+#endif
 
 	if (ret < 0)
 		__MEMPOOL_STAT_ADD(mp, get_fail, n);
@@ -1485,6 +1538,7 @@ ssize_t rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
  */
 void rte_mempool_walk(void (*func)(const struct rte_mempool *, void *arg),
 		      void *arg);
+#ifdef RTE_NEXT_ABI
 
 /**
  * Function to get the name of a mempool handler
@@ -1559,6 +1613,7 @@ rte_mempool_create_ext(const char *name, unsigned n, unsigned elt_size,
 		rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
 		int socket_id, unsigned flags,
 		const char *handler_name);
+#endif
 
 #ifdef __cplusplus
 }
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 0/4] external mempool manager
  @ 2016-03-09  9:50  3% ` David Hunt
  2016-03-09  9:50  4%   ` [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages David Hunt
  2016-04-14 13:57  2%   ` [dpdk-dev] [PATCH v4 0/3] external mempool manager Olivier Matz
  0 siblings, 2 replies; 200+ results
From: David Hunt @ 2016-03-09  9:50 UTC (permalink / raw)
  To: dev

Hi list.

Here's the v3 version patch for an external mempool manager

v3 changes:
 * simplified the file layout, renamed to rte_mempool_handler.[hc]
 * moved the default handlers into rte_mempool_default.c
 * moved the example handler out into app/test/test_ext_mempool.c
 * removed is_mc/is_mp change, slight perf degredation on sp cached operation
 * removed stack hanler, may re-introduce at a later date
 * Changes out of code reviews

v2 changes:
 * There was a lot of duplicate code between rte_mempool_xmem_create and
   rte_mempool_create_ext. This has now been refactored and is now
   hopefully cleaner.
 * The RTE_NEXT_ABI define is now used to allow building of the library
   in a format that is compatible with binaries built against previous
   versions of DPDK.
 * Changes out of code reviews. Hopefully I've got most of them included.

The External Mempool Manager is an extension to the mempool API that allows
users to add and use an external mempool manager, which allows external memory
subsystems such as external hardware memory management systems and software
based memory allocators to be used with DPDK.

The existing API to the internal DPDK mempool manager will remain unchanged
and will be backward compatible. However, there will be an ABI breakage, as
the mempool struct is changing. These changes are all contained withing
RTE_NEXT_ABI defs, and the current or next code can be changed with
the CONFIG_RTE_NEXT_ABI config setting

There are two aspects to external mempool manager.
  1. Adding the code for your new mempool handler. This is achieved by adding a
     new mempool handler source file into the librte_mempool library, and
     using the REGISTER_MEMPOOL_HANDLER macro.
  2. Using the new API to call rte_mempool_create_ext to create a new mempool
     using the name parameter to identify which handler to use.

New API calls added
 1. A new mempool 'create' function which accepts mempool handler name.
 2. A new mempool 'rte_get_mempool_handler' function which accepts mempool
    handler name, and returns the index to the relevant set of callbacks for
    that mempool handler

Several external mempool managers may be used in the same application. A new
mempool can then be created by using the new 'create' function, providing the
mempool handler name to point the mempool to the relevant mempool manager
callback structure.

The old 'create' function can still be called by legacy programs, and will
internally work out the mempool handle based on the flags provided (single
producer, single consumer, etc). By default handles are created internally to
implement the built-in DPDK mempool manager and mempool types.

The external mempool manager needs to provide the following functions.
 1. alloc     - allocates the mempool memory, and adds each object onto a ring
 2. put       - puts an object back into the mempool once an application has
                finished with it
 3. get       - gets an object from the mempool for use by the application
 4. get_count - gets the number of available objects in the mempool
 5. free      - frees the mempool memory

Every time a get/put/get_count is called from the application/PMD, the
callback for that mempool is called. These functions are in the fastpath,
and any unoptimised handlers may limit performance.

The new APIs are as follows:

1. rte_mempool_create_ext

struct rte_mempool *
rte_mempool_create_ext(const char * name, unsigned n,
        unsigned cache_size, unsigned private_data_size,
        int socket_id, unsigned flags,
        const char * handler_name);

2. rte_mempool_get_handler_name

char *
rte_mempool_get_handler_name(struct rte_mempool *mp);

Please see rte_mempool.h for further information on the parameters.


The important thing to note is that the mempool handler is passed by name
to rte_mempool_create_ext, and that in turn calls rte_get_mempool_handler to
get the handler index, which is stored in the rte_memool structure. This
allow multiple processes to use the same mempool, as the function pointers
are accessed via handler index.

The mempool handler structure contains callbacks to the implementation of
the handler, and is set up for registration as follows:

static struct rte_mempool_handler handler_sp_mc = {
    .name = "ring_sp_mc",
    .alloc = rte_mempool_common_ring_alloc,
    .put = common_ring_sp_put,
    .get = common_ring_mc_get,
    .get_count = common_ring_get_count,
    .free = common_ring_free,
};

And then the following macro will register the handler in the array of handlers

REGISTER_MEMPOOL_HANDLER(handler_mp_mc);

For and example of a simple malloc based mempool manager, see
lib/librte_mempool/custom_mempool.c

For an example of API usage, please see app/test/test_ext_mempool.c, which
implements a rudimentary mempool manager using simple mallocs for each
mempool object. This file also contains the callbacks and self registration
for the new handler.

David Hunt (4):
  mempool: add external mempool manager support
  mempool: add custom mempool handler example
  mempool: allow rte_pktmbuf_pool_create switch between memool handlers
  mempool: add in the RTE_NEXT_ABI for ABI breakages

 app/test/Makefile                          |   3 +
 app/test/test_ext_mempool.c                | 451 +++++++++++++++++++++++++++++
 app/test/test_mempool_perf.c               |   2 +
 config/common_base                         |   2 +
 lib/librte_mbuf/rte_mbuf.c                 |  15 +
 lib/librte_mempool/Makefile                |   5 +
 lib/librte_mempool/rte_mempool.c           | 389 +++++++++++++++++++++++--
 lib/librte_mempool/rte_mempool.h           | 224 +++++++++++++-
 lib/librte_mempool/rte_mempool_default.c   | 136 +++++++++
 lib/librte_mempool/rte_mempool_handler.c   | 140 +++++++++
 lib/librte_mempool/rte_mempool_handler.h   |  75 +++++
 lib/librte_mempool/rte_mempool_version.map |   1 +
 12 files changed, 1415 insertions(+), 28 deletions(-)
 create mode 100644 app/test/test_ext_mempool.c
 create mode 100644 lib/librte_mempool/rte_mempool_default.c
 create mode 100644 lib/librte_mempool/rte_mempool_handler.c
 create mode 100644 lib/librte_mempool/rte_mempool_handler.h

-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver
  2016-03-09  5:42  4% ` [dpdk-dev] [PATCH v3 00/12] extend flow director " Jingjing Wu
  2016-03-09  5:42 18%   ` [dpdk-dev] [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
@ 2016-03-09  6:18  0%   ` Zhang, Helin
  2016-03-10  3:25  4%   ` [dpdk-dev] [PATCH v4 " Jingjing Wu
  2 siblings, 0 replies; 200+ results
From: Zhang, Helin @ 2016-03-09  6:18 UTC (permalink / raw)
  To: Wu, Jingjing, Richardson, Bruce; +Cc: dev

Acked-by: Helin Zhang <helin.zhang@intel.com>

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, March 9, 2016 1:43 PM
> To: Richardson, Bruce <bruce.richardson@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Pei, Yulong
> <yulong.pei@intel.com>
> Subject: [PATCH v3 00/12] extend flow director fields in i40e driver
> 
> v3 changes:
>  - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
>  - use AQ rx control register read/write for some registers
>  - remove few useless lines
>  - patch title rewording
> 
> v2 changes:
>  - rebase on dpdk-next-net/rel_16_04
>  - comments rewording.
>  - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to avoid ABI breaking.
>  - remove ABI announce in Deprecation.
>  - fix the ethertype setting when program filter in v1 patch set.
> 
> This patch set extends flow director to support filtering by additional fields below
> in i40e driver:
>  - TOS, Protocol and TTL in IP header
>  - Tunnel id if NVGRE/GRE/VxLAN packets
>  - single vlan or inner vlan
> 
> 
> Andrey Chilikin (1):
>   i40e: fix VLAN bitmasks for input set
> 
> Jingjing Wu (11):
>   ethdev: extend flow director for input selection
>   i40e: split function for hash and fdir input
>   i40e: remove flex payload from input selection
>   i40e: restore default setting on input set
>   i40e: extend flow director to filter by IP Header
>   testpmd: extend input set related commands
>   librte_ether: extend flow director struct
>   i40e: extend flow director to filter by tunnel ID
>   testpmd: extend flow director commands
>   i40e: extend flow director to filter by vlan id
>   testpmd: extend flow director commands
> 
>  app/test-pmd/cmdline.c                      | 121 +++++++--
>  doc/guides/rel_notes/deprecation.rst        |   4 -
>  doc/guides/rel_notes/release_16_04.rst      |   5 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
>  drivers/net/i40e/i40e_ethdev.c              | 403
> +++++++++++++++++-----------
>  drivers/net/i40e/i40e_ethdev.h              |  11 +-
>  drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
>  lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
>  8 files changed, 570 insertions(+), 271 deletions(-)
> 
> --
> 2.4.0

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3 07/12] librte_ether: extend flow director struct
  2016-03-09  5:42  4% ` [dpdk-dev] [PATCH v3 00/12] extend flow director " Jingjing Wu
@ 2016-03-09  5:42 18%   ` Jingjing Wu
  2016-03-09  6:18  0%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
  2016-03-10  3:25  4%   ` [dpdk-dev] [PATCH v4 " Jingjing Wu
  2 siblings, 0 replies; 200+ results
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  4 ----
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 27 +++++++++++++++------------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..7fa8639 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,10 +20,6 @@ Deprecation Notices
   tables (512 queues).
   It should be integrated in release 2.3.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index eab5f92..26af339 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -224,6 +224,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 8c51023..b6a5c50 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

^ permalink raw reply	[relevance 18%]

* [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver
  @ 2016-03-09  5:42  4% ` Jingjing Wu
  2016-03-09  5:42 18%   ` [dpdk-dev] [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
                     ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan 


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (11):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  librte_ether: extend flow director struct
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend flow director commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 403 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 8 files changed, 570 insertions(+), 271 deletions(-)

-- 
2.4.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v8 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load
  2016-03-09  3:35  3% ` [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
  2016-03-09  3:35  4%   ` [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
@ 2016-03-09  3:35  7%   ` Wenzhuo Lu
  1 sibling, 0 replies; 200+ results
From: Wenzhuo Lu @ 2016-03-09  3:35 UTC (permalink / raw)
  To: dev

The patch add VxLAN & NVGRE TX checksum off-load. When the flag of
outer IP header checksum offload is set, we'll set the context
descriptor to enable this checksum off-load.

Also update release note for VxLAN & NVGRE checksum off-load support
and ABI change.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 14 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  4 +++
 drivers/net/ixgbe/ixgbe_rxtx.c         | 56 +++++++++++++++++++++++++++-------
 drivers/net/ixgbe/ixgbe_rxtx.h         |  6 +++-
 4 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 8273817..efb7d87 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,15 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added support for VxLAN & NVGRE checksum off-load on X550.**
+
+  * Added support for VxLAN & NVGRE RX/TX checksum off-load on
+    X550. RX/TX checksum off-load is provided on both inner and
+    outer IP header and TCP header.
+  * Added functions to support VxLAN port configuration. The
+    default VxLAN port number is 4789 but this can be updated
+    programmatically.
+
 
 Resolved Issues
 ---------------
@@ -113,6 +122,11 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* New API ``rte_eth_dev_udp_tunnel_port_add`` has been introduced to replace
+  ``rte_eth_dev_udp_tunnel_add``.
+
+* New API ``rte_eth_dev_udp_tunnel_port_delete`` has been introduced to replace
+  ``rte_eth_dev_udp_tunnel_delete``.
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4722ea4..71606fb 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2811,6 +2811,10 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		DEV_TX_OFFLOAD_SCTP_CKSUM  |
 		DEV_TX_OFFLOAD_TCP_TSO;
 
+	if (hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550EM_x)
+		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
 			.pthresh = IXGBE_DEFAULT_RX_PTHRESH,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 6b913ee..c2c71de 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -85,7 +85,8 @@
 		PKT_TX_VLAN_PKT |		 \
 		PKT_TX_IP_CKSUM |		 \
 		PKT_TX_L4_MASK |		 \
-		PKT_TX_TCP_SEG)
+		PKT_TX_TCP_SEG |		 \
+		PKT_TX_OUTER_IP_CKSUM)
 
 static inline struct rte_mbuf *
 rte_rxmbuf_alloc(struct rte_mempool *mp)
@@ -364,9 +365,11 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
 	uint32_t ctx_idx;
 	uint32_t vlan_macip_lens;
 	union ixgbe_tx_offload tx_offload_mask;
+	uint32_t seqnum_seed = 0;
 
 	ctx_idx = txq->ctx_curr;
-	tx_offload_mask.data = 0;
+	tx_offload_mask.data[0] = 0;
+	tx_offload_mask.data[1] = 0;
 	type_tucmd_mlhl = 0;
 
 	/* Specify which HW CTX to upload. */
@@ -430,18 +433,35 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,
 		}
 	}
 
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM) {
+		tx_offload_mask.outer_l2_len |= ~0;
+		tx_offload_mask.outer_l3_len |= ~0;
+		tx_offload_mask.l2_len |= ~0;
+		seqnum_seed |= tx_offload.outer_l3_len
+			       << IXGBE_ADVTXD_OUTER_IPLEN;
+		seqnum_seed |= tx_offload.l2_len
+			       << IXGBE_ADVTXD_TUNNEL_LEN;
+	}
+
 	txq->ctx_cache[ctx_idx].flags = ol_flags;
-	txq->ctx_cache[ctx_idx].tx_offload.data  =
-		tx_offload_mask.data & tx_offload.data;
+	txq->ctx_cache[ctx_idx].tx_offload.data[0]  =
+		tx_offload_mask.data[0] & tx_offload.data[0];
+	txq->ctx_cache[ctx_idx].tx_offload.data[1]  =
+		tx_offload_mask.data[1] & tx_offload.data[1];
 	txq->ctx_cache[ctx_idx].tx_offload_mask    = tx_offload_mask;
 
 	ctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);
 	vlan_macip_lens = tx_offload.l3_len;
-	vlan_macip_lens |= (tx_offload.l2_len << IXGBE_ADVTXD_MACLEN_SHIFT);
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+		vlan_macip_lens |= (tx_offload.outer_l2_len <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
+	else
+		vlan_macip_lens |= (tx_offload.l2_len <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
 	vlan_macip_lens |= ((uint32_t)tx_offload.vlan_tci << IXGBE_ADVTXD_VLAN_SHIFT);
 	ctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);
 	ctx_txd->mss_l4len_idx   = rte_cpu_to_le_32(mss_l4len_idx);
-	ctx_txd->seqnum_seed     = 0;
+	ctx_txd->seqnum_seed     = seqnum_seed;
 }
 
 /*
@@ -454,16 +474,24 @@ what_advctx_update(struct ixgbe_tx_queue *txq, uint64_t flags,
 {
 	/* If match with the current used context */
 	if (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&
-		(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==
-		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[0] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[0]
+		 & tx_offload.data[0])) &&
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[1] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[1]
+		 & tx_offload.data[1])))) {
 			return txq->ctx_curr;
 	}
 
 	/* What if match with the next context  */
 	txq->ctx_curr ^= 1;
 	if (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&
-		(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==
-		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[0] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[0]
+		 & tx_offload.data[0])) &&
+		(txq->ctx_cache[txq->ctx_curr].tx_offload.data[1] ==
+		(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data[1]
+		 & tx_offload.data[1])))) {
 			return txq->ctx_curr;
 	}
 
@@ -492,6 +520,8 @@ tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags)
 		cmdtype |= IXGBE_ADVTXD_DCMD_VLE;
 	if (ol_flags & PKT_TX_TCP_SEG)
 		cmdtype |= IXGBE_ADVTXD_DCMD_TSE;
+	if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+		cmdtype |= (1 << IXGBE_ADVTXD_OUTERIPCS_SHIFT);
 	return cmdtype;
 }
 
@@ -588,8 +618,10 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	uint64_t tx_ol_req;
 	uint32_t ctx = 0;
 	uint32_t new_ctx;
-	union ixgbe_tx_offload tx_offload = {0};
+	union ixgbe_tx_offload tx_offload;
 
+	tx_offload.data[0] = 0;
+	tx_offload.data[1] = 0;
 	txq = tx_queue;
 	sw_ring = txq->sw_ring;
 	txr     = txq->tx_ring;
@@ -623,6 +655,8 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			tx_offload.l4_len = tx_pkt->l4_len;
 			tx_offload.vlan_tci = tx_pkt->vlan_tci;
 			tx_offload.tso_segsz = tx_pkt->tso_segsz;
+			tx_offload.outer_l2_len = tx_pkt->outer_l2_len;
+			tx_offload.outer_l3_len = tx_pkt->outer_l3_len;
 
 			/* If new context need be built or reuse the exist ctx. */
 			ctx = what_advctx_update(txq, tx_ol_req,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 475a800..c15f9fa 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -163,7 +163,7 @@ enum ixgbe_advctx_num {
 
 /** Offload features */
 union ixgbe_tx_offload {
-	uint64_t data;
+	uint64_t data[2];
 	struct {
 		uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
 		uint64_t l3_len:9; /**< L3 (IP) Header Length. */
@@ -171,6 +171,10 @@ union ixgbe_tx_offload {
 		uint64_t tso_segsz:16; /**< TCP TSO segment size */
 		uint64_t vlan_tci:16;
 		/**< VLAN Tag Control Identifier (CPU order). */
+
+		/* fields for TX offloading of tunnels */
+		uint64_t outer_l3_len:8; /**< Outer L3 (IP) Hdr Length. */
+		uint64_t outer_l2_len:8; /**< Outer L2 (MAC) Hdr Length. */
 	};
 };
 
-- 
1.9.3

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-09  3:35  3% ` [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
@ 2016-03-09  3:35  4%   ` Wenzhuo Lu
    2016-03-09  3:35  7%   ` [dpdk-dev] [PATCH v8 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
  1 sibling, 1 reply; 200+ results
From: Wenzhuo Lu @ 2016-03-09  3:35 UTC (permalink / raw)
  To: dev

The names of function for tunnel port configuration are not
accurate. They're tunnel_add/del, better change them to
tunnel_port_add/del.
As it may be an ABI change if change the names directly, the
new functions are added but not remove the old ones. The old
ones will be removed in the next release after an ABI change
announcement.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 app/test-pmd/cmdline.c                 |  6 +++--
 examples/tep_termination/vxlan_setup.c |  2 +-
 lib/librte_ether/rte_ethdev.c          | 45 ++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 32 ++++++++++++++++++++----
 lib/librte_ether/rte_ether_version.map |  7 ++++++
 5 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..0fae655 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6782,9 +6782,11 @@ cmd_tunnel_udp_config_parsed(void *parsed_result,
 		tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
 
 	if (!strcmp(res->what, "add"))
-		ret = rte_eth_dev_udp_tunnel_add(res->port_id, &tunnel_udp);
+		ret = rte_eth_dev_udp_tunnel_port_add(res->port_id,
+						      &tunnel_udp);
 	else
-		ret = rte_eth_dev_udp_tunnel_delete(res->port_id, &tunnel_udp);
+		ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id,
+							 &tunnel_udp);
 
 	if (ret < 0)
 		printf("udp tunneling add error: (%s)\n", strerror(-ret));
diff --git a/examples/tep_termination/vxlan_setup.c b/examples/tep_termination/vxlan_setup.c
index 51ad133..8836603 100644
--- a/examples/tep_termination/vxlan_setup.c
+++ b/examples/tep_termination/vxlan_setup.c
@@ -191,7 +191,7 @@ vxlan_port_init(uint8_t port, struct rte_mempool *mbuf_pool)
 	/* Configure UDP port for UDP tunneling */
 	tunnel_udp.udp_port = udp_port;
 	tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
-	retval = rte_eth_dev_udp_tunnel_add(port, &tunnel_udp);
+	retval = rte_eth_dev_udp_tunnel_port_add(port, &tunnel_udp);
 	if (retval < 0)
 		return retval;
 	rte_eth_macaddr_get(port, &ports_eth_addr[port]);
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..937b348 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1949,6 +1949,28 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,
 }
 
 int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	if (udp_tunnel == NULL) {
+		RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+		return -EINVAL;
+	}
+
+	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
+		RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
+	return (*dev->dev_ops->udp_tunnel_port_add)(dev, udp_tunnel);
+}
+
+int
 rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 			      struct rte_eth_udp_tunnel *udp_tunnel)
 {
@@ -1972,6 +1994,29 @@ rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 }
 
 int
+rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
+				   struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (udp_tunnel == NULL) {
+		RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+		return -EINVAL;
+	}
+
+	if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
+		RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_del, -ENOTSUP);
+	return (*dev->dev_ops->udp_tunnel_port_del)(dev, udp_tunnel);
+}
+
+int
 rte_eth_led_on(uint8_t port_id)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..377dbe7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -740,8 +740,8 @@ struct rte_fdir_conf {
  * UDP tunneling configuration.
  */
 struct rte_eth_udp_tunnel {
-	uint16_t udp_port;
-	uint8_t prot_type;
+	uint16_t udp_port; /**< UDP port used for the tunnel. */
+	uint8_t prot_type; /**< Tunnel type. */
 };
 
 /**
@@ -1261,6 +1261,14 @@ typedef int (*eth_set_eeprom_t)(struct rte_eth_dev *dev,
 				struct rte_dev_eeprom_info *info);
 /**< @internal Program eeprom data  */
 
+typedef int (*eth_udp_tunnel_port_add_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Add tunneling UDP port */
+
+typedef int (*eth_udp_tunnel_port_del_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Delete tunneling UDP port */
+
 #ifdef RTE_NIC_BYPASS
 
 enum {
@@ -1443,6 +1451,10 @@ struct eth_dev_ops {
 	eth_timesync_read_time timesync_read_time;
 	/** Set the device clock time. */
 	eth_timesync_write_time timesync_write_time;
+	/** Add UDP tunnel port. */
+	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
+	/** Del UDP tunnel port. */
+	eth_udp_tunnel_port_del_t udp_tunnel_port_del;
 };
 
 /**
@@ -3387,8 +3399,8 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
 			      struct rte_eth_rss_conf *rss_conf);
 
  /**
- * Add UDP tunneling port of an Ethernet device for filtering a specific
- * tunneling packet by UDP port number.
+ * Add UDP tunneling port for a specific type of tunnel.
+ * The packets with this UDP port will be parsed as this type of tunnel.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
@@ -3401,11 +3413,17 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
  *   - (-ENOTSUP) if hardware doesn't support tunnel type.
  */
 int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
+/* Below is deprecated. Replaced by rte_eth_dev_udp_tunnel_port_add. */
+int
 rte_eth_dev_udp_tunnel_add(uint8_t port_id,
 			   struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
- * Detete UDP tunneling port configuration of Ethernet device
+ * Delete UDP tunneling port a specific type of tunnel.
+ * The packets with this UDP port will not be parsed as this type of tunnel
+ * any more.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
@@ -3418,6 +3436,10 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,
  *   - (-ENOTSUP) if hardware doesn't support tunnel type.
  */
 int
+rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
+				   struct rte_eth_udp_tunnel *tunnel_udp);
+/* Below is deprecated. Replaced by rte_eth_dev_udp_tunnel_port_delete. */
+int
 rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
 			      struct rte_eth_udp_tunnel *tunnel_udp);
 
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..5400717 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_2.3 {
+	global:
+
+	rte_eth_dev_udp_tunnel_port_add;
+	rte_eth_dev_udp_tunnel_port_delete;
+}DPDK_2.2;
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550
    @ 2016-03-09  3:35  3% ` Wenzhuo Lu
  2016-03-09  3:35  4%   ` [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
  2016-03-09  3:35  7%   ` [dpdk-dev] [PATCH v8 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
  2016-03-10  2:42  3% ` [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
  2 siblings, 2 replies; 200+ results
From: Wenzhuo Lu @ 2016-03-09  3:35 UTC (permalink / raw)
  To: dev

v2:
- Update release note.

v3:
- Update RX/TX offload capability.
- Reuse PKT_RX_EIP_CKSUM_BAD but not add a new one.
- Correct the tunnel len for TX, and remove the useless out_l2_len.
- Don't set the tunnel type for TX, and remove the unused ol_flag_nvgre.

v4:
- Fix the issue that not setting the MAC length correctly.

v5:
- Change the behavior of VxLAN port add/del to make it align with i40e.

v6:
- Fix x86_64-native-linuxapp-gcc-shared compile error.

v7:
- Change the return value from hardcode to macro.

v8:
- Add more comments for tunnel port add/del.
- Add ABI change announce.

Wenzhuo Lu (5):
  lib/librte_ether: change function name of tunnel port config
  i40e: rename the tunnel port config functions
  ixgbe: support UDP tunnel port config
  ixgbe: support VxLAN &  NVGRE RX checksum off-load
  ixgbe: support VxLAN &  NVGRE TX checksum off-load

 app/test-pmd/cmdline.c                 |   6 +-
 doc/guides/rel_notes/release_16_04.rst |  14 ++++
 drivers/net/i40e/i40e_ethdev.c         |  22 +++---
 drivers/net/ixgbe/ixgbe_ethdev.c       | 131 +++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_rxtx.c         |  67 ++++++++++++++---
 drivers/net/ixgbe/ixgbe_rxtx.h         |   6 +-
 examples/tep_termination/vxlan_setup.c |   2 +-
 lib/librte_ether/rte_ethdev.c          |  45 +++++++++++
 lib/librte_ether/rte_ethdev.h          |  33 +++++++--
 lib/librte_ether/rte_ether_version.map |   7 ++
 lib/librte_mbuf/rte_mbuf.c             |   2 +-
 lib/librte_mbuf/rte_mbuf.h             |   2 +-
 12 files changed, 304 insertions(+), 33 deletions(-)

-- 
1.9.3

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-09  1:04  0%         ` Thomas Monjalon
@ 2016-03-09  1:25  0%           ` Lu, Wenzhuo
  0 siblings, 0 replies; 200+ results
From: Lu, Wenzhuo @ 2016-03-09  1:25 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 9, 2016 9:04 AM
> To: Lu, Wenzhuo
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name
> of tunnel port config
> 
> 2016-03-09 00:53, Lu, Wenzhuo:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-03-04 10:35, Wenzhuo Lu:
> > > > The names of function for tunnel port configuration are not accurate.
> > > > They're tunnel_add/del, better change them to tunnel_port_add/del.
> > >
> > > As a lot of ethdev API, it is really badly documented.
> > >
> > > Please explain why this renaming and let's try to reword the
> > > doxygen:
> > >  * Add UDP tunneling port of an Ethernet device for filtering a
> > > specific
> > >  * tunneling packet by UDP port number.
> >
> > As we discussed before, these APIs only change the UDP port value of the
> tunnel.
> > But according to their names, seems like they're trying to add/delete a whole
> tunnel.
> > The names don't tell us what the functions really do, so we want to change the
> names.
> 
> Neither the comment nor the name explain what means filtering here.
> I think we should explain more.
> We add a port number and a protocol type. What is it made for?
Prot_type means the tunnel type, VxLAN, GENEVE.., actually it's rte_eth_tunnel_type.
Udp_port means the UDP port value used for the specific type of tunnel.
I'll add some comments in the structure.

> 
> > > Please what are the values of
> > > struct rte_eth_udp_tunnel {
> > >     uint16_t udp_port;
> > >     uint8_t prot_type;
> > > };
> >
> > > When I see an API struct without any comment, I feel it must be dropped.
> > I'm confused.  I don't do anything about this structure. You want me to add
> more comments for it?
> 
> Yes please, comment at least prot_type. Which values to set?
> Any reference to some constants?
I think I've explained this above.

> 
> > > By the way, it is yet another filtering API, so it must be totally reworked.
> >
> > Not quite understand. I only try to change the name. If rework needed, could
> we do this with a new patch?
> 
> I know you are trying to improve the situation :) I'm just saying that the whole
> filtering APIs suck and we need to re-think it.
> But it's another discussion. Let's improve this one for 16.04 while talking about
> future design in other threads.
Great :)

> 
> > > > As it may be an ABI change if change the names directly, the new
> > > > functions are added but not remove the old ones. The old ones will
> > > > be removed in the next release after an ABI change announcement.
> > >
> > > Please make the announce in this patch.
> >
> > Sure, I'll do that.
> 
> Thanks
> 
> > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > @@ -3403,6 +3415,9 @@ rte_eth_dev_rss_hash_conf_get(uint8_t
> > > > port_id, int  rte_eth_dev_udp_tunnel_add(uint8_t port_id,
> > > >  			   struct rte_eth_udp_tunnel *tunnel_udp);
> > >
> > > You must deprecate this one and put a comment above with something
> > > like @see rte_eth_dev_udp_tunnel_port_add.
> > I'll add this. Thanks.
> >
> > >
> > > > +int
> > > > +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> > > > +				struct rte_eth_udp_tunnel *tunnel_udp);
> > >
> > > You must move it below the doxygen comment.
> > OK. Honestly, I'd like to act like that. But seems the style is to put
> > the function above the comment.(Don't know the reason.)
> 
> Do you mean the function below the comment?
No, I really mean above. Like this,
typedef int (*eth_get_reg_t)(struct rte_eth_dev *dev,
				struct rte_dev_reg_info *info);
/**< @internal Retrieve registers  */

typedef int (*eth_get_eeprom_length_t)(struct rte_eth_dev *dev);
/**< @internal Retrieve eeprom size  */

typedef int (*eth_get_eeprom_t)(struct rte_eth_dev *dev,
				struct rte_dev_eeprom_info *info);
/**< @internal Retrieve eeprom data  */

typedef int (*eth_set_eeprom_t)(struct rte_eth_dev *dev,
				struct rte_dev_eeprom_info *info);
/**< @internal Program eeprom data  */

> 
> > It'll be a little strange if I do something different.
> 
> Just check the doxygen output.
> We must have the comments associated with the new function and a
> deprecation comment with the old one.
> 
> > > > --- a/lib/librte_ether/rte_ether_version.map
> > > > +++ b/lib/librte_ether/rte_ether_version.map
> > > > @@ -114,6 +114,8 @@ DPDK_2.2 {
> > > >  	rte_eth_tx_queue_setup;
> > > >  	rte_eth_xstats_get;
> > > >  	rte_eth_xstats_reset;
> > > > +	rte_eth_dev_udp_tunnel_port_add;
> > > > +	rte_eth_dev_udp_tunnel_port_delete;
> > > >
> > > >  	local: *;
> > > >  };
> > >
> > > Panu already made a comment about adding a new section for 16.04.
> >
> > Thanks for the info. Let me follow it.
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-09  0:53  0%       ` Lu, Wenzhuo
@ 2016-03-09  1:04  0%         ` Thomas Monjalon
  2016-03-09  1:25  0%           ` Lu, Wenzhuo
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-09  1:04 UTC (permalink / raw)
  To: Lu, Wenzhuo; +Cc: dev

2016-03-09 00:53, Lu, Wenzhuo:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-03-04 10:35, Wenzhuo Lu:
> > > The names of function for tunnel port configuration are not accurate.
> > > They're tunnel_add/del, better change them to tunnel_port_add/del.
> > 
> > As a lot of ethdev API, it is really badly documented.
> > 
> > Please explain why this renaming and let's try to reword the
> > doxygen:
> >  * Add UDP tunneling port of an Ethernet device for filtering a specific
> >  * tunneling packet by UDP port number.
> 
> As we discussed before, these APIs only change the UDP port value of the tunnel. 
> But according to their names, seems like they're trying to add/delete a whole tunnel.
> The names don't tell us what the functions really do, so we want to change the names.

Neither the comment nor the name explain what means filtering here.
I think we should explain more.
We add a port number and a protocol type. What is it made for?

> > Please what are the values of
> > struct rte_eth_udp_tunnel {
> >     uint16_t udp_port;
> >     uint8_t prot_type;
> > };
> 
> > When I see an API struct without any comment, I feel it must be dropped.
> I'm confused.  I don't do anything about this structure. You want me to add more comments for it?

Yes please, comment at least prot_type. Which values to set?
Any reference to some constants?

> > By the way, it is yet another filtering API, so it must be totally reworked.
> 
> Not quite understand. I only try to change the name. If rework needed, could we do this with a new patch?

I know you are trying to improve the situation :)
I'm just saying that the whole filtering APIs suck and we need to re-think it.
But it's another discussion. Let's improve this one for 16.04 while talking
about future design in other threads.

> > > As it may be an ABI change if change the names directly, the new
> > > functions are added but not remove the old ones. The old ones will be
> > > removed in the next release after an ABI change announcement.
> > 
> > Please make the announce in this patch.
> 
> Sure, I'll do that.

Thanks

> > > --- a/lib/librte_ether/rte_ethdev.h
> > > +++ b/lib/librte_ether/rte_ethdev.h
> > > @@ -3403,6 +3415,9 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
> > > int  rte_eth_dev_udp_tunnel_add(uint8_t port_id,
> > >  			   struct rte_eth_udp_tunnel *tunnel_udp);
> > 
> > You must deprecate this one and put a comment above with something like
> > @see rte_eth_dev_udp_tunnel_port_add.
> I'll add this. Thanks.
> 
> > 
> > > +int
> > > +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> > > +				struct rte_eth_udp_tunnel *tunnel_udp);
> > 
> > You must move it below the doxygen comment.
> OK. Honestly, I'd like to act like that. But seems the style is to put the function above the comment.(Don't know the reason.)

Do you mean the function below the comment?

> It'll be a little strange if I do something different.

Just check the doxygen output.
We must have the comments associated with the new function
and a deprecation comment with the old one.

> > > --- a/lib/librte_ether/rte_ether_version.map
> > > +++ b/lib/librte_ether/rte_ether_version.map
> > > @@ -114,6 +114,8 @@ DPDK_2.2 {
> > >  	rte_eth_tx_queue_setup;
> > >  	rte_eth_xstats_get;
> > >  	rte_eth_xstats_reset;
> > > +	rte_eth_dev_udp_tunnel_port_add;
> > > +	rte_eth_dev_udp_tunnel_port_delete;
> > >
> > >  	local: *;
> > >  };
> > 
> > Panu already made a comment about adding a new section for 16.04.
> 
> Thanks for the info. Let me follow it.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-08 23:35  0%     ` Thomas Monjalon
@ 2016-03-09  0:53  0%       ` Lu, Wenzhuo
  2016-03-09  1:04  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Lu, Wenzhuo @ 2016-03-09  0:53 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 9, 2016 7:35 AM
> To: Lu, Wenzhuo
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name
> of tunnel port config
> 
> 2016-03-04 10:35, Wenzhuo Lu:
> > The names of function for tunnel port configuration are not accurate.
> > They're tunnel_add/del, better change them to tunnel_port_add/del.
> 
> As a lot of ethdev API, it is really badly documented.
> 
> Please explain why this renaming and let's try to reword the
> doxygen:
>  * Add UDP tunneling port of an Ethernet device for filtering a specific
>  * tunneling packet by UDP port number.
As we discussed before, these APIs only change the UDP port value of the tunnel. 
But according to their names, seems like they're trying to add/delete a whole tunnel.
The names don't tell us what the functions really do, so we want to change the names.

> 
> Please what are the values of
> struct rte_eth_udp_tunnel {
>     uint16_t udp_port;
>     uint8_t prot_type;
> };
> When I see an API struct without any comment, I feel it must be dropped.
I'm confused.  I don't do anything about this structure. You want me to add more comments for it?

> 
> By the way, it is yet another filtering API, so it must be totally reworked.
Not quite understand. I only try to change the name. If rework needed, could we do this with a new patch?

> 
> > As it may be an ABI change if change the names directly, the new
> > functions are added but not remove the old ones. The old ones will be
> > removed in the next release after an ABI change announcement.
> 
> Please make the announce in this patch.
Sure, I'll do that.

> 
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -3403,6 +3415,9 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
> > int  rte_eth_dev_udp_tunnel_add(uint8_t port_id,
> >  			   struct rte_eth_udp_tunnel *tunnel_udp);
> 
> You must deprecate this one and put a comment above with something like
> @see rte_eth_dev_udp_tunnel_port_add.
I'll add this. Thanks.

> 
> > +int
> > +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> > +				struct rte_eth_udp_tunnel *tunnel_udp);
> 
> You must move it below the doxygen comment.
OK. Honestly, I'd like to act like that. But seems the style is to put the function above the comment.(Don't know the reason.)
It'll be a little strange if I do something different.

> >
> >   /**
> >   * Detete UDP tunneling port configuration of Ethernet device @@
> > -3420,6 +3435,9 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,  int
> > rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
> >  			      struct rte_eth_udp_tunnel *tunnel_udp);
> > +int
> > +rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
> > +				   struct rte_eth_udp_tunnel *tunnel_udp);
> 
> idem
> 
> > --- a/lib/librte_ether/rte_ether_version.map
> > +++ b/lib/librte_ether/rte_ether_version.map
> > @@ -114,6 +114,8 @@ DPDK_2.2 {
> >  	rte_eth_tx_queue_setup;
> >  	rte_eth_xstats_get;
> >  	rte_eth_xstats_reset;
> > +	rte_eth_dev_udp_tunnel_port_add;
> > +	rte_eth_dev_udp_tunnel_port_delete;
> >
> >  	local: *;
> >  };
> 
> Panu already made a comment about adding a new section for 16.04.
Thanks for the info. Let me follow it.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-03-08 23:35  0%     ` Thomas Monjalon
  2016-03-09  0:53  0%       ` Lu, Wenzhuo
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-08 23:35 UTC (permalink / raw)
  To: Wenzhuo Lu; +Cc: dev

2016-03-04 10:35, Wenzhuo Lu:
> The names of function for tunnel port configuration are not
> accurate. They're tunnel_add/del, better change them to
> tunnel_port_add/del.

As a lot of ethdev API, it is really badly documented.

Please explain why this renaming and let's try to reword the
doxygen:
 * Add UDP tunneling port of an Ethernet device for filtering a specific
 * tunneling packet by UDP port number.

Please what are the values of
struct rte_eth_udp_tunnel {                                                                                      
    uint16_t udp_port;
    uint8_t prot_type;
};
When I see an API struct without any comment, I feel it must be dropped.

By the way, it is yet another filtering API, so it must be totally reworked.

> As it may be an ABI change if change the names directly, the
> new functions are added but not remove the old ones. The old
> ones will be removed in the next release after an ABI change
> announcement.

Please make the announce in this patch.

> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -3403,6 +3415,9 @@ rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
>  int
>  rte_eth_dev_udp_tunnel_add(uint8_t port_id,
>  			   struct rte_eth_udp_tunnel *tunnel_udp);

You must deprecate this one and put a comment above
with something like @see rte_eth_dev_udp_tunnel_port_add.

> +int
> +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> +				struct rte_eth_udp_tunnel *tunnel_udp);

You must move it below the doxygen comment.
>  
>   /**
>   * Detete UDP tunneling port configuration of Ethernet device
> @@ -3420,6 +3435,9 @@ rte_eth_dev_udp_tunnel_add(uint8_t port_id,
>  int
>  rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
>  			      struct rte_eth_udp_tunnel *tunnel_udp);
> +int
> +rte_eth_dev_udp_tunnel_port_delete(uint8_t port_id,
> +				   struct rte_eth_udp_tunnel *tunnel_udp);

idem

> --- a/lib/librte_ether/rte_ether_version.map
> +++ b/lib/librte_ether/rte_ether_version.map
> @@ -114,6 +114,8 @@ DPDK_2.2 {
>  	rte_eth_tx_queue_setup;
>  	rte_eth_xstats_get;
>  	rte_eth_xstats_reset;
> +	rte_eth_dev_udp_tunnel_port_add;
> +	rte_eth_dev_udp_tunnel_port_delete;
>  
>  	local: *;
>  };

Panu already made a comment about adding a new section for 16.04.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  2016-03-08 23:08  0%     ` Thomas Monjalon
@ 2016-03-08 23:20  0%       ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-08 23:20 UTC (permalink / raw)
  To: Xutao Sun; +Cc: dev

2016-03-09 00:08, Thomas Monjalon:
> Hi,
> 
> 2016-03-01 16:41, Xutao Sun:
> > --- a/doc/guides/rel_notes/release_16_04.rst
> > +++ b/doc/guides/rel_notes/release_16_04.rst
> > @@ -123,6 +123,8 @@ ABI Changes
> >    the previous releases and made in this release. Use fixed width quotes for
> >    ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
> >  
> > +* The fields of outer_mac and inner_mac were changed from pointer
> > +  to struct in order to keep the code's readability.
> 
> It is an API change. Proof: you changed the testpmd code.

Please move it and reword to precise the ethdev context.
Also the fields should be enclosed with backquotes as in the template.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] ethdev: fix byte order inconsistence between fdir flow and mask
  @ 2016-03-08 23:12  0%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-08 23:12 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

Hi Jingjing,

2016-02-01 10:48, Jingjing Wu:
> @@ -39,6 +43,8 @@ API Changes
>  ABI Changes
>  -----------
>  
> +* The fields in ethdev structure ``rte_eth_fdir_masks`` were
> +  changed to be in big endian.

I think it is an API change.
Please could you fix it? Thanks

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  @ 2016-03-08 23:08  0%     ` Thomas Monjalon
  2016-03-08 23:20  0%       ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-08 23:08 UTC (permalink / raw)
  To: Xutao Sun; +Cc: dev

Hi,

2016-03-01 16:41, Xutao Sun:
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -123,6 +123,8 @@ ABI Changes
>    the previous releases and made in this release. Use fixed width quotes for
>    ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
>  
> +* The fields of outer_mac and inner_mac were changed from pointer
> +  to struct in order to keep the code's readability.

It is an API change. Proof: you changed the testpmd code.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3 2/3] pci: remove config of extended tag
  2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 0/3] enable extended tag for i40e Thomas Monjalon
@ 2016-03-08 18:38  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-08 18:38 UTC (permalink / raw)
  To: helin.zhang; +Cc: dev

From: Helin Zhang <helin.zhang@intel.com>

Remove pci configuration of 'extended tag' and 'max read request
size', as they are not required by all devices and it lets PMD to
configure them if necessary.
In addition, 'pci_config_space_set()' is deprecated.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 config/common_base                      |  1 +
 doc/guides/rel_notes/deprecation.rst    |  5 ++
 lib/librte_eal/common/eal_common_pci.c  |  7 ---
 lib/librte_eal/common/include/rte_pci.h |  5 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c   | 90 +++------------------------------
 5 files changed, 16 insertions(+), 92 deletions(-)

diff --git a/config/common_base b/config/common_base
index 1af28c8..c73f71a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -102,6 +102,7 @@ CONFIG_RTE_EAL_PMD_PATH=""
 
 #
 # Special configurations in PCI Config Space for high performance
+# They are all deprecated, and will be removed later.
 #
 CONFIG_RTE_PCI_CONFIG=n
 CONFIG_RTE_PCI_EXTENDED_TAG=""
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9930b5a..9979982 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,11 @@ API and ABI deprecation notices are to be posted here.
 Deprecation Notices
 -------------------
 
+* The EAL function pci_config_space_set is deprecated in release 16.04
+  and will be removed from 16.07.
+  Macros CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and
+  CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE will be removed.
+
 * The following fields have been deprecated in rte_eth_stats:
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 96d5113..366fb46 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -180,13 +180,6 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
 		}
 
 		if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-#ifdef RTE_PCI_CONFIG
-			/*
-			 * Set PCIe config space for high performance.
-			 * Return value can be ignored.
-			 */
-			pci_config_space_set(dev);
-#endif
 			/* map resources for devices that use igb_uio */
 			ret = rte_eal_pci_map_device(dev);
 			if (ret != 0)
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 067e084..e692094 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -578,14 +578,17 @@ void rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
 			      const void *data, size_t len, off_t offset);
 
 #ifdef RTE_PCI_CONFIG
+#include <rte_common.h>
 /**
  * Set special config space registers for performance purpose.
+ * It is deprecated, as all configurations have been moved into
+ * each PMDs respectively.
  *
  * @param dev
  *   A pointer to a rte_pci_device structure describing the device
  *   to use
  */
-void pci_config_space_set(struct rte_pci_device *dev);
+void pci_config_space_set(struct rte_pci_device *dev) __rte_deprecated;
 #endif /* RTE_PCI_CONFIG */
 
 #ifdef __cplusplus
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 4346973..4c45452 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -482,92 +482,14 @@ error:
 }
 
 #ifdef RTE_PCI_CONFIG
-static int
-pci_config_extended_tag(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ];
-	FILE *f;
-
-	/* not configured, let it as is */
-	if (strncmp(RTE_PCI_EXTENDED_TAG, "on", 2) != 0 &&
-		strncmp(RTE_PCI_EXTENDED_TAG, "off", 3) != 0)
-		return 0;
-
-	snprintf(filename, sizeof(filename),
-		SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/" "extended_tag",
-		loc->domain, loc->bus, loc->devid, loc->function);
-	f = fopen(filename, "rw+");
-	if (!f)
-		return -1;
-
-	fgets(buf, sizeof(buf), f);
-	if (strncmp(RTE_PCI_EXTENDED_TAG, "on", 2) == 0) {
-		/* enable Extended Tag*/
-		if (strncmp(buf, "on", 2) != 0) {
-			fseek(f, 0, SEEK_SET);
-			fputs("on", f);
-		}
-	} else {
-		/* disable Extended Tag */
-		if (strncmp(buf, "off", 3) != 0) {
-			fseek(f, 0, SEEK_SET);
-			fputs("off", f);
-		}
-	}
-	fclose(f);
-
-	return 0;
-}
-
-static int
-pci_config_max_read_request_size(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ], param[BUFSIZ];
-	FILE *f;
-	/* size can be 128, 256, 512, 1024, 2048, 4096 */
-	uint32_t max_size = RTE_PCI_MAX_READ_REQUEST_SIZE;
-
-	/* not configured, let it as is */
-	if (!max_size)
-		return 0;
-
-	snprintf(filename, sizeof(filename),
-		SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/" "max_read_request_size",
-			loc->domain, loc->bus, loc->devid, loc->function);
-	f = fopen(filename, "rw+");
-	if (!f)
-		return -1;
-
-	fgets(buf, sizeof(buf), f);
-	snprintf(param, sizeof(param), "%d", max_size);
-
-	/* check if the size to be set is the same as current */
-	if (strcmp(buf, param) == 0) {
-		fclose(f);
-		return 0;
-	}
-	fseek(f, 0, SEEK_SET);
-	fputs(param, f);
-	fclose(f);
-
-	return 0;
-}
-
+/*
+ * It is deprecated, all its configurations have been moved into
+ * each PMD respectively.
+ */
 void
-pci_config_space_set(struct rte_pci_device *dev)
+pci_config_space_set(__rte_unused struct rte_pci_device *dev)
 {
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return;
-
-	/* configure extended tag */
-	pci_config_extended_tag(dev);
-
-	/* configure max read request size */
-	pci_config_max_read_request_size(dev);
+	RTE_LOG(DEBUG, EAL, "Nothing here, as it is deprecated\n");
 }
 #endif
 
-- 
2.7.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 0/3] enable extended tag for i40e
    @ 2016-03-08 18:38  3%   ` Thomas Monjalon
  2016-03-08 18:38  4%     ` [dpdk-dev] [PATCH v3 2/3] pci: remove config of extended tag Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-08 18:38 UTC (permalink / raw)
  To: helin.zhang; +Cc: dev

It enables 'extended tag' for i40e devices only during its port
initialization, which is key for 40G performance. It also deprecates
the similar in igb_uio, and eal lib.

v3:
 - fix build with deprecated attribute
 - keep deprecated attribute
 - reword release notes a bit
 - revert doc move from v2
 - better split the patches

v2:
 - Changed the type of return value of i40e_enable_extended_tag() to 'void'.
 - Fixed the compile warnings.
 - Kept the sys files as they were, and added ABI change announcement for them.
 - Moved high performance part of i40e from 'GSG' to a new for .nics'.

Helin Zhang (3):
  i40e: enable extended tag
  pci: remove config of extended tag
  igb_uio: deprecate extended tag

 config/common_base                        |  1 +
 doc/guides/linux_gsg/enable_func.rst      | 27 ++++------
 doc/guides/rel_notes/deprecation.rst      |  7 +++
 doc/guides/rel_notes/release_16_04.rst    |  6 +++
 drivers/net/i40e/i40e_ethdev.c            | 65 ++++++++++++++++++++--
 lib/librte_eal/common/eal_common_pci.c    |  7 ---
 lib/librte_eal/common/include/rte_pci.h   |  5 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c     | 90 +++----------------------------
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 72 +++----------------------
 9 files changed, 104 insertions(+), 176 deletions(-)

-- 
2.7.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files
  @ 2016-03-08 18:02  0%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-08 18:02 UTC (permalink / raw)
  To: Helin Zhang; +Cc: dev

2016-02-22 11:59, Helin Zhang:
> It deprecated sys files of 'extended_tag' and
> 'max_read_request_size', and announced the planned ABI changes of
> them.
[...]
>  - Moved high performance part of i40e from 'GSG' to a new for .nics'.

This change is not related to extended tag only.
Let's move the docs after Jingjing have created i40e.rst.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v5 1/2] librte_pipeline: add support for packet redirection at action handlers
  @ 2016-03-08 18:07  2% ` Jasvinder Singh
  0 siblings, 0 replies; 200+ results
From: Jasvinder Singh @ 2016-03-08 18:07 UTC (permalink / raw)
  To: dev

Currently, there is no mechanism that allows the pipeline ports (in/out)
and table action handlers to override the default forwarding decision
(as previously configured per input port or in the table entry). The port
(in/out) and table action handler prototypes have been changed to allow
pipeline action handlers (port in/out, table) to remove the selected
packets from the further pipeline processing and to take full ownership
for these packets. This feature will be helpful to implement functions
such as exception handling (e.g. TTL =0), load balancing etc.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
v5
* separating patch into two commits.

v4
* merged library and app commits

v3
* improved comments in "rte_pipeline.h"

v2
* rebased on master

 app/test-pipeline/pipeline_acl.c                   |   3 +-
 app/test-pipeline/pipeline_hash.c                  |   3 +-
 app/test-pipeline/pipeline_lpm.c                   |   3 +-
 app/test-pipeline/pipeline_lpm_ipv6.c              |   3 +-
 app/test-pipeline/pipeline_stub.c                  |   3 +-
 app/test/test_table_acl.c                          |   3 +-
 app/test/test_table_pipeline.c                     |   9 +-
 doc/guides/rel_notes/deprecation.rst               |   5 -
 doc/guides/rel_notes/release_16_04.rst             |   6 +-
 .../ip_pipeline/pipeline/pipeline_actions_common.h |  43 +-
 .../ip_pipeline/pipeline/pipeline_firewall_be.c    |   3 +-
 .../pipeline/pipeline_flow_actions_be.c            |   3 +-
 .../pipeline/pipeline_flow_classification_be.c     |   3 +-
 .../ip_pipeline/pipeline/pipeline_passthrough_be.c |   3 +-
 .../ip_pipeline/pipeline/pipeline_routing_be.c     |   3 +-
 lib/librte_pipeline/Makefile                       |   4 +-
 lib/librte_pipeline/rte_pipeline.c                 | 441 ++++++++++-----------
 lib/librte_pipeline/rte_pipeline.h                 |  67 ++--
 18 files changed, 289 insertions(+), 319 deletions(-)

diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c
index f163e55..22d5f36 100644
--- a/app/test-pipeline/pipeline_acl.c
+++ b/app/test-pipeline/pipeline_acl.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -159,7 +159,6 @@ app_main_loop_worker_pipeline_acl(void) {
 			.ops = &rte_port_ring_writer_ops,
 			.arg_create = (void *) &port_ring_params,
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 8b888d7..f8aac0d 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -140,7 +140,6 @@ app_main_loop_worker_pipeline_hash(void) {
 			.ops = &rte_port_ring_writer_ops,
 			.arg_create = (void *) &port_ring_params,
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c
index 2d7bc01..916abd4 100644
--- a/app/test-pipeline/pipeline_lpm.c
+++ b/app/test-pipeline/pipeline_lpm.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,6 @@ app_main_loop_worker_pipeline_lpm(void) {
 			.ops = &rte_port_ring_writer_ops,
 			.arg_create = (void *) &port_ring_params,
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c
index c895b62..3352e89 100644
--- a/app/test-pipeline/pipeline_lpm_ipv6.c
+++ b/app/test-pipeline/pipeline_lpm_ipv6.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -100,7 +100,6 @@ app_main_loop_worker_pipeline_lpm_ipv6(void) {
 			.ops = &rte_port_ring_writer_ops,
 			.arg_create = (void *) &port_ring_params,
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c
index 0ad6f9b..ba710ca 100644
--- a/app/test-pipeline/pipeline_stub.c
+++ b/app/test-pipeline/pipeline_stub.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -94,7 +94,6 @@ app_main_loop_worker_pipeline_stub(void) {
 			.ops = &rte_port_ring_writer_ops,
 			.arg_create = (void *) &port_ring_params,
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
index 38e3a8e..b3bfda4 100644
--- a/app/test/test_table_acl.c
+++ b/app/test/test_table_acl.c
@@ -702,7 +702,8 @@ test_pipeline_single_filter(int expected_count)
 	}
 
 	/* Run pipeline once */
-	rte_pipeline_run(p);
+	for (i = 0; i< N_PORTS; i++)
+		rte_pipeline_run(p);
 
 	rte_pipeline_flush(p);
 
diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
index ff07cda..4bcce2b 100644
--- a/app/test/test_table_pipeline.c
+++ b/app/test/test_table_pipeline.c
@@ -433,7 +433,8 @@ test_pipeline_single_filter(int test_type, int expected_count)
 	RTE_LOG(INFO, PIPELINE, "%s: **** Running %s test\n",
 		__func__, pipeline_test_names[test_type]);
 	/* Run pipeline once */
-	rte_pipeline_run(p);
+	for (i = 0; i < N_PORTS; i++)
+		rte_pipeline_run(p);
 
 
 	ret = rte_pipeline_flush(NULL);
@@ -469,7 +470,8 @@ test_pipeline_single_filter(int test_type, int expected_count)
 		}
 
 	/* Run pipeline once */
-	rte_pipeline_run(p);
+	for (i = 0; i < N_PORTS; i++)
+		rte_pipeline_run(p);
 
    /*
 	* need to flush the pipeline, as there may be less hits than the burst
@@ -535,6 +537,7 @@ test_table_pipeline(void)
 	setup_pipeline(e_TEST_STUB);
 	if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
 		return -1;
+#if 0
 
 	/* TEST - one packet per port */
 	action_handler_hit = NULL;
@@ -582,6 +585,8 @@ test_table_pipeline(void)
 		return -1;
 	connect_miss_action_to_table = 0;
 
+#endif
+
 	if (check_pipeline_invalid_params()) {
 		RTE_LOG(INFO, PIPELINE, "%s: Check pipeline invalid params "
 			"failed.\n", __func__);
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9930b5a..b03b533 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -34,8 +34,3 @@ Deprecation Notices
 
 * The scheduler statistics structure will change to allow keeping track of
   RED actions.
-
-* librte_pipeline: The prototype for the pipeline input port, output port
-  and table action handlers will be updated:
-  the pipeline parameter will be added, the packets mask parameter will be
-  either removed (for input port action handler) or made input-only.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 24f15bf..0b1796a 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -142,6 +142,10 @@ ABI Changes
 * The fields in ethdev structure ``rte_eth_fdir_masks`` were changed
   to be in big endian.
 
+* librte_pipeline: The prototype for the pipeline input port, output port
+  and table action handlers are updated:the pipeline parameter is added,
+  the packets mask parameter has been either removed or made input-only.
+
 
 Shared Library Versions
 -----------------------
@@ -168,7 +172,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_mbuf.so.2
      librte_mempool.so.1
      librte_meter.so.1
-     librte_pipeline.so.2
+   + librte_pipeline.so.3
      librte_pmd_bond.so.1
      librte_pmd_ring.so.2
      librte_port.so.2
diff --git a/examples/ip_pipeline/pipeline/pipeline_actions_common.h b/examples/ip_pipeline/pipeline/pipeline_actions_common.h
index aa1dd59..73cf562 100644
--- a/examples/ip_pipeline/pipeline/pipeline_actions_common.h
+++ b/examples/ip_pipeline/pipeline/pipeline_actions_common.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -33,12 +33,19 @@
 #ifndef __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
 #define __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
 
+#include <stdint.h>
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_mbuf.h>
+#include <rte_pipeline.h>
+
 #define PIPELINE_PORT_IN_AH(f_ah, f_pkt_work, f_pkt4_work)		\
 static int								\
 f_ah(									\
+	__rte_unused struct rte_pipeline *p,				\
 	struct rte_mbuf **pkts,						\
 	uint32_t n_pkts,						\
-	uint64_t *pkts_mask,						\
 	void *arg)							\
 {									\
 	uint32_t i;							\
@@ -49,21 +56,18 @@ f_ah(									\
 	for ( ; i < n_pkts; i++)					\
 		f_pkt_work(pkts[i], arg);				\
 									\
-	*pkts_mask = (~0LLU) >> (64 - n_pkts);				\
-									\
 	return 0;							\
 }
 
 #define PIPELINE_TABLE_AH_HIT(f_ah, f_pkt_work, f_pkt4_work)		\
 static int								\
 f_ah(									\
+	__rte_unused struct rte_pipeline *p,				\
 	struct rte_mbuf **pkts,						\
-	uint64_t *pkts_mask,						\
+	uint64_t pkts_in_mask,						\
 	struct rte_pipeline_table_entry **entries,			\
 	void *arg)							\
 {									\
-	uint64_t pkts_in_mask = *pkts_mask;				\
-									\
 	if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {			\
 		uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);	\
 		uint32_t i;						\
@@ -88,13 +92,12 @@ f_ah(									\
 #define PIPELINE_TABLE_AH_MISS(f_ah, f_pkt_work, f_pkt4_work)		\
 static int								\
 f_ah(									\
+	__rte_unused struct rte_pipeline *p,				\
 	struct rte_mbuf **pkts,						\
-	uint64_t *pkts_mask,						\
+	uint64_t pkts_in_mask,						\
 	struct rte_pipeline_table_entry *entry,				\
 	void *arg)							\
 {									\
-	uint64_t pkts_in_mask = *pkts_mask;				\
-									\
 	if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {			\
 		uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);	\
 		uint32_t i;						\
@@ -119,13 +122,14 @@ f_ah(									\
 #define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)	\
 static int								\
 f_ah(									\
+	__rte_unused struct rte_pipeline *p,			\
 	struct rte_mbuf **pkts,						\
-	uint64_t *pkts_mask,						\
+	uint64_t pkts_mask,						\
 	struct rte_pipeline_table_entry **entries,			\
 	void *arg)							\
 {									\
-	uint64_t pkts_in_mask = *pkts_mask;				\
-	uint64_t pkts_out_mask = *pkts_mask;				\
+	uint64_t pkts_in_mask = pkts_mask;				\
+	uint64_t pkts_out_mask = pkts_mask;				\
 	uint64_t time = rte_rdtsc();					\
 									\
 	if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {			\
@@ -134,13 +138,13 @@ f_ah(									\
 									\
 		for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {		\
 			uint64_t mask = f_pkt4_work(&pkts[i],		\
-				&entries[i], arg, time);	\
+				&entries[i], arg, time);		\
 			pkts_out_mask ^= mask << i;			\
 		}							\
 									\
 		for ( ; i < n_pkts; i++) {				\
 			uint64_t mask = f_pkt_work(pkts[i],		\
-				entries[i], arg, time);		\
+				entries[i], arg, time);			\
 			pkts_out_mask ^= mask << i;			\
 		}							\
 	} else								\
@@ -154,20 +158,20 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
-	*pkts_mask = pkts_out_mask;					\
 	return 0;							\
 }
 
 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)	\
 static int								\
 f_ah(									\
+	__rte_unused struct rte_pipeline *p,			\
 	struct rte_mbuf **pkts,						\
-	uint64_t *pkts_mask,						\
+	uint64_t pkts_mask,						\
 	struct rte_pipeline_table_entry *entry,				\
 	void *arg)							\
 {									\
-	uint64_t pkts_in_mask = *pkts_mask;				\
-	uint64_t pkts_out_mask = *pkts_mask;				\
+	uint64_t pkts_in_mask = pkts_mask;				\
+	uint64_t pkts_out_mask = pkts_mask;				\
 	uint64_t time = rte_rdtsc();					\
 									\
 	if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {			\
@@ -195,7 +199,6 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
-	*pkts_mask = pkts_out_mask;					\
 	return 0;							\
 }
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
index 1981cc7..e7a8a4c 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -450,7 +450,6 @@ pipeline_firewall_init(struct pipeline_params *params,
 			.arg_create = pipeline_port_out_params_convert(
 				&params->port_out[i]),
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
index 0dfdb05..3ad3ee6 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -624,7 +624,6 @@ static void *pipeline_fa_init(struct pipeline_params *params,
 			.arg_create = pipeline_port_out_params_convert(
 				&params->port_out[i]),
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
index c528dfb..60e9c39 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -462,7 +462,6 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.arg_create = pipeline_port_out_params_convert(
 				&params->port_out[i]),
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
index 630de3b..3e3fdd0 100644
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -499,7 +499,6 @@ pipeline_passthrough_init(struct pipeline_params *params,
 			.arg_create = pipeline_port_out_params_convert(
 				&params->port_out[i]),
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
index 4fb6b59..8342b7b 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -1264,7 +1264,6 @@ pipeline_routing_init(struct pipeline_params *params,
 			.arg_create = pipeline_port_out_params_convert(
 				&params->port_out[i]),
 			.f_action = NULL,
-			.f_action_bulk = NULL,
 			.arg_ah = NULL,
 		};
 
diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index 1166d3c..822fd41 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_pipeline_version.map
 
-LIBABIVER := 2
+LIBABIVER := 3
 
 #
 # all source are stored in SRCS-y
diff --git a/lib/librte_pipeline/rte_pipeline.c b/lib/librte_pipeline/rte_pipeline.c
index d625fd2..b7a02d6 100644
--- a/lib/librte_pipeline/rte_pipeline.c
+++ b/lib/librte_pipeline/rte_pipeline.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -49,14 +49,30 @@
 #define RTE_TABLE_INVALID                                 UINT32_MAX
 
 #ifdef RTE_PIPELINE_STATS_COLLECT
-#define RTE_PIPELINE_STATS_ADD(counter, val) \
-	({ (counter) += (val); })
 
-#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
-	({ (counter) += __builtin_popcountll(mask); })
+#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)			\
+	({ (p)->n_pkts_ah_drop = __builtin_popcountll(mask); })
+
+#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)			\
+	({ (counter) += (p)->n_pkts_ah_drop; (p)->n_pkts_ah_drop = 0; })
+
+#define RTE_PIPELINE_STATS_TABLE_DROP0(p)				\
+	({ (p)->pkts_drop_mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; })
+
+#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)			\
+({									\
+	uint64_t mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP];	\
+	mask ^= (p)->pkts_drop_mask;					\
+	(counter) += __builtin_popcountll(mask);			\
+})
+
 #else
-#define RTE_PIPELINE_STATS_ADD(counter, val)
-#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
+
+#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)
+#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)
+#define RTE_PIPELINE_STATS_TABLE_DROP0(p)
+#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)
+
 #endif
 
 struct rte_port_in {
@@ -75,6 +91,7 @@ struct rte_port_in {
 	/* List of enabled ports */
 	struct rte_port_in *next;
 
+	/* Statistics */
 	uint64_t n_pkts_dropped_by_ah;
 };
 
@@ -82,12 +99,12 @@ struct rte_port_out {
 	/* Input parameters */
 	struct rte_port_out_ops ops;
 	rte_pipeline_port_out_action_handler f_action;
-	rte_pipeline_port_out_action_handler_bulk f_action_bulk;
 	void *arg_ah;
 
 	/* Handle to low-level port */
 	void *h_port;
 
+	/* Statistics */
 	uint64_t n_pkts_dropped_by_ah;
 };
 
@@ -106,7 +123,7 @@ struct rte_table {
 	/* Handle to the low-level table object */
 	void *h_table;
 
-	/* Stats for this table. */
+	/* Statistics */
 	uint64_t n_pkts_dropped_by_lkp_hit_ah;
 	uint64_t n_pkts_dropped_by_lkp_miss_ah;
 	uint64_t n_pkts_dropped_lkp_hit;
@@ -133,13 +150,16 @@ struct rte_pipeline {
 
 	/* List of enabled ports */
 	uint64_t enabled_port_in_mask;
-	struct rte_port_in *port_in_first;
+	struct rte_port_in *port_in_next;
 
 	/* Pipeline run structures */
 	struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
 	struct rte_pipeline_table_entry *entries[RTE_PORT_IN_BURST_SIZE_MAX];
 	uint64_t action_mask0[RTE_PIPELINE_ACTIONS];
 	uint64_t action_mask1[RTE_PIPELINE_ACTIONS];
+	uint64_t pkts_mask;
+	uint64_t n_pkts_ah_drop;
+	uint64_t pkts_drop_mask;
 } __rte_cache_aligned;
 
 static inline uint32_t
@@ -234,7 +254,9 @@ rte_pipeline_create(struct rte_pipeline_params *params)
 	p->num_ports_out = 0;
 	p->num_tables = 0;
 	p->enabled_port_in_mask = 0;
-	p->port_in_first = NULL;
+	p->port_in_next = NULL;
+	p->pkts_mask = 0;
+	p->n_pkts_ah_drop = 0;
 
 	return p;
 }
@@ -759,9 +781,6 @@ rte_pipeline_port_out_check_params(struct rte_pipeline *p,
 		struct rte_pipeline_port_out_params *params,
 		uint32_t *port_id)
 {
-	rte_pipeline_port_out_action_handler f_ah;
-	rte_pipeline_port_out_action_handler_bulk f_ah_bulk;
-
 	if (p == NULL) {
 		RTE_LOG(ERR, PIPELINE, "%s: pipeline parameter NULL\n",
 			__func__);
@@ -794,7 +813,7 @@ rte_pipeline_port_out_check_params(struct rte_pipeline *p,
 
 	if (params->ops->f_tx == NULL) {
 		RTE_LOG(ERR, PIPELINE,
-				"%s: f_tx function pointer NULL\n", __func__);
+			"%s: f_tx function pointer NULL\n", __func__);
 		return -EINVAL;
 	}
 
@@ -804,15 +823,6 @@ rte_pipeline_port_out_check_params(struct rte_pipeline *p,
 		return -EINVAL;
 	}
 
-	f_ah = params->f_action;
-	f_ah_bulk = params->f_action_bulk;
-	if (((f_ah != NULL) && (f_ah_bulk == NULL)) ||
-	    ((f_ah == NULL) && (f_ah_bulk != NULL))) {
-		RTE_LOG(ERR, PIPELINE, "%s: Action handlers have to be either"
-			"both enabled or both disabled\n", __func__);
-		return -EINVAL;
-	}
-
 	/* Do we have room for one more port? */
 	if (p->num_ports_out == RTE_PIPELINE_PORT_OUT_MAX) {
 		RTE_LOG(ERR, PIPELINE,
@@ -905,7 +915,6 @@ rte_pipeline_port_out_create(struct rte_pipeline *p,
 	/* Save input parameters */
 	memcpy(&port->ops, params->ops, sizeof(struct rte_port_out_ops));
 	port->f_action = params->f_action;
-	port->f_action_bulk = params->f_action_bulk;
 	port->arg_ah = params->arg_ah;
 
 	/* Initialize port internal data structure */
@@ -959,9 +968,8 @@ int
 rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
 {
 	struct rte_port_in *port, *port_prev, *port_next;
-	struct rte_port_in *port_first, *port_last;
 	uint64_t port_mask;
-	uint32_t port_prev_id, port_next_id, port_first_id, port_last_id;
+	uint32_t port_prev_id, port_next_id;
 
 	/* Check input arguments */
 	if (p == NULL) {
@@ -977,6 +985,8 @@ rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
 		return -EINVAL;
 	}
 
+	port = &p->ports_in[port_id];
+
 	/* Return if current input port is already enabled */
 	port_mask = 1LLU << port_id;
 	if (p->enabled_port_in_mask & port_mask)
@@ -990,20 +1000,13 @@ rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
 
 	port_prev = &p->ports_in[port_prev_id];
 	port_next = &p->ports_in[port_next_id];
-	port = &p->ports_in[port_id];
 
 	port_prev->next = port;
 	port->next = port_next;
 
-	/* Update the first and last input ports in the chain */
-	port_first_id = __builtin_ctzll(p->enabled_port_in_mask);
-	port_last_id = 63 - __builtin_clzll(p->enabled_port_in_mask);
-
-	port_first = &p->ports_in[port_first_id];
-	port_last = &p->ports_in[port_last_id];
-
-	p->port_in_first = port_first;
-	port_last->next = NULL;
+	/* Check if list of enabled ports was previously empty */
+	if (p->enabled_port_in_mask == port_mask)
+		p->port_in_next = port;
 
 	return 0;
 }
@@ -1011,9 +1014,9 @@ rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
 int
 rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
 {
-	struct rte_port_in *port_prev, *port_next, *port_first, *port_last;
+	struct rte_port_in *port, *port_prev, *port_next;
 	uint64_t port_mask;
-	uint32_t port_prev_id, port_next_id, port_first_id, port_last_id;
+	uint32_t port_prev_id, port_next_id;
 
 	/* Check input arguments */
 	if (p == NULL) {
@@ -1028,15 +1031,18 @@ rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
 		return -EINVAL;
 	}
 
+	port = &p->ports_in[port_id];
+
 	/* Return if current input port is already disabled */
 	port_mask = 1LLU << port_id;
 	if ((p->enabled_port_in_mask & port_mask) == 0)
 		return 0;
 
+	p->enabled_port_in_mask &= ~port_mask;
+
 	/* Return if no other enabled ports */
-	if (__builtin_popcountll(p->enabled_port_in_mask) == 1) {
-		p->enabled_port_in_mask &= ~port_mask;
-		p->port_in_first = NULL;
+	if (p->enabled_port_in_mask == 0) {
+		p->port_in_next = NULL;
 
 		return 0;
 	}
@@ -1049,17 +1055,10 @@ rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
 	port_next = &p->ports_in[port_next_id];
 
 	port_prev->next = port_next;
-	p->enabled_port_in_mask &= ~port_mask;
-
-	/* Update the first and last input ports in the chain */
-	port_first_id = __builtin_ctzll(p->enabled_port_in_mask);
-	port_last_id = 63 - __builtin_clzll(p->enabled_port_in_mask);
-
-	port_first = &p->ports_in[port_first_id];
-	port_last = &p->ports_in[port_last_id];
 
-	p->port_in_first = port_first;
-	port_last->next = NULL;
+	/* Check if the port which has just been disabled is next to serve */
+	if (port == p->port_in_next)
+		p->port_in_next = port_next;
 
 	return 0;
 }
@@ -1149,28 +1148,32 @@ rte_pipeline_compute_masks(struct rte_pipeline *p, uint64_t pkts_mask)
 
 static inline void
 rte_pipeline_action_handler_port_bulk(struct rte_pipeline *p,
-		uint64_t pkts_mask, uint32_t port_id)
+	uint64_t pkts_mask, uint32_t port_id)
 {
 	struct rte_port_out *port_out = &p->ports_out[port_id];
 
+	p->pkts_mask = pkts_mask;
+
 	/* Output port user actions */
-	if (port_out->f_action_bulk != NULL) {
-		uint64_t mask = pkts_mask;
+	if (port_out->f_action != NULL) {
+		port_out->f_action(p, p->pkts, pkts_mask, port_out->arg_ah);
 
-		port_out->f_action_bulk(p->pkts, &pkts_mask, port_out->arg_ah);
-		p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask ^  mask;
-		RTE_PIPELINE_STATS_ADD_M(port_out->n_pkts_dropped_by_ah,
-				pkts_mask ^  mask);
+		RTE_PIPELINE_STATS_AH_DROP_READ(p,
+			port_out->n_pkts_dropped_by_ah);
 	}
 
 	/* Output port TX */
-	if (pkts_mask != 0)
-		port_out->ops.f_tx_bulk(port_out->h_port, p->pkts, pkts_mask);
+	if (p->pkts_mask != 0)
+		port_out->ops.f_tx_bulk(port_out->h_port,
+			p->pkts,
+			p->pkts_mask);
 }
 
 static inline void
 rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
 {
+	p->pkts_mask = pkts_mask;
+
 	if ((pkts_mask & (pkts_mask + 1)) == 0) {
 		uint64_t n_pkts = __builtin_popcountll(pkts_mask);
 		uint32_t i;
@@ -1185,18 +1188,18 @@ rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
 			if (port_out->f_action == NULL) /* Output port TX */
 				port_out->ops.f_tx(port_out->h_port, pkt);
 			else {
-				uint64_t pkt_mask = 1LLU;
+				uint64_t pkt_mask = 1LLU << i;
 
-				port_out->f_action(pkt, &pkt_mask,
+				port_out->f_action(p,
+					p->pkts,
+					pkt_mask,
 					port_out->arg_ah);
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-					(pkt_mask ^ 1LLU) << i;
 
-				RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
-						pkt_mask ^ 1LLU);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					port_out->n_pkts_dropped_by_ah);
 
 				/* Output port TX */
-				if (pkt_mask != 0)
+				if (pkt_mask & p->pkts_mask)
 					port_out->ops.f_tx(port_out->h_port,
 						pkt);
 			}
@@ -1221,18 +1224,16 @@ rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
 			if (port_out->f_action == NULL) /* Output port TX */
 				port_out->ops.f_tx(port_out->h_port, pkt);
 			else {
-				pkt_mask = 1LLU;
-
-				port_out->f_action(pkt, &pkt_mask,
+				port_out->f_action(p,
+					p->pkts,
+					pkt_mask,
 					port_out->arg_ah);
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-					(pkt_mask ^ 1LLU) << i;
 
-				RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
-						pkt_mask ^ 1LLU);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					port_out->n_pkts_dropped_by_ah);
 
 				/* Output port TX */
-				if (pkt_mask != 0)
+				if (pkt_mask & p->pkts_mask)
 					port_out->ops.f_tx(port_out->h_port,
 						pkt);
 			}
@@ -1244,6 +1245,8 @@ static inline void
 rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
 	uint64_t pkts_mask)
 {
+	p->pkts_mask = pkts_mask;
+
 	if ((pkts_mask & (pkts_mask + 1)) == 0) {
 		uint64_t n_pkts = __builtin_popcountll(pkts_mask);
 		uint32_t i;
@@ -1260,18 +1263,18 @@ rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
 			if (port_out->f_action == NULL) /* Output port TX */
 				port_out->ops.f_tx(port_out->h_port, pkt);
 			else {
-				uint64_t pkt_mask = 1LLU;
+				uint64_t pkt_mask = 1LLU << i;
 
-				port_out->f_action(pkt, &pkt_mask,
+				port_out->f_action(p,
+					p->pkts,
+					pkt_mask,
 					port_out->arg_ah);
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-					(pkt_mask ^ 1LLU) << i;
 
-				RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
-						pkt_mask ^ 1ULL);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					port_out->n_pkts_dropped_by_ah);
 
 				/* Output port TX */
-				if (pkt_mask != 0)
+				if (pkt_mask & p->pkts_mask)
 					port_out->ops.f_tx(port_out->h_port,
 						pkt);
 			}
@@ -1297,18 +1300,16 @@ rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
 			if (port_out->f_action == NULL) /* Output port TX */
 				port_out->ops.f_tx(port_out->h_port, pkt);
 			else {
-				pkt_mask = 1LLU;
-
-				port_out->f_action(pkt, &pkt_mask,
+				port_out->f_action(p,
+					p->pkts,
+					pkt_mask,
 					port_out->arg_ah);
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-					(pkt_mask ^ 1LLU) << i;
 
-				RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
-						pkt_mask ^ 1ULL);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					port_out->n_pkts_dropped_by_ah);
 
 				/* Output port TX */
-				if (pkt_mask != 0)
+				if (pkt_mask & p->pkts_mask)
 					port_out->ops.f_tx(port_out->h_port,
 						pkt);
 			}
@@ -1342,136 +1343,140 @@ rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask)
 int
 rte_pipeline_run(struct rte_pipeline *p)
 {
-	struct rte_port_in *port_in;
-
-	for (port_in = p->port_in_first; port_in != NULL;
-		port_in = port_in->next) {
-		uint64_t pkts_mask;
-		uint32_t n_pkts, table_id;
-
-		/* Input port RX */
-		n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
-			port_in->burst_size);
-		if (n_pkts == 0)
-			continue;
-
-		pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
-		p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
-		p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
-		p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
-		p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
+	struct rte_port_in *port_in = p->port_in_next;
+	uint32_t n_pkts, table_id;
+
+	if (port_in == NULL)
+		return 0;
 
-		/* Input port user actions */
-		if (port_in->f_action != NULL) {
-			uint64_t mask = pkts_mask;
+	/* Input port RX */
+	n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
+		port_in->burst_size);
+	if (n_pkts == 0) {
+		p->port_in_next = port_in->next;
+		return 0;
+	}
 
-			port_in->f_action(p->pkts, n_pkts, &pkts_mask, port_in->arg_ah);
-			mask ^= pkts_mask;
-			p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= mask;
-			RTE_PIPELINE_STATS_ADD_M(port_in->n_pkts_dropped_by_ah, mask);
-		}
+	p->pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
+	p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
+	p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
+	p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
+	p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
 
-		/* Table */
-		for (table_id = port_in->table_id; pkts_mask != 0; ) {
-			struct rte_table *table;
-			uint64_t lookup_hit_mask, lookup_miss_mask;
-
-			/* Lookup */
-			table = &p->tables[table_id];
-			table->ops.f_lookup(table->h_table, p->pkts, pkts_mask,
-					&lookup_hit_mask, (void **) p->entries);
-			lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
-
-			/* Lookup miss */
-			if (lookup_miss_mask != 0) {
-				struct rte_pipeline_table_entry *default_entry =
-					table->default_entry;
-
-				/* Table user actions */
-				if (table->f_action_miss != NULL) {
-					uint64_t mask = lookup_miss_mask;
-
-					table->f_action_miss(p->pkts,
-						&lookup_miss_mask,
-						default_entry, table->arg_ah);
-					mask ^= lookup_miss_mask;
-					p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= mask;
-					RTE_PIPELINE_STATS_ADD_M(
-						table->n_pkts_dropped_by_lkp_miss_ah, mask);
-				}
-
-				/* Table reserved actions */
-				if ((default_entry->action ==
-					RTE_PIPELINE_ACTION_PORT) &&
-					(lookup_miss_mask != 0))
-					rte_pipeline_action_handler_port_bulk(p,
-						lookup_miss_mask,
-						default_entry->port_id);
-				else {
-					uint32_t pos = default_entry->action;
-
-					p->action_mask0[pos] = lookup_miss_mask;
-					if (pos == RTE_PIPELINE_ACTION_DROP) {
-						RTE_PIPELINE_STATS_ADD_M(table->n_pkts_dropped_lkp_miss,
-							lookup_miss_mask);
-					}
-				}
-			}
+	/* Input port user actions */
+	if (port_in->f_action != NULL) {
+		port_in->f_action(p, p->pkts, n_pkts, port_in->arg_ah);
+
+		RTE_PIPELINE_STATS_AH_DROP_READ(p,
+			port_in->n_pkts_dropped_by_ah);
+	}
+
+	/* Table */
+	for (table_id = port_in->table_id; p->pkts_mask != 0; ) {
+		struct rte_table *table;
+		uint64_t lookup_hit_mask, lookup_miss_mask;
 
-			/* Lookup hit */
-			if (lookup_hit_mask != 0) {
-				/* Table user actions */
-				if (table->f_action_hit != NULL) {
-					uint64_t mask = lookup_hit_mask;
-
-					table->f_action_hit(p->pkts,
-						&lookup_hit_mask,
-						p->entries, table->arg_ah);
-					mask ^= lookup_hit_mask;
-					p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= mask;
-					RTE_PIPELINE_STATS_ADD_M(
-						table->n_pkts_dropped_by_lkp_hit_ah, mask);
-				}
-
-				/* Table reserved actions */
-				rte_pipeline_compute_masks(p, lookup_hit_mask);
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-					p->action_mask1[
-						RTE_PIPELINE_ACTION_DROP];
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
-					p->action_mask1[
-						RTE_PIPELINE_ACTION_PORT];
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
-					p->action_mask1[
-						RTE_PIPELINE_ACTION_PORT_META];
-				p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
-					p->action_mask1[
-						RTE_PIPELINE_ACTION_TABLE];
-
-				RTE_PIPELINE_STATS_ADD_M(table->n_pkts_dropped_lkp_hit,
-						p->action_mask1[RTE_PIPELINE_ACTION_DROP]);
+		/* Lookup */
+		table = &p->tables[table_id];
+		table->ops.f_lookup(table->h_table, p->pkts, p->pkts_mask,
+			&lookup_hit_mask, (void **) p->entries);
+		lookup_miss_mask = p->pkts_mask & (~lookup_hit_mask);
+
+		/* Lookup miss */
+		if (lookup_miss_mask != 0) {
+			struct rte_pipeline_table_entry *default_entry =
+				table->default_entry;
+
+			p->pkts_mask = lookup_miss_mask;
+
+			/* Table user actions */
+			if (table->f_action_miss != NULL) {
+				table->f_action_miss(p,
+					p->pkts,
+					lookup_miss_mask,
+					default_entry,
+					table->arg_ah);
+
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					table->n_pkts_dropped_by_lkp_miss_ah);
 			}
 
-			/* Prepare for next iteration */
-			pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
-			table_id = table->table_next_id;
-			p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
+			/* Table reserved actions */
+			if ((default_entry->action == RTE_PIPELINE_ACTION_PORT) &&
+				(p->pkts_mask != 0))
+				rte_pipeline_action_handler_port_bulk(p,
+					p->pkts_mask,
+					default_entry->port_id);
+			else {
+				uint32_t pos = default_entry->action;
+
+				RTE_PIPELINE_STATS_TABLE_DROP0(p);
+
+				p->action_mask0[pos] |= p->pkts_mask;
+
+				RTE_PIPELINE_STATS_TABLE_DROP1(p,
+					table->n_pkts_dropped_lkp_miss);
+			}
 		}
 
-		/* Table reserved action PORT */
-		rte_pipeline_action_handler_port(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
+		/* Lookup hit */
+		if (lookup_hit_mask != 0) {
+			p->pkts_mask = lookup_hit_mask;
+
+			/* Table user actions */
+			if (table->f_action_hit != NULL) {
+				table->f_action_hit(p,
+					p->pkts,
+					lookup_hit_mask,
+					p->entries,
+					table->arg_ah);
+
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					table->n_pkts_dropped_by_lkp_hit_ah);
+			}
 
-		/* Table reserved action PORT META */
-		rte_pipeline_action_handler_port_meta(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
+			/* Table reserved actions */
+			RTE_PIPELINE_STATS_TABLE_DROP0(p);
+			rte_pipeline_compute_masks(p, p->pkts_mask);
+			p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
+				p->action_mask1[
+					RTE_PIPELINE_ACTION_DROP];
+			p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
+				p->action_mask1[
+					RTE_PIPELINE_ACTION_PORT];
+			p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
+				p->action_mask1[
+					RTE_PIPELINE_ACTION_PORT_META];
+			p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
+				p->action_mask1[
+					RTE_PIPELINE_ACTION_TABLE];
+
+			RTE_PIPELINE_STATS_TABLE_DROP1(p,
+				table->n_pkts_dropped_lkp_hit);
+		}
 
-		/* Table reserved action DROP */
-		rte_pipeline_action_handler_drop(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
+		/* Prepare for next iteration */
+		p->pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
+		table_id = table->table_next_id;
+		p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
 	}
 
-	return 0;
+	/* Table reserved action PORT */
+	rte_pipeline_action_handler_port(p,
+		p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
+
+	/* Table reserved action PORT META */
+	rte_pipeline_action_handler_port_meta(p,
+		p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
+
+	/* Table reserved action DROP */
+	rte_pipeline_action_handler_drop(p,
+		p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
+
+	/* Pick candidate for next port IN to serve */
+	p->port_in_next = port_in->next;
+
+	return (int) n_pkts;
 }
 
 int
@@ -1498,25 +1503,11 @@ rte_pipeline_flush(struct rte_pipeline *p)
 
 int
 rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
-		uint32_t port_id, struct rte_mbuf *pkt)
+	uint32_t port_id, struct rte_mbuf *pkt)
 {
 	struct rte_port_out *port_out = &p->ports_out[port_id];
 
-	/* Output port user actions */
-	if (port_out->f_action == NULL)
-		port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
-	else {
-		uint64_t pkt_mask = 1LLU;
-
-		port_out->f_action(pkt, &pkt_mask, port_out->arg_ah);
-
-		if (pkt_mask != 0) /* Output port TX */
-			port_out->ops.f_tx(port_out->h_port, pkt);
-		else {
-			rte_pktmbuf_free(pkt);
-			RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah, 1);
-		}
-	}
+	port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
 
 	return 0;
 }
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 7302a62..0b02969 100644
--- a/lib/librte_pipeline/rte_pipeline.h
+++ b/lib/librte_pipeline/rte_pipeline.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -142,12 +142,12 @@ struct rte_pipeline_table_stats {
 	/** Number of packets dropped by lookup miss action handler. */
 	uint64_t n_pkts_dropped_by_lkp_miss_ah;
 
-	/** Number of packets dropped by pipeline in behalf of this table based on
-	 * on action specified in table entry. */
+	/** Number of packets dropped by pipeline in behalf of this
+	 * table based on action specified in table entry. */
 	uint64_t n_pkts_dropped_lkp_hit;
 
-	/** Number of packets dropped by pipeline in behalf of this table based on
-	 * on action specified in table entry. */
+	/** Number of packets dropped by pipeline in behalf of this
+	 *  table based on action specified in table entry. */
 	uint64_t n_pkts_dropped_lkp_miss;
 };
 
@@ -187,7 +187,7 @@ int rte_pipeline_check(struct rte_pipeline *p);
  * @param p
  *   Handle to pipeline instance
  * @return
- *   0 on success, error code otherwise
+ *   Number of packets read and processed
  */
 int rte_pipeline_run(struct rte_pipeline *p);
 
@@ -263,6 +263,8 @@ struct rte_pipeline_table_entry {
  * required not to free the packet buffer, which will be freed eventually by
  * the pipeline.
  *
+ * @param p
+ *   Handle to pipeline instance
  * @param pkts
  *   Burst of input packets specified as array of up to 64 pointers to struct
  *   rte_mbuf
@@ -283,8 +285,9 @@ struct rte_pipeline_table_entry {
  *   0 on success, error code otherwise
  */
 typedef int (*rte_pipeline_table_action_handler_hit)(
+	struct rte_pipeline *p,
 	struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
+	uint64_t pkts_mask,
 	struct rte_pipeline_table_entry **entries,
 	void *arg);
 
@@ -296,6 +299,8 @@ typedef int (*rte_pipeline_table_action_handler_hit)(
  * required not to free the packet buffer, which will be freed eventually by
  * the pipeline.
  *
+ * @param p
+ *   Handle to pipeline instance
  * @param pkts
  *   Burst of input packets specified as array of up to 64 pointers to struct
  *   rte_mbuf
@@ -316,8 +321,9 @@ typedef int (*rte_pipeline_table_action_handler_hit)(
  *   0 on success, error code otherwise
  */
 typedef int (*rte_pipeline_table_action_handler_miss)(
+	struct rte_pipeline *p,
 	struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
+	uint64_t pkts_mask,
 	struct rte_pipeline_table_entry *entry,
 	void *arg);
 
@@ -565,16 +571,14 @@ int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
  * required not to free the packet buffer, which will be freed eventually by
  * the pipeline.
  *
+ * @param p
+ *   Handle to pipeline instance
  * @param pkts
  *   Burst of input packets specified as array of up to 64 pointers to struct
  *   rte_mbuf
  * @param n
  *   Number of packets in the input burst. This parameter specifies that
  *   elements 0 to (n-1) of pkts array are valid.
- * @param pkts_mask
- *   64-bit bitmask specifying which packets in the input burst are still valid
- *   after the action handler is executed. When pkts_mask bit n is set, then
- *   element n of pkts array is pointing to a valid packet.
  * @param arg
  *   Opaque parameter registered by the user at the pipeline table creation
  *   time
@@ -582,9 +586,9 @@ int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
  *   0 on success, error code otherwise
  */
 typedef int (*rte_pipeline_port_in_action_handler)(
+	struct rte_pipeline *p,
 	struct rte_mbuf **pkts,
 	uint32_t n,
-	uint64_t *pkts_mask,
 	void *arg);
 
 /** Parameters for pipeline input port creation */
@@ -692,36 +696,15 @@ int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
 #define RTE_PIPELINE_PORT_OUT_MAX                                   64
 
 /**
- * Pipeline output port action handler for single packet
- *
- * The action handler can decide to drop packets by resetting the pkt_mask
- * argument. In this case, the action handler is required not to free the
- * packet buffer, which will be freed eventually by the pipeline.
- *
- * @param pkt
- *   Input packet
- * @param pkt_mask
- *   Output argument set to 0 when the action handler decides to drop the input
- *   packet and to 1LLU otherwise
- * @param arg
- *   Opaque parameter registered by the user at the pipeline table creation
- *   time
- * @return
- *   0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_out_action_handler)(
-	struct rte_mbuf *pkt,
-	uint64_t *pkt_mask,
-	void *arg);
-
-/**
- * Pipeline output port action handler bulk
+ * Pipeline output port action handler
  *
  * The action handler can decide to drop packets by resetting the associated
  * packet bit in the pkts_mask parameter. In this case, the action handler is
  * required not to free the packet buffer, which will be freed eventually by
  * the pipeline.
  *
+ * @param p
+ *   Handle to pipeline instance
  * @param pkts
  *   Burst of input packets specified as array of up to 64 pointers to struct
  *   rte_mbuf
@@ -735,9 +718,10 @@ typedef int (*rte_pipeline_port_out_action_handler)(
  * @return
  *   0 on success, error code otherwise
  */
-typedef int (*rte_pipeline_port_out_action_handler_bulk)(
+typedef int (*rte_pipeline_port_out_action_handler)(
+	struct rte_pipeline *p,
 	struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
+	uint64_t pkts_mask,
 	void *arg);
 
 /** Parameters for pipeline output port creation. The action handlers have to
@@ -750,12 +734,9 @@ struct rte_pipeline_port_out_params {
 	/** Opaque parameter to be passed to create operation when invoked */
 	void *arg_create;
 
-	/** Callback function executing the user actions on single input
-	packet */
-	rte_pipeline_port_out_action_handler f_action;
 	/** Callback function executing the user actions on bust of input
 	packets */
-	rte_pipeline_port_out_action_handler_bulk f_action_bulk;
+	rte_pipeline_port_out_action_handler f_action;
 	/** Opaque parameter to be passed to the action handler when invoked */
 	void *arg_ah;
 };
-- 
2.5.0

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port
  2016-03-08  8:36  4%     ` Dumitrescu, Cristian
  2016-03-08  9:06  4%       ` Panu Matilainen
@ 2016-03-08 10:14  4%       ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-08 10:14 UTC (permalink / raw)
  To: Dumitrescu, Cristian; +Cc: dev

2016-03-08 08:36, Dumitrescu, Cristian:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > If this struct is used in a table, changing its size will break the ABI.
> 
> This structure is already present in the API of the source port in file librte_port/rte_port_source_sink.h, this patch is simply adding two new fields at the end of it. I think we accepted adding parameters at the end of the API parameter structures in other parts of DPDK without considering them ABI breakages?

It depends of the struct but generally it is considered an ABI break.

> Per Panu's previous comment, this structure is indeed used within an array of unions in the ip_pipeline application, but (1) it is very unlikely a "regular" user application will use it this same way; and (2) somebody using the ip_pipeline application will upgrade both the library and the application at the same time.
> 
> If you guys still think this is breaking the ABI, please let us know asap and we'll go with your suggestion.

Yes it is.

> > More generally, are you sure of the benefits of exposing a configuration
> > structure in the API?
> 
> This is not an internal (implementation side) structure, it is the external (API side) structure with the parameters required from the user for creating this object, I am not sure I understand your comment?

There are 2 ways of passing parameters: struct or individual params.
By using some functions with individual params, you can avoid ABI break
(see librte_compat).
In this case you would have a function pcap_config(). Just an idea.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port
  2016-03-08  8:36  4%     ` Dumitrescu, Cristian
@ 2016-03-08  9:06  4%       ` Panu Matilainen
  2016-03-08 10:14  4%       ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-08  9:06 UTC (permalink / raw)
  To: Dumitrescu, Cristian, Thomas Monjalon, Zhang, Roy Fan; +Cc: dev

On 03/08/2016 10:36 AM, Dumitrescu, Cristian wrote:
>
>
>> -----Original Message-----
>> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>> Sent: Monday, March 7, 2016 11:18 AM
>> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>
>> Cc: dev@dpdk.org; Panu Matilainen <pmatilai@redhat.com>; Dumitrescu,
>> Cristian <cristian.dumitrescu@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support
>> to source port
>>
>> 2016-02-17 11:11, Fan Zhang:
>>> --- a/lib/librte_port/rte_port_source_sink.h
>>> +++ b/lib/librte_port/rte_port_source_sink.h
>>> @@ -53,6 +53,13 @@ extern "C" {
>>>   struct rte_port_source_params {
>>>          /** Pre-initialized buffer pool */
>>>          struct rte_mempool *mempool;
>>> +       /** The full path of the pcap file to read packets from */
>>> +       char *file_name;
>>> +       /** The number of bytes to be read from each packet in the
>>> +        *  pcap file. If this value is 0, the whole packet is read;
>>> +        *  if it is bigger than packet size, the generated packets
>>> +        *  will contain the whole packet */
>>> +       uint32_t n_bytes_per_pkt;
>>>   };
>>
>> If this struct is used in a table, changing its size will break the ABI.
>
> This structure is already present in the API of the source port in file librte_port/rte_port_source_sink.h, this patch is simply adding two new fields at the end of it. I think we accepted adding parameters at the end of the API parameter structures in other parts of DPDK without considering them ABI breakages?
>
> Per Panu's previous comment, this structure is indeed used within an array of unions in the ip_pipeline application, but (1) it is very unlikely a "regular" user application will use it this same way; and (2) somebody using the ip_pipeline application will upgrade both the library and the application at the same time.
>
> If you guys still think this is breaking the ABI, please let us know asap and we'll go with your suggestion.

That it breaks ip_pipeline means it quite obviously is an ABI break. 
Adding elements to end of struct might be borderline okay in some 
limited cases but in general, who's to say a struct is not embedded in 
somebody elses struct in some other program, or in an array? There's no 
room for such guessing if ABI compatibility is to mean anything at all. 
Explicitly breaking the ABI is not a bad thing, lying about it is.

	- Panu -

>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  2016-03-07 13:13  0%     ` Yuanhan Liu
  2016-03-08  1:55  0%       ` Tan, Jianfeng
@ 2016-03-08  8:49  0%       ` Panu Matilainen
  1 sibling, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-08  8:49 UTC (permalink / raw)
  To: Yuanhan Liu, Jianfeng Tan
  Cc: nakajima.yoshihiro, mst, dev, p.fedin, ann.zhuangyanying

On 03/07/2016 03:13 PM, Yuanhan Liu wrote:
> CC'ed EAL hugepage maintainer, which is something you should do when
> send a patch.
>
> On Fri, Feb 05, 2016 at 07:20:24PM +0800, Jianfeng Tan wrote:
>> Originally, there're two cons in using hugepage: a. needs root
>> privilege to touch /proc/self/pagemap, which is a premise to
>> alllocate physically contiguous memseg; b. possibly too many
>> hugepage file are created, especially used with 2M hugepage.
>>
>> For virtual devices, they don't care about physical-contiguity
>> of allocated hugepages at all. Option --single-file is to
>> provide a way to allocate all hugepages into single mem-backed
>> file.
>>
>> Known issue:
>> a. single-file option relys on kernel to allocate numa-affinitive
>> memory.
>> b. possible ABI break, originally, --no-huge uses anonymous memory
>> instead of file-backed way to create memory.
>>
>> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ...
>> @@ -956,6 +961,16 @@ eal_check_common_options(struct internal_config *internal_cfg)
>>   			"be specified together with --"OPT_NO_HUGE"\n");
>>   		return -1;
>>   	}
>> +	if (internal_cfg->single_file && internal_cfg->force_sockets == 1) {
>> +		RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE" cannot "
>> +			"be specified together with --"OPT_SOCKET_MEM"\n");
>> +		return -1;
>> +	}
>> +	if (internal_cfg->single_file && internal_cfg->hugepage_unlink) {
>> +		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
>> +			"be specified together with --"OPT_SINGLE_FILE"\n");
>> +		return -1;
>> +	}
>
> The two limitation doesn't make sense to me.
>
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
>> index 6008533..68ef49a 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_memory.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
>> @@ -1102,20 +1102,54 @@ rte_eal_hugepage_init(void)
>>   	/* get pointer to global configuration */
>>   	mcfg = rte_eal_get_configuration()->mem_config;
>>
>> -	/* hugetlbfs can be disabled */
>> -	if (internal_config.no_hugetlbfs) {
>> -		addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
>> -				MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
>> +	/* when hugetlbfs is disabled or single-file option is specified */
>> +	if (internal_config.no_hugetlbfs || internal_config.single_file) {
>> +		int fd;
>> +		uint64_t pagesize;
>> +		unsigned socket_id = rte_socket_id();
>> +		char filepath[MAX_HUGEPAGE_PATH];
>> +
>> +		if (internal_config.no_hugetlbfs) {
>> +			eal_get_hugefile_path(filepath, sizeof(filepath),
>> +					      "/dev/shm", 0);
>> +			pagesize = RTE_PGSIZE_4K;
>> +		} else {
>> +			struct hugepage_info *hpi;
>> +
>> +			hpi = &internal_config.hugepage_info[0];
>> +			eal_get_hugefile_path(filepath, sizeof(filepath),
>> +					      hpi->hugedir, 0);
>> +			pagesize = hpi->hugepage_sz;
>> +		}
>> +		fd = open(filepath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
>> +		if (fd < 0) {
>> +			RTE_LOG(ERR, EAL, "%s: open %s failed: %s\n",
>> +				__func__, filepath, strerror(errno));
>> +			return -1;
>> +		}
>> +
>> +		if (ftruncate(fd, internal_config.memory) < 0) {
>> +			RTE_LOG(ERR, EAL, "ftuncate %s failed: %s\n",
>> +				filepath, strerror(errno));
>> +			return -1;
>> +		}
>> +
>> +		addr = mmap(NULL, internal_config.memory,
>> +			    PROT_READ | PROT_WRITE,
>> +			    MAP_SHARED | MAP_POPULATE, fd, 0);
>>   		if (addr == MAP_FAILED) {
>> -			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
>> -					strerror(errno));
>> +			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n",
>> +				__func__, strerror(errno));
>>   			return -1;
>>   		}
>>   		mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;
>>   		mcfg->memseg[0].addr = addr;
>> -		mcfg->memseg[0].hugepage_sz = RTE_PGSIZE_4K;
>> +		mcfg->memseg[0].hugepage_sz = pagesize;
>>   		mcfg->memseg[0].len = internal_config.memory;
>> -		mcfg->memseg[0].socket_id = 0;
>> +		mcfg->memseg[0].socket_id = socket_id;
>
> I saw quite few issues:
>
> - Assume I have a system with two hugepage sizes: 1G (x4) and 2M (x512),
>    mounted at /dev/hugepages and /mnt, respectively.
>
>    Here we then got an 5G internal_config.memory, and your code will
>    try to mmap 5G on the first mount point (/dev/hugepages) due to the
>    hardcode logic in your code:
>
>        hpi = &internal_config.hugepage_info[0];
>        eal_get_hugefile_path(filepath, sizeof(filepath),
>        		      hpi->hugedir, 0);
>
>    But it has 4G in total, therefore, it will fails.
>
> - As you stated, socket_id is hardcoded, which could be wrong.
>
> - As stated in above, the option limitation doesn't seem right to me.
>
>    I mean, --single-file should be able to work with --socket-mem option
>    in semantic.
>
>
> And I have been thinking how to deal with those issues properly, and a
> __very immature__ solution come to my mind (which could be simply not
> working), but anyway, here is FYI: we go through the same process to
> handle normal huge page initilization to --single-file option as well.
> But we take different actions or no actions at all at some stages when
> that option is given, which is a bit similiar with the way of handling
> RTE_EAL_SINGLE_FILE_SEGMENTS.
>
> And we create one hugepage file for each node, each page size. For a
> system like mine above (2 nodes), it may populate files like following:
>
> - 1G x 2 on node0
> - 1G x 2 on node1
> - 2M x 256 on node0
> - 2M x 256 on node1
>
> That could normally fit your case. Though 4 nodes looks like the maximum
> node number, --socket-mem option may relieve the limit a bit.
>
> And if we "could" not care the socket_id being set correctly, we could
> just simply allocate one file for each hugepage size. That would work
> well for your container enabling.
>
> BTW, since we already have SINGLE_FILE_SEGMENTS (config) option, adding
> another option --single-file looks really confusing to me.
>
> To me, maybe you could base the SINGLE_FILE_SEGMENTS option, and add
> another option, say --no-sort (I confess this name sucks, but you get
> my point). With that, we could make sure to create as least huge page
> files as possible, to fit your case.

Note that SINGLE_FILE_SEGMENTS is a nasty hack that only the IVSHMEM 
config uses, getting rid of it (by replacing with a runtime switch) 
would be great. OTOH IVSHMEM itself seems to have fallen out of the 
fashion since the memnic driver is unmaintained and broken since dpdk 
2.0... CC'ing the IVSHMEM maintainer in case he has thoughts on this.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port
  2016-03-07 11:17  3%   ` Thomas Monjalon
@ 2016-03-08  8:36  4%     ` Dumitrescu, Cristian
  2016-03-08  9:06  4%       ` Panu Matilainen
  2016-03-08 10:14  4%       ` Thomas Monjalon
  0 siblings, 2 replies; 200+ results
From: Dumitrescu, Cristian @ 2016-03-08  8:36 UTC (permalink / raw)
  To: Thomas Monjalon, Zhang, Roy Fan; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Monday, March 7, 2016 11:18 AM
> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>
> Cc: dev@dpdk.org; Panu Matilainen <pmatilai@redhat.com>; Dumitrescu,
> Cristian <cristian.dumitrescu@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support
> to source port
> 
> 2016-02-17 11:11, Fan Zhang:
> > --- a/lib/librte_port/rte_port_source_sink.h
> > +++ b/lib/librte_port/rte_port_source_sink.h
> > @@ -53,6 +53,13 @@ extern "C" {
> >  struct rte_port_source_params {
> >         /** Pre-initialized buffer pool */
> >         struct rte_mempool *mempool;
> > +       /** The full path of the pcap file to read packets from */
> > +       char *file_name;
> > +       /** The number of bytes to be read from each packet in the
> > +        *  pcap file. If this value is 0, the whole packet is read;
> > +        *  if it is bigger than packet size, the generated packets
> > +        *  will contain the whole packet */
> > +       uint32_t n_bytes_per_pkt;
> >  };
> 
> If this struct is used in a table, changing its size will break the ABI.

This structure is already present in the API of the source port in file librte_port/rte_port_source_sink.h, this patch is simply adding two new fields at the end of it. I think we accepted adding parameters at the end of the API parameter structures in other parts of DPDK without considering them ABI breakages?

Per Panu's previous comment, this structure is indeed used within an array of unions in the ip_pipeline application, but (1) it is very unlikely a "regular" user application will use it this same way; and (2) somebody using the ip_pipeline application will upgrade both the library and the application at the same time.

If you guys still think this is breaking the ABI, please let us know asap and we'll go with your suggestion.

> More generally, are you sure of the benefits of exposing a configuration
> structure in the API?

This is not an internal (implementation side) structure, it is the external (API side) structure with the parameters required from the user for creating this object, I am not sure I understand your comment?


> 
> [...]
> > --- a/mk/rte.app.mk
> > +++ b/mk/rte.app.mk
> > @@ -111,6 +111,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT)
> += -lxenstore
> >  _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lgxio
> >  # QAT PMD has a dependency on libcrypto (from openssl) for calculating
> HMAC precomputes
> >  _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)        += -lcrypto
> > +_LDLIBS-$(CONFIG_RTE_PORT_PCAP)                        += -lpcap
> 
> Please move this line upper before PMD_PCAP.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  2016-03-08  1:55  0%       ` Tan, Jianfeng
@ 2016-03-08  2:44  0%         ` Yuanhan Liu
  2016-03-09 14:44  0%           ` Tan, Jianfeng
  0 siblings, 1 reply; 200+ results
From: Yuanhan Liu @ 2016-03-08  2:44 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: nakajima.yoshihiro, mst, dev, p.fedin, ann.zhuangyanying

On Tue, Mar 08, 2016 at 09:55:10AM +0800, Tan, Jianfeng wrote:
> Hi Yuanhan,
> 
> On 3/7/2016 9:13 PM, Yuanhan Liu wrote:
> >CC'ed EAL hugepage maintainer, which is something you should do when
> >send a patch.
> 
> Thanks for doing this.
> 
> >
> >On Fri, Feb 05, 2016 at 07:20:24PM +0800, Jianfeng Tan wrote:
> >>Originally, there're two cons in using hugepage: a. needs root
> >>privilege to touch /proc/self/pagemap, which is a premise to
> >>alllocate physically contiguous memseg; b. possibly too many
> >>hugepage file are created, especially used with 2M hugepage.
> >>
> >>For virtual devices, they don't care about physical-contiguity
> >>of allocated hugepages at all. Option --single-file is to
> >>provide a way to allocate all hugepages into single mem-backed
> >>file.
> >>
> >>Known issue:
> >>a. single-file option relys on kernel to allocate numa-affinitive
> >>memory.
> >>b. possible ABI break, originally, --no-huge uses anonymous memory
> >>instead of file-backed way to create memory.
> >>
> >>Signed-off-by: Huawei Xie <huawei.xie@intel.com>
> >>Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >...
> >>@@ -956,6 +961,16 @@ eal_check_common_options(struct internal_config *internal_cfg)
> >>  			"be specified together with --"OPT_NO_HUGE"\n");
> >>  		return -1;
> >>  	}
> >>+	if (internal_cfg->single_file && internal_cfg->force_sockets == 1) {
> >>+		RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE" cannot "
> >>+			"be specified together with --"OPT_SOCKET_MEM"\n");
> >>+		return -1;
> >>+	}
> >>+	if (internal_cfg->single_file && internal_cfg->hugepage_unlink) {
> >>+		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
> >>+			"be specified together with --"OPT_SINGLE_FILE"\n");
> >>+		return -1;
> >>+	}
> >The two limitation doesn't make sense to me.
> 
> For the force_sockets option, my original thought on --single-file option
> is, we don't sort those pages (require root/cap_sys_admin) and even don't
> look up numa information because it may contain both sockets' memory.
> 
> For the hugepage_unlink option, those hugepage files get closed in the end
> of memory initialization, if we even unlink those hugepage files, so we
> cannot share those with other processes (say backend).

Yeah, I know how the two limitations come, from your implementation. I
was just wondering if they both are __truly__ the limitations. I mean,
can we get rid of them somehow?

For --socket-mem option, if we can't handle it well, or if we could
ignore the socket_id for allocated huge page, yes, the limitation is
a true one.

But for the second option, no, we should be able to co-work it with
well. One extra action is you should not invoke "close(fd)" for those
huge page files. And then you can get all the informations as I stated
in a reply to your 2nd patch.

> >
> >>diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
> >>index 6008533..68ef49a 100644
> >>--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
> >>+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
> >>@@ -1102,20 +1102,54 @@ rte_eal_hugepage_init(void)
> >>  	/* get pointer to global configuration */
> >>  	mcfg = rte_eal_get_configuration()->mem_config;
> >>-	/* hugetlbfs can be disabled */
> >>-	if (internal_config.no_hugetlbfs) {
> >>-		addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
> >>-				MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
> >>+	/* when hugetlbfs is disabled or single-file option is specified */
> >>+	if (internal_config.no_hugetlbfs || internal_config.single_file) {
> >>+		int fd;
> >>+		uint64_t pagesize;
> >>+		unsigned socket_id = rte_socket_id();
> >>+		char filepath[MAX_HUGEPAGE_PATH];
> >>+
> >>+		if (internal_config.no_hugetlbfs) {
> >>+			eal_get_hugefile_path(filepath, sizeof(filepath),
> >>+					      "/dev/shm", 0);
> >>+			pagesize = RTE_PGSIZE_4K;
> >>+		} else {
> >>+			struct hugepage_info *hpi;
> >>+
> >>+			hpi = &internal_config.hugepage_info[0];
> >>+			eal_get_hugefile_path(filepath, sizeof(filepath),
> >>+					      hpi->hugedir, 0);
> >>+			pagesize = hpi->hugepage_sz;
> >>+		}
> >>+		fd = open(filepath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
> >>+		if (fd < 0) {
> >>+			RTE_LOG(ERR, EAL, "%s: open %s failed: %s\n",
> >>+				__func__, filepath, strerror(errno));
> >>+			return -1;
> >>+		}
> >>+
> >>+		if (ftruncate(fd, internal_config.memory) < 0) {
> >>+			RTE_LOG(ERR, EAL, "ftuncate %s failed: %s\n",
> >>+				filepath, strerror(errno));
> >>+			return -1;
> >>+		}
> >>+
> >>+		addr = mmap(NULL, internal_config.memory,
> >>+			    PROT_READ | PROT_WRITE,
> >>+			    MAP_SHARED | MAP_POPULATE, fd, 0);
> >>  		if (addr == MAP_FAILED) {
> >>-			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
> >>-					strerror(errno));
> >>+			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n",
> >>+				__func__, strerror(errno));
> >>  			return -1;
> >>  		}
> >>  		mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;
> >>  		mcfg->memseg[0].addr = addr;
> >>-		mcfg->memseg[0].hugepage_sz = RTE_PGSIZE_4K;
> >>+		mcfg->memseg[0].hugepage_sz = pagesize;
> >>  		mcfg->memseg[0].len = internal_config.memory;
> >>-		mcfg->memseg[0].socket_id = 0;
> >>+		mcfg->memseg[0].socket_id = socket_id;
> >I saw quite few issues:
> >
> >- Assume I have a system with two hugepage sizes: 1G (x4) and 2M (x512),
> >   mounted at /dev/hugepages and /mnt, respectively.
> >
> >   Here we then got an 5G internal_config.memory, and your code will
> >   try to mmap 5G on the first mount point (/dev/hugepages) due to the
> >   hardcode logic in your code:
> >
> >       hpi = &internal_config.hugepage_info[0];
> >       eal_get_hugefile_path(filepath, sizeof(filepath),
> >       		      hpi->hugedir, 0);
> >
> >   But it has 4G in total, therefore, it will fails.
> 
> As mentioned above, this case is not for original design of --single-file.

But it's a so common case, isn't it?

> >
> >- As you stated, socket_id is hardcoded, which could be wrong.
> 
> We rely on OS to allocate hugepages, and cannot promise physical hugepages
> in the big hugepage file are from the same socket.
> 
> >
> >- As stated in above, the option limitation doesn't seem right to me.
> >
> >   I mean, --single-file should be able to work with --socket-mem option
> >   in semantic.
> 
> If we'd like to work well with --socket-mem option, we need to use syscalls
> like set_mempolicy(), mbind(). So it'll bring bigger change related to
> current one. I don't know if it's acceptable?

Yes, if that's the right way to go. But also as you stated, I doubt we
really need handle the numa affinitive here, due to it's complex.

> >
> >
> >And I have been thinking how to deal with those issues properly, and a
> >__very immature__ solution come to my mind (which could be simply not
> >working), but anyway, here is FYI: we go through the same process to
> >handle normal huge page initilization to --single-file option as well.
> >But we take different actions or no actions at all at some stages when
> >that option is given, which is a bit similiar with the way of handling
> >RTE_EAL_SINGLE_FILE_SEGMENTS.
> >
> >And we create one hugepage file for each node, each page size. For a
> >system like mine above (2 nodes), it may populate files like following:
> >
> >- 1G x 2 on node0
> >- 1G x 2 on node1
> >- 2M x 256 on node0
> >- 2M x 256 on node1
> >
> >That could normally fit your case. Though 4 nodes looks like the maximum
> >node number, --socket-mem option may relieve the limit a bit.
> >
> >And if we "could" not care the socket_id being set correctly, we could
> >just simply allocate one file for each hugepage size. That would work
> >well for your container enabling.
> 
> This way seems a good option at first sight. Let's compare this new way with
> original design.
> 
> The original design just covers the simplest scenario:
> a. just one hugetlbfs (new way can provide support for multiple number of
> hugetlbfs)
> b. does not require a root privilege (new way can achieve this by using
> above-mentioned mind() or set_mempolicy() syscall)
> c. no sorting (both way are OK)
> d. performance, from the perspective of virtio for container, we take more
> consideration about the performance of address translation in the vhost. In
> the vhost, now we adopt a O(n) linear comparison to translate address (this
> can be optimized to O(logn) using segment tree, or even better using a
> cache, sorry, it's just another problem), so we should maintain as few files
> as possible. (new way can achieve this by used with --socket-mem,
> --huge-dir)
> e. numa aware is not required (and it's complex). (new way can solve this
> without promise)
> 
> In all, this new way seems great for me.
> 
> Another thing is if "go through the same process to handle normal huge page
> initilization", my consideration is: RTE_EAL_SINGLE_FILE_SEGMENTS goes such
> way to maximize code reuse. But the new way has few common code with
> original ways. And mixing these options together leads to bad readability.
> How do you think?

Indeed. I've already found that the code is a bit hard to read, due to
many "#ifdef ... #else .. #endif" blocks, for RTE_EAL_SINGLE_FILE_SEGMENTS
as well as some special archs.

Therefore, I would suggest to do it as below: add another option based
on the SINGLE_FILE_SEGMENTS implementation.

I mean SINGLE_FILE_SEGMENTS already tries to generate as few files as
possible. If we add another option, say --no-sort (or --no-phys-continuity),
we could add just few lines of code to let it generate one file for
each huge page size (if we don't consider the numa affinity).

> >
> >BTW, since we already have SINGLE_FILE_SEGMENTS (config) option, adding
> >another option --single-file looks really confusing to me.
> >
> >To me, maybe you could base the SINGLE_FILE_SEGMENTS option, and add
> >another option, say --no-sort (I confess this name sucks, but you get
> >my point). With that, we could make sure to create as least huge page
> >files as possible, to fit your case.
> 
> This is a great advice. So how do you think of --converged, or
> --no-scattered-mem, or any better idea?

TBH, none of them looks great to me, either. But I have no better
options. Well, --no-phys-continuity looks like the best option to
me so far :)

	--yliu

> 
> Thanks for valuable input.
> 
> Jianfeng
> 
> >
> >	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  2016-03-07 13:13  0%     ` Yuanhan Liu
@ 2016-03-08  1:55  0%       ` Tan, Jianfeng
  2016-03-08  2:44  0%         ` Yuanhan Liu
  2016-03-08  8:49  0%       ` Panu Matilainen
  1 sibling, 1 reply; 200+ results
From: Tan, Jianfeng @ 2016-03-08  1:55 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: nakajima.yoshihiro, mst, dev, p.fedin, ann.zhuangyanying

Hi Yuanhan,

On 3/7/2016 9:13 PM, Yuanhan Liu wrote:
> CC'ed EAL hugepage maintainer, which is something you should do when
> send a patch.

Thanks for doing this.

>
> On Fri, Feb 05, 2016 at 07:20:24PM +0800, Jianfeng Tan wrote:
>> Originally, there're two cons in using hugepage: a. needs root
>> privilege to touch /proc/self/pagemap, which is a premise to
>> alllocate physically contiguous memseg; b. possibly too many
>> hugepage file are created, especially used with 2M hugepage.
>>
>> For virtual devices, they don't care about physical-contiguity
>> of allocated hugepages at all. Option --single-file is to
>> provide a way to allocate all hugepages into single mem-backed
>> file.
>>
>> Known issue:
>> a. single-file option relys on kernel to allocate numa-affinitive
>> memory.
>> b. possible ABI break, originally, --no-huge uses anonymous memory
>> instead of file-backed way to create memory.
>>
>> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ...
>> @@ -956,6 +961,16 @@ eal_check_common_options(struct internal_config *internal_cfg)
>>   			"be specified together with --"OPT_NO_HUGE"\n");
>>   		return -1;
>>   	}
>> +	if (internal_cfg->single_file && internal_cfg->force_sockets == 1) {
>> +		RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE" cannot "
>> +			"be specified together with --"OPT_SOCKET_MEM"\n");
>> +		return -1;
>> +	}
>> +	if (internal_cfg->single_file && internal_cfg->hugepage_unlink) {
>> +		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
>> +			"be specified together with --"OPT_SINGLE_FILE"\n");
>> +		return -1;
>> +	}
> The two limitation doesn't make sense to me.

For the force_sockets option, my original thought on --single-file 
option is, we don't sort those pages (require root/cap_sys_admin) and 
even don't look up numa information because it may contain both sockets' 
memory.

For the hugepage_unlink option, those hugepage files get closed in the 
end of memory initialization, if we even unlink those hugepage files, so 
we cannot share those with other processes (say backend).

>
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
>> index 6008533..68ef49a 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_memory.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
>> @@ -1102,20 +1102,54 @@ rte_eal_hugepage_init(void)
>>   	/* get pointer to global configuration */
>>   	mcfg = rte_eal_get_configuration()->mem_config;
>>   
>> -	/* hugetlbfs can be disabled */
>> -	if (internal_config.no_hugetlbfs) {
>> -		addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
>> -				MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
>> +	/* when hugetlbfs is disabled or single-file option is specified */
>> +	if (internal_config.no_hugetlbfs || internal_config.single_file) {
>> +		int fd;
>> +		uint64_t pagesize;
>> +		unsigned socket_id = rte_socket_id();
>> +		char filepath[MAX_HUGEPAGE_PATH];
>> +
>> +		if (internal_config.no_hugetlbfs) {
>> +			eal_get_hugefile_path(filepath, sizeof(filepath),
>> +					      "/dev/shm", 0);
>> +			pagesize = RTE_PGSIZE_4K;
>> +		} else {
>> +			struct hugepage_info *hpi;
>> +
>> +			hpi = &internal_config.hugepage_info[0];
>> +			eal_get_hugefile_path(filepath, sizeof(filepath),
>> +					      hpi->hugedir, 0);
>> +			pagesize = hpi->hugepage_sz;
>> +		}
>> +		fd = open(filepath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
>> +		if (fd < 0) {
>> +			RTE_LOG(ERR, EAL, "%s: open %s failed: %s\n",
>> +				__func__, filepath, strerror(errno));
>> +			return -1;
>> +		}
>> +
>> +		if (ftruncate(fd, internal_config.memory) < 0) {
>> +			RTE_LOG(ERR, EAL, "ftuncate %s failed: %s\n",
>> +				filepath, strerror(errno));
>> +			return -1;
>> +		}
>> +
>> +		addr = mmap(NULL, internal_config.memory,
>> +			    PROT_READ | PROT_WRITE,
>> +			    MAP_SHARED | MAP_POPULATE, fd, 0);
>>   		if (addr == MAP_FAILED) {
>> -			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
>> -					strerror(errno));
>> +			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n",
>> +				__func__, strerror(errno));
>>   			return -1;
>>   		}
>>   		mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;
>>   		mcfg->memseg[0].addr = addr;
>> -		mcfg->memseg[0].hugepage_sz = RTE_PGSIZE_4K;
>> +		mcfg->memseg[0].hugepage_sz = pagesize;
>>   		mcfg->memseg[0].len = internal_config.memory;
>> -		mcfg->memseg[0].socket_id = 0;
>> +		mcfg->memseg[0].socket_id = socket_id;
> I saw quite few issues:
>
> - Assume I have a system with two hugepage sizes: 1G (x4) and 2M (x512),
>    mounted at /dev/hugepages and /mnt, respectively.
>
>    Here we then got an 5G internal_config.memory, and your code will
>    try to mmap 5G on the first mount point (/dev/hugepages) due to the
>    hardcode logic in your code:
>
>        hpi = &internal_config.hugepage_info[0];
>        eal_get_hugefile_path(filepath, sizeof(filepath),
>        		      hpi->hugedir, 0);
>
>    But it has 4G in total, therefore, it will fails.

As mentioned above, this case is not for original design of --single-file.

>
> - As you stated, socket_id is hardcoded, which could be wrong.

We rely on OS to allocate hugepages, and cannot promise physical 
hugepages in the big hugepage file are from the same socket.

>
> - As stated in above, the option limitation doesn't seem right to me.
>
>    I mean, --single-file should be able to work with --socket-mem option
>    in semantic.

If we'd like to work well with --socket-mem option, we need to use 
syscalls like set_mempolicy(), mbind(). So it'll bring bigger change 
related to current one. I don't know if it's acceptable?

>
>
> And I have been thinking how to deal with those issues properly, and a
> __very immature__ solution come to my mind (which could be simply not
> working), but anyway, here is FYI: we go through the same process to
> handle normal huge page initilization to --single-file option as well.
> But we take different actions or no actions at all at some stages when
> that option is given, which is a bit similiar with the way of handling
> RTE_EAL_SINGLE_FILE_SEGMENTS.
>
> And we create one hugepage file for each node, each page size. For a
> system like mine above (2 nodes), it may populate files like following:
>
> - 1G x 2 on node0
> - 1G x 2 on node1
> - 2M x 256 on node0
> - 2M x 256 on node1
>
> That could normally fit your case. Though 4 nodes looks like the maximum
> node number, --socket-mem option may relieve the limit a bit.
>
> And if we "could" not care the socket_id being set correctly, we could
> just simply allocate one file for each hugepage size. That would work
> well for your container enabling.

This way seems a good option at first sight. Let's compare this new way 
with original design.

The original design just covers the simplest scenario:
a. just one hugetlbfs (new way can provide support for multiple number 
of hugetlbfs)
b. does not require a root privilege (new way can achieve this by using 
above-mentioned mind() or set_mempolicy() syscall)
c. no sorting (both way are OK)
d. performance, from the perspective of virtio for container, we take 
more consideration about the performance of address translation in the 
vhost. In the vhost, now we adopt a O(n) linear comparison to translate 
address (this can be optimized to O(logn) using segment tree, or even 
better using a cache, sorry, it's just another problem), so we should 
maintain as few files as possible. (new way can achieve this by used 
with --socket-mem, --huge-dir)
e. numa aware is not required (and it's complex). (new way can solve 
this without promise)

In all, this new way seems great for me.

Another thing is if "go through the same process to handle normal huge 
page initilization", my consideration is: RTE_EAL_SINGLE_FILE_SEGMENTS 
goes such way to maximize code reuse. But the new way has few common 
code with original ways. And mixing these options together leads to bad 
readability. How do you think?

>
> BTW, since we already have SINGLE_FILE_SEGMENTS (config) option, adding
> another option --single-file looks really confusing to me.
>
> To me, maybe you could base the SINGLE_FILE_SEGMENTS option, and add
> another option, say --no-sort (I confess this name sucks, but you get
> my point). With that, we could make sure to create as least huge page
> files as possible, to fit your case.

This is a great advice. So how do you think of --converged, or 
--no-scattered-mem, or any better idea?

Thanks for valuable input.

Jianfeng

>
> 	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  @ 2016-03-07 13:13  0%     ` Yuanhan Liu
  2016-03-08  1:55  0%       ` Tan, Jianfeng
  2016-03-08  8:49  0%       ` Panu Matilainen
  0 siblings, 2 replies; 200+ results
From: Yuanhan Liu @ 2016-03-07 13:13 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: nakajima.yoshihiro, mst, dev, p.fedin, ann.zhuangyanying

CC'ed EAL hugepage maintainer, which is something you should do when
send a patch.

On Fri, Feb 05, 2016 at 07:20:24PM +0800, Jianfeng Tan wrote:
> Originally, there're two cons in using hugepage: a. needs root
> privilege to touch /proc/self/pagemap, which is a premise to
> alllocate physically contiguous memseg; b. possibly too many
> hugepage file are created, especially used with 2M hugepage.
> 
> For virtual devices, they don't care about physical-contiguity
> of allocated hugepages at all. Option --single-file is to
> provide a way to allocate all hugepages into single mem-backed
> file.
> 
> Known issue:
> a. single-file option relys on kernel to allocate numa-affinitive
> memory.
> b. possible ABI break, originally, --no-huge uses anonymous memory
> instead of file-backed way to create memory.
> 
> Signed-off-by: Huawei Xie <huawei.xie@intel.com>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
...
> @@ -956,6 +961,16 @@ eal_check_common_options(struct internal_config *internal_cfg)
>  			"be specified together with --"OPT_NO_HUGE"\n");
>  		return -1;
>  	}
> +	if (internal_cfg->single_file && internal_cfg->force_sockets == 1) {
> +		RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE" cannot "
> +			"be specified together with --"OPT_SOCKET_MEM"\n");
> +		return -1;
> +	}
> +	if (internal_cfg->single_file && internal_cfg->hugepage_unlink) {
> +		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
> +			"be specified together with --"OPT_SINGLE_FILE"\n");
> +		return -1;
> +	}

The two limitation doesn't make sense to me.

> diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
> index 6008533..68ef49a 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_memory.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
> @@ -1102,20 +1102,54 @@ rte_eal_hugepage_init(void)
>  	/* get pointer to global configuration */
>  	mcfg = rte_eal_get_configuration()->mem_config;
>  
> -	/* hugetlbfs can be disabled */
> -	if (internal_config.no_hugetlbfs) {
> -		addr = mmap(NULL, internal_config.memory, PROT_READ | PROT_WRITE,
> -				MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
> +	/* when hugetlbfs is disabled or single-file option is specified */
> +	if (internal_config.no_hugetlbfs || internal_config.single_file) {
> +		int fd;
> +		uint64_t pagesize;
> +		unsigned socket_id = rte_socket_id();
> +		char filepath[MAX_HUGEPAGE_PATH];
> +
> +		if (internal_config.no_hugetlbfs) {
> +			eal_get_hugefile_path(filepath, sizeof(filepath),
> +					      "/dev/shm", 0);
> +			pagesize = RTE_PGSIZE_4K;
> +		} else {
> +			struct hugepage_info *hpi;
> +
> +			hpi = &internal_config.hugepage_info[0];
> +			eal_get_hugefile_path(filepath, sizeof(filepath),
> +					      hpi->hugedir, 0);
> +			pagesize = hpi->hugepage_sz;
> +		}
> +		fd = open(filepath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
> +		if (fd < 0) {
> +			RTE_LOG(ERR, EAL, "%s: open %s failed: %s\n",
> +				__func__, filepath, strerror(errno));
> +			return -1;
> +		}
> +
> +		if (ftruncate(fd, internal_config.memory) < 0) {
> +			RTE_LOG(ERR, EAL, "ftuncate %s failed: %s\n",
> +				filepath, strerror(errno));
> +			return -1;
> +		}
> +
> +		addr = mmap(NULL, internal_config.memory,
> +			    PROT_READ | PROT_WRITE,
> +			    MAP_SHARED | MAP_POPULATE, fd, 0);
>  		if (addr == MAP_FAILED) {
> -			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n", __func__,
> -					strerror(errno));
> +			RTE_LOG(ERR, EAL, "%s: mmap() failed: %s\n",
> +				__func__, strerror(errno));
>  			return -1;
>  		}
>  		mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;
>  		mcfg->memseg[0].addr = addr;
> -		mcfg->memseg[0].hugepage_sz = RTE_PGSIZE_4K;
> +		mcfg->memseg[0].hugepage_sz = pagesize;
>  		mcfg->memseg[0].len = internal_config.memory;
> -		mcfg->memseg[0].socket_id = 0;
> +		mcfg->memseg[0].socket_id = socket_id;

I saw quite few issues:

- Assume I have a system with two hugepage sizes: 1G (x4) and 2M (x512),
  mounted at /dev/hugepages and /mnt, respectively.

  Here we then got an 5G internal_config.memory, and your code will
  try to mmap 5G on the first mount point (/dev/hugepages) due to the
  hardcode logic in your code:

      hpi = &internal_config.hugepage_info[0];
      eal_get_hugefile_path(filepath, sizeof(filepath),
      		      hpi->hugedir, 0);

  But it has 4G in total, therefore, it will fails.

- As you stated, socket_id is hardcoded, which could be wrong.

- As stated in above, the option limitation doesn't seem right to me.

  I mean, --single-file should be able to work with --socket-mem option
  in semantic.


And I have been thinking how to deal with those issues properly, and a
__very immature__ solution come to my mind (which could be simply not
working), but anyway, here is FYI: we go through the same process to
handle normal huge page initilization to --single-file option as well.
But we take different actions or no actions at all at some stages when
that option is given, which is a bit similiar with the way of handling
RTE_EAL_SINGLE_FILE_SEGMENTS.

And we create one hugepage file for each node, each page size. For a
system like mine above (2 nodes), it may populate files like following:

- 1G x 2 on node0
- 1G x 2 on node1
- 2M x 256 on node0
- 2M x 256 on node1

That could normally fit your case. Though 4 nodes looks like the maximum
node number, --socket-mem option may relieve the limit a bit.

And if we "could" not care the socket_id being set correctly, we could
just simply allocate one file for each hugepage size. That would work
well for your container enabling.

BTW, since we already have SINGLE_FILE_SEGMENTS (config) option, adding
another option --single-file looks really confusing to me.

To me, maybe you could base the SINGLE_FILE_SEGMENTS option, and add
another option, say --no-sort (I confess this name sucks, but you get
my point). With that, we could make sure to create as least huge page
files as possible, to fit your case.

	--yliu

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port
  @ 2016-03-07 11:17  3%   ` Thomas Monjalon
  2016-03-08  8:36  4%     ` Dumitrescu, Cristian
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-07 11:17 UTC (permalink / raw)
  To: Fan Zhang; +Cc: dev

2016-02-17 11:11, Fan Zhang:
> --- a/lib/librte_port/rte_port_source_sink.h
> +++ b/lib/librte_port/rte_port_source_sink.h
> @@ -53,6 +53,13 @@ extern "C" {
>  struct rte_port_source_params {
>         /** Pre-initialized buffer pool */
>         struct rte_mempool *mempool;
> +       /** The full path of the pcap file to read packets from */
> +       char *file_name;
> +       /** The number of bytes to be read from each packet in the
> +        *  pcap file. If this value is 0, the whole packet is read;
> +        *  if it is bigger than packet size, the generated packets
> +        *  will contain the whole packet */
> +       uint32_t n_bytes_per_pkt;
>  };

If this struct is used in a table, changing its size will break the ABI.
More generally, are you sure of the benefits of exposing a configuration
structure in the API?

[...]
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -111,6 +111,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT)    += -lxenstore
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lgxio
>  # QAT PMD has a dependency on libcrypto (from openssl) for calculating HMAC precomputes
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)        += -lcrypto
> +_LDLIBS-$(CONFIG_RTE_PORT_PCAP)                        += -lpcap

Please move this line upper before PMD_PCAP.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs
  2016-03-07  8:12  4% ` [dpdk-dev] [PATCH v2 0/3] " Helin Zhang
  2016-03-07  8:12  8%   ` [dpdk-dev] [PATCH v2 1/3] ethdev: add vlan type for setting ether type Helin Zhang
  2016-03-07  8:12  3%   ` [dpdk-dev] [PATCH v2 2/3] i40e: add VLAN ether type config Helin Zhang
@ 2016-03-07  9:28  0%   ` Thomas Monjalon
  2016-03-09 15:20  0%     ` Zhang, Helin
  2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
  3 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-07  9:28 UTC (permalink / raw)
  To: Helin Zhang; +Cc: dev

2016-03-07 16:12, Helin Zhang:
> The patch set was branched off rel_16_04 of repo dpdk-next-net,
> on below commit.
>  - commit 4ac366ba647909c3b71818f9be9db86ba5e871da
>      nfp: fix non-x86 build

Currently, changes on ethdev are directly applied on dpdk.git.

> v2:
>  - Used RTE_NEXT_ABI to avoid ABI change issue.

RTE_NEXT_ABI must be used only when it is really too difficult to keep
the compatibility with librte_compat.
Here you are just adding a parameter to some functions, so you should
try versionning the functions with the help of macros in librte_compat.

About the API change, you want to be able to insert a QinQ inner-vlan, right?
The current comment of rte_eth_dev_set_vlan_ether_type is:
 * Set the Outer VLAN Ether Type by an Ethernet device, it can be inserted to
 * the VLAN Header. This is a register setup available on some Intel NIC, not
 * but all, please check the data sheet for availability.

2 comments:
- you haven't changed "Outer VLAN" so the API description is wrong
- it is announced as something Intel-specific

About the new enum:
+ * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
+ * Note that most of time single VLAN is treated the same as inner VLAN.

You cannot say "most of time" in an API.

More generally, I am not convinced by the current VLAN API that you are extending.
Why this function is not merged with rte_eth_dev_set_vlan_pvid?

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2 2/3] i40e: add VLAN ether type config
  2016-03-07  8:12  4% ` [dpdk-dev] [PATCH v2 0/3] " Helin Zhang
  2016-03-07  8:12  8%   ` [dpdk-dev] [PATCH v2 1/3] ethdev: add vlan type for setting ether type Helin Zhang
@ 2016-03-07  8:12  3%   ` Helin Zhang
  2016-03-07  9:28  0%   ` [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs Thomas Monjalon
  2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
  3 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-03-07  8:12 UTC (permalink / raw)
  To: dev

It adds the setting VLAN ether type of single VLAN, inner and
outer VLAN. Single VLAN is treated as inner VLAN as usual.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 68 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 64 insertions(+), 4 deletions(-)

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 1da5690..a5b9289 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -273,6 +273,11 @@
 #define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
 #define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
 
+#define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
+#define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK \
+	I40E_MASK(0xFFFF, I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT)
+
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
@@ -2324,13 +2329,58 @@ i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-i40e_vlan_tpid_set(__rte_unused struct rte_eth_dev *dev,
+i40e_vlan_tpid_set(struct rte_eth_dev *dev,
 #ifdef RTE_NEXT_ABI
-		   __rte_unused enum rte_vlan_type vlan_type,
+		   enum rte_vlan_type vlan_type,
 #endif
-		   __rte_unused uint16_t tpid)
+		   uint16_t tpid)
 {
-	PMD_INIT_FUNC_TRACE();
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t reg_r = 0, reg_w = 0;
+	uint16_t reg_id = 0;
+	int ret;
+
+#ifdef RTE_NEXT_ABI
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_OUTER:
+		reg_id = 2;
+		break;
+	case ETH_VLAN_TYPE_INNER:
+		reg_id = 3;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d", vlan_type);
+		return;
+	}
+#else
+	reg_id = 3;
+#endif /* RTE_NEXT_ABI */
+
+	ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					  &reg_r, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug read from "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: "
+		    "0x%08"PRIx64"", reg_id, reg_r);
+
+	reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
+	reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
+	if (reg_r == reg_w) {
+		PMD_DRV_LOG(DEBUG, "No need to write");
+		return;
+	}
+	ret = i40e_aq_debug_write_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
+					   reg_w, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Fail to debug write to "
+			    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+		return;
+	}
+	PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
+		    "I40E_GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
 }
 
 static void
@@ -7345,11 +7395,21 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void
 i40e_hw_init(struct i40e_hw *hw)
 {
+	struct rte_eth_dev *dev = ((struct i40e_adapter *)(hw->back))->eth_dev;
+
 	/* clear the PF Queue Filter control register */
 	I40E_WRITE_REG(hw, I40E_PFQF_CTL_0, 0);
 
 	/* Disable symmetric hash per port */
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
+
+	/* Set the global registers with default ether type value */
+#ifdef RTE_NEXT_ABI
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
+	i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, ETHER_TYPE_VLAN);
+#else
+	i40e_vlan_tpid_set(dev, ETHER_TYPE_VLAN);
+#endif /* RTE_NEXT_ABI */
 }
 
 enum i40e_filter_pctype
-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 1/3] ethdev: add vlan type for setting ether type
  2016-03-07  8:12  4% ` [dpdk-dev] [PATCH v2 0/3] " Helin Zhang
@ 2016-03-07  8:12  8%   ` Helin Zhang
  2016-03-07  8:12  3%   ` [dpdk-dev] [PATCH v2 2/3] i40e: add VLAN ether type config Helin Zhang
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-03-07  8:12 UTC (permalink / raw)
  To: dev

In order to set ether type of VLAN for single VLAN, inner
and outer VLAN, the VLAN type as an input parameter is added
to 'rte_eth_dev_set_vlan_ether_type()'.
In addition, corresponding changes in e1000, ixgbe and i40e are
also added.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                 | 29 ++++++++++++++++++++---------
 app/test-pmd/config.c                  | 14 +++++++++++---
 app/test-pmd/testpmd.h                 |  3 ++-
 doc/guides/rel_notes/deprecation.rst   |  6 ++++++
 doc/guides/rel_notes/release_16_04.rst |  4 ++++
 drivers/net/e1000/igb_ethdev.c         | 26 +++++++++++++++++++++++---
 drivers/net/i40e/i40e_ethdev.c         |  9 ++++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c       | 25 ++++++++++++++++++++++---
 lib/librte_ether/rte_ethdev.c          | 12 ++++++++++--
 lib/librte_ether/rte_ethdev.h          | 24 ++++++++++++++++++++++--
 10 files changed, 128 insertions(+), 24 deletions(-)

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..39a1202 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -277,8 +277,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Set the VLAN QinQ (extended queue in queue)"
 			" on a port.\n\n"
 
-			"vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
+			"vlan set (inner|outer) tpid (value) (port_id)\n"
+			"    Set the VLAN TPID for Packet Filtering on"
 			" a port\n\n"
 
 			"rx_vlan add (vlan_id|all) (port_id)\n"
@@ -297,10 +297,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Remove a vlan_id, to the set of VLAN identifiers"
 			"filtered for VF(s) from port_id.\n\n"
 
-			"rx_vlan set tpid (value) (port_id)\n"
-			"    Set the outer VLAN TPID for Packet Filtering on"
-			" a port\n\n"
-
 			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
 			"(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
 			"   add a tunnel filter of a port.\n\n"
@@ -2847,6 +2843,7 @@ cmdline_parse_inst_t cmd_vlan_offload = {
 struct cmd_vlan_tpid_result {
 	cmdline_fixed_string_t vlan;
 	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vlan_type;
 	cmdline_fixed_string_t what;
 	uint16_t tp_id;
 	uint8_t port_id;
@@ -2858,8 +2855,17 @@ cmd_vlan_tpid_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	struct cmd_vlan_tpid_result *res = parsed_result;
-	vlan_tpid_set(res->port_id, res->tp_id);
-	return;
+	enum rte_vlan_type vlan_type;
+
+	if (!strcmp(res->vlan_type, "inner"))
+		vlan_type = ETH_VLAN_TYPE_INNER;
+	else if (!strcmp(res->vlan_type, "outer"))
+		vlan_type = ETH_VLAN_TYPE_OUTER;
+	else {
+		printf("Unknown vlan type\n");
+		return;
+	}
+	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
 }
 
 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
@@ -2868,6 +2874,9 @@ cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
 cmdline_parse_token_string_t cmd_vlan_tpid_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 set, "set");
+cmdline_parse_token_string_t cmd_vlan_type =
+	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+				 vlan_type, "inner#outer");
 cmdline_parse_token_string_t cmd_vlan_tpid_what =
 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
 				 what, "tpid");
@@ -2881,10 +2890,12 @@ cmdline_parse_token_num_t cmd_vlan_tpid_portid =
 cmdline_parse_inst_t cmd_vlan_tpid = {
 	.f = cmd_vlan_tpid_parsed,
 	.data = NULL,
-	.help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+	.help_str = "set inner|outer tpid tp_id port_id, set the VLAN "
+		    "Ether type",
 	.tokens = {
 		(void *)&cmd_vlan_tpid_vlan,
 		(void *)&cmd_vlan_tpid_set,
+		(void *)&cmd_vlan_type,
 		(void *)&cmd_vlan_tpid_what,
 		(void *)&cmd_vlan_tpid_tpid,
 		(void *)&cmd_vlan_tpid_portid,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..db64d57 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1821,19 +1821,27 @@ rx_vlan_all_filter_set(portid_t port_id, int on)
 }
 
 void
-vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type, uint16_t tp_id)
 {
 	int diag;
 	if (port_id_is_invalid(port_id, ENABLED_WARN))
 		return;
 
+#ifdef RTE_NEXT_ABI
+	diag = rte_eth_dev_set_vlan_ether_type(port_id, vlan_type, tp_id);
+#else
+	if (vlan_type != ETH_VLAN_TYPE_INNER) {
+		printf("VLAN type not supported\n");
+		return;
+	}
 	diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+#endif /* RTE_NEXT_ABI */
 	if (diag == 0)
 		return;
 
-	printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+	printf("tx_vlan_tpid_set(port_pi=%d, vlan_type=%d, tpid=%d) failed "
 	       "diag=%d\n",
-	       port_id, tp_id, diag);
+	       port_id, vlan_type, tp_id, diag);
 }
 
 void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b618998..0f72ca1 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -508,7 +508,8 @@ void rx_vlan_filter_set(portid_t port_id, int on);
 void rx_vlan_all_filter_set(portid_t port_id, int on);
 int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
 void vlan_extend_set(portid_t port_id, int on);
-void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
+void vlan_tpid_set(portid_t port_id, enum rte_vlan_type vlan_type,
+		   uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
 void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer);
 void tx_vlan_reset(portid_t port_id);
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..dd10501 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,3 +49,9 @@ Deprecation Notices
   commands (such as RETA update in testpmd).  This should impact
   CMDLINE_PARSE_RESULT_BUFSIZE, STR_TOKEN_SIZE and RDLINE_BUF_SIZE.
   It should be integrated in release 2.3.
+
+* ABI changes are planned for typedef of ``vlan_tpid_set_t``, one more
+  parameter of ``vlan_type`` will be added, and its return value will be
+  changed from ``void`` to ``int``, from release 16.07. Thus, ethdev structure
+  of ``eth_dev_ops`` and interface of ``rte_eth_dev_set_vlan_ether_type`` will
+  be affected.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 73494f9..d1a3e7e 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -74,6 +74,10 @@ This section should contain new features added in this release. Sample format:
 
 * **szedata2: Add functions for setting link up/down.**
 
+* **Added modifying ether type of both single and double VLAN for i40e**
+
+  Macro of RTE_NEXT_ABI was introduced, as ABI change involved.
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 41c107d..5b2e381 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -126,7 +126,11 @@ static int  eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int eth_igb_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+				  enum rte_vlan_type vlan_type,
+#endif
+				  uint16_t tpid_id);
 static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
@@ -2194,14 +2198,30 @@ eth_igb_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static void
-eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+		      enum rte_vlan_type vlan_type,
+#endif
+		      uint16_t tpid)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t reg = ETHER_TYPE_VLAN ;
+	uint32_t reg = ETHER_TYPE_VLAN;
 
+#ifdef RTE_NEXT_ABI
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		reg |= (tpid << 16);
+		E1000_WRITE_REG(hw, E1000_VET, reg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
+#else
 	reg |= (tpid << 16);
 	E1000_WRITE_REG(hw, E1000_VET, reg);
+#endif /* RTE_NEXT_ABI */
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c86febc..1da5690 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -299,7 +299,11 @@ static void i40e_dev_info_get(struct rte_eth_dev *dev,
 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
 				uint16_t vlan_id,
 				int on);
-static void i40e_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid);
+static void i40e_vlan_tpid_set(struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+			       enum rte_vlan_type vlan_type,
+#endif
+			       uint16_t tpid);
 static void i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
 				      uint16_t queue,
@@ -2321,6 +2325,9 @@ i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 
 static void
 i40e_vlan_tpid_set(__rte_unused struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+		   __rte_unused enum rte_vlan_type vlan_type,
+#endif
 		   __rte_unused uint16_t tpid)
 {
 	PMD_INIT_FUNC_TRACE();
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 2d8eaac..a2175a0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -172,7 +172,11 @@ static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
-static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static void ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+				enum rte_vlan_type vlan_type,
+#endif
+				uint16_t tpid_id);
 static void ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
 		uint16_t queue, bool on);
 static void ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
@@ -1519,13 +1523,28 @@ ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 }
 
 static void
-ixgbe_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+#ifdef RTE_NEXT_ABI
+		    enum rte_vlan_type vlan_type,
+#endif
+		    uint16_t tpid)
 {
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/* Only the high 16-bits is valid */
+#ifdef RTE_NEXT_ABI
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		/* Only the high 16-bits is valid */
+		IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+		break;
+	}
+#else
 	IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
+#endif /* RTE_NEXT_ABI */
 }
 
 void
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..3337321 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1697,14 +1697,22 @@ rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id, int o
 }
 
 int
-rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tpid)
+rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+#ifdef RTE_NEXT_ABI
+				enum rte_vlan_type vlan_type,
+#endif
+				uint16_t tpid)
 {
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
-	(*dev->dev_ops->vlan_tpid_set)(dev, tpid);
+	(*dev->dev_ops->vlan_tpid_set)(dev,
+#ifdef RTE_NEXT_ABI
+				       vlan_type,
+#endif
+				       tpid);
 
 	return 0;
 }
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..f8d49af 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -351,6 +351,17 @@ struct rte_eth_rxmode {
 };
 
 /**
+ * VLAN types to indicate if it is for single VLAN, inner VLAN or outer VLAN.
+ * Note that most of time single VLAN is treated the same as inner VLAN.
+ */
+enum rte_vlan_type {
+	ETH_VLAN_TYPE_UNKNOWN = 0,
+	ETH_VLAN_TYPE_INNER, /**< Single VLAN, or inner VLAN. */
+	ETH_VLAN_TYPE_OUTER, /**< Outer VLAN. */
+	ETH_VLAN_TYPE_MAX,
+};
+
+/**
  * A structure used to configure the Receive Side Scaling (RSS) feature
  * of an Ethernet port.
  * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1077,7 +1088,10 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
 /**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
 
 typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
-				  uint16_t tpid);
+#ifdef RTE_NEXT_ABI
+				enum rte_vlan_type type,
+#endif
+				uint16_t tpid);
 /**< @internal set the outer VLAN-TPID by an Ethernet device. */
 
 typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
@@ -2346,6 +2360,8 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @vlan_type
+ *   The vlan type.
  * @param tag_type
  *   The Tag Protocol ID
  * @return
@@ -2353,7 +2369,11 @@ int rte_eth_dev_set_vlan_strip_on_queue(uint8_t port_id, uint16_t rx_queue_id,
  *   - (-ENOSUP) if hardware-assisted VLAN TPID setup is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  */
-int rte_eth_dev_set_vlan_ether_type(uint8_t port_id, uint16_t tag_type);
+int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
+#ifdef RTE_NEXT_ABI
+				    enum rte_vlan_type vlan_type,
+#endif
+				    uint16_t tag_type);
 
 /**
  * Set VLAN offload configuration on an Ethernet device
-- 
2.5.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs
  @ 2016-03-07  8:12  4% ` Helin Zhang
  2016-03-07  8:12  8%   ` [dpdk-dev] [PATCH v2 1/3] ethdev: add vlan type for setting ether type Helin Zhang
                     ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Helin Zhang @ 2016-03-07  8:12 UTC (permalink / raw)
  To: dev

It adds setting ether type of both single VLAN(inner VLAN) and outer
VLAN for i40e. For ixgbe and e1000/igb, it supports setting single
VLAN(inner VLAN) only, and can be extended in the future.

The patch set was branched off rel_16_04 of repo dpdk-next-net,
on below commit.
 - commit 4ac366ba647909c3b71818f9be9db86ba5e871da
     nfp: fix non-x86 build

v2:
 - Used RTE_NEXT_ABI to avoid ABI change issue.
 - Reworked the announcement of ABI change for release 16.07.
 - Fixed a i40e overflow issue.

Helin Zhang (3):
  ethdev: add vlan type for setting ether type
  i40e: add VLAN ether type config
  i40e: fix the overflow issue

 app/test-pmd/cmdline.c                 | 29 +++++++++----
 app/test-pmd/config.c                  | 14 +++++--
 app/test-pmd/testpmd.h                 |  3 +-
 doc/guides/rel_notes/deprecation.rst   |  6 +++
 doc/guides/rel_notes/release_16_04.rst |  4 ++
 drivers/net/e1000/igb_ethdev.c         | 26 ++++++++++--
 drivers/net/i40e/i40e_ethdev.c         | 75 ++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_rxtx.c           |  4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c       | 25 ++++++++++--
 lib/librte_ether/rte_ethdev.c          | 12 +++++-
 lib/librte_ether/rte_ethdev.h          | 24 ++++++++++-
 11 files changed, 193 insertions(+), 29 deletions(-)

-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3] config: remove duplicate configuration information
    2016-03-04 17:01  6% ` [dpdk-dev] [PATCH v2] " Keith Wiles
@ 2016-03-04 18:11  6% ` Keith Wiles
  1 sibling, 0 replies; 200+ results
From: Keith Wiles @ 2016-03-04 18:11 UTC (permalink / raw)
  To: dev

In order to cleanup the configuration files some and reduce
the number of duplicate configuration information. Add a new
file called common_base which contains just about all of the
configuration lines in one place. Then have the common_bsdapp,
common_linuxapp files include this one file. Then in those OS
specific files add the delta configuration lines.

Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
 config/common_base     | 519 +++++++++++++++++++++++++++++++++++++++++++++++++
 config/common_bsdapp   | 436 +----------------------------------------
 config/common_linuxapp | 460 +------------------------------------------
 3 files changed, 528 insertions(+), 887 deletions(-)
 create mode 100644 config/common_base

diff --git a/config/common_base b/config/common_base
new file mode 100644
index 0000000..0d30cd0
--- /dev/null
+++ b/config/common_base
@@ -0,0 +1,519 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# The following three configs are for reference only and should be
+# enabled in the correct defconfig_XXX file(s).
+#
+
+################
+#
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE values are the directories in mk/machine/
+#
+CONFIG_RTE_MACHINE=
+
+#
+# define the architecture we compile for.
+# RTE_ARCH values are the directories in mk/arch/
+#
+CONFIG_RTE_ARCH=
+
+#
+# The compiler we use.
+# RTE_TOOLCHAIN values are the directories in mk/toolchain/
+#
+CONFIG_RTE_TOOLCHAIN=
+
+################
+
+#
+# Use intrinsics or assembly code for key routines
+#
+CONFIG_RTE_FORCE_INTRINSICS=n
+
+#
+# Machine forces strict alignment constraints.
+#
+CONFIG_RTE_ARCH_STRICT_ALIGN=n
+
+#
+# Compile to share library
+#
+CONFIG_RTE_BUILD_SHARED_LIB=n
+
+#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
+# Machine's cache line size
+#
+CONFIG_RTE_CACHE_LINE_SIZE=64
+
+#
+# Compile Environment Abstraction Layer
+#
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=128
+CONFIG_RTE_MAX_NUMA_NODES=8
+CONFIG_RTE_MAX_MEMSEG=256
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_LOG_LEVEL=8
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_LIBEAL_USE_HPET=n
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=n
+CONFIG_RTE_MALLOC_DEBUG=n
+
+# Default driver path (or "" to disable)
+CONFIG_RTE_EAL_PMD_PATH=""
+
+#
+# Special configurations in PCI Config Space for high performance
+#
+CONFIG_RTE_PCI_CONFIG=n
+CONFIG_RTE_PCI_EXTENDED_TAG=""
+CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
+
+#
+# Compile Environment Abstraction Layer to support Vmware TSC map
+#
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
+
+#
+# Compile the argument parser library
+#
+CONFIG_RTE_LIBRTE_KVARGS=y
+
+#
+# Compile generic ethernet library
+#
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
+
+#
+# Support NIC bypass logic
+#
+CONFIG_RTE_NIC_BYPASS=n
+
+#
+# Compile burst-oriented IGB & EM PMD drivers
+#
+CONFIG_RTE_LIBRTE_EM_PMD=y
+CONFIG_RTE_LIBRTE_IGB_PMD=y
+CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+
+#
+# Compile burst-oriented IXGBE PMD driver
+#
+CONFIG_RTE_LIBRTE_IXGBE_PMD=y
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
+
+#
+# Compile burst-oriented I40E PMD driver
+#
+CONFIG_RTE_LIBRTE_I40E_PMD=y
+CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
+CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
+# interval up to 8160 us, aligned to 2 (or default value)
+CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
+
+#
+# Compile burst-oriented FM10K PMD
+#
+CONFIG_RTE_LIBRTE_FM10K_PMD=y
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
+
+#
+# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
+#
+CONFIG_RTE_LIBRTE_MLX4_PMD=n
+CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
+CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
+CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
+CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
+
+#
+# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
+#
+CONFIG_RTE_LIBRTE_MLX5_PMD=n
+CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
+CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
+CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
+
+#
+# Compile burst-oriented Broadcom PMD driver
+#
+CONFIG_RTE_LIBRTE_BNX2X_PMD=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
+
+#
+# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
+#
+CONFIG_RTE_LIBRTE_CXGBE_PMD=y
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
+
+#
+# Compile burst-oriented Cisco ENIC PMD driver
+#
+CONFIG_RTE_LIBRTE_ENIC_PMD=y
+CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
+
+#
+# Compile burst-oriented Netronome NFP PMD driver
+#
+CONFIG_RTE_LIBRTE_NFP_PMD=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG=n
+
+#
+# Compile software PMD backed by SZEDATA2 device
+#
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+
+#
+# Compile burst-oriented VIRTIO PMD driver
+#
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+
+#
+# Compile burst-oriented VMXNET3 PMD driver
+#
+CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
+
+#
+# Compile example software rings based PMD
+#
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+
+#
+# Compile software PMD backed by PCAP files
+#
+CONFIG_RTE_LIBRTE_PMD_PCAP=n
+
+#
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+
+#
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
+#
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+
+#
+# Compile Xen PMD
+#
+CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
+
+#
+# Compile null PMD
+#
+CONFIG_RTE_LIBRTE_PMD_NULL=y
+
+#
+# Do prefetch of packet data within PMD driver receive function
+#
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+
+#
+# Compile generic crypto device library
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_CRYPTODEV=y
+CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
+CONFIG_RTE_CRYPTO_MAX_DEVS=64
+CONFIG_RTE_CRYPTODEV_NAME_LEN=64
+
+#
+# Compile PMD for QuickAssist based devices
+#
+CONFIG_RTE_LIBRTE_PMD_QAT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
+#
+# Number of sessions to create in the session memory pool
+# on a single QuickAssist device.
+#
+CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
+
+#
+# Compile PMD for AESNI backed device
+#
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
+CONFIG_RTE_AESNI_MB_PMD_MAX_NB_QUEUE_PAIRS=8
+CONFIG_RTE_AESNI_MB_PMD_MAX_NB_SESSIONS=2048
+
+#
+# Compile librte_ring
+#
+CONFIG_RTE_LIBRTE_RING=y
+CONFIG_RTE_LIBRTE_RING_DEBUG=n
+CONFIG_RTE_RING_SPLIT_PROD_CONS=n
+CONFIG_RTE_RING_PAUSE_REP_COUNT=0
+
+#
+# Compile librte_mempool
+#
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+
+#
+# Compile librte_mbuf
+#
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+
+#
+# Compile librte_mbuf_offload
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
+CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
+
+#
+# Compile librte_timer
+#
+CONFIG_RTE_LIBRTE_TIMER=y
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+
+#
+# Compile librte_cfgfile
+#
+CONFIG_RTE_LIBRTE_CFGFILE=y
+
+#
+# Compile librte_cmdline
+#
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+
+#
+# Compile librte_hash
+#
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+
+#
+# Compile librte_jobstats
+#
+CONFIG_RTE_LIBRTE_JOBSTATS=y
+
+#
+# Compile librte_lpm
+#
+CONFIG_RTE_LIBRTE_LPM=y
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+
+#
+# Compile librte_acl
+#
+CONFIG_RTE_LIBRTE_ACL=y
+CONFIG_RTE_LIBRTE_ACL_DEBUG=n
+
+#
+# Compile librte_power
+#
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+
+#
+# Compile librte_net
+#
+CONFIG_RTE_LIBRTE_NET=y
+
+#
+# Compile librte_ip_frag
+#
+CONFIG_RTE_LIBRTE_IP_FRAG=y
+CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
+CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
+CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
+
+#
+# Compile librte_meter
+#
+CONFIG_RTE_LIBRTE_METER=y
+
+#
+# Compile librte_sched
+#
+CONFIG_RTE_LIBRTE_SCHED=y
+CONFIG_RTE_SCHED_DEBUG=n
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+CONFIG_RTE_SCHED_VECTOR=n
+
+#
+# Compile the distributor library
+#
+CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
+
+#
+# Compile the reorder library
+#
+CONFIG_RTE_LIBRTE_REORDER=y
+
+#
+# Compile librte_port
+#
+CONFIG_RTE_LIBRTE_PORT=y
+CONFIG_RTE_PORT_STATS_COLLECT=n
+
+#
+# Compile librte_table
+#
+CONFIG_RTE_LIBRTE_TABLE=y
+CONFIG_RTE_TABLE_STATS_COLLECT=n
+
+#
+# Compile librte_pipeline
+#
+CONFIG_RTE_LIBRTE_PIPELINE=y
+CONFIG_RTE_PIPELINE_STATS_COLLECT=n
+
+#
+# Compile librte_kni
+#
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
+CONFIG_RTE_KNI_KO_DEBUG=n
+CONFIG_RTE_KNI_VHOST=n
+CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
+CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
+CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
+CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
+
+#
+# Compile vhost library
+# fuse-devel is needed to run vhost-cuse.
+# fuse-devel enables user space char driver development
+# vhost-user is turned on by default.
+#
+CONFIG_RTE_LIBRTE_VHOST=n
+CONFIG_RTE_LIBRTE_VHOST_USER=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=n
+CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
+
+#
+#Compile Xen domain0 support
+#
+CONFIG_RTE_LIBRTE_XEN_DOM0=n
+
+#
+# Enable warning directives
+#
+CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
+
+#
+# Compile the test application
+#
+CONFIG_RTE_APP_TEST=y
+
+#
+# Compile the PMD test application
+#
+CONFIG_RTE_TEST_PMD=y
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 7df5ac6..2fdaf19 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -37,69 +37,12 @@
 CONFIG_RTE_EXEC_ENV="bsdapp"
 CONFIG_RTE_EXEC_ENV_BSDAPP=y
 
-##
-## machine can define specific variables or action for a specific board
-## RTE_MACHINE values are the directories in mk/machine/
-##
-#CONFIG_RTE_MACHINE="native"
-#
-##
-## define the architecture we compile for.
-## RTE_ARCH values are the directories in mk/arch/
-##
-#CONFIG_RTE_ARCH="x86_64"
-#CONFIG_RTE_ARCH_X86_64=y
-#CONFIG_RTE_ARCH_X86=y
-#
-##
-## The compiler we use.
-## RTE_TOOLCHAIN values are the directories in mk/toolchain/
-##
-#CONFIG_RTE_TOOLCHAIN="gcc"
-#CONFIG_RTE_TOOLCHAIN_GCC=y
-
-#
-# Use intrinsics or assembly code for key routines
-#
-CONFIG_RTE_FORCE_INTRINSICS=n
-
-#
-# Machine forces strict alignment constraints.
-#
-CONFIG_RTE_ARCH_STRICT_ALIGN=n
-
-#
-# Compile to share library
-#
-CONFIG_RTE_BUILD_SHARED_LIB=n
+#include "common_base"
 
 #
-# Use newest code breaking previous ABI
+# Compile Environment Abstraction Layer for FreeBSD
 #
-CONFIG_RTE_NEXT_ABI=y
-
-#
-# Machine's cache line size
-#
-CONFIG_RTE_CACHE_LINE_SIZE=64
-
-#
-# Compile Environment Abstraction Layer
-#
-CONFIG_RTE_LIBRTE_EAL=y
-CONFIG_RTE_MAX_LCORE=128
-CONFIG_RTE_MAX_NUMA_NODES=8
-CONFIG_RTE_MAX_MEMSEG=256
-CONFIG_RTE_MAX_MEMZONE=2560
-CONFIG_RTE_MAX_TAILQ=32
-CONFIG_RTE_LOG_LEVEL=8
-CONFIG_RTE_LOG_HISTORY=256
-CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
-CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
-CONFIG_RTE_MALLOC_DEBUG=n
-
-# Default driver path (or "" to disable)
-CONFIG_RTE_EAL_PMD_PATH=""
+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
 
 #
 # FreeBSD contiguous memory driver settings
@@ -107,374 +50,3 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_CONTIGMEM_MAX_NUM_BUFS=64
 CONFIG_RTE_CONTIGMEM_DEFAULT_NUM_BUFS=2
 CONFIG_RTE_CONTIGMEM_DEFAULT_BUF_SIZE=1024*1024*1024
-
-#
-# Compile Environment Abstraction Layer for BSD
-#
-CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
-
-#
-# Compile Environment Abstraction Layer for linux
-#
-CONFIG_RTE_LIBRTE_EAL_LINUXAPP=n
-
-#
-# Compile Environment Abstraction Layer to support Vmware TSC map
-#
-CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
-
-#
-# Compile the argument parser library
-#
-CONFIG_RTE_LIBRTE_KVARGS=y
-
-#
-# Compile generic ethernet library
-#
-CONFIG_RTE_LIBRTE_ETHER=y
-CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
-CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
-CONFIG_RTE_LIBRTE_IEEE1588=n
-CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
-CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
-
-#
-# Support NIC bypass logic
-#
-CONFIG_RTE_NIC_BYPASS=n
-
-#
-# Compile burst-oriented IGB & EM PMD drivers
-#
-CONFIG_RTE_LIBRTE_EM_PMD=y
-CONFIG_RTE_LIBRTE_IGB_PMD=y
-CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
-
-#
-# Compile burst-oriented IXGBE PMD driver
-#
-CONFIG_RTE_LIBRTE_IXGBE_PMD=y
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
-CONFIG_RTE_IXGBE_INC_VECTOR=y
-CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented I40E PMD driver
-#
-CONFIG_RTE_LIBRTE_I40E_PMD=y
-CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
-CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
-# interval up to 8160 us, aligned to 2 (or default value)
-CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
-
-#
-# Compile burst-oriented FM10K PMD
-#
-CONFIG_RTE_LIBRTE_FM10K_PMD=y
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
-#
-CONFIG_RTE_LIBRTE_MLX4_PMD=n
-CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
-
-#
-# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
-#
-CONFIG_RTE_LIBRTE_MLX5_PMD=n
-CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
-
-#
-# Compile burst-oriented Broadcom PMD driver
-#
-CONFIG_RTE_LIBRTE_BNX2X_PMD=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
-
-#
-# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
-#
-CONFIG_RTE_LIBRTE_CXGBE_PMD=y
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
-
-#
-# Compile burst-oriented Cisco ENIC PMD driver
-#
-CONFIG_RTE_LIBRTE_ENIC_PMD=y
-CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
-
-#
-# Compile software PMD backed by SZEDATA2 device
-#
-CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
-
-#
-# Compile burst-oriented VIRTIO PMD driver
-#
-CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
-
-#
-# Compile burst-oriented VMXNET3 PMD driver
-#
-CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
-
-#
-# Compile example software rings based PMD
-#
-CONFIG_RTE_LIBRTE_PMD_RING=y
-CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
-CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
-
-#
-# Compile software PMD backed by PCAP files
-#
-CONFIG_RTE_LIBRTE_PMD_PCAP=y
-
-#
-# Compile link bonding PMD library
-#
-CONFIG_RTE_LIBRTE_PMD_BOND=y
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
-
-#
-# Compile null PMD
-#
-CONFIG_RTE_LIBRTE_PMD_NULL=y
-
-#
-# Do prefetch of packet data within PMD driver receive function
-#
-CONFIG_RTE_PMD_PACKET_PREFETCH=y
-
-#
-# Compile generic crypto device library
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_CRYPTODEV=y
-CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
-CONFIG_RTE_CRYPTO_MAX_DEVS=64
-CONFIG_RTE_CRYPTODEV_NAME_LEN=64
-
-#
-# Compile PMD for QuickAssist based devices
-#
-CONFIG_RTE_LIBRTE_PMD_QAT=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_DRIVER=n
-#
-# Number of sessions to create in the session memory pool
-# on a single QuickAssist device.
-#
-CONFIG_RTE_MAX_QAT_SESSIONS=200
-
-#
-# Compile PMD for AESNI backed device
-#
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
-CONFIG_RTE_LIBRTE_AESNI_MB_DEBUG=n
-
-#
-# Compile librte_ring
-#
-CONFIG_RTE_LIBRTE_RING=y
-CONFIG_RTE_LIBRTE_RING_DEBUG=n
-CONFIG_RTE_RING_SPLIT_PROD_CONS=n
-CONFIG_RTE_RING_PAUSE_REP_COUNT=0
-
-#
-# Compile librte_mempool
-#
-CONFIG_RTE_LIBRTE_MEMPOOL=y
-CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
-CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
-
-#
-# Compile librte_mbuf
-#
-CONFIG_RTE_LIBRTE_MBUF=y
-CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
-CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
-CONFIG_RTE_PKTMBUF_HEADROOM=128
-
-#
-# Compile librte_mbuf_offload
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
-
-#
-# Compile librte_timer
-#
-CONFIG_RTE_LIBRTE_TIMER=y
-CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
-
-#
-# Compile librte_cfgfile
-#
-CONFIG_RTE_LIBRTE_CFGFILE=y
-
-#
-# Compile librte_cmdline
-#
-CONFIG_RTE_LIBRTE_CMDLINE=y
-CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
-
-#
-# Compile librte_hash
-#
-CONFIG_RTE_LIBRTE_HASH=y
-CONFIG_RTE_LIBRTE_HASH_DEBUG=n
-
-#
-# Compile librte_jobstats
-#
-CONFIG_RTE_LIBRTE_JOBSTATS=y
-
-#
-# Compile librte_lpm
-#
-CONFIG_RTE_LIBRTE_LPM=y
-CONFIG_RTE_LIBRTE_LPM_DEBUG=n
-
-#
-# Compile librte_acl
-#
-CONFIG_RTE_LIBRTE_ACL=y
-CONFIG_RTE_LIBRTE_ACL_DEBUG=n
-
-#
-# Compile librte_power
-#
-CONFIG_RTE_LIBRTE_POWER=n
-CONFIG_RTE_LIBRTE_POWER_DEBUG=n
-CONFIG_RTE_MAX_LCORE_FREQS=64
-
-#
-# Compile librte_net
-#
-CONFIG_RTE_LIBRTE_NET=y
-
-#
-# Compile librte_ip_frag
-#
-CONFIG_RTE_LIBRTE_IP_FRAG=y
-CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
-CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
-CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
-
-#
-# Compile librte_meter
-#
-CONFIG_RTE_LIBRTE_METER=y
-
-#
-# Compile librte_sched
-#
-CONFIG_RTE_LIBRTE_SCHED=y
-CONFIG_RTE_SCHED_DEBUG=n
-CONFIG_RTE_SCHED_RED=n
-CONFIG_RTE_SCHED_COLLECT_STATS=n
-CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
-CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
-CONFIG_RTE_SCHED_VECTOR=n
-
-#
-# Compile the distributor library
-#
-CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
-
-#
-# Compile the reorder library
-#
-CONFIG_RTE_LIBRTE_REORDER=y
-
-#
-# Compile librte_port
-#
-CONFIG_RTE_LIBRTE_PORT=y
-CONFIG_RTE_PORT_STATS_COLLECT=n
-
-#
-# Compile librte_table
-#
-CONFIG_RTE_LIBRTE_TABLE=y
-CONFIG_RTE_TABLE_STATS_COLLECT=n
-
-#
-# Compile librte_pipeline
-#
-CONFIG_RTE_LIBRTE_PIPELINE=y
-CONFIG_RTE_PIPELINE_STATS_COLLECT=n
-
-#
-# Enable warning directives
-#
-CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
-
-#
-# Compile the test application
-#
-CONFIG_RTE_APP_TEST=y
-
-#
-# Compile the PMD test application
-#
-CONFIG_RTE_TEST_PMD=y
-CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
-CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 26df137..2d8e67a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -37,78 +37,7 @@
 CONFIG_RTE_EXEC_ENV="linuxapp"
 CONFIG_RTE_EXEC_ENV_LINUXAPP=y
 
-##
-## machine can define specific variables or action for a specific board
-## RTE_MACHINE values are the directories in mk/machine/
-##
-#CONFIG_RTE_MACHINE="native"
-#
-##
-## define the architecture we compile for.
-## RTE_ARCH values are the directories in mk/arch/
-##
-#CONFIG_RTE_ARCH="x86_64"
-#CONFIG_RTE_ARCH_X86_64=y
-#CONFIG_RTE_ARCH_X86=y
-#
-##
-## The compiler we use.
-## RTE_TOOLCHAIN values are the directories in mk/toolchain/
-##
-#CONFIG_RTE_TOOLCHAIN="gcc"
-#CONFIG_RTE_TOOLCHAIN_GCC=y
-
-#
-# Use intrinsics or assembly code for key routines
-#
-CONFIG_RTE_FORCE_INTRINSICS=n
-
-#
-# Machine forces strict alignment constraints.
-#
-CONFIG_RTE_ARCH_STRICT_ALIGN=n
-
-#
-# Compile to share library
-#
-CONFIG_RTE_BUILD_SHARED_LIB=n
-
-#
-# Use newest code breaking previous ABI
-#
-CONFIG_RTE_NEXT_ABI=y
-
-#
-# Machine's cache line size
-#
-CONFIG_RTE_CACHE_LINE_SIZE=64
-
-#
-# Compile Environment Abstraction Layer
-#
-CONFIG_RTE_LIBRTE_EAL=y
-CONFIG_RTE_MAX_LCORE=128
-CONFIG_RTE_MAX_NUMA_NODES=8
-CONFIG_RTE_MAX_MEMSEG=256
-CONFIG_RTE_MAX_MEMZONE=2560
-CONFIG_RTE_MAX_TAILQ=32
-CONFIG_RTE_LOG_LEVEL=8
-CONFIG_RTE_LOG_HISTORY=256
-CONFIG_RTE_LIBEAL_USE_HPET=n
-CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
-CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
-CONFIG_RTE_EAL_IGB_UIO=y
-CONFIG_RTE_EAL_VFIO=y
-CONFIG_RTE_MALLOC_DEBUG=n
-# Default driver path (or "" to disable)
-CONFIG_RTE_EAL_PMD_PATH=""
-
-#
-# Special configurations in PCI Config Space for high performance
-#
-CONFIG_RTE_PCI_CONFIG=n
-CONFIG_RTE_PCI_EXTENDED_TAG=""
-CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
+#include "common_base"
 
 #
 # Compile Environment Abstraction Layer for linux
@@ -116,182 +45,10 @@ CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
 CONFIG_RTE_LIBRTE_EAL_LINUXAPP=y
 
 #
-# Compile Environment Abstraction Layer to support Vmware TSC map
-#
-CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
-
-#
-# Compile the argument parser library
-#
-CONFIG_RTE_LIBRTE_KVARGS=y
-
-#
-# Compile generic ethernet library
-#
-CONFIG_RTE_LIBRTE_ETHER=y
-CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
-CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
-CONFIG_RTE_LIBRTE_IEEE1588=n
-CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
-CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
-
-#
-# Support NIC bypass logic
-#
-CONFIG_RTE_NIC_BYPASS=n
-
-#
-# Compile burst-oriented IGB & EM PMD drivers
-#
-CONFIG_RTE_LIBRTE_EM_PMD=y
-CONFIG_RTE_LIBRTE_IGB_PMD=y
-CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
-
-#
-# Compile burst-oriented IXGBE PMD driver
-#
-CONFIG_RTE_LIBRTE_IXGBE_PMD=y
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
-CONFIG_RTE_IXGBE_INC_VECTOR=y
-CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented I40E PMD driver
-#
-CONFIG_RTE_LIBRTE_I40E_PMD=y
-CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
-CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
-# interval up to 8160 us, aligned to 2 (or default value)
-CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
-
-#
-# Compile burst-oriented FM10K PMD
-#
-CONFIG_RTE_LIBRTE_FM10K_PMD=y
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
-
-#
-# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
-#
-CONFIG_RTE_LIBRTE_MLX4_PMD=n
-CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
-
-#
-# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
-#
-CONFIG_RTE_LIBRTE_MLX5_PMD=n
-CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
-
-#
-# Compile burst-oriented Broadcom PMD driver
-#
-CONFIG_RTE_LIBRTE_BNX2X_PMD=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
-
-#
-# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
-#
-CONFIG_RTE_LIBRTE_CXGBE_PMD=y
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
-
-#
-# Compile burst-oriented Cisco ENIC PMD driver
-#
-CONFIG_RTE_LIBRTE_ENIC_PMD=y
-CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
-
-#
-# Compile burst-oriented Netronome NFP PMD driver
-#
-CONFIG_RTE_LIBRTE_NFP_PMD=n
-CONFIG_RTE_LIBRTE_NFP_DEBUG=n
-
-#
-# Compile software PMD backed by SZEDATA2 device
-#
-CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
-
-#
-# Compile burst-oriented VIRTIO PMD driver
-#
-CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
-
-#
-# Compile burst-oriented VMXNET3 PMD driver
-#
-CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
-
-#
-# Compile example software rings based PMD
-#
-CONFIG_RTE_LIBRTE_PMD_RING=y
-CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
-CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
-
-#
-# Compile software PMD backed by PCAP files
-#
-CONFIG_RTE_LIBRTE_PMD_PCAP=n
-
-#
-# Compile link bonding PMD library
+# Common configurations for Linux support enabled here from 'common_base' file.
 #
-CONFIG_RTE_LIBRTE_PMD_BOND=y
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+CONFIG_RTE_EAL_IGB_UIO=y
+CONFIG_RTE_EAL_VFIO=y
 
 #
 # Compile software PMD backed by AF_PACKET sockets (Linux only)
@@ -299,197 +56,15 @@ CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
 
 #
-# Compile Xen PMD
-#
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
-
-#
-# Compile null PMD
-#
-CONFIG_RTE_LIBRTE_PMD_NULL=y
-
-#
-# Do prefetch of packet data within PMD driver receive function
-#
-CONFIG_RTE_PMD_PACKET_PREFETCH=y
-
-#
-# Compile generic crypto device library
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_CRYPTODEV=y
-CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
-CONFIG_RTE_CRYPTO_MAX_DEVS=64
-CONFIG_RTE_CRYPTODEV_NAME_LEN=64
-
-#
-# Compile PMD for QuickAssist based devices
-#
-CONFIG_RTE_LIBRTE_PMD_QAT=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
-#
-# Number of sessions to create in the session memory pool
-# on a single QuickAssist device.
-#
-CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
-
-#
-# Compile PMD for AESNI backed device
-#
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
-CONFIG_RTE_AESNI_MB_PMD_MAX_NB_QUEUE_PAIRS=8
-CONFIG_RTE_AESNI_MB_PMD_MAX_NB_SESSIONS=2048
-
-#
-# Compile librte_ring
-#
-CONFIG_RTE_LIBRTE_RING=y
-CONFIG_RTE_LIBRTE_RING_DEBUG=n
-CONFIG_RTE_RING_SPLIT_PROD_CONS=n
-CONFIG_RTE_RING_PAUSE_REP_COUNT=0
-
-#
-# Compile librte_mempool
-#
-CONFIG_RTE_LIBRTE_MEMPOOL=y
-CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
-CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
-
-#
-# Compile librte_mbuf
-#
-CONFIG_RTE_LIBRTE_MBUF=y
-CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
-CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
-CONFIG_RTE_PKTMBUF_HEADROOM=128
-
-#
-# Compile librte_mbuf_offload
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
-
-#
-# Compile librte_timer
-#
-CONFIG_RTE_LIBRTE_TIMER=y
-CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
-
-#
-# Compile librte_cfgfile
-#
-CONFIG_RTE_LIBRTE_CFGFILE=y
-
-#
-# Compile librte_cmdline
-#
-CONFIG_RTE_LIBRTE_CMDLINE=y
-CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
-
-#
-# Compile librte_hash
-#
-CONFIG_RTE_LIBRTE_HASH=y
-CONFIG_RTE_LIBRTE_HASH_DEBUG=n
-
-#
-# Compile librte_jobstats
-#
-CONFIG_RTE_LIBRTE_JOBSTATS=y
-
-#
-# Compile librte_lpm
-#
-CONFIG_RTE_LIBRTE_LPM=y
-CONFIG_RTE_LIBRTE_LPM_DEBUG=n
-
-#
-# Compile librte_acl
-#
-CONFIG_RTE_LIBRTE_ACL=y
-CONFIG_RTE_LIBRTE_ACL_DEBUG=n
-
-#
 # Compile librte_power
 #
 CONFIG_RTE_LIBRTE_POWER=y
-CONFIG_RTE_LIBRTE_POWER_DEBUG=n
-CONFIG_RTE_MAX_LCORE_FREQS=64
-
-#
-# Compile librte_net
-#
-CONFIG_RTE_LIBRTE_NET=y
-
-#
-# Compile librte_ip_frag
-#
-CONFIG_RTE_LIBRTE_IP_FRAG=y
-CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
-CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
-CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
-
-#
-# Compile librte_meter
-#
-CONFIG_RTE_LIBRTE_METER=y
-
-#
-# Compile librte_sched
-#
-CONFIG_RTE_LIBRTE_SCHED=y
-CONFIG_RTE_SCHED_DEBUG=n
-CONFIG_RTE_SCHED_RED=n
-CONFIG_RTE_SCHED_COLLECT_STATS=n
-CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
-CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
-CONFIG_RTE_SCHED_VECTOR=n
-
-#
-# Compile the distributor library
-#
-CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
-
-#
-# Compile the reorder library
-#
-CONFIG_RTE_LIBRTE_REORDER=y
-
-#
-# Compile librte_port
-#
-CONFIG_RTE_LIBRTE_PORT=y
-CONFIG_RTE_PORT_STATS_COLLECT=n
-
-#
-# Compile librte_table
-#
-CONFIG_RTE_LIBRTE_TABLE=y
-CONFIG_RTE_TABLE_STATS_COLLECT=n
-
-#
-# Compile librte_pipeline
-#
-CONFIG_RTE_LIBRTE_PIPELINE=y
-CONFIG_RTE_PIPELINE_STATS_COLLECT=n
 
 #
 # Compile librte_kni
 #
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_KNI_KMOD=y
-CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
-CONFIG_RTE_KNI_KO_DEBUG=n
-CONFIG_RTE_KNI_VHOST=n
-CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
-CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
-CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
-CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 
 #
 # Compile vhost library
@@ -498,28 +73,3 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 # vhost-user is turned on by default.
 #
 CONFIG_RTE_LIBRTE_VHOST=y
-CONFIG_RTE_LIBRTE_VHOST_USER=y
-CONFIG_RTE_LIBRTE_VHOST_NUMA=n
-CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
-
-#
-#Compile Xen domain0 support
-#
-CONFIG_RTE_LIBRTE_XEN_DOM0=n
-
-#
-# Enable warning directives
-#
-CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
-
-#
-# Compile the test application
-#
-CONFIG_RTE_APP_TEST=y
-
-#
-# Compile the PMD test application
-#
-CONFIG_RTE_TEST_PMD=y
-CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
-CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
-- 
2.5.4 (Apple Git-61)

^ permalink raw reply	[relevance 6%]

* [dpdk-dev] [PATCH v2] config: remove duplicate configuration information
  @ 2016-03-04 17:01  6% ` Keith Wiles
  2016-03-04 18:11  6% ` [dpdk-dev] [PATCH v3] " Keith Wiles
  1 sibling, 0 replies; 200+ results
From: Keith Wiles @ 2016-03-04 17:01 UTC (permalink / raw)
  To: dev

In order to cleanup the configuration files some and reduce
the number of duplicate configuration information. Add a new
file called common_base which contains just about all of the
configuration lines in one place. Then have the common_bsdapp,
common_linuxapp files include this one file. Then in those OS
specific files add the delta configuration lines.

Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---

v2 - split out ARCH_64 missing defines into new patch.
     Turned off linux specific items in common_base and enable them
     in common_linux file.

 config/common_base     | 524 +++++++++++++++++++++++++++++++++++++++++++++++++
 config/common_bsdapp   | 436 +---------------------------------------
 config/common_linuxapp | 460 +------------------------------------------
 3 files changed, 533 insertions(+), 887 deletions(-)
 create mode 100644 config/common_base

diff --git a/config/common_base b/config/common_base
new file mode 100644
index 0000000..7ce0bd8
--- /dev/null
+++ b/config/common_base
@@ -0,0 +1,524 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# The following three configs are for reference only and should be
+# enabled in the correct defconfig_XXX file(s).
+#
+
+################
+#
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE values are the directories in mk/machine/
+#
+CONFIG_RTE_MACHINE=
+
+#
+# define the architecture we compile for.
+# RTE_ARCH values are the directories in mk/arch/
+#
+CONFIG_RTE_ARCH=
+
+#
+# The compiler we use.
+# RTE_TOOLCHAIN values are the directories in mk/toolchain/
+#
+CONFIG_RTE_TOOLCHAIN=
+
+################
+
+#
+# Use intrinsics or assembly code for key routines
+#
+CONFIG_RTE_FORCE_INTRINSICS=n
+
+#
+# Machine forces strict alignment constraints.
+#
+CONFIG_RTE_ARCH_STRICT_ALIGN=n
+
+#
+# Compile to share library
+#
+CONFIG_RTE_BUILD_SHARED_LIB=n
+
+#
+# Combine to one single library
+#
+CONFIG_RTE_BUILD_COMBINE_LIBS=n
+
+#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
+# Machine's cache line size
+#
+CONFIG_RTE_CACHE_LINE_SIZE=64
+
+#
+# Compile Environment Abstraction Layer
+#
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=128
+CONFIG_RTE_MAX_NUMA_NODES=8
+CONFIG_RTE_MAX_MEMSEG=256
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_LOG_LEVEL=8
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_LIBEAL_USE_HPET=n
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=n
+CONFIG_RTE_MALLOC_DEBUG=n
+
+# Default driver path (or "" to disable)
+CONFIG_RTE_EAL_PMD_PATH=""
+
+#
+# Special configurations in PCI Config Space for high performance
+#
+CONFIG_RTE_PCI_CONFIG=n
+CONFIG_RTE_PCI_EXTENDED_TAG=""
+CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
+
+#
+# Compile Environment Abstraction Layer to support Vmware TSC map
+#
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
+
+#
+# Compile the argument parser library
+#
+CONFIG_RTE_LIBRTE_KVARGS=y
+
+#
+# Compile generic ethernet library
+#
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
+
+#
+# Support NIC bypass logic
+#
+CONFIG_RTE_NIC_BYPASS=n
+
+#
+# Compile burst-oriented IGB & EM PMD drivers
+#
+CONFIG_RTE_LIBRTE_EM_PMD=y
+CONFIG_RTE_LIBRTE_IGB_PMD=y
+CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+
+#
+# Compile burst-oriented IXGBE PMD driver
+#
+CONFIG_RTE_LIBRTE_IXGBE_PMD=y
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
+
+#
+# Compile burst-oriented I40E PMD driver
+#
+CONFIG_RTE_LIBRTE_I40E_PMD=y
+CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
+CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
+# interval up to 8160 us, aligned to 2 (or default value)
+CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
+
+#
+# Compile burst-oriented FM10K PMD
+#
+CONFIG_RTE_LIBRTE_FM10K_PMD=y
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
+
+#
+# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
+#
+CONFIG_RTE_LIBRTE_MLX4_PMD=n
+CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
+CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
+CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
+CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
+
+#
+# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
+#
+CONFIG_RTE_LIBRTE_MLX5_PMD=n
+CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
+CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
+CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
+
+#
+# Compile burst-oriented Broadcom PMD driver
+#
+CONFIG_RTE_LIBRTE_BNX2X_PMD=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
+
+#
+# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
+#
+CONFIG_RTE_LIBRTE_CXGBE_PMD=y
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
+
+#
+# Compile burst-oriented Cisco ENIC PMD driver
+#
+CONFIG_RTE_LIBRTE_ENIC_PMD=y
+CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
+
+#
+# Compile burst-oriented Netronome NFP PMD driver
+#
+CONFIG_RTE_LIBRTE_NFP_PMD=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG=n
+
+#
+# Compile software PMD backed by SZEDATA2 device
+#
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+
+#
+# Compile burst-oriented VIRTIO PMD driver
+#
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+
+#
+# Compile burst-oriented VMXNET3 PMD driver
+#
+CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
+
+#
+# Compile example software rings based PMD
+#
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+
+#
+# Compile software PMD backed by PCAP files
+#
+CONFIG_RTE_LIBRTE_PMD_PCAP=n
+
+#
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+
+#
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
+#
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+
+#
+# Compile Xen PMD
+#
+CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
+
+#
+# Compile null PMD
+#
+CONFIG_RTE_LIBRTE_PMD_NULL=y
+
+#
+# Do prefetch of packet data within PMD driver receive function
+#
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+
+#
+# Compile generic crypto device library
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_CRYPTODEV=y
+CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
+CONFIG_RTE_CRYPTO_MAX_DEVS=64
+CONFIG_RTE_CRYPTODEV_NAME_LEN=64
+
+#
+# Compile PMD for QuickAssist based devices
+#
+CONFIG_RTE_LIBRTE_PMD_QAT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
+#
+# Number of sessions to create in the session memory pool
+# on a single QuickAssist device.
+#
+CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
+
+#
+# Compile PMD for AESNI backed device
+#
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
+CONFIG_RTE_AESNI_MB_PMD_MAX_NB_QUEUE_PAIRS=8
+CONFIG_RTE_AESNI_MB_PMD_MAX_NB_SESSIONS=2048
+
+#
+# Compile librte_ring
+#
+CONFIG_RTE_LIBRTE_RING=y
+CONFIG_RTE_LIBRTE_RING_DEBUG=n
+CONFIG_RTE_RING_SPLIT_PROD_CONS=n
+CONFIG_RTE_RING_PAUSE_REP_COUNT=0
+
+#
+# Compile librte_mempool
+#
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+
+#
+# Compile librte_mbuf
+#
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+
+#
+# Compile librte_mbuf_offload
+# EXPERIMENTAL: API may change without prior notice
+#
+CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
+CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
+
+#
+# Compile librte_timer
+#
+CONFIG_RTE_LIBRTE_TIMER=y
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+
+#
+# Compile librte_cfgfile
+#
+CONFIG_RTE_LIBRTE_CFGFILE=y
+
+#
+# Compile librte_cmdline
+#
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+
+#
+# Compile librte_hash
+#
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+
+#
+# Compile librte_jobstats
+#
+CONFIG_RTE_LIBRTE_JOBSTATS=y
+
+#
+# Compile librte_lpm
+#
+CONFIG_RTE_LIBRTE_LPM=y
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+
+#
+# Compile librte_acl
+#
+CONFIG_RTE_LIBRTE_ACL=y
+CONFIG_RTE_LIBRTE_ACL_DEBUG=n
+
+#
+# Compile librte_power
+#
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+
+#
+# Compile librte_net
+#
+CONFIG_RTE_LIBRTE_NET=y
+
+#
+# Compile librte_ip_frag
+#
+CONFIG_RTE_LIBRTE_IP_FRAG=y
+CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
+CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
+CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
+
+#
+# Compile librte_meter
+#
+CONFIG_RTE_LIBRTE_METER=y
+
+#
+# Compile librte_sched
+#
+CONFIG_RTE_LIBRTE_SCHED=y
+CONFIG_RTE_SCHED_DEBUG=n
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+CONFIG_RTE_SCHED_VECTOR=n
+
+#
+# Compile the distributor library
+#
+CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
+
+#
+# Compile the reorder library
+#
+CONFIG_RTE_LIBRTE_REORDER=y
+
+#
+# Compile librte_port
+#
+CONFIG_RTE_LIBRTE_PORT=y
+CONFIG_RTE_PORT_STATS_COLLECT=n
+
+#
+# Compile librte_table
+#
+CONFIG_RTE_LIBRTE_TABLE=y
+CONFIG_RTE_TABLE_STATS_COLLECT=n
+
+#
+# Compile librte_pipeline
+#
+CONFIG_RTE_LIBRTE_PIPELINE=y
+CONFIG_RTE_PIPELINE_STATS_COLLECT=n
+
+#
+# Compile librte_kni
+#
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
+CONFIG_RTE_KNI_KO_DEBUG=n
+CONFIG_RTE_KNI_VHOST=n
+CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
+CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
+CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
+CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
+
+#
+# Compile vhost library
+# fuse-devel is needed to run vhost-cuse.
+# fuse-devel enables user space char driver development
+# vhost-user is turned on by default.
+#
+CONFIG_RTE_LIBRTE_VHOST=n
+CONFIG_RTE_LIBRTE_VHOST_USER=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=n
+CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
+
+#
+#Compile Xen domain0 support
+#
+CONFIG_RTE_LIBRTE_XEN_DOM0=n
+
+#
+# Enable warning directives
+#
+CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
+
+#
+# Compile the test application
+#
+CONFIG_RTE_APP_TEST=y
+
+#
+# Compile the PMD test application
+#
+CONFIG_RTE_TEST_PMD=y
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 7df5ac6..2fdaf19 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -37,69 +37,12 @@
 CONFIG_RTE_EXEC_ENV="bsdapp"
 CONFIG_RTE_EXEC_ENV_BSDAPP=y
 
-##
-## machine can define specific variables or action for a specific board
-## RTE_MACHINE values are the directories in mk/machine/
-##
-#CONFIG_RTE_MACHINE="native"
-#
-##
-## define the architecture we compile for.
-## RTE_ARCH values are the directories in mk/arch/
-##
-#CONFIG_RTE_ARCH="x86_64"
-#CONFIG_RTE_ARCH_X86_64=y
-#CONFIG_RTE_ARCH_X86=y
-#
-##
-## The compiler we use.
-## RTE_TOOLCHAIN values are the directories in mk/toolchain/
-##
-#CONFIG_RTE_TOOLCHAIN="gcc"
-#CONFIG_RTE_TOOLCHAIN_GCC=y
-
-#
-# Use intrinsics or assembly code for key routines
-#
-CONFIG_RTE_FORCE_INTRINSICS=n
-
-#
-# Machine forces strict alignment constraints.
-#
-CONFIG_RTE_ARCH_STRICT_ALIGN=n
-
-#
-# Compile to share library
-#
-CONFIG_RTE_BUILD_SHARED_LIB=n
+#include "common_base"
 
 #
-# Use newest code breaking previous ABI
+# Compile Environment Abstraction Layer for FreeBSD
 #
-CONFIG_RTE_NEXT_ABI=y
-
-#
-# Machine's cache line size
-#
-CONFIG_RTE_CACHE_LINE_SIZE=64
-
-#
-# Compile Environment Abstraction Layer
-#
-CONFIG_RTE_LIBRTE_EAL=y
-CONFIG_RTE_MAX_LCORE=128
-CONFIG_RTE_MAX_NUMA_NODES=8
-CONFIG_RTE_MAX_MEMSEG=256
-CONFIG_RTE_MAX_MEMZONE=2560
-CONFIG_RTE_MAX_TAILQ=32
-CONFIG_RTE_LOG_LEVEL=8
-CONFIG_RTE_LOG_HISTORY=256
-CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
-CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
-CONFIG_RTE_MALLOC_DEBUG=n
-
-# Default driver path (or "" to disable)
-CONFIG_RTE_EAL_PMD_PATH=""
+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
 
 #
 # FreeBSD contiguous memory driver settings
@@ -107,374 +50,3 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_CONTIGMEM_MAX_NUM_BUFS=64
 CONFIG_RTE_CONTIGMEM_DEFAULT_NUM_BUFS=2
 CONFIG_RTE_CONTIGMEM_DEFAULT_BUF_SIZE=1024*1024*1024
-
-#
-# Compile Environment Abstraction Layer for BSD
-#
-CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
-
-#
-# Compile Environment Abstraction Layer for linux
-#
-CONFIG_RTE_LIBRTE_EAL_LINUXAPP=n
-
-#
-# Compile Environment Abstraction Layer to support Vmware TSC map
-#
-CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
-
-#
-# Compile the argument parser library
-#
-CONFIG_RTE_LIBRTE_KVARGS=y
-
-#
-# Compile generic ethernet library
-#
-CONFIG_RTE_LIBRTE_ETHER=y
-CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
-CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
-CONFIG_RTE_LIBRTE_IEEE1588=n
-CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
-CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
-
-#
-# Support NIC bypass logic
-#
-CONFIG_RTE_NIC_BYPASS=n
-
-#
-# Compile burst-oriented IGB & EM PMD drivers
-#
-CONFIG_RTE_LIBRTE_EM_PMD=y
-CONFIG_RTE_LIBRTE_IGB_PMD=y
-CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
-
-#
-# Compile burst-oriented IXGBE PMD driver
-#
-CONFIG_RTE_LIBRTE_IXGBE_PMD=y
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
-CONFIG_RTE_IXGBE_INC_VECTOR=y
-CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented I40E PMD driver
-#
-CONFIG_RTE_LIBRTE_I40E_PMD=y
-CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
-CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
-# interval up to 8160 us, aligned to 2 (or default value)
-CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
-
-#
-# Compile burst-oriented FM10K PMD
-#
-CONFIG_RTE_LIBRTE_FM10K_PMD=y
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
-#
-CONFIG_RTE_LIBRTE_MLX4_PMD=n
-CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
-
-#
-# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
-#
-CONFIG_RTE_LIBRTE_MLX5_PMD=n
-CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
-
-#
-# Compile burst-oriented Broadcom PMD driver
-#
-CONFIG_RTE_LIBRTE_BNX2X_PMD=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
-
-#
-# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
-#
-CONFIG_RTE_LIBRTE_CXGBE_PMD=y
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
-
-#
-# Compile burst-oriented Cisco ENIC PMD driver
-#
-CONFIG_RTE_LIBRTE_ENIC_PMD=y
-CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
-
-#
-# Compile software PMD backed by SZEDATA2 device
-#
-CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
-
-#
-# Compile burst-oriented VIRTIO PMD driver
-#
-CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
-
-#
-# Compile burst-oriented VMXNET3 PMD driver
-#
-CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
-
-#
-# Compile example software rings based PMD
-#
-CONFIG_RTE_LIBRTE_PMD_RING=y
-CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
-CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
-
-#
-# Compile software PMD backed by PCAP files
-#
-CONFIG_RTE_LIBRTE_PMD_PCAP=y
-
-#
-# Compile link bonding PMD library
-#
-CONFIG_RTE_LIBRTE_PMD_BOND=y
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
-
-#
-# Compile null PMD
-#
-CONFIG_RTE_LIBRTE_PMD_NULL=y
-
-#
-# Do prefetch of packet data within PMD driver receive function
-#
-CONFIG_RTE_PMD_PACKET_PREFETCH=y
-
-#
-# Compile generic crypto device library
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_CRYPTODEV=y
-CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
-CONFIG_RTE_CRYPTO_MAX_DEVS=64
-CONFIG_RTE_CRYPTODEV_NAME_LEN=64
-
-#
-# Compile PMD for QuickAssist based devices
-#
-CONFIG_RTE_LIBRTE_PMD_QAT=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_QAT_DEBUG_DRIVER=n
-#
-# Number of sessions to create in the session memory pool
-# on a single QuickAssist device.
-#
-CONFIG_RTE_MAX_QAT_SESSIONS=200
-
-#
-# Compile PMD for AESNI backed device
-#
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
-CONFIG_RTE_LIBRTE_AESNI_MB_DEBUG=n
-
-#
-# Compile librte_ring
-#
-CONFIG_RTE_LIBRTE_RING=y
-CONFIG_RTE_LIBRTE_RING_DEBUG=n
-CONFIG_RTE_RING_SPLIT_PROD_CONS=n
-CONFIG_RTE_RING_PAUSE_REP_COUNT=0
-
-#
-# Compile librte_mempool
-#
-CONFIG_RTE_LIBRTE_MEMPOOL=y
-CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
-CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
-
-#
-# Compile librte_mbuf
-#
-CONFIG_RTE_LIBRTE_MBUF=y
-CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
-CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
-CONFIG_RTE_PKTMBUF_HEADROOM=128
-
-#
-# Compile librte_mbuf_offload
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
-
-#
-# Compile librte_timer
-#
-CONFIG_RTE_LIBRTE_TIMER=y
-CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
-
-#
-# Compile librte_cfgfile
-#
-CONFIG_RTE_LIBRTE_CFGFILE=y
-
-#
-# Compile librte_cmdline
-#
-CONFIG_RTE_LIBRTE_CMDLINE=y
-CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
-
-#
-# Compile librte_hash
-#
-CONFIG_RTE_LIBRTE_HASH=y
-CONFIG_RTE_LIBRTE_HASH_DEBUG=n
-
-#
-# Compile librte_jobstats
-#
-CONFIG_RTE_LIBRTE_JOBSTATS=y
-
-#
-# Compile librte_lpm
-#
-CONFIG_RTE_LIBRTE_LPM=y
-CONFIG_RTE_LIBRTE_LPM_DEBUG=n
-
-#
-# Compile librte_acl
-#
-CONFIG_RTE_LIBRTE_ACL=y
-CONFIG_RTE_LIBRTE_ACL_DEBUG=n
-
-#
-# Compile librte_power
-#
-CONFIG_RTE_LIBRTE_POWER=n
-CONFIG_RTE_LIBRTE_POWER_DEBUG=n
-CONFIG_RTE_MAX_LCORE_FREQS=64
-
-#
-# Compile librte_net
-#
-CONFIG_RTE_LIBRTE_NET=y
-
-#
-# Compile librte_ip_frag
-#
-CONFIG_RTE_LIBRTE_IP_FRAG=y
-CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
-CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
-CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
-
-#
-# Compile librte_meter
-#
-CONFIG_RTE_LIBRTE_METER=y
-
-#
-# Compile librte_sched
-#
-CONFIG_RTE_LIBRTE_SCHED=y
-CONFIG_RTE_SCHED_DEBUG=n
-CONFIG_RTE_SCHED_RED=n
-CONFIG_RTE_SCHED_COLLECT_STATS=n
-CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
-CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
-CONFIG_RTE_SCHED_VECTOR=n
-
-#
-# Compile the distributor library
-#
-CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
-
-#
-# Compile the reorder library
-#
-CONFIG_RTE_LIBRTE_REORDER=y
-
-#
-# Compile librte_port
-#
-CONFIG_RTE_LIBRTE_PORT=y
-CONFIG_RTE_PORT_STATS_COLLECT=n
-
-#
-# Compile librte_table
-#
-CONFIG_RTE_LIBRTE_TABLE=y
-CONFIG_RTE_TABLE_STATS_COLLECT=n
-
-#
-# Compile librte_pipeline
-#
-CONFIG_RTE_LIBRTE_PIPELINE=y
-CONFIG_RTE_PIPELINE_STATS_COLLECT=n
-
-#
-# Enable warning directives
-#
-CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
-
-#
-# Compile the test application
-#
-CONFIG_RTE_APP_TEST=y
-
-#
-# Compile the PMD test application
-#
-CONFIG_RTE_TEST_PMD=y
-CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
-CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 26df137..2d8e67a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -37,78 +37,7 @@
 CONFIG_RTE_EXEC_ENV="linuxapp"
 CONFIG_RTE_EXEC_ENV_LINUXAPP=y
 
-##
-## machine can define specific variables or action for a specific board
-## RTE_MACHINE values are the directories in mk/machine/
-##
-#CONFIG_RTE_MACHINE="native"
-#
-##
-## define the architecture we compile for.
-## RTE_ARCH values are the directories in mk/arch/
-##
-#CONFIG_RTE_ARCH="x86_64"
-#CONFIG_RTE_ARCH_X86_64=y
-#CONFIG_RTE_ARCH_X86=y
-#
-##
-## The compiler we use.
-## RTE_TOOLCHAIN values are the directories in mk/toolchain/
-##
-#CONFIG_RTE_TOOLCHAIN="gcc"
-#CONFIG_RTE_TOOLCHAIN_GCC=y
-
-#
-# Use intrinsics or assembly code for key routines
-#
-CONFIG_RTE_FORCE_INTRINSICS=n
-
-#
-# Machine forces strict alignment constraints.
-#
-CONFIG_RTE_ARCH_STRICT_ALIGN=n
-
-#
-# Compile to share library
-#
-CONFIG_RTE_BUILD_SHARED_LIB=n
-
-#
-# Use newest code breaking previous ABI
-#
-CONFIG_RTE_NEXT_ABI=y
-
-#
-# Machine's cache line size
-#
-CONFIG_RTE_CACHE_LINE_SIZE=64
-
-#
-# Compile Environment Abstraction Layer
-#
-CONFIG_RTE_LIBRTE_EAL=y
-CONFIG_RTE_MAX_LCORE=128
-CONFIG_RTE_MAX_NUMA_NODES=8
-CONFIG_RTE_MAX_MEMSEG=256
-CONFIG_RTE_MAX_MEMZONE=2560
-CONFIG_RTE_MAX_TAILQ=32
-CONFIG_RTE_LOG_LEVEL=8
-CONFIG_RTE_LOG_HISTORY=256
-CONFIG_RTE_LIBEAL_USE_HPET=n
-CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
-CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
-CONFIG_RTE_EAL_IGB_UIO=y
-CONFIG_RTE_EAL_VFIO=y
-CONFIG_RTE_MALLOC_DEBUG=n
-# Default driver path (or "" to disable)
-CONFIG_RTE_EAL_PMD_PATH=""
-
-#
-# Special configurations in PCI Config Space for high performance
-#
-CONFIG_RTE_PCI_CONFIG=n
-CONFIG_RTE_PCI_EXTENDED_TAG=""
-CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
+#include "common_base"
 
 #
 # Compile Environment Abstraction Layer for linux
@@ -116,182 +45,10 @@ CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
 CONFIG_RTE_LIBRTE_EAL_LINUXAPP=y
 
 #
-# Compile Environment Abstraction Layer to support Vmware TSC map
-#
-CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
-
-#
-# Compile the argument parser library
-#
-CONFIG_RTE_LIBRTE_KVARGS=y
-
-#
-# Compile generic ethernet library
-#
-CONFIG_RTE_LIBRTE_ETHER=y
-CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
-CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
-CONFIG_RTE_LIBRTE_IEEE1588=n
-CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
-CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
-
-#
-# Support NIC bypass logic
-#
-CONFIG_RTE_NIC_BYPASS=n
-
-#
-# Compile burst-oriented IGB & EM PMD drivers
-#
-CONFIG_RTE_LIBRTE_EM_PMD=y
-CONFIG_RTE_LIBRTE_IGB_PMD=y
-CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
-
-#
-# Compile burst-oriented IXGBE PMD driver
-#
-CONFIG_RTE_LIBRTE_IXGBE_PMD=y
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
-CONFIG_RTE_IXGBE_INC_VECTOR=y
-CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
-
-#
-# Compile burst-oriented I40E PMD driver
-#
-CONFIG_RTE_LIBRTE_I40E_PMD=y
-CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
-CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
-CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
-# interval up to 8160 us, aligned to 2 (or default value)
-CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
-
-#
-# Compile burst-oriented FM10K PMD
-#
-CONFIG_RTE_LIBRTE_FM10K_PMD=y
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_FM10K_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
-CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
-
-#
-# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
-#
-CONFIG_RTE_LIBRTE_MLX4_PMD=n
-CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
-
-#
-# Compile burst-oriented Mellanox ConnectX-4 (MLX5) PMD
-#
-CONFIG_RTE_LIBRTE_MLX5_PMD=n
-CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX5_SGE_WR_N=4
-CONFIG_RTE_LIBRTE_MLX5_MAX_INLINE=0
-CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
-
-#
-# Compile burst-oriented Broadcom PMD driver
-#
-CONFIG_RTE_LIBRTE_BNX2X_PMD=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
-CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
-
-#
-# Compile burst-oriented Chelsio Terminator 10GbE/40GbE (CXGBE) PMD
-#
-CONFIG_RTE_LIBRTE_CXGBE_PMD=y
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
-
-#
-# Compile burst-oriented Cisco ENIC PMD driver
-#
-CONFIG_RTE_LIBRTE_ENIC_PMD=y
-CONFIG_RTE_LIBRTE_ENIC_DEBUG=n
-
-#
-# Compile burst-oriented Netronome NFP PMD driver
-#
-CONFIG_RTE_LIBRTE_NFP_PMD=n
-CONFIG_RTE_LIBRTE_NFP_DEBUG=n
-
-#
-# Compile software PMD backed by SZEDATA2 device
-#
-CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
-
-#
-# Compile burst-oriented VIRTIO PMD driver
-#
-CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
-CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
-
-#
-# Compile burst-oriented VMXNET3 PMD driver
-#
-CONFIG_RTE_LIBRTE_VMXNET3_PMD=y
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
-CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
-
-#
-# Compile example software rings based PMD
-#
-CONFIG_RTE_LIBRTE_PMD_RING=y
-CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
-CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
-
-#
-# Compile software PMD backed by PCAP files
-#
-CONFIG_RTE_LIBRTE_PMD_PCAP=n
-
-#
-# Compile link bonding PMD library
+# Common configurations for Linux support enabled here from 'common_base' file.
 #
-CONFIG_RTE_LIBRTE_PMD_BOND=y
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
-CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+CONFIG_RTE_EAL_IGB_UIO=y
+CONFIG_RTE_EAL_VFIO=y
 
 #
 # Compile software PMD backed by AF_PACKET sockets (Linux only)
@@ -299,197 +56,15 @@ CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
 
 #
-# Compile Xen PMD
-#
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
-
-#
-# Compile null PMD
-#
-CONFIG_RTE_LIBRTE_PMD_NULL=y
-
-#
-# Do prefetch of packet data within PMD driver receive function
-#
-CONFIG_RTE_PMD_PACKET_PREFETCH=y
-
-#
-# Compile generic crypto device library
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_CRYPTODEV=y
-CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
-CONFIG_RTE_CRYPTO_MAX_DEVS=64
-CONFIG_RTE_CRYPTODEV_NAME_LEN=64
-
-#
-# Compile PMD for QuickAssist based devices
-#
-CONFIG_RTE_LIBRTE_PMD_QAT=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
-#
-# Number of sessions to create in the session memory pool
-# on a single QuickAssist device.
-#
-CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
-
-#
-# Compile PMD for AESNI backed device
-#
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
-CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
-CONFIG_RTE_AESNI_MB_PMD_MAX_NB_QUEUE_PAIRS=8
-CONFIG_RTE_AESNI_MB_PMD_MAX_NB_SESSIONS=2048
-
-#
-# Compile librte_ring
-#
-CONFIG_RTE_LIBRTE_RING=y
-CONFIG_RTE_LIBRTE_RING_DEBUG=n
-CONFIG_RTE_RING_SPLIT_PROD_CONS=n
-CONFIG_RTE_RING_PAUSE_REP_COUNT=0
-
-#
-# Compile librte_mempool
-#
-CONFIG_RTE_LIBRTE_MEMPOOL=y
-CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
-CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
-
-#
-# Compile librte_mbuf
-#
-CONFIG_RTE_LIBRTE_MBUF=y
-CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
-CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
-CONFIG_RTE_PKTMBUF_HEADROOM=128
-
-#
-# Compile librte_mbuf_offload
-# EXPERIMENTAL: API may change without prior notice
-#
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD=y
-CONFIG_RTE_LIBRTE_MBUF_OFFLOAD_DEBUG=n
-
-#
-# Compile librte_timer
-#
-CONFIG_RTE_LIBRTE_TIMER=y
-CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
-
-#
-# Compile librte_cfgfile
-#
-CONFIG_RTE_LIBRTE_CFGFILE=y
-
-#
-# Compile librte_cmdline
-#
-CONFIG_RTE_LIBRTE_CMDLINE=y
-CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
-
-#
-# Compile librte_hash
-#
-CONFIG_RTE_LIBRTE_HASH=y
-CONFIG_RTE_LIBRTE_HASH_DEBUG=n
-
-#
-# Compile librte_jobstats
-#
-CONFIG_RTE_LIBRTE_JOBSTATS=y
-
-#
-# Compile librte_lpm
-#
-CONFIG_RTE_LIBRTE_LPM=y
-CONFIG_RTE_LIBRTE_LPM_DEBUG=n
-
-#
-# Compile librte_acl
-#
-CONFIG_RTE_LIBRTE_ACL=y
-CONFIG_RTE_LIBRTE_ACL_DEBUG=n
-
-#
 # Compile librte_power
 #
 CONFIG_RTE_LIBRTE_POWER=y
-CONFIG_RTE_LIBRTE_POWER_DEBUG=n
-CONFIG_RTE_MAX_LCORE_FREQS=64
-
-#
-# Compile librte_net
-#
-CONFIG_RTE_LIBRTE_NET=y
-
-#
-# Compile librte_ip_frag
-#
-CONFIG_RTE_LIBRTE_IP_FRAG=y
-CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
-CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
-CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
-
-#
-# Compile librte_meter
-#
-CONFIG_RTE_LIBRTE_METER=y
-
-#
-# Compile librte_sched
-#
-CONFIG_RTE_LIBRTE_SCHED=y
-CONFIG_RTE_SCHED_DEBUG=n
-CONFIG_RTE_SCHED_RED=n
-CONFIG_RTE_SCHED_COLLECT_STATS=n
-CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
-CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
-CONFIG_RTE_SCHED_VECTOR=n
-
-#
-# Compile the distributor library
-#
-CONFIG_RTE_LIBRTE_DISTRIBUTOR=y
-
-#
-# Compile the reorder library
-#
-CONFIG_RTE_LIBRTE_REORDER=y
-
-#
-# Compile librte_port
-#
-CONFIG_RTE_LIBRTE_PORT=y
-CONFIG_RTE_PORT_STATS_COLLECT=n
-
-#
-# Compile librte_table
-#
-CONFIG_RTE_LIBRTE_TABLE=y
-CONFIG_RTE_TABLE_STATS_COLLECT=n
-
-#
-# Compile librte_pipeline
-#
-CONFIG_RTE_LIBRTE_PIPELINE=y
-CONFIG_RTE_PIPELINE_STATS_COLLECT=n
 
 #
 # Compile librte_kni
 #
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_KNI_KMOD=y
-CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
-CONFIG_RTE_KNI_KO_DEBUG=n
-CONFIG_RTE_KNI_VHOST=n
-CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
-CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
-CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
-CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 
 #
 # Compile vhost library
@@ -498,28 +73,3 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 # vhost-user is turned on by default.
 #
 CONFIG_RTE_LIBRTE_VHOST=y
-CONFIG_RTE_LIBRTE_VHOST_USER=y
-CONFIG_RTE_LIBRTE_VHOST_NUMA=n
-CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
-
-#
-#Compile Xen domain0 support
-#
-CONFIG_RTE_LIBRTE_XEN_DOM0=n
-
-#
-# Enable warning directives
-#
-CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
-
-#
-# Compile the test application
-#
-CONFIG_RTE_APP_TEST=y
-
-#
-# Compile the PMD test application
-#
-CONFIG_RTE_TEST_PMD=y
-CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
-CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
-- 
2.7.0

^ permalink raw reply	[relevance 6%]

Results 12201-12400 of ~19000   |  | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2015-11-05 18:31     [dpdk-dev] [RFC 0/5] virtio support for container Jianfeng Tan
2016-02-05 11:20     ` [dpdk-dev] [PATCH v2 " Jianfeng Tan
2016-02-05 11:20       ` [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file Jianfeng Tan
2016-03-07 13:13  0%     ` Yuanhan Liu
2016-03-08  1:55  0%       ` Tan, Jianfeng
2016-03-08  2:44  0%         ` Yuanhan Liu
2016-03-09 14:44  0%           ` Tan, Jianfeng
2016-03-08  8:49  0%       ` Panu Matilainen
2015-12-21  2:38     [dpdk-dev] [PATCH 2/3] eal: remove pci config of extended tag Helin Zhang
2016-02-22  3:59     ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
2016-02-22  3:59       ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
2016-03-08 18:02  0%     ` Thomas Monjalon
2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 0/3] enable extended tag for i40e Thomas Monjalon
2016-03-08 18:38  4%     ` [dpdk-dev] [PATCH v3 2/3] pci: remove config of extended tag Thomas Monjalon
2015-12-31  6:53     [dpdk-dev] [PATCH 00/12] Add API to get packet type info Jianfeng Tan
2016-03-09 19:31     ` [dpdk-dev] [PATCH v7 00/11] " Jianfeng Tan
2016-03-09 19:31  4%   ` [dpdk-dev] [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
2016-01-04 14:46     [dpdk-dev] [PATCH] vhost: remove lockless enqueue to the virtio ring Huawei Xie
2016-01-05  7:16     ` Xie, Huawei
2016-03-14 23:13  0%   ` Thomas Monjalon
2016-03-16  8:20  0%     ` Xie, Huawei
2016-03-16  8:30  0%       ` Yuanhan Liu
2016-01-11  7:07     [dpdk-dev] [PATCH 0/4] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-04  2:35     ` [dpdk-dev] [PATCH v7 0/5] " Wenzhuo Lu
2016-03-04  2:35       ` [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-08 23:35  0%     ` Thomas Monjalon
2016-03-09  0:53  0%       ` Lu, Wenzhuo
2016-03-09  1:04  0%         ` Thomas Monjalon
2016-03-09  1:25  0%           ` Lu, Wenzhuo
2016-03-09  3:35  3% ` [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-09  3:35  4%   ` [dpdk-dev] [PATCH v8 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-09  9:48         ` Thomas Monjalon
2016-03-10  0:40  3%       ` Lu, Wenzhuo
2016-03-09  3:35  7%   ` [dpdk-dev] [PATCH v8 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
2016-03-10  2:42  3% ` [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-10  2:42  3%   ` [dpdk-dev] [PATCH v9 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-11 23:02  3%     ` Thomas Monjalon
2016-03-10  2:42  7%   ` [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
2016-01-22  1:37     [dpdk-dev] [PATCH 0/2] i40e setting ether type of VLANs Helin Zhang
2016-03-07  8:12  4% ` [dpdk-dev] [PATCH v2 0/3] " Helin Zhang
2016-03-07  8:12  8%   ` [dpdk-dev] [PATCH v2 1/3] ethdev: add vlan type for setting ether type Helin Zhang
2016-03-07  8:12  3%   ` [dpdk-dev] [PATCH v2 2/3] i40e: add VLAN ether type config Helin Zhang
2016-03-07  9:28  0%   ` [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs Thomas Monjalon
2016-03-09 15:20  0%     ` Zhang, Helin
2016-03-10 16:36  4%   ` [dpdk-dev] [PATCH v3 0/2] " Helin Zhang
2016-03-10 16:36  7%     ` [dpdk-dev] [PATCH v3 1/2] ethdev: add vlan type for setting ether type Helin Zhang
2016-03-11  2:36  0%     ` [dpdk-dev] [PATCH v3 0/2] i40e setting ether type of VLANs Lu, Wenzhuo
2016-03-11  8:49  4%     ` [dpdk-dev] [PATCH v4 " Helin Zhang
2016-03-11  8:49  7%       ` [dpdk-dev] [PATCH v4 1/2] ethdev: add vlan type for setting ether type Helin Zhang
2016-03-11 11:19  3%         ` Panu Matilainen
2016-03-11 11:20  0%           ` Thomas Monjalon
2016-03-11 14:17  4%             ` Zhang, Helin
2016-03-11 14:20  3%               ` Thomas Monjalon
2016-03-11 16:50  5%       ` [dpdk-dev] [PATCH v5 0/2] i40e setting ether type of VLANs Helin Zhang
2016-03-11 16:50  7%         ` [dpdk-dev] [PATCH v5 1/2] ethdev: add vlan type for setting ether type Helin Zhang
2016-01-27  8:37     [dpdk-dev] [PATCH] ethdev: fix byte order inconsistence between fdir flow and mask Jingjing Wu
2016-02-01  2:48     ` [dpdk-dev] [PATCH v2] " Jingjing Wu
2016-03-08 23:12  0%   ` Thomas Monjalon
2016-02-12 18:36     [dpdk-dev] [PATCH v4] mempool: reduce rte_mempool structure size Keith Wiles
2016-04-14  9:42  2% ` [dpdk-dev] [PATCH v5] " Olivier Matz
2016-04-14 13:28  0%   ` Wiles, Keith
2016-04-14 13:53  0%   ` Wiles, Keith
2016-02-16  4:15     [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure Ziye Yang
2016-02-17  1:54     ` [dpdk-dev] [PATCH v3] " Ziye Yang
2016-02-17 10:14       ` Bruce Richardson
2016-04-05 15:31  4%     ` Thomas Monjalon
2016-02-16 14:48     [dpdk-dev] [PATCH 0/6] external mempool manager David Hunt
2016-03-09  9:50  3% ` [dpdk-dev] [PATCH v3 0/4] " David Hunt
2016-03-09  9:50  4%   ` [dpdk-dev] [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages David Hunt
2016-03-09 10:46  7%     ` Panu Matilainen
2016-03-09 11:30  4%       ` Hunt, David
2016-03-09 14:59  4%         ` Olivier MATZ
2016-03-09 16:28  7%           ` Hunt, David
2016-03-09 16:31  4%             ` Olivier MATZ
2016-03-09 16:39  4%               ` Hunt, David
2016-04-14 13:57  2%   ` [dpdk-dev] [PATCH v4 0/3] external mempool manager Olivier Matz
2016-02-17 11:11     [dpdk-dev] [PATCH v2 0/4] Add PCAP support to source and sink port Fan Zhang
2016-02-17 11:11     ` [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port Fan Zhang
2016-03-07 11:17  3%   ` Thomas Monjalon
2016-03-08  8:36  4%     ` Dumitrescu, Cristian
2016-03-08  9:06  4%       ` Panu Matilainen
2016-03-08 10:14  4%       ` Thomas Monjalon
2016-02-17 14:20     [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data Ferruh Yigit
2016-03-10  0:00  0% ` Thomas Monjalon
2016-03-10 13:37  0%   ` Ferruh Yigit
2016-02-19  6:32     [dpdk-dev] [PATCH RFC 0/4] Thread safe rte_vhost_enqueue_burst() Ilya Maximets
2016-02-19  6:32     ` [dpdk-dev] [PATCH RFC 2/4] vhost: make buf vector for scatter RX local Ilya Maximets
2016-02-19  7:06       ` Yuanhan Liu
2016-04-05  5:47  4%     ` [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local Yuanhan Liu
2016-04-05  8:37  0%       ` Thomas Monjalon
2016-04-05 14:06  0%         ` Yuanhan Liu
2016-04-06  4:14  0%       ` Flavio Leitner
2016-02-24 17:08     [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Tomasz Kulasek
2016-03-10 10:57  4% ` [dpdk-dev] [PATCH v3 " Tomasz Kulasek
2016-03-10 11:31  0%   ` Ananyev, Konstantin
2016-03-10 16:01  0%     ` Jastrzebski, MichalX K
2016-03-10 17:19  4%   ` [dpdk-dev] [PATCH v4 " Tomasz Kulasek
2016-03-01  3:47     [dpdk-dev] [PATCH v6 0/4] Add tunnel filter support for IP in GRE on i40e Xutao Sun
2016-03-01  8:41     ` [dpdk-dev] [PATCH v7 " Xutao Sun
2016-03-01  8:41       ` [dpdk-dev] [PATCH v7 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure Xutao Sun
2016-03-08 23:08  0%     ` Thomas Monjalon
2016-03-08 23:20  0%       ` Thomas Monjalon
2016-03-10  3:05       ` [dpdk-dev] [PATCH v8 0/4] This patch set adds tunnel filter support for IP in GRE on i40e Jingjing Wu
2016-03-10  3:05 13%     ` [dpdk-dev] [PATCH v8 1/4] lib/ether: optimize struct rte_eth_tunnel_filter_conf Jingjing Wu
2016-03-01 15:41     [dpdk-dev] [PATCH v4 0/4] Use common Linux tools to control DPDK ports Ferruh Yigit
2016-03-09 11:41     ` [dpdk-dev] [PATCH v5 " Ferruh Yigit
2016-03-09 11:41  1%   ` [dpdk-dev] [PATCH v5 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder Ferruh Yigit
2016-03-02 11:29     [dpdk-dev] [PATCH v2 00/12] extend flow director's fields in i40e driver Jingjing Wu
2016-03-09  5:42  4% ` [dpdk-dev] [PATCH v3 00/12] extend flow director " Jingjing Wu
2016-03-09  5:42 18%   ` [dpdk-dev] [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
2016-03-09  6:18  0%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
2016-03-10  3:25  4%   ` [dpdk-dev] [PATCH v4 " Jingjing Wu
2016-03-10  3:25 18%     ` [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
2016-03-21  6:18  4%     ` [dpdk-dev] [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
2016-03-21  6:18 18%       ` [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
2016-03-22 22:05  0%         ` Thomas Monjalon
2016-03-23  0:42  0%           ` Wu, Jingjing
2016-03-23  8:45  0%             ` Thomas Monjalon
2016-03-23 13:07  4%       ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Jingjing Wu
2016-03-23 13:07 19%         ` [dpdk-dev] [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
2016-03-23 14:46  0%         ` [dpdk-dev] [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson
2016-03-03 11:01     [dpdk-dev] [PATCH v4] librte_pipeline: add support for packet redirection at action handlers Jasvinder Singh
2016-03-08 18:07  2% ` [dpdk-dev] [PATCH v5 1/2] " Jasvinder Singh
2016-03-03 18:37     [dpdk-dev] [PATCH] config: remove duplicate configuration information Thomas Monjalon
2016-03-04 17:01  6% ` [dpdk-dev] [PATCH v2] " Keith Wiles
2016-03-04 18:11  6% ` [dpdk-dev] [PATCH v3] " Keith Wiles
2016-03-08 20:52     [dpdk-dev] [PATCH v3 0/2] Increased number of next hops for LPM IPv4 Michal Kobylinski
2016-03-09 12:40     ` [dpdk-dev] [PATCH v4] lpm: extended ipv4 next_hop field Michal Jastrzebski
2016-03-09 13:39  3%   ` Thomas Monjalon
2016-03-09 11:59 13% [dpdk-dev] [PATCH] doc: fix API change in release note Jingjing Wu
2016-03-09 16:15  0% ` Thomas Monjalon
2016-03-09 14:14  8% [dpdk-dev] [PATCH 1/2] ethdev: bump library version Thomas Monjalon
2016-03-09 14:14  8% ` [dpdk-dev] [PATCH 2/2] cmdline: " Thomas Monjalon
2016-03-09 15:09  0% ` [dpdk-dev] [PATCH 1/2] ethdev: " Nélio Laranjeiro
2016-03-09 15:16  0%   ` Thomas Monjalon
2016-03-09 16:19  2% [dpdk-dev] [RFC 00/35] mempool: rework memory allocation Olivier Matz
2016-03-17  9:05 15% ` [dpdk-dev] [PATCH] doc: mempool ABI deprecation notice for 16.07 Olivier Matz
2016-04-04 14:38  4%   ` Thomas Monjalon
2016-04-05  9:27  4%     ` Hunt, David
2016-04-05 14:08  4%       ` Wiles, Keith
2016-04-05 15:17  4%         ` Thomas Monjalon
2016-04-14 10:19  2% ` [dpdk-dev] [PATCH 00/36] mempool: rework memory allocation Olivier Matz
2016-04-14 13:50  0%   ` Wiles, Keith
2016-04-14 14:01  0%     ` Olivier MATZ
2016-04-14 14:03  0%       ` Wiles, Keith
     [not found]     <1453911849-16562-1-git-send-email-ferruh.yigit@intel.com>
2016-03-02 11:21     ` [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module Thomas Monjalon
2016-03-02 22:35       ` Thomas Monjalon
2016-03-10  0:04  0%     ` Thomas Monjalon
2016-03-10  6:31  0%       ` Vincent JARDIN
2016-03-10 10:53 31% [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Panu Matilainen
2016-03-10 10:53 19% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
2016-03-10 12:25  4%   ` Ferruh Yigit
2016-03-10 12:36  4%     ` Panu Matilainen
2016-03-10 10:53 15% ` [dpdk-dev] [PATCH 3/3] scripts: ignore self-generated directories in validate-abi startup check Panu Matilainen
2016-03-10 12:22  4%   ` Ferruh Yigit
2016-03-10 12:29  4%     ` Panu Matilainen
2016-03-10 12:34  4%       ` Ferruh Yigit
2016-03-10 12:39  4%         ` Panu Matilainen
2016-03-10 12:47  4%           ` Ferruh Yigit
2016-03-10 12:52  7% ` [dpdk-dev] [PATCH 1/3] scripts: support parallel building in validate-abi.sh via -j[N] option Ferruh Yigit
2016-03-10 11:55  7% [dpdk-dev] [PATCH] doc: add mempool mgr ABI deprication notice David Hunt
2016-03-10 12:37  4% ` Olivier MATZ
2016-03-10 13:15  4%   ` Bruce Richardson
2016-03-10 13:56  4%     ` Wiles, Keith
2016-03-10 14:55  4%       ` Thomas Monjalon
2016-04-05 14:06  4%         ` Wiles, Keith
2016-04-04 14:49  4%       ` Thomas Monjalon
2016-03-10 16:23  4% ` Mcnamara, John
2016-03-10 14:44     [dpdk-dev] [PATCH] mempool: allow for user-owned mempool caches Lazaros Koromilas
2016-03-21 12:22  4% ` Olivier Matz
2016-03-21 13:49  3%   ` Wiles, Keith
2016-03-24 14:35  0%     ` Lazaros Koromilas
2016-03-24 14:58  0%       ` Venkatesan, Venky
2016-03-24 15:03  0%       ` Wiles, Keith
2016-03-17 18:08     [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
2016-03-25 19:42     ` [dpdk-dev] [PATCH v12 " Thomas Monjalon
2016-03-25 19:42  3%   ` [dpdk-dev] [PATCH v12 6/8] ethdev: redesign link speed config Thomas Monjalon
2016-03-26  1:27       ` [dpdk-dev] [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
2016-03-26  1:27         ` [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants Marc Sune
2016-04-06  8:34  2%       ` Weglicki, MichalX
2016-04-06  8:52  0%         ` Thomas Monjalon
2016-04-06  9:16  3%           ` Weglicki, MichalX
2016-04-06  9:34  3%             ` Thomas Monjalon
2016-03-26  1:27  3%     ` [dpdk-dev] [PATCH v13 6/8] ethdev: redesign link speed config Marc Sune
2016-03-31 22:12         ` [dpdk-dev] [PATCH v14 0/8] ethdev: 100G and link speed API refactoring Marc Sune
2016-03-31 22:12  3%       ` [dpdk-dev] [PATCH v14 6/8] ethdev: redesign link speed config Marc Sune
2016-03-18 17:16     [dpdk-dev] DPDK and HW offloads Stephen Hemminger
2016-03-18 18:00     ` Thomas Monjalon
2016-03-20 14:17       ` Zhang, Helin
2016-03-20 19:18         ` Thomas Monjalon
2016-03-21 14:52           ` Bruce Richardson
2016-03-21 15:26  3%         ` Kyle Larose
2016-03-22  5:50  0%           ` Qiu, Michael
2016-03-22 10:19  0%             ` Bruce Richardson
2016-03-23  2:47  0%               ` Qiu, Michael
2016-03-25 16:29  5% [dpdk-dev] [PATCH] doc: postpone flow director changes planned for cxgbe Thomas Monjalon
2016-03-31  8:21  2% [dpdk-dev] 16.07 Roadmap O'Driscoll, Tim
2016-03-31 13:28 16% [dpdk-dev] [PATCH] doc: announce ABI change for rte_port_source_params structure Fan Zhang
2016-03-31 13:29 16% Fan Zhang
2016-04-05 15:45  7% ` Thomas Monjalon
2016-04-05 21:16  4% ` Singh, Jasvinder
2016-04-06  8:51  4%   ` Azarewicz, PiotrX T
2016-04-07 21:24  4%     ` Thomas Monjalon
2016-04-12 12:39  4%       ` Thomas Monjalon
2016-04-05  9:23  9% [dpdk-dev] [PATCH] doc: announce ABI changes for user-owned mempool caches Lazaros Koromilas
2016-04-05 15:42  4% ` Olivier Matz
2016-04-08 14:01  4%   ` Hunt, David
2016-04-10  9:55  4%     ` Thomas Monjalon
2016-04-05 13:56     [dpdk-dev] DPDK namespace Thomas Monjalon
2016-04-05 14:13  3% ` Trahe, Fiona
2016-04-05 14:31  0%   ` Trahe, Fiona
2016-04-05 14:31  0%   ` Arnon Warshavsky
2016-04-06  5:26  0%     ` Yuanhan Liu
2016-04-06 12:07  0%       ` Panu Matilainen
2016-04-06 12:34  0%         ` Ananyev, Konstantin
2016-04-06 14:36  0%         ` Wiles, Keith
2016-04-06 20:21             ` Dave Neary
2016-04-07  8:22  3%           ` Marc
2016-04-07  9:18     ` Thomas Monjalon
2016-04-07  9:33  3%   ` Panu Matilainen
2016-04-07 10:16  5%     ` Marc Sune
2016-04-07 11:51  9%       ` [dpdk-dev] On DPDK ABI policy Panu Matilainen
2016-04-07 21:52  4%         ` Matthew Hall
2016-04-08  8:29  4%           ` Marc Sune
2016-04-08  8:47  9%         ` Marc Sune
2016-04-07 21:48  0%       ` [dpdk-dev] DPDK namespace Matthew Hall
2016-04-05 17:58  9% [dpdk-dev] [PATCH] doc: announce xstats api change for 16.07 Harry van Haaren
2016-04-05 18:45  0% ` Thomas Monjalon
2016-04-06  9:02  0%   ` Van Haaren, Harry
2016-04-06  9:22  0%     ` Thomas Monjalon
2016-04-06 11:16  3%       ` Van Haaren, Harry
2016-04-06 12:14  0%         ` Thomas Monjalon
2016-04-06 13:49  0%           ` David Harton (dharton)
2016-04-06 14:00  0% ` David Harton (dharton)
2016-04-06  5:11  0% [dpdk-dev] [RFC] vhost-user public struct refactor (was Re: [PATCH RFC 2/4] vhost: make buf vector for scatter RX) local Ilya Maximets
2016-04-06  6:53 15% [dpdk-dev] [PATCH] vhost: ABI/API change announcement due to refactor Yuanhan Liu
2016-04-07  7:12  7% ` Panu Matilainen
2016-04-10  9:58  4%   ` Thomas Monjalon
2016-04-10 10:02  4%     ` Thomas Monjalon
2016-04-06  9:53     [dpdk-dev] Fw: dpdk-armv7-testing - Build # 43 - Failure! Jan Viktorin
2016-04-06 10:05     ` Thomas Monjalon
2016-04-06 10:18  4%   ` Jan Viktorin
2016-04-07 15:33  5% [dpdk-dev] [PATCH] doc: announce API changes for device objects David Marchand
2016-04-07 15:46  0% ` Jan Viktorin
2016-04-07 17:00  0%   ` David Marchand
2016-04-07 17:09  3%     ` Jan Viktorin
2016-04-07 17:24  0%       ` David Marchand
2016-04-07 16:02  8% [dpdk-dev] [PATCH v1] doc: fix release notes for 16.04 John McNamara
2016-04-12 12:01  6% [dpdk-dev] [PATCH v1] doc: add template release notes for 16.11 John McNamara
2016-04-12 12:55  6% [dpdk-dev] [PATCH v1] doc: add template release notes for 16.07 John McNamara
2016-04-14  9:44  4% [dpdk-dev] [RFC 0/2] add new fields to rte_eth_dev_info structure Reshma Pattan
2016-04-14  9:44  9% ` [dpdk-dev] [RFC 1/2] doc: announce ABI change for " Reshma Pattan
2016-04-15  9:42  4%   ` Mcnamara, John
2016-04-15 10:02  8%   ` Thomas Monjalon
2016-04-14  9:44     ` [dpdk-dev] [RFC 2/2] librte_ether: add new fields to rte_eth_dev_info struct Reshma Pattan
2016-04-15 10:36  3%   ` Thomas Monjalon
2016-04-14 18:33 25% [dpdk-dev] [PATCH] port: bump ABI for pcap file support Thomas Monjalon
2016-04-15 10:32  4% ` Dumitrescu, Cristian
2016-04-14 21:33  4% [dpdk-dev] [PATCH] pci: remove deprecated specific config Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).