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] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  @ 2016-02-03 17:23  0%       ` Olivier MATZ
  2016-02-22 14:49  0%         ` Xie, Huawei
  0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2016-02-03 17:23 UTC (permalink / raw)
  To: Panu Matilainen, Huawei Xie, dev; +Cc: dprovan

Hi,

On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>
> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
> the library ABI and should not be listed in the version map.
>
> I assume its inline for performance reasons, but then you lose the
> benefits of dynamic linking such as ability to fix bugs and/or improve
> itby just updating the library. Since the point of having a bulk API is
> to improve performance by reducing the number of calls required, does it
> really have to be inline? As in, have you actually measured the
> difference between inline and non-inline and decided its worth all the
> downsides?

Agree with Panu. It would be interesting to compare the performance
between inline and non inline to decide whether inlining it or not.

Also, it would be nice to have a simple test function in
app/test/test_mbuf.c. For instance, you could update
test_one_pktmbuf() to take a mbuf pointer as a parameter and remove
the mbuf allocation from the function. Then it could be called with
a mbuf allocated with rte_pktmbuf_alloc() (like before) and with
all the mbufs of rte_pktmbuf_alloc_bulk().

Regards,
Olivier

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2 1/5] mem: add --single-file to create single mem-backed file
  @ 2016-02-05 11:20  2%   ` Jianfeng Tan
  2016-03-07 13:13  0%     ` Yuanhan Liu
  0 siblings, 1 reply; 200+ results
From: Jianfeng Tan @ 2016-02-05 11:20 UTC (permalink / raw)
  To: dev; +Cc: nakajima.yoshihiro, mst, ann.zhuangyanying

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>
---
 lib/librte_eal/common/eal_common_options.c | 17 ++++++++++
 lib/librte_eal/common/eal_internal_cfg.h   |  1 +
 lib/librte_eal/common/eal_options.h        |  2 ++
 lib/librte_eal/linuxapp/eal/eal.c          |  4 +--
 lib/librte_eal/linuxapp/eal/eal_memory.c   | 50 +++++++++++++++++++++++++-----
 5 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..65bccbd 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_SINGLE_FILE,       0, NULL, OPT_SINGLE_FILE_NUM      },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -897,6 +898,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		}
 		break;
 
+	case OPT_SINGLE_FILE_NUM:
+		conf->single_file = 1;
+		break;
+
 	/* don't know what to do, leave this to caller */
 	default:
 		return 1;
@@ -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;
+	}
 
 	if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink) {
 		RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
@@ -994,6 +1009,8 @@ eal_common_usage(void)
 	       "  -n CHANNELS         Number of memory channels\n"
 	       "  -m MB               Memory to allocate (see also --"OPT_SOCKET_MEM")\n"
 	       "  -r RANKS            Force number of memory ranks (don't detect)\n"
+	       "  --"OPT_SINGLE_FILE" Create just single file for shared memory, and \n"
+	       "                      do not promise physical contiguity of memseg\n"
 	       "  -b, --"OPT_PCI_BLACKLIST" Add a PCI device in black list.\n"
 	       "                      Prevent EAL from using this PCI device. The argument\n"
 	       "                      format is <domain:bus:devid.func>.\n"
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..9117ed9 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -61,6 +61,7 @@ struct hugepage_info {
  */
 struct internal_config {
 	volatile size_t memory;           /**< amount of asked memory */
+	volatile unsigned single_file;    /**< mmap all hugepages in single file */
 	volatile unsigned force_nchannel; /**< force number of channels */
 	volatile unsigned force_nrank;    /**< force number of ranks */
 	volatile unsigned no_hugetlbfs;   /**< true to disable hugetlbfs */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..e5da14a 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_SINGLE_FILE       "single-file"
+	OPT_SINGLE_FILE_NUM,
 	OPT_LONG_MAX_NUM
 };
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 635ec36..2bc84f7 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -790,6 +790,8 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init IVSHMEM\n");
 #endif
 
+	eal_thread_init_master(rte_config.master_lcore);
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
@@ -823,8 +825,6 @@ rte_eal_init(int argc, char **argv)
 	if (eal_plugins_init() < 0)
 		rte_panic("Cannot init plugins\n");
 
-	eal_thread_init_master(rte_config.master_lcore);
-
 	ret = eal_thread_dump_affinity(cpuset, RTE_CPU_AFFINITY_STR_LEN);
 
 	RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%x;cpuset=[%s%s])\n",
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;
+
+		close(fd);
+
 		return 0;
 	}
 
-- 
2.1.4

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v2 0/5] clean-up cpuflags
  @ 2016-02-06 22:17  3% ` Thomas Monjalon
  2016-02-06 22:17  1%   ` [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
  2016-02-16  7:30  0%   ` [dpdk-dev] [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon
  0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

Following the work of Ferruh, I suggest this cleanup to remove as much
as possible of the code from the cpuflags headers.
The goal is to un-inline these functions (not performance sensitive)
and remove the CPU flags table from the ABI (just added recently).
The bonus is to stop mimic x86 in ARM and PPC implementations.

WARNING: it has not been tested nor compiled on Tilera and POWER8.

v2 changes:
- fix maintainers file
- fix include from C++ app
- fix missing REG_PLATFORM for ARM
- suggested ARM refactor from Jerin

Thomas Monjalon (5):
  eal: get CPU flag name
  eal: move CPU flag functions out of headers
  eal/arm: adapt CPU flags check to the arch
  eal/ppc: adapt CPU flags check to the arch
  eal: remove compiler optimization workaround

 MAINTAINERS                                        |   4 +
 app/test/test_hash_scaling.c                       |   2 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   2 +-
 lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 179 ++++++++++++++++-----
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   | 145 +++++++++++++----
 lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  91 +++++++++++
 lib/librte_eal/common/eal_common_cpuflags.c        |  18 +--
 .../common/include/arch/arm/rte_cpuflags_32.h      |  80 +--------
 .../common/include/arch/arm/rte_cpuflags_64.h      |  81 +---------
 .../common/include/arch/ppc_64/rte_cpuflags.h      |  66 +-------
 .../common/include/arch/tile/rte_cpuflags.h        |  31 +---
 .../common/include/arch/x86/rte_cpuflags.h         |  68 +-------
 .../common/include/generic/rte_cpuflags.h          |  56 ++-----
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   2 +-
 15 files changed, 378 insertions(+), 458 deletions(-)

-- 
2.7.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers
  2016-02-06 22:17  3% ` [dpdk-dev] [PATCH v2 " Thomas Monjalon
@ 2016-02-06 22:17  1%   ` Thomas Monjalon
  2016-02-08  8:59  0%     ` Jerin Jacob
  2016-02-16  7:30  0%   ` [dpdk-dev] [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The patch c344eab3ee has moved the hardware definition of CPU flags.
Now the functions checking these hardware flags are also moved.
The function rte_cpu_get_flag_enabled() is no more inline.

The benefits are:
- remove rte_cpu_feature_table from the ABI (recently added)
- hide hardware details from the API
- allow to adapt structures per arch (done in next patch)

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 MAINTAINERS                                        |   4 +
 app/test/test_hash_scaling.c                       |   2 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   1 -
 lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 125 ++++++++++++++++++---
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   |  79 +++++++++++++
 lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  83 ++++++++++++++
 lib/librte_eal/common/eal_common_cpuflags.c        |   3 +
 .../common/include/arch/arm/rte_cpuflags_32.h      |  80 +------------
 .../common/include/arch/arm/rte_cpuflags_64.h      |  81 +------------
 .../common/include/arch/ppc_64/rte_cpuflags.h      |  66 +----------
 .../common/include/arch/tile/rte_cpuflags.h        |  31 +----
 .../common/include/arch/x86/rte_cpuflags.h         |  68 +----------
 .../common/include/generic/rte_cpuflags.h          |  50 +--------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   1 -
 15 files changed, 300 insertions(+), 385 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b90aeea..628bc05 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -131,6 +131,7 @@ F: doc/guides/sample_app_ug/multi_process.rst
 ARM v7
 M: Jan Viktorin <viktorin@rehivetech.com>
 M: Jianbo Liu <jianbo.liu@linaro.org>
+F: lib/librte_eal/common/arch/arm/
 F: lib/librte_eal/common/include/arch/arm/
 
 ARM v8
@@ -141,16 +142,19 @@ F: lib/librte_acl/acl_run_neon.*
 
 EZchip TILE-Gx
 M: Zhigang Lu <zlu@ezchip.com>
+F: lib/librte_eal/common/arch/tile/
 F: lib/librte_eal/common/include/arch/tile/
 F: drivers/net/mpipe/
 
 IBM POWER
 M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
+F: lib/librte_eal/common/arch/ppc_64/
 F: lib/librte_eal/common/include/arch/ppc_64/
 
 Intel x86
 M: Bruce Richardson <bruce.richardson@intel.com>
 M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: lib/librte_eal/common/arch/x86/
 F: lib/librte_eal/common/include/arch/x86/
 
 Linux EAL (with overlaps)
diff --git a/app/test/test_hash_scaling.c b/app/test/test_hash_scaling.c
index 744e5e3..1c4c75d 100644
--- a/app/test/test_hash_scaling.c
+++ b/app/test/test_hash_scaling.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stdio.h>
+
 #include <rte_cycles.h>
 #include <rte_hash.h>
 #include <rte_hash_crc.h>
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 9bea0e2..1a96203 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -142,6 +142,5 @@ DPDK_2.3 {
 	rte_cpu_get_flag_name;
 	rte_eal_pci_map_device;
 	rte_eal_pci_unmap_device;
-	rte_cpu_feature_table;
 
 } DPDK_2.2;
diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index 62e0791..cd7a7b1 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright (C) Cavium networks Ltd. 2015.
+ *   Copyright(c) 2015 RehiveTech. All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
@@ -32,19 +33,51 @@
 
 #include "rte_cpuflags.h"
 
-#ifdef RTE_ARCH_64
-const struct feature_entry rte_cpu_feature_table[] = {
-	FEAT_DEF(FP,		0x00000001, 0, REG_HWCAP,  0)
-	FEAT_DEF(NEON,		0x00000001, 0, REG_HWCAP,  1)
-	FEAT_DEF(EVTSTRM,	0x00000001, 0, REG_HWCAP,  2)
-	FEAT_DEF(AES,		0x00000001, 0, REG_HWCAP,  3)
-	FEAT_DEF(PMULL,		0x00000001, 0, REG_HWCAP,  4)
-	FEAT_DEF(SHA1,		0x00000001, 0, REG_HWCAP,  5)
-	FEAT_DEF(SHA2,		0x00000001, 0, REG_HWCAP,  6)
-	FEAT_DEF(CRC32,		0x00000001, 0, REG_HWCAP,  7)
-	FEAT_DEF(AARCH64,	0x00000001, 0, REG_PLATFORM, 1)
+#include <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef AT_HWCAP
+#define AT_HWCAP 16
+#endif
+
+#ifndef AT_HWCAP2
+#define AT_HWCAP2 26
+#endif
+
+#ifndef AT_PLATFORM
+#define AT_PLATFORM 15
+#endif
+
+enum cpu_register_t {
+	REG_HWCAP = 0,
+	REG_HWCAP2,
+	REG_PLATFORM,
+};
+
+typedef uint32_t cpuid_registers_t[4];
+
+/**
+ * Struct to hold a processor feature entry
+ */
+struct feature_entry {
+	uint32_t leaf;				/**< cpuid leaf */
+	uint32_t subleaf;			/**< cpuid subleaf */
+	uint32_t reg;				/**< cpuid register */
+	uint32_t bit;				/**< cpuid register bit */
+#define CPU_FLAG_NAME_MAX_LEN 64
+	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
 };
-#else
+
+#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
+	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+
+#ifdef RTE_ARCH_ARMv7
+#define PLATFORM_STR "v7l"
+typedef Elf32_auxv_t _Elfx_auxv_t;
+
 const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(SWP,       0x00000001, 0, REG_HWCAP,  0)
 	FEAT_DEF(HALF,      0x00000001, 0, REG_HWCAP,  1)
@@ -75,7 +108,73 @@ const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(CRC32,     0x00000001, 0, REG_HWCAP2,  4)
 	FEAT_DEF(V7L,       0x00000001, 0, REG_PLATFORM, 0)
 };
-#endif
+
+#elif defined RTE_ARCH_ARM64
+#define PLATFORM_STR "aarch64"
+typedef Elf64_auxv_t _Elfx_auxv_t;
+
+const struct feature_entry rte_cpu_feature_table[] = {
+	FEAT_DEF(FP,		0x00000001, 0, REG_HWCAP,  0)
+	FEAT_DEF(NEON,		0x00000001, 0, REG_HWCAP,  1)
+	FEAT_DEF(EVTSTRM,	0x00000001, 0, REG_HWCAP,  2)
+	FEAT_DEF(AES,		0x00000001, 0, REG_HWCAP,  3)
+	FEAT_DEF(PMULL,		0x00000001, 0, REG_HWCAP,  4)
+	FEAT_DEF(SHA1,		0x00000001, 0, REG_HWCAP,  5)
+	FEAT_DEF(SHA2,		0x00000001, 0, REG_HWCAP,  6)
+	FEAT_DEF(CRC32,		0x00000001, 0, REG_HWCAP,  7)
+	FEAT_DEF(AARCH64,	0x00000001, 0, REG_PLATFORM, 1)
+};
+#endif /* RTE_ARCH */
+
+/*
+ * Read AUXV software register and get cpu features for ARM
+ */
+static void
+rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
+	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
+{
+	int auxv_fd;
+	_Elfx_auxv_t auxv;
+
+	auxv_fd = open("/proc/self/auxv", O_RDONLY);
+	assert(auxv_fd);
+	while (read(auxv_fd, &auxv, sizeof(auxv)) == sizeof(auxv)) {
+		if (auxv.a_type == AT_HWCAP) {
+			out[REG_HWCAP] = auxv.a_un.a_val;
+		} else if (auxv.a_type == AT_HWCAP2) {
+			out[REG_HWCAP2] = auxv.a_un.a_val;
+		} else if (auxv.a_type == AT_PLATFORM) {
+			if (!strcmp((const char *)auxv.a_un.a_val, PLATFORM_STR))
+				out[REG_PLATFORM] = 0x0001;
+		}
+	}
+}
+
+/*
+ * Checks if a particular flag is available on current machine.
+ */
+int
+rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
+{
+	const struct feature_entry *feat;
+	cpuid_registers_t regs = {0};
+
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		/* Flag does not match anything in the feature tables */
+		return -ENOENT;
+
+	feat = &rte_cpu_feature_table[feature];
+
+	if (!feat->leaf)
+		/* This entry in the table wasn't filled out! */
+		return -EFAULT;
+
+	/* get the cpuid leaf containing the desired feature */
+	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
+
+	/* check if the feature is enabled */
+	return (regs[feat->reg] >> feat->bit) & 1;
+}
 
 const char *
 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
diff --git a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
index a270ccc..b7e0b72 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -32,6 +32,38 @@
 
 #include "rte_cpuflags.h"
 
+#include <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+
+/* Symbolic values for the entries in the auxiliary table */
+#define AT_HWCAP  16
+#define AT_HWCAP2 26
+
+/* software based registers */
+enum cpu_register_t {
+	REG_HWCAP = 0,
+	REG_HWCAP2,
+};
+
+typedef uint32_t cpuid_registers_t[4];
+
+/**
+ * Struct to hold a processor feature entry
+ */
+struct feature_entry {
+	uint32_t leaf;				/**< cpuid leaf */
+	uint32_t subleaf;			/**< cpuid subleaf */
+	uint32_t reg;				/**< cpuid register */
+	uint32_t bit;				/**< cpuid register bit */
+#define CPU_FLAG_NAME_MAX_LEN 64
+	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+};
+
+#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
+	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+
 const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(PPC_LE, 0x00000001, 0, REG_HWCAP,  0)
 	FEAT_DEF(TRUE_LE, 0x00000001, 0, REG_HWCAP,  1)
@@ -69,6 +101,53 @@ const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
 };
 
+/*
+ * Read AUXV software register and get cpu features for Power
+ */
+static void
+rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
+	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
+{
+	int auxv_fd;
+	Elf64_auxv_t auxv;
+
+	auxv_fd = open("/proc/self/auxv", O_RDONLY);
+	assert(auxv_fd);
+	while (read(auxv_fd, &auxv,
+		sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
+		if (auxv.a_type == AT_HWCAP)
+			out[REG_HWCAP] = auxv.a_un.a_val;
+		else if (auxv.a_type == AT_HWCAP2)
+			out[REG_HWCAP2] = auxv.a_un.a_val;
+	}
+}
+
+/*
+ * Checks if a particular flag is available on current machine.
+ */
+int
+rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
+{
+	const struct feature_entry *feat;
+	cpuid_registers_t regs = {0};
+
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		/* Flag does not match anything in the feature tables */
+		return -ENOENT;
+
+	feat = &rte_cpu_feature_table[feature];
+
+	if (!feat->leaf)
+		/* This entry in the table wasn't filled out! */
+		return -EFAULT;
+
+	/* get the cpuid leaf containing the desired feature */
+	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
+
+	/* check if the feature is enabled */
+	return (regs[feat->reg] >> feat->bit) & 1;
+}
+
 const char *
 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
 {
diff --git a/lib/librte_eal/common/arch/tile/rte_cpuflags.c b/lib/librte_eal/common/arch/tile/rte_cpuflags.c
index 4ca0a7b..a2b6c51 100644
--- a/lib/librte_eal/common/arch/tile/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/tile/rte_cpuflags.c
@@ -32,5 +32,16 @@
 
 #include "rte_cpuflags.h"
 
+#include <errno.h>
+
 const struct feature_entry rte_cpu_feature_table[] = {
 };
+
+/*
+ * Checks if a particular flag is available on current machine.
+ */
+int
+rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature)
+{
+	return -ENOENT;
+}
diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
index 3346fde..0138257 100644
--- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
@@ -33,6 +33,34 @@
 
 #include "rte_cpuflags.h"
 
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+
+enum cpu_register_t {
+	RTE_REG_EAX = 0,
+	RTE_REG_EBX,
+	RTE_REG_ECX,
+	RTE_REG_EDX,
+};
+
+typedef uint32_t cpuid_registers_t[4];
+
+/**
+ * Struct to hold a processor feature entry
+ */
+struct feature_entry {
+	uint32_t leaf;				/**< cpuid leaf */
+	uint32_t subleaf;			/**< cpuid subleaf */
+	uint32_t reg;				/**< cpuid register */
+	uint32_t bit;				/**< cpuid register bit */
+#define CPU_FLAG_NAME_MAX_LEN 64
+	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+};
+
+#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
+	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+
 const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX,  0)
 	FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX,  1)
@@ -128,6 +156,61 @@ const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX,  8)
 };
 
+/*
+ * Execute CPUID instruction and get contents of a specific register
+ *
+ * This function, when compiled with GCC, will generate architecture-neutral
+ * code, as per GCC manual.
+ */
+static void
+rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out)
+{
+#if defined(__i386__) && defined(__PIC__)
+	/* %ebx is a forbidden register if we compile with -fPIC or -fPIE */
+	asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0"
+		 : "=r" (out[RTE_REG_EBX]),
+		   "=a" (out[RTE_REG_EAX]),
+		   "=c" (out[RTE_REG_ECX]),
+		   "=d" (out[RTE_REG_EDX])
+		 : "a" (leaf), "c" (subleaf));
+#else
+	asm volatile("cpuid"
+		 : "=a" (out[RTE_REG_EAX]),
+		   "=b" (out[RTE_REG_EBX]),
+		   "=c" (out[RTE_REG_ECX]),
+		   "=d" (out[RTE_REG_EDX])
+		 : "a" (leaf), "c" (subleaf));
+#endif
+}
+
+int
+rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
+{
+	const struct feature_entry *feat;
+	cpuid_registers_t regs;
+
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		/* Flag does not match anything in the feature tables */
+		return -ENOENT;
+
+	feat = &rte_cpu_feature_table[feature];
+
+	if (!feat->leaf)
+		/* This entry in the table wasn't filled out! */
+		return -EFAULT;
+
+	rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs);
+	if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) ||
+	      regs[RTE_REG_EAX] < feat->leaf)
+		return 0;
+
+	/* get the cpuid leaf containing the desired feature */
+	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
+
+	/* check if the feature is enabled */
+	return (regs[feat->reg] >> feat->bit) & 1;
+}
+
 const char *
 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
 {
diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index 8c0576d..a4c5a29 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -30,6 +30,9 @@
  *   (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 <rte_common.h>
 #include <rte_cpuflags.h>
 
diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
index 2ec0c2e..eb02d9b 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
@@ -37,35 +37,6 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "generic/rte_cpuflags.h"
-
-extern const struct feature_entry rte_cpu_feature_table[];
-
-#ifndef AT_HWCAP
-#define AT_HWCAP 16
-#endif
-
-#ifndef AT_HWCAP2
-#define AT_HWCAP2 26
-#endif
-
-#ifndef AT_PLATFORM
-#define AT_PLATFORM 15
-#endif
-
-/* software based registers */
-enum cpu_register_t {
-	REG_HWCAP = 0,
-	REG_HWCAP2,
-	REG_PLATFORM,
-};
-
 /**
  * Enumeration of all CPU features supported
  */
@@ -102,56 +73,7 @@ enum rte_cpu_flag_t {
 	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
 };
 
-/*
- * Read AUXV software register and get cpu features for ARM
- */
-static inline void
-rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
-	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
-{
-	int auxv_fd;
-	Elf32_auxv_t auxv;
-
-	auxv_fd = open("/proc/self/auxv", O_RDONLY);
-	assert(auxv_fd);
-	while (read(auxv_fd, &auxv,
-		sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) {
-		if (auxv.a_type == AT_HWCAP)
-			out[REG_HWCAP] = auxv.a_un.a_val;
-		else if (auxv.a_type == AT_HWCAP2)
-			out[REG_HWCAP2] = auxv.a_un.a_val;
-		else if (auxv.a_type == AT_PLATFORM) {
-			if (!strcmp((const char *)auxv.a_un.a_val, "v7l"))
-				out[REG_PLATFORM] = 0x0001;
-		}
-	}
-}
-
-/*
- * Checks if a particular flag is available on current machine.
- */
-static inline int
-rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
-{
-	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
-
-	if (feature >= RTE_CPUFLAG_NUMFLAGS)
-		/* Flag does not match anything in the feature tables */
-		return -ENOENT;
-
-	feat = &rte_cpu_feature_table[feature];
-
-	if (!feat->leaf)
-		/* This entry in the table wasn't filled out! */
-		return -EFAULT;
-
-	/* get the cpuid leaf containing the desired feature */
-	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
-
-	/* check if the feature is enabled */
-	return (regs[feat->reg] >> feat->bit) & 1;
-}
+#include "generic/rte_cpuflags.h"
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
index b36040b..810e8a0 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
@@ -37,35 +37,6 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "generic/rte_cpuflags.h"
-
-extern const struct feature_entry rte_cpu_feature_table[];
-
-#ifndef AT_HWCAP
-#define AT_HWCAP 16
-#endif
-
-#ifndef AT_HWCAP2
-#define AT_HWCAP2 26
-#endif
-
-#ifndef AT_PLATFORM
-#define AT_PLATFORM 15
-#endif
-
-/* software based registers */
-enum cpu_register_t {
-	REG_HWCAP = 0,
-	REG_HWCAP2,
-	REG_PLATFORM,
-};
-
 /**
  * Enumeration of all CPU features supported
  */
@@ -83,57 +54,7 @@ enum rte_cpu_flag_t {
 	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
 };
 
-/*
- * Read AUXV software register and get cpu features for ARM
- */
-static inline void
-rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
-		     __attribute__((unused)) uint32_t subleaf,
-		     cpuid_registers_t out)
-{
-	int auxv_fd;
-	Elf64_auxv_t auxv;
-
-	auxv_fd = open("/proc/self/auxv", O_RDONLY);
-	assert(auxv_fd);
-	while (read(auxv_fd, &auxv,
-		    sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
-		if (auxv.a_type == AT_HWCAP) {
-			out[REG_HWCAP] = auxv.a_un.a_val;
-		} else if (auxv.a_type == AT_HWCAP2) {
-			out[REG_HWCAP2] = auxv.a_un.a_val;
-		} else if (auxv.a_type == AT_PLATFORM) {
-			if (!strcmp((const char *)auxv.a_un.a_val, "aarch64"))
-				out[REG_PLATFORM] = 0x0001;
-		}
-	}
-}
-
-/*
- * Checks if a particular flag is available on current machine.
- */
-static inline int
-rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
-{
-	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
-
-	if (feature >= RTE_CPUFLAG_NUMFLAGS)
-		/* Flag does not match anything in the feature tables */
-		return -ENOENT;
-
-	feat = &rte_cpu_feature_table[feature];
-
-	if (!feat->leaf)
-		/* This entry in the table wasn't filled out! */
-		return -EFAULT;
-
-	/* get the cpuid leaf containing the desired feature */
-	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
-
-	/* check if the feature is enabled */
-	return (regs[feat->reg] >> feat->bit) & 1;
-}
+#include "generic/rte_cpuflags.h"
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
index 85c4c1a..7cc2b3c 100644
--- a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
@@ -37,25 +37,6 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
-#include "generic/rte_cpuflags.h"
-
-extern const struct feature_entry rte_cpu_feature_table[];
-
-/* Symbolic values for the entries in the auxiliary table */
-#define AT_HWCAP  16
-#define AT_HWCAP2 26
-
-/* software based registers */
-enum cpu_register_t {
-	REG_HWCAP = 0,
-	REG_HWCAP2,
-};
-
 /**
  * Enumeration of all CPU features supported
  */
@@ -98,52 +79,7 @@ enum rte_cpu_flag_t {
 	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
 };
 
-/*
- * Read AUXV software register and get cpu features for Power
- */
-static inline void
-rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
-	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
-{
-	int auxv_fd;
-	Elf64_auxv_t auxv;
-
-	auxv_fd = open("/proc/self/auxv", O_RDONLY);
-	assert(auxv_fd);
-	while (read(auxv_fd, &auxv,
-		sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
-		if (auxv.a_type == AT_HWCAP)
-			out[REG_HWCAP] = auxv.a_un.a_val;
-		else if (auxv.a_type == AT_HWCAP2)
-			out[REG_HWCAP2] = auxv.a_un.a_val;
-	}
-}
-
-/*
- * Checks if a particular flag is available on current machine.
- */
-static inline int
-rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
-{
-	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
-
-	if (feature >= RTE_CPUFLAG_NUMFLAGS)
-		/* Flag does not match anything in the feature tables */
-		return -ENOENT;
-
-	feat = &rte_cpu_feature_table[feature];
-
-	if (!feat->leaf)
-		/* This entry in the table wasn't filled out! */
-		return -EFAULT;
-
-	/* get the cpuid leaf containing the desired feature */
-	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
-
-	/* check if the feature is enabled */
-	return (regs[feat->reg] >> feat->bit) & 1;
-}
+#include "generic/rte_cpuflags.h"
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
index a415857..1849b52 100644
--- a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
@@ -37,18 +37,6 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
-#include "generic/rte_cpuflags.h"
-
-/* software based registers */
-enum cpu_register_t {
-	REG_DUMMY = 0
-};
-
 /**
  * Enumeration of all CPU features supported
  */
@@ -56,24 +44,7 @@ enum rte_cpu_flag_t {
 	RTE_CPUFLAG_NUMFLAGS /**< This should always be the last! */
 };
 
-/*
- * Read AUXV software register and get cpu features for Power
- */
-static inline void
-rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
-		     __attribute__((unused)) uint32_t subleaf,
-		     __attribute__((unused)) cpuid_registers_t out)
-{
-}
-
-/*
- * Checks if a particular flag is available on current machine.
- */
-static inline int
-rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature)
-{
-	return -ENOENT;
-}
+#include "generic/rte_cpuflags.h"
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
index 120ea24..26204fa 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
@@ -38,15 +38,6 @@
 extern "C" {
 #endif
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include "generic/rte_cpuflags.h"
-
-extern const struct feature_entry rte_cpu_feature_table[];
-
 enum rte_cpu_flag_t {
 	/* (EAX 01h) ECX features*/
 	RTE_CPUFLAG_SSE3 = 0,               /**< SSE3 */
@@ -153,64 +144,7 @@ enum rte_cpu_flag_t {
 	RTE_CPUFLAG_NUMFLAGS,               /**< This should always be the last! */
 };
 
-enum cpu_register_t {
-	RTE_REG_EAX = 0,
-	RTE_REG_EBX,
-	RTE_REG_ECX,
-	RTE_REG_EDX,
-};
-
-static inline void
-rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out)
-{
-#if defined(__i386__) && defined(__PIC__)
-    /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */
-    asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0"
-		 : "=r" (out[RTE_REG_EBX]),
-		   "=a" (out[RTE_REG_EAX]),
-		   "=c" (out[RTE_REG_ECX]),
-		   "=d" (out[RTE_REG_EDX])
-		 : "a" (leaf), "c" (subleaf));
-#else
-
-    asm volatile("cpuid"
-		 : "=a" (out[RTE_REG_EAX]),
-		   "=b" (out[RTE_REG_EBX]),
-		   "=c" (out[RTE_REG_ECX]),
-		   "=d" (out[RTE_REG_EDX])
-		 : "a" (leaf), "c" (subleaf));
-
-#endif
-}
-
-static inline int
-rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
-{
-	const struct feature_entry *feat;
-	cpuid_registers_t regs;
-
-
-	if (feature >= RTE_CPUFLAG_NUMFLAGS)
-		/* Flag does not match anything in the feature tables */
-		return -ENOENT;
-
-	feat = &rte_cpu_feature_table[feature];
-
-	if (!feat->leaf)
-		/* This entry in the table wasn't filled out! */
-		return -EFAULT;
-
-	rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs);
-	if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) ||
-	      regs[RTE_REG_EAX] < feat->leaf)
-		return 0;
-
-	/* get the cpuid leaf containing the desired feature */
-	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
-
-	/* check if the feature is enabled */
-	return (regs[feat->reg] >> feat->bit) & 1;
-}
+#include "generic/rte_cpuflags.h"
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h
index 3ca2e36..c1da357 100644
--- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
@@ -39,10 +39,7 @@
  * Architecture specific API to determine available CPU features at runtime.
  */
 
-#include <stdlib.h>
-#include <stdio.h>
 #include <errno.h>
-#include <stdint.h>
 
 /**
  * Enumeration of all CPU features supported
@@ -50,49 +47,6 @@
 enum rte_cpu_flag_t;
 
 /**
- * Enumeration of CPU registers
- */
-#ifdef __DOXYGEN__
-enum cpu_register_t;
-#endif
-
-typedef uint32_t cpuid_registers_t[4];
-
-#define CPU_FLAG_NAME_MAX_LEN 64
-
-/**
- * Struct to hold a processor feature entry
- */
-struct feature_entry {
-	uint32_t leaf;				/**< cpuid leaf */
-	uint32_t subleaf;			/**< cpuid subleaf */
-	uint32_t reg;				/**< cpuid register */
-	uint32_t bit;				/**< cpuid register bit */
-	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
-};
-
-#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
-	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
-
-/**
- * An array that holds feature entries
- *
- * Defined in arch-specific rte_cpuflags.h.
- */
-#ifdef __DOXYGEN__
-static const struct feature_entry cpu_feature_table[];
-#endif
-
-/**
- * Execute CPUID instruction and get contents of a specific register
- *
- * This function, when compiled with GCC, will generate architecture-neutral
- * code, as per GCC manual.
- */
-static inline void
-rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out);
-
-/**
  * Get name of CPU flag
  *
  * @param feature
@@ -114,10 +68,8 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature);
  *     0 if flag is not available
  *     -ENOENT if flag is invalid
  */
-#ifdef __DOXYGEN__
-static inline int
+int
 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature);
-#endif
 
 /**
  * This function checks that the currently used CPU supports the CPU features
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 48e8e4f..440fac2 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -145,6 +145,5 @@ DPDK_2.3 {
 	rte_cpu_get_flag_name;
 	rte_eal_pci_map_device;
 	rte_eal_pci_unmap_device;
-	rte_cpu_feature_table;
 
 } DPDK_2.2;
-- 
2.7.0

^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers
  2016-02-06 22:17  1%   ` [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
@ 2016-02-08  8:59  0%     ` Jerin Jacob
  0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2016-02-08  8:59 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin

On Sat, Feb 06, 2016 at 11:17:10PM +0100, Thomas Monjalon wrote:
> The patch c344eab3ee has moved the hardware definition of CPU flags.
> Now the functions checking these hardware flags are also moved.
> The function rte_cpu_get_flag_enabled() is no more inline.
> 
> The benefits are:
> - remove rte_cpu_feature_table from the ABI (recently added)
> - hide hardware details from the API
> - allow to adapt structures per arch (done in next patch)
> 
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>

arm64 specific changes looks good.

Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

> ---
>  MAINTAINERS                                        |   4 +
>  app/test/test_hash_scaling.c                       |   2 +
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   1 -
>  lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 125 ++++++++++++++++++---
>  lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   |  79 +++++++++++++
>  lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
>  lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  83 ++++++++++++++
>  lib/librte_eal/common/eal_common_cpuflags.c        |   3 +
>  .../common/include/arch/arm/rte_cpuflags_32.h      |  80 +------------
>  .../common/include/arch/arm/rte_cpuflags_64.h      |  81 +------------
>  .../common/include/arch/ppc_64/rte_cpuflags.h      |  66 +----------
>  .../common/include/arch/tile/rte_cpuflags.h        |  31 +----
>  .../common/include/arch/x86/rte_cpuflags.h         |  68 +----------
>  .../common/include/generic/rte_cpuflags.h          |  50 +--------
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   1 -
>  15 files changed, 300 insertions(+), 385 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b90aeea..628bc05 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -131,6 +131,7 @@ F: doc/guides/sample_app_ug/multi_process.rst
>  ARM v7
>  M: Jan Viktorin <viktorin@rehivetech.com>
>  M: Jianbo Liu <jianbo.liu@linaro.org>
> +F: lib/librte_eal/common/arch/arm/
>  F: lib/librte_eal/common/include/arch/arm/
>  
>  ARM v8
> @@ -141,16 +142,19 @@ F: lib/librte_acl/acl_run_neon.*
>  
>  EZchip TILE-Gx
>  M: Zhigang Lu <zlu@ezchip.com>
> +F: lib/librte_eal/common/arch/tile/
>  F: lib/librte_eal/common/include/arch/tile/
>  F: drivers/net/mpipe/
>  
>  IBM POWER
>  M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
> +F: lib/librte_eal/common/arch/ppc_64/
>  F: lib/librte_eal/common/include/arch/ppc_64/
>  
>  Intel x86
>  M: Bruce Richardson <bruce.richardson@intel.com>
>  M: Konstantin Ananyev <konstantin.ananyev@intel.com>
> +F: lib/librte_eal/common/arch/x86/
>  F: lib/librte_eal/common/include/arch/x86/
>  
>  Linux EAL (with overlaps)
> diff --git a/app/test/test_hash_scaling.c b/app/test/test_hash_scaling.c
> index 744e5e3..1c4c75d 100644
> --- a/app/test/test_hash_scaling.c
> +++ b/app/test/test_hash_scaling.c
> @@ -31,6 +31,8 @@
>   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>   */
>  
> +#include <stdio.h>
> +
>  #include <rte_cycles.h>
>  #include <rte_hash.h>
>  #include <rte_hash_crc.h>
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 9bea0e2..1a96203 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -142,6 +142,5 @@ DPDK_2.3 {
>  	rte_cpu_get_flag_name;
>  	rte_eal_pci_map_device;
>  	rte_eal_pci_unmap_device;
> -	rte_cpu_feature_table;
>  
>  } DPDK_2.2;
> diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> index 62e0791..cd7a7b1 100644
> --- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> +++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> @@ -2,6 +2,7 @@
>   *   BSD LICENSE
>   *
>   *   Copyright (C) Cavium networks Ltd. 2015.
> + *   Copyright(c) 2015 RehiveTech. All rights reserved.
>   *
>   *   Redistribution and use in source and binary forms, with or without
>   *   modification, are permitted provided that the following conditions
> @@ -32,19 +33,51 @@
>  
>  #include "rte_cpuflags.h"
>  
> -#ifdef RTE_ARCH_64
> -const struct feature_entry rte_cpu_feature_table[] = {
> -	FEAT_DEF(FP,		0x00000001, 0, REG_HWCAP,  0)
> -	FEAT_DEF(NEON,		0x00000001, 0, REG_HWCAP,  1)
> -	FEAT_DEF(EVTSTRM,	0x00000001, 0, REG_HWCAP,  2)
> -	FEAT_DEF(AES,		0x00000001, 0, REG_HWCAP,  3)
> -	FEAT_DEF(PMULL,		0x00000001, 0, REG_HWCAP,  4)
> -	FEAT_DEF(SHA1,		0x00000001, 0, REG_HWCAP,  5)
> -	FEAT_DEF(SHA2,		0x00000001, 0, REG_HWCAP,  6)
> -	FEAT_DEF(CRC32,		0x00000001, 0, REG_HWCAP,  7)
> -	FEAT_DEF(AARCH64,	0x00000001, 0, REG_PLATFORM, 1)
> +#include <elf.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +#include <unistd.h>
> +#include <string.h>
> +
> +#ifndef AT_HWCAP
> +#define AT_HWCAP 16
> +#endif
> +
> +#ifndef AT_HWCAP2
> +#define AT_HWCAP2 26
> +#endif
> +
> +#ifndef AT_PLATFORM
> +#define AT_PLATFORM 15
> +#endif
> +
> +enum cpu_register_t {
> +	REG_HWCAP = 0,
> +	REG_HWCAP2,
> +	REG_PLATFORM,
> +};
> +
> +typedef uint32_t cpuid_registers_t[4];
> +
> +/**
> + * Struct to hold a processor feature entry
> + */
> +struct feature_entry {
> +	uint32_t leaf;				/**< cpuid leaf */
> +	uint32_t subleaf;			/**< cpuid subleaf */
> +	uint32_t reg;				/**< cpuid register */
> +	uint32_t bit;				/**< cpuid register bit */
> +#define CPU_FLAG_NAME_MAX_LEN 64
> +	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
>  };
> -#else
> +
> +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
> +	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
> +
> +#ifdef RTE_ARCH_ARMv7
> +#define PLATFORM_STR "v7l"
> +typedef Elf32_auxv_t _Elfx_auxv_t;
> +
>  const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(SWP,       0x00000001, 0, REG_HWCAP,  0)
>  	FEAT_DEF(HALF,      0x00000001, 0, REG_HWCAP,  1)
> @@ -75,7 +108,73 @@ const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(CRC32,     0x00000001, 0, REG_HWCAP2,  4)
>  	FEAT_DEF(V7L,       0x00000001, 0, REG_PLATFORM, 0)
>  };
> -#endif
> +
> +#elif defined RTE_ARCH_ARM64
> +#define PLATFORM_STR "aarch64"
> +typedef Elf64_auxv_t _Elfx_auxv_t;
> +
> +const struct feature_entry rte_cpu_feature_table[] = {
> +	FEAT_DEF(FP,		0x00000001, 0, REG_HWCAP,  0)
> +	FEAT_DEF(NEON,		0x00000001, 0, REG_HWCAP,  1)
> +	FEAT_DEF(EVTSTRM,	0x00000001, 0, REG_HWCAP,  2)
> +	FEAT_DEF(AES,		0x00000001, 0, REG_HWCAP,  3)
> +	FEAT_DEF(PMULL,		0x00000001, 0, REG_HWCAP,  4)
> +	FEAT_DEF(SHA1,		0x00000001, 0, REG_HWCAP,  5)
> +	FEAT_DEF(SHA2,		0x00000001, 0, REG_HWCAP,  6)
> +	FEAT_DEF(CRC32,		0x00000001, 0, REG_HWCAP,  7)
> +	FEAT_DEF(AARCH64,	0x00000001, 0, REG_PLATFORM, 1)
> +};
> +#endif /* RTE_ARCH */
> +
> +/*
> + * Read AUXV software register and get cpu features for ARM
> + */
> +static void
> +rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> +	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
> +{
> +	int auxv_fd;
> +	_Elfx_auxv_t auxv;
> +
> +	auxv_fd = open("/proc/self/auxv", O_RDONLY);
> +	assert(auxv_fd);
> +	while (read(auxv_fd, &auxv, sizeof(auxv)) == sizeof(auxv)) {
> +		if (auxv.a_type == AT_HWCAP) {
> +			out[REG_HWCAP] = auxv.a_un.a_val;
> +		} else if (auxv.a_type == AT_HWCAP2) {
> +			out[REG_HWCAP2] = auxv.a_un.a_val;
> +		} else if (auxv.a_type == AT_PLATFORM) {
> +			if (!strcmp((const char *)auxv.a_un.a_val, PLATFORM_STR))
> +				out[REG_PLATFORM] = 0x0001;
> +		}
> +	}
> +}
> +
> +/*
> + * Checks if a particular flag is available on current machine.
> + */
> +int
> +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> +{
> +	const struct feature_entry *feat;
> +	cpuid_registers_t regs = {0};
> +
> +	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> +		/* Flag does not match anything in the feature tables */
> +		return -ENOENT;
> +
> +	feat = &rte_cpu_feature_table[feature];
> +
> +	if (!feat->leaf)
> +		/* This entry in the table wasn't filled out! */
> +		return -EFAULT;
> +
> +	/* get the cpuid leaf containing the desired feature */
> +	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> +
> +	/* check if the feature is enabled */
> +	return (regs[feat->reg] >> feat->bit) & 1;
> +}
>  
>  const char *
>  rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
> diff --git a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
> index a270ccc..b7e0b72 100644
> --- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
> +++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
> @@ -32,6 +32,38 @@
>  
>  #include "rte_cpuflags.h"
>  
> +#include <elf.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +#include <unistd.h>
> +
> +/* Symbolic values for the entries in the auxiliary table */
> +#define AT_HWCAP  16
> +#define AT_HWCAP2 26
> +
> +/* software based registers */
> +enum cpu_register_t {
> +	REG_HWCAP = 0,
> +	REG_HWCAP2,
> +};
> +
> +typedef uint32_t cpuid_registers_t[4];
> +
> +/**
> + * Struct to hold a processor feature entry
> + */
> +struct feature_entry {
> +	uint32_t leaf;				/**< cpuid leaf */
> +	uint32_t subleaf;			/**< cpuid subleaf */
> +	uint32_t reg;				/**< cpuid register */
> +	uint32_t bit;				/**< cpuid register bit */
> +#define CPU_FLAG_NAME_MAX_LEN 64
> +	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
> +};
> +
> +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
> +	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
> +
>  const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(PPC_LE, 0x00000001, 0, REG_HWCAP,  0)
>  	FEAT_DEF(TRUE_LE, 0x00000001, 0, REG_HWCAP,  1)
> @@ -69,6 +101,53 @@ const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
>  };
>  
> +/*
> + * Read AUXV software register and get cpu features for Power
> + */
> +static void
> +rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> +	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
> +{
> +	int auxv_fd;
> +	Elf64_auxv_t auxv;
> +
> +	auxv_fd = open("/proc/self/auxv", O_RDONLY);
> +	assert(auxv_fd);
> +	while (read(auxv_fd, &auxv,
> +		sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
> +		if (auxv.a_type == AT_HWCAP)
> +			out[REG_HWCAP] = auxv.a_un.a_val;
> +		else if (auxv.a_type == AT_HWCAP2)
> +			out[REG_HWCAP2] = auxv.a_un.a_val;
> +	}
> +}
> +
> +/*
> + * Checks if a particular flag is available on current machine.
> + */
> +int
> +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> +{
> +	const struct feature_entry *feat;
> +	cpuid_registers_t regs = {0};
> +
> +	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> +		/* Flag does not match anything in the feature tables */
> +		return -ENOENT;
> +
> +	feat = &rte_cpu_feature_table[feature];
> +
> +	if (!feat->leaf)
> +		/* This entry in the table wasn't filled out! */
> +		return -EFAULT;
> +
> +	/* get the cpuid leaf containing the desired feature */
> +	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> +
> +	/* check if the feature is enabled */
> +	return (regs[feat->reg] >> feat->bit) & 1;
> +}
> +
>  const char *
>  rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
>  {
> diff --git a/lib/librte_eal/common/arch/tile/rte_cpuflags.c b/lib/librte_eal/common/arch/tile/rte_cpuflags.c
> index 4ca0a7b..a2b6c51 100644
> --- a/lib/librte_eal/common/arch/tile/rte_cpuflags.c
> +++ b/lib/librte_eal/common/arch/tile/rte_cpuflags.c
> @@ -32,5 +32,16 @@
>  
>  #include "rte_cpuflags.h"
>  
> +#include <errno.h>
> +
>  const struct feature_entry rte_cpu_feature_table[] = {
>  };
> +
> +/*
> + * Checks if a particular flag is available on current machine.
> + */
> +int
> +rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature)
> +{
> +	return -ENOENT;
> +}
> diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
> index 3346fde..0138257 100644
> --- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c
> +++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
> @@ -33,6 +33,34 @@
>  
>  #include "rte_cpuflags.h"
>  
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdint.h>
> +
> +enum cpu_register_t {
> +	RTE_REG_EAX = 0,
> +	RTE_REG_EBX,
> +	RTE_REG_ECX,
> +	RTE_REG_EDX,
> +};
> +
> +typedef uint32_t cpuid_registers_t[4];
> +
> +/**
> + * Struct to hold a processor feature entry
> + */
> +struct feature_entry {
> +	uint32_t leaf;				/**< cpuid leaf */
> +	uint32_t subleaf;			/**< cpuid subleaf */
> +	uint32_t reg;				/**< cpuid register */
> +	uint32_t bit;				/**< cpuid register bit */
> +#define CPU_FLAG_NAME_MAX_LEN 64
> +	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
> +};
> +
> +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
> +	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
> +
>  const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX,  0)
>  	FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX,  1)
> @@ -128,6 +156,61 @@ const struct feature_entry rte_cpu_feature_table[] = {
>  	FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX,  8)
>  };
>  
> +/*
> + * Execute CPUID instruction and get contents of a specific register
> + *
> + * This function, when compiled with GCC, will generate architecture-neutral
> + * code, as per GCC manual.
> + */
> +static void
> +rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out)
> +{
> +#if defined(__i386__) && defined(__PIC__)
> +	/* %ebx is a forbidden register if we compile with -fPIC or -fPIE */
> +	asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0"
> +		 : "=r" (out[RTE_REG_EBX]),
> +		   "=a" (out[RTE_REG_EAX]),
> +		   "=c" (out[RTE_REG_ECX]),
> +		   "=d" (out[RTE_REG_EDX])
> +		 : "a" (leaf), "c" (subleaf));
> +#else
> +	asm volatile("cpuid"
> +		 : "=a" (out[RTE_REG_EAX]),
> +		   "=b" (out[RTE_REG_EBX]),
> +		   "=c" (out[RTE_REG_ECX]),
> +		   "=d" (out[RTE_REG_EDX])
> +		 : "a" (leaf), "c" (subleaf));
> +#endif
> +}
> +
> +int
> +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> +{
> +	const struct feature_entry *feat;
> +	cpuid_registers_t regs;
> +
> +	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> +		/* Flag does not match anything in the feature tables */
> +		return -ENOENT;
> +
> +	feat = &rte_cpu_feature_table[feature];
> +
> +	if (!feat->leaf)
> +		/* This entry in the table wasn't filled out! */
> +		return -EFAULT;
> +
> +	rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs);
> +	if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) ||
> +	      regs[RTE_REG_EAX] < feat->leaf)
> +		return 0;
> +
> +	/* get the cpuid leaf containing the desired feature */
> +	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> +
> +	/* check if the feature is enabled */
> +	return (regs[feat->reg] >> feat->bit) & 1;
> +}
> +
>  const char *
>  rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
>  {
> diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
> index 8c0576d..a4c5a29 100644
> --- a/lib/librte_eal/common/eal_common_cpuflags.c
> +++ b/lib/librte_eal/common/eal_common_cpuflags.c
> @@ -30,6 +30,9 @@
>   *   (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 <rte_common.h>
>  #include <rte_cpuflags.h>
>  
> diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
> index 2ec0c2e..eb02d9b 100644
> --- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
> +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h
> @@ -37,35 +37,6 @@
>  extern "C" {
>  #endif
>  
> -#include <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -#include <string.h>
> -
> -#include "generic/rte_cpuflags.h"
> -
> -extern const struct feature_entry rte_cpu_feature_table[];
> -
> -#ifndef AT_HWCAP
> -#define AT_HWCAP 16
> -#endif
> -
> -#ifndef AT_HWCAP2
> -#define AT_HWCAP2 26
> -#endif
> -
> -#ifndef AT_PLATFORM
> -#define AT_PLATFORM 15
> -#endif
> -
> -/* software based registers */
> -enum cpu_register_t {
> -	REG_HWCAP = 0,
> -	REG_HWCAP2,
> -	REG_PLATFORM,
> -};
> -
>  /**
>   * Enumeration of all CPU features supported
>   */
> @@ -102,56 +73,7 @@ enum rte_cpu_flag_t {
>  	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
>  };
>  
> -/*
> - * Read AUXV software register and get cpu features for ARM
> - */
> -static inline void
> -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> -	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
> -{
> -	int auxv_fd;
> -	Elf32_auxv_t auxv;
> -
> -	auxv_fd = open("/proc/self/auxv", O_RDONLY);
> -	assert(auxv_fd);
> -	while (read(auxv_fd, &auxv,
> -		sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) {
> -		if (auxv.a_type == AT_HWCAP)
> -			out[REG_HWCAP] = auxv.a_un.a_val;
> -		else if (auxv.a_type == AT_HWCAP2)
> -			out[REG_HWCAP2] = auxv.a_un.a_val;
> -		else if (auxv.a_type == AT_PLATFORM) {
> -			if (!strcmp((const char *)auxv.a_un.a_val, "v7l"))
> -				out[REG_PLATFORM] = 0x0001;
> -		}
> -	}
> -}
> -
> -/*
> - * Checks if a particular flag is available on current machine.
> - */
> -static inline int
> -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> -{
> -	const struct feature_entry *feat;
> -	cpuid_registers_t regs = {0};
> -
> -	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> -		/* Flag does not match anything in the feature tables */
> -		return -ENOENT;
> -
> -	feat = &rte_cpu_feature_table[feature];
> -
> -	if (!feat->leaf)
> -		/* This entry in the table wasn't filled out! */
> -		return -EFAULT;
> -
> -	/* get the cpuid leaf containing the desired feature */
> -	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> -
> -	/* check if the feature is enabled */
> -	return (regs[feat->reg] >> feat->bit) & 1;
> -}
> +#include "generic/rte_cpuflags.h"
>  
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
> index b36040b..810e8a0 100644
> --- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
> +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h
> @@ -37,35 +37,6 @@
>  extern "C" {
>  #endif
>  
> -#include <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -#include <string.h>
> -
> -#include "generic/rte_cpuflags.h"
> -
> -extern const struct feature_entry rte_cpu_feature_table[];
> -
> -#ifndef AT_HWCAP
> -#define AT_HWCAP 16
> -#endif
> -
> -#ifndef AT_HWCAP2
> -#define AT_HWCAP2 26
> -#endif
> -
> -#ifndef AT_PLATFORM
> -#define AT_PLATFORM 15
> -#endif
> -
> -/* software based registers */
> -enum cpu_register_t {
> -	REG_HWCAP = 0,
> -	REG_HWCAP2,
> -	REG_PLATFORM,
> -};
> -
>  /**
>   * Enumeration of all CPU features supported
>   */
> @@ -83,57 +54,7 @@ enum rte_cpu_flag_t {
>  	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
>  };
>  
> -/*
> - * Read AUXV software register and get cpu features for ARM
> - */
> -static inline void
> -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> -		     __attribute__((unused)) uint32_t subleaf,
> -		     cpuid_registers_t out)
> -{
> -	int auxv_fd;
> -	Elf64_auxv_t auxv;
> -
> -	auxv_fd = open("/proc/self/auxv", O_RDONLY);
> -	assert(auxv_fd);
> -	while (read(auxv_fd, &auxv,
> -		    sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
> -		if (auxv.a_type == AT_HWCAP) {
> -			out[REG_HWCAP] = auxv.a_un.a_val;
> -		} else if (auxv.a_type == AT_HWCAP2) {
> -			out[REG_HWCAP2] = auxv.a_un.a_val;
> -		} else if (auxv.a_type == AT_PLATFORM) {
> -			if (!strcmp((const char *)auxv.a_un.a_val, "aarch64"))
> -				out[REG_PLATFORM] = 0x0001;
> -		}
> -	}
> -}
> -
> -/*
> - * Checks if a particular flag is available on current machine.
> - */
> -static inline int
> -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> -{
> -	const struct feature_entry *feat;
> -	cpuid_registers_t regs = {0};
> -
> -	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> -		/* Flag does not match anything in the feature tables */
> -		return -ENOENT;
> -
> -	feat = &rte_cpu_feature_table[feature];
> -
> -	if (!feat->leaf)
> -		/* This entry in the table wasn't filled out! */
> -		return -EFAULT;
> -
> -	/* get the cpuid leaf containing the desired feature */
> -	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> -
> -	/* check if the feature is enabled */
> -	return (regs[feat->reg] >> feat->bit) & 1;
> -}
> +#include "generic/rte_cpuflags.h"
>  
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
> index 85c4c1a..7cc2b3c 100644
> --- a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
> +++ b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h
> @@ -37,25 +37,6 @@
>  extern "C" {
>  #endif
>  
> -#include <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -
> -#include "generic/rte_cpuflags.h"
> -
> -extern const struct feature_entry rte_cpu_feature_table[];
> -
> -/* Symbolic values for the entries in the auxiliary table */
> -#define AT_HWCAP  16
> -#define AT_HWCAP2 26
> -
> -/* software based registers */
> -enum cpu_register_t {
> -	REG_HWCAP = 0,
> -	REG_HWCAP2,
> -};
> -
>  /**
>   * Enumeration of all CPU features supported
>   */
> @@ -98,52 +79,7 @@ enum rte_cpu_flag_t {
>  	RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
>  };
>  
> -/*
> - * Read AUXV software register and get cpu features for Power
> - */
> -static inline void
> -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> -	__attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
> -{
> -	int auxv_fd;
> -	Elf64_auxv_t auxv;
> -
> -	auxv_fd = open("/proc/self/auxv", O_RDONLY);
> -	assert(auxv_fd);
> -	while (read(auxv_fd, &auxv,
> -		sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
> -		if (auxv.a_type == AT_HWCAP)
> -			out[REG_HWCAP] = auxv.a_un.a_val;
> -		else if (auxv.a_type == AT_HWCAP2)
> -			out[REG_HWCAP2] = auxv.a_un.a_val;
> -	}
> -}
> -
> -/*
> - * Checks if a particular flag is available on current machine.
> - */
> -static inline int
> -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> -{
> -	const struct feature_entry *feat;
> -	cpuid_registers_t regs = {0};
> -
> -	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> -		/* Flag does not match anything in the feature tables */
> -		return -ENOENT;
> -
> -	feat = &rte_cpu_feature_table[feature];
> -
> -	if (!feat->leaf)
> -		/* This entry in the table wasn't filled out! */
> -		return -EFAULT;
> -
> -	/* get the cpuid leaf containing the desired feature */
> -	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> -
> -	/* check if the feature is enabled */
> -	return (regs[feat->reg] >> feat->bit) & 1;
> -}
> +#include "generic/rte_cpuflags.h"
>  
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
> index a415857..1849b52 100644
> --- a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
> +++ b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h
> @@ -37,18 +37,6 @@
>  extern "C" {
>  #endif
>  
> -#include <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -
> -#include "generic/rte_cpuflags.h"
> -
> -/* software based registers */
> -enum cpu_register_t {
> -	REG_DUMMY = 0
> -};
> -
>  /**
>   * Enumeration of all CPU features supported
>   */
> @@ -56,24 +44,7 @@ enum rte_cpu_flag_t {
>  	RTE_CPUFLAG_NUMFLAGS /**< This should always be the last! */
>  };
>  
> -/*
> - * Read AUXV software register and get cpu features for Power
> - */
> -static inline void
> -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
> -		     __attribute__((unused)) uint32_t subleaf,
> -		     __attribute__((unused)) cpuid_registers_t out)
> -{
> -}
> -
> -/*
> - * Checks if a particular flag is available on current machine.
> - */
> -static inline int
> -rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature)
> -{
> -	return -ENOENT;
> -}
> +#include "generic/rte_cpuflags.h"
>  
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
> index 120ea24..26204fa 100644
> --- a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
> +++ b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
> @@ -38,15 +38,6 @@
>  extern "C" {
>  #endif
>  
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <errno.h>
> -#include <stdint.h>
> -
> -#include "generic/rte_cpuflags.h"
> -
> -extern const struct feature_entry rte_cpu_feature_table[];
> -
>  enum rte_cpu_flag_t {
>  	/* (EAX 01h) ECX features*/
>  	RTE_CPUFLAG_SSE3 = 0,               /**< SSE3 */
> @@ -153,64 +144,7 @@ enum rte_cpu_flag_t {
>  	RTE_CPUFLAG_NUMFLAGS,               /**< This should always be the last! */
>  };
>  
> -enum cpu_register_t {
> -	RTE_REG_EAX = 0,
> -	RTE_REG_EBX,
> -	RTE_REG_ECX,
> -	RTE_REG_EDX,
> -};
> -
> -static inline void
> -rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out)
> -{
> -#if defined(__i386__) && defined(__PIC__)
> -    /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */
> -    asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0"
> -		 : "=r" (out[RTE_REG_EBX]),
> -		   "=a" (out[RTE_REG_EAX]),
> -		   "=c" (out[RTE_REG_ECX]),
> -		   "=d" (out[RTE_REG_EDX])
> -		 : "a" (leaf), "c" (subleaf));
> -#else
> -
> -    asm volatile("cpuid"
> -		 : "=a" (out[RTE_REG_EAX]),
> -		   "=b" (out[RTE_REG_EBX]),
> -		   "=c" (out[RTE_REG_ECX]),
> -		   "=d" (out[RTE_REG_EDX])
> -		 : "a" (leaf), "c" (subleaf));
> -
> -#endif
> -}
> -
> -static inline int
> -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
> -{
> -	const struct feature_entry *feat;
> -	cpuid_registers_t regs;
> -
> -
> -	if (feature >= RTE_CPUFLAG_NUMFLAGS)
> -		/* Flag does not match anything in the feature tables */
> -		return -ENOENT;
> -
> -	feat = &rte_cpu_feature_table[feature];
> -
> -	if (!feat->leaf)
> -		/* This entry in the table wasn't filled out! */
> -		return -EFAULT;
> -
> -	rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs);
> -	if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) ||
> -	      regs[RTE_REG_EAX] < feat->leaf)
> -		return 0;
> -
> -	/* get the cpuid leaf containing the desired feature */
> -	rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
> -
> -	/* check if the feature is enabled */
> -	return (regs[feat->reg] >> feat->bit) & 1;
> -}
> +#include "generic/rte_cpuflags.h"
>  
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h
> index 3ca2e36..c1da357 100644
> --- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
> +++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
> @@ -39,10 +39,7 @@
>   * Architecture specific API to determine available CPU features at runtime.
>   */
>  
> -#include <stdlib.h>
> -#include <stdio.h>
>  #include <errno.h>
> -#include <stdint.h>
>  
>  /**
>   * Enumeration of all CPU features supported
> @@ -50,49 +47,6 @@
>  enum rte_cpu_flag_t;
>  
>  /**
> - * Enumeration of CPU registers
> - */
> -#ifdef __DOXYGEN__
> -enum cpu_register_t;
> -#endif
> -
> -typedef uint32_t cpuid_registers_t[4];
> -
> -#define CPU_FLAG_NAME_MAX_LEN 64
> -
> -/**
> - * Struct to hold a processor feature entry
> - */
> -struct feature_entry {
> -	uint32_t leaf;				/**< cpuid leaf */
> -	uint32_t subleaf;			/**< cpuid subleaf */
> -	uint32_t reg;				/**< cpuid register */
> -	uint32_t bit;				/**< cpuid register bit */
> -	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
> -};
> -
> -#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
> -	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
> -
> -/**
> - * An array that holds feature entries
> - *
> - * Defined in arch-specific rte_cpuflags.h.
> - */
> -#ifdef __DOXYGEN__
> -static const struct feature_entry cpu_feature_table[];
> -#endif
> -
> -/**
> - * Execute CPUID instruction and get contents of a specific register
> - *
> - * This function, when compiled with GCC, will generate architecture-neutral
> - * code, as per GCC manual.
> - */
> -static inline void
> -rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out);
> -
> -/**
>   * Get name of CPU flag
>   *
>   * @param feature
> @@ -114,10 +68,8 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature);
>   *     0 if flag is not available
>   *     -ENOENT if flag is invalid
>   */
> -#ifdef __DOXYGEN__
> -static inline int
> +int
>  rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature);
> -#endif
>  
>  /**
>   * This function checks that the currently used CPU supports the CPU features
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 48e8e4f..440fac2 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -145,6 +145,5 @@ DPDK_2.3 {
>  	rte_cpu_get_flag_name;
>  	rte_eal_pci_map_device;
>  	rte_eal_pci_unmap_device;
> -	rte_cpu_feature_table;
>  
>  } DPDK_2.2;
> -- 
> 2.7.0
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] mempool: Reduce rte_mempool structure size
  @ 2016-02-08 11:02  4% ` Olivier MATZ
  2016-02-08 15:57  0%   ` Wiles, Keith
  2016-02-09 17:30  2% ` [dpdk-dev] [PATCH v2] mempool: reduce " Keith Wiles
  1 sibling, 1 reply; 200+ results
From: Olivier MATZ @ 2016-02-08 11:02 UTC (permalink / raw)
  To: Keith Wiles, dev

Hi Keith,

Looks good, thanks. Please find some comments below.

> [PATCH] mempool: Reduce rte_mempool structure size

nit: we usually avoid uppercase letters in title

On 02/03/2016 12:02 AM, Keith Wiles wrote:
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index aff5f6d..bdf8e2e 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -450,15 +450,11 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
>  	int page_size = getpagesize();
>  
>  	/* compilation-time checks */
> +#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>  	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

I don't think the #ifdef RTE_LIBRTE_MEMPOOL_DEBUG should be moved.
It should only protects the checks on stats which are enabled
in debug mode.

> @@ -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. */

As you noticed it in your initial mail, this changes the ABI. I
think your patch justifies the ABI change, so I think it should
follow the ABI change process described in
dpdk/doc/guides/contributing/versioning.rst.

>From what I understand of versioning.rst, these kind of changes
requires a deprecation notice first, and will be integrated in
next version. I don't think it's easy to keep a backward compat
in this case, especially because the rte_mempool structure is
used by several inlined functions.

Regards,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 1/5] mempool: add external mempool manager support
  @ 2016-02-08 11:02  4%       ` Olivier MATZ
  0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2016-02-08 11:02 UTC (permalink / raw)
  To: Hunt, David, dev

Hi David,

On 02/04/2016 05:47 PM, Hunt, David wrote:
> Olivier,
>     Thanks for your comprehensive comments. I'm working on a v2 patch
> based on feedback already received from Jerin, and I'll be sure to
> include your feedback also.
> Many thanks,
> David.


While answering to Keith, I realized there is the same kind of ABI
changes in your patchset too. It means it should also follow the
ABI deprecation process: dpdk/doc/guides/contributing/versioning.rst.

Regards,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] mempool: Reduce rte_mempool structure size
  2016-02-08 11:02  4% ` Olivier MATZ
@ 2016-02-08 15:57  0%   ` Wiles, Keith
  0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-02-08 15:57 UTC (permalink / raw)
  To: Olivier MATZ, dev


>Hi Keith,
>
>Looks good, thanks. Please find some comments below.
>
>> [PATCH] mempool: Reduce rte_mempool structure size
>
>nit: we usually avoid uppercase letters in title

Will make that change for v2. Why no uppercase letters in the title, seems a bit odd to me in this case??
>
>On 02/03/2016 12:02 AM, Keith Wiles wrote:
>> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>> index aff5f6d..bdf8e2e 100644
>> --- a/lib/librte_mempool/rte_mempool.c
>> +++ b/lib/librte_mempool/rte_mempool.c
>> @@ -450,15 +450,11 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
>>  	int page_size = getpagesize();
>>  
>>  	/* compilation-time checks */
>> +#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>>  	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
>
>I don't think the #ifdef RTE_LIBRTE_MEMPOOL_DEBUG should be moved.
>It should only protects the checks on stats which are enabled
>in debug mode.

Will make that change for v2.
>
>> @@ -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. */
>
>As you noticed it in your initial mail, this changes the ABI. I
>think your patch justifies the ABI change, so I think it should
>follow the ABI change process described in
>dpdk/doc/guides/contributing/versioning.rst.
>
>From what I understand of versioning.rst, these kind of changes
>requires a deprecation notice first, and will be integrated in
>next version. I don't think it's easy to keep a backward compat
>in this case, especially because the rte_mempool structure is
>used by several inlined functions.

I am reading the API doc and need to understand this process a bit more, but from what I can tell I need to add a ifdef RTE_NEXT_ABI around the new structure and old. Not sure where else I need to do that as compat is a bit hard as you stated. The API revision file is there something that needs to be done in that vile too?

You can reply to me directly it you like to save some bandwidth.
>
>Regards,
>Olivier
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size
    2016-02-08 11:02  4% ` Olivier MATZ
@ 2016-02-09 17:30  2% ` Keith Wiles
  2016-02-10 21:18  7%   ` [dpdk-dev] [PATCH v3] " Keith Wiles
                     ` (2 more replies)
  1 sibling, 3 replies; 200+ results
From: Keith Wiles @ 2016-02-09 17:30 UTC (permalink / raw)
  To: dev

Patch v2 to add some comments and setup for RTE_NEXT_ABI changes.

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.

Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
 app/test/test_mempool.c                     |  5 ++
 config/defconfig_x86_64-native-linuxapp-gcc |  5 ++
 lib/librte_mempool/rte_mempool.c            | 83 ++++++++++++++++++++++++++---
 lib/librte_mempool/rte_mempool.h            | 57 +++++++++++++++++++-
 4 files changed, 143 insertions(+), 7 deletions(-)

diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
index 72f8fb6..2829d40 100644
--- a/app/test/test_mempool.c
+++ b/app/test/test_mempool.c
@@ -122,8 +122,13 @@ test_mempool_basic(void)
 		return -1;
 
 	printf("get private data\n");
+#ifdef RTE_NEXT_ABI
+	if (rte_mempool_get_priv(mp) != (char *)mp +
+			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))
+#else
 	if (rte_mempool_get_priv(mp) !=
 			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
+#endif
 		return -1;
 
 	printf("get physical address of an object\n");
diff --git a/config/defconfig_x86_64-native-linuxapp-gcc b/config/defconfig_x86_64-native-linuxapp-gcc
index 60baf5b..02e9ace 100644
--- a/config/defconfig_x86_64-native-linuxapp-gcc
+++ b/config/defconfig_x86_64-native-linuxapp-gcc
@@ -40,3 +40,8 @@ CONFIG_RTE_ARCH_64=y
 
 CONFIG_RTE_TOOLCHAIN="gcc"
 CONFIG_RTE_TOOLCHAIN_GCC=y
+CONFIG_RTE_BUILD_SHARED_LIB=y
+CONFIG_RTE_NEXT_ABI=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_KNI_KMOD=n
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index aff5f6d..c61dc44 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -452,12 +452,17 @@ 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);
+#ifdef RTE_NEXT_ABI
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#else
 #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
+#endif /* RTE_NEXT_ABI */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
 			  RTE_CACHE_LINE_MASK) != 0);
@@ -527,9 +532,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 +548,12 @@ 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.
 	 */
+#ifdef RTE_NEXT_ABI
+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
+	mempool_size += private_data_size;
+#else
 	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
+#endif /* RTE_NEXT_ABI */
 	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
 	if (vaddr == NULL)
 		mempool_size += (size_t)objsz.total_size * n;
@@ -598,9 +607,22 @@ 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;
 
+#ifdef RTE_NEXT_ABI
+	/*
+	 * 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 *)
+			((char *)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, cache_size) +
+		private_data_size;
+#else
 	/* calculate address of the first element for continuous mempool. */
 	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
 		private_data_size;
+#endif /* RTE_NEXT_ABI */
 	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
 
 	/* populate address translation fields. */
@@ -613,9 +635,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);
 	}
@@ -645,10 +666,21 @@ unsigned
 rte_mempool_count(const struct rte_mempool *mp)
 {
 	unsigned count;
+#ifdef RTE_NEXT_ABI
+	unsigned lcore_id;
 
 	count = rte_ring_count(mp->ring);
 
+	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;
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+
+	count = rte_ring_count(mp->ring);
+
 	{
 		unsigned lcore_id;
 		if (mp->cache_size == 0)
@@ -658,7 +690,7 @@ rte_mempool_count(const struct rte_mempool *mp)
 			count += mp->local_cache[lcore_id].len;
 	}
 #endif
-
+#endif /* RTE_NEXT_ABI */
 	/*
 	 * due to race condition (access to len is not locked), the
 	 * total can be greater than size... so fix the result
@@ -672,6 +704,24 @@ rte_mempool_count(const struct rte_mempool *mp)
 static unsigned
 rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 {
+#ifdef RTE_NEXT_ABI
+	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);
+		count += cache_count;
+	}
+	fprintf(f, "    total_cache_count=%u\n", count);
+	return count;
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	unsigned lcore_id;
 	unsigned count = 0;
@@ -691,6 +741,7 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 	fprintf(f, "  cache disabled\n");
 	return 0;
 #endif
+#endif /* RTE_NEXT_ABI */
 }
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -755,6 +806,26 @@ mempool_audit_cookies(const struct rte_mempool *mp)
 #define mempool_audit_cookies(mp) do {} while(0)
 #endif
 
+#ifdef RTE_NEXT_ABI
+/* 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",
+				lcore_id);
+			rte_panic("MEMPOOL: invalid cache len\n");
+		}
+	}
+}
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 /* check cookies before and after objects */
 static void
@@ -773,7 +844,7 @@ mempool_audit_cache(const struct rte_mempool *mp)
 #else
 #define mempool_audit_cache(mp) do {} while(0)
 #endif
-
+#endif /* RTE_NEXT_ABI */
 
 /* 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 6e2390a..fc9b595 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -95,6 +95,19 @@ struct rte_mempool_debug_stats {
 } __rte_cache_aligned;
 #endif
 
+#ifdef RTE_NEXT_ABI
+/**
+ * A structure that stores a per-core object cache.
+ */
+struct rte_mempool_cache {
+	unsigned len; /**< Cache len */
+	/*
+	 * 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;
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 /**
  * A structure that stores a per-core object cache.
@@ -108,6 +121,7 @@ struct rte_mempool_cache {
 	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
 } __rte_cache_aligned;
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_NEXT_ABI */
 
 /**
  * A structure that stores the size of mempool elements.
@@ -194,10 +208,14 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
+#ifdef RTE_NEXT_ABI
+	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/** Per-lcore local cache. */
 	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
 #endif
+#endif  /* RTE_NEXT_ABI */
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	/** Per-lcore statistics. */
@@ -246,6 +264,26 @@ struct rte_mempool {
 #define __MEMPOOL_STAT_ADD(mp, name, n) do {} while(0)
 #endif
 
+#ifdef RTE_NEXT_ABI
+/**
+ * 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
+ *   Pointer to the memory pool.
+ * @param pgn
+ *   Number of pages used to store mempool objects.
+ */
+#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
+	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
+	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
+#else
 /**
  * Calculate the size of the mempool header.
  *
@@ -257,7 +295,7 @@ struct rte_mempool {
 #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))
-
+#endif /* RTE_NEXT_ABI */
 /**
  * Return true if the whole mempool is in contiguous memory.
  */
@@ -755,19 +793,25 @@ static inline void __attribute__((always_inline))
 __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 		    unsigned n, int is_mp)
 {
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#endif /* RTE_NEXT_ABI */
 	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;
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_NEXT_ABI */
 
 	/* increment stat now, adding in mempool always success */
 	__MEMPOOL_STAT_ADD(mp, put, n);
 
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#endif /* RTE_NEXT_ABI */
 	/* 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 +846,9 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 	return;
 
 ring_enqueue:
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_NEXT_ABI */
 
 	/* push remaining objects in ring */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -946,7 +992,9 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 		   unsigned n, int is_mc)
 {
 	int ret;
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#endif /* RTE_NEXT_ABI */
 	struct rte_mempool_cache *cache;
 	uint32_t index, len;
 	void **cache_objs;
@@ -992,7 +1040,9 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 	return 0;
 
 ring_dequeue:
+#ifndef RTE_NEXT_ABI	/* Note: ifndef */
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_NEXT_ABI */
 
 	/* get remaining objects from ring */
 	if (is_mc)
@@ -1293,7 +1343,12 @@ void rte_mempool_audit(const struct rte_mempool *mp);
  */
 static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
 {
+#ifdef RTE_NEXT_ABI
+	return (char *)mp +
+		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
+#else
 	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
+#endif /* RTE_NEXT_ABI */
 }
 
 /**
-- 
2.7.0

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v2 2/2] doc: rename release notes 2.3 to 16.04
  @ 2016-02-10 14:33  9%   ` John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2016-02-10 14:33 UTC (permalink / raw)
  To: dev

From: "Richardson, Bruce" <bruce.richardson@intel.com>

Updated release documentation to reflect new numbering scheme.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/index.rst         |   2 +-
 doc/guides/rel_notes/release_16_04.rst | 138 +++++++++++++++++++++++++++++++++
 doc/guides/rel_notes/release_2_3.rst   | 138 ---------------------------------
 3 files changed, 139 insertions(+), 139 deletions(-)
 create mode 100644 doc/guides/rel_notes/release_16_04.rst
 delete mode 100644 doc/guides/rel_notes/release_2_3.rst

diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 29013cf..84317b8 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -36,7 +36,7 @@ Release Notes
     :numbered:
 
     rel_description
-    release_2_3
+    release_16_04
     release_2_2
     release_2_1
     release_2_0
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
new file mode 100644
index 0000000..27fc624
--- /dev/null
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -0,0 +1,138 @@
+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.
+
+* **Virtio 1.0.**
+
+  Enabled virtio 1.0 support for virtio pmd driver.
+
+
+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.2
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.1
+     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.2
+     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
diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
deleted file mode 100644
index 7945694..0000000
--- a/doc/guides/rel_notes/release_2_3.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-DPDK Release 2.3
-================
-
-
-**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_2_3.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.
-
-* **Virtio 1.0.**
-
-  Enabled virtio 1.0 support for virtio pmd driver.
-
-
-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.2
-     librte_acl.so.2
-     librte_cfgfile.so.2
-     librte_cmdline.so.1
-     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.2
-     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
-- 
2.5.0

^ permalink raw reply	[relevance 9%]

* [dpdk-dev] [PATCH v3 2/2] doc: rename release notes 2.3 to 16.04
  @ 2016-02-10 17:02  9%   ` John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2016-02-10 17:02 UTC (permalink / raw)
  To: dev

From: "Richardson, Bruce" <bruce.richardson@intel.com>

Updated release documentation to reflect new numbering scheme.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/index.rst         |   2 +-
 doc/guides/rel_notes/release_16_04.rst | 138 +++++++++++++++++++++++++++++++++
 doc/guides/rel_notes/release_2_3.rst   | 138 ---------------------------------
 3 files changed, 139 insertions(+), 139 deletions(-)
 create mode 100644 doc/guides/rel_notes/release_16_04.rst
 delete mode 100644 doc/guides/rel_notes/release_2_3.rst

diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 29013cf..84317b8 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -36,7 +36,7 @@ Release Notes
     :numbered:
 
     rel_description
-    release_2_3
+    release_16_04
     release_2_2
     release_2_1
     release_2_0
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
new file mode 100644
index 0000000..27fc624
--- /dev/null
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -0,0 +1,138 @@
+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.
+
+* **Virtio 1.0.**
+
+  Enabled virtio 1.0 support for virtio pmd driver.
+
+
+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.2
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.1
+     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.2
+     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
diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
deleted file mode 100644
index 7945694..0000000
--- a/doc/guides/rel_notes/release_2_3.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-DPDK Release 2.3
-================
-
-
-**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_2_3.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.
-
-* **Virtio 1.0.**
-
-  Enabled virtio 1.0 support for virtio pmd driver.
-
-
-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.2
-     librte_acl.so.2
-     librte_cfgfile.so.2
-     librte_cmdline.so.1
-     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.2
-     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
-- 
2.5.0

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size
@ 2016-02-10 18:01  3% Wiles, Keith
  2016-02-10 18:02  3% ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2016-02-10 18:01 UTC (permalink / raw)
  To: Olivier MATZ, dev

>>Hi Keith,
>>
>>Thank you for adding the RTE_NEXT_ABI. I think this is the way
>>described in the process. Your changes will be available in next
>>version (16.4) for people compiling with RTE_NEXT_ABI=y, and in
>>16.7 without option (I'm just surprised that RTE_NEXT_ABI=y in
>>default configs...).
>>
>>I think a deprecation notice should also be added in this commit
>>in doc/guides/rel_notes/deprecation.rst.
>
>Will add the text.
>>
>>Please also find comments below.
>>
>>On 02/09/2016 06:30 PM, Keith Wiles wrote:
>>
>>> diff --git a/config/defconfig_x86_64-native-linuxapp-gcc b/config/defconfig_x86_64-native-linuxapp-gcc
>>> index 60baf5b..02e9ace 100644
>>> --- a/config/defconfig_x86_64-native-linuxapp-gcc
>>> +++ b/config/defconfig_x86_64-native-linuxapp-gcc
>>> @@ -40,3 +40,8 @@ CONFIG_RTE_ARCH_64=y
>>>  
>>>  CONFIG_RTE_TOOLCHAIN="gcc"
>>>  CONFIG_RTE_TOOLCHAIN_GCC=y
>>> +CONFIG_RTE_BUILD_SHARED_LIB=y
>>> +CONFIG_RTE_NEXT_ABI=n
>>> +CONFIG_RTE_EAL_IGB_UIO=n
>>> +CONFIG_RTE_LIBRTE_KNI=n
>>> +CONFIG_RTE_KNI_KMOD=n
>
>Hmm, not sure where this came from, but will remove it.

I think this was from the ABI-Checker I ran and the tool should leave the repo in its original state.

>>
>>I think this should not be part of the patch.
>>
>>> @@ -672,6 +704,24 @@ rte_mempool_count(const struct rte_mempool *mp)
>>>  static unsigned
>>>  rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
>>>  {
>>> +#ifdef RTE_NEXT_ABI
>>> +	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);
>>> +		count += cache_count;
>>> +	}
>>> +	fprintf(f, "    total_cache_count=%u\n", count);
>>> +	return count;
>>> +#else
>>>  #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>>  	unsigned lcore_id;
>>>  	unsigned count = 0;
>>
>>I think in this case we could avoid to duplicate the code without
>>beeing unclear by using the proper #ifdefs:
>
>I was struggling with how it should be done. I like to see clear ifdefs and be able to see the complete code for a given case. In these cases I wanted to make it simple to remove the code quickly by just deleting lines instead of editing lines. I will follow your suggestion.
>>
>>#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI)
>>	/* common code */
>>#ifdef RTE_NEXT_ABI
>>	if (mp->cache_size == 0)
>>		return count;
>>#endif
>>	/* common code */
>>#else
>>...
>>#endif
>>
>>
>>> @@ -755,6 +806,26 @@ mempool_audit_cookies(const struct rte_mempool *mp)
>>>  #define mempool_audit_cookies(mp) do {} while(0)
>>>  #endif
>>>  
>>> +#ifdef RTE_NEXT_ABI
>>> +/* 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",
>>> +				lcore_id);
>>> +			rte_panic("MEMPOOL: invalid cache len\n");
>>> +		}
>>> +	}
>>> +}
>>> +#else
>>
>>same here
>>
>>> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
>>> index 6e2390a..fc9b595 100644
>>> --- a/lib/librte_mempool/rte_mempool.h
>>> +++ b/lib/librte_mempool/rte_mempool.h
>>> @@ -95,6 +95,19 @@ struct rte_mempool_debug_stats {
>>>  } __rte_cache_aligned;
>>>  #endif
>>>  
>>> +#ifdef RTE_NEXT_ABI
>>> +/**
>>> + * A structure that stores a per-core object cache.
>>> + */
>>> +struct rte_mempool_cache {
>>> +	unsigned len; /**< Cache len */
>>> +	/*
>>> +	 * 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;
>>> +#else
>>
>>same here
>>
>>
>>
>>> @@ -755,19 +793,25 @@ static inline void __attribute__((always_inline))
>>>  __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
>>>  		    unsigned n, int is_mp)
>>>  {
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>> +#endif /* RTE_NEXT_ABI */
>>>  	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;
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
>>> +#endif /* RTE_NEXT_ABI */
>>
>>this looks strange... I think it does not work properly.
>>Why not
>>#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI)
>
>Yes, it is strange :-(
>>
>>>  	/* increment stat now, adding in mempool always success */
>>>  	__MEMPOOL_STAT_ADD(mp, put, n);
>>>  
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>> +#endif /* RTE_NEXT_ABI */
>>>  	/* 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 +846,9 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
>>>  	return;
>>>  
>>>  ring_enqueue:
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
>>> +#endif /* RTE_NEXT_ABI */
>>>  
>>>  	/* push remaining objects in ring */
>>>  #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>>> @@ -946,7 +992,9 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
>>>  		   unsigned n, int is_mc)
>>>  {
>>>  	int ret;
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>>> +#endif /* RTE_NEXT_ABI */
>>>  	struct rte_mempool_cache *cache;
>>>  	uint32_t index, len;
>>>  	void **cache_objs;
>>> @@ -992,7 +1040,9 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
>>>  	return 0;
>>>  
>>>  ring_dequeue:
>>> +#ifndef RTE_NEXT_ABI	/* Note: ifndef */
>>>  #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
>>> +#endif /* RTE_NEXT_ABI */
>>>  
>>>  	/* get remaining objects from ring */
>>>  	if (is_mc)
>>
>>Same in those cases.
>>
>>
>>
>>Regards,
>>Olivier
>>
>
>
>Regards,
>Keith
>
>
>
>
>


Regards,
Keith





^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size
  2016-02-10 18:01  3% [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size Wiles, Keith
@ 2016-02-10 18:02  3% ` Thomas Monjalon
  2016-02-12 11:52  3%   ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-02-10 18:02 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dev, Neil Horman

2016-02-10 18:01, Wiles, Keith:
> >>> --- a/config/defconfig_x86_64-native-linuxapp-gcc
> >>> +++ b/config/defconfig_x86_64-native-linuxapp-gcc
> >>> @@ -40,3 +40,8 @@ CONFIG_RTE_ARCH_64=y
> >>>  
> >>>  CONFIG_RTE_TOOLCHAIN="gcc"
> >>>  CONFIG_RTE_TOOLCHAIN_GCC=y
> >>> +CONFIG_RTE_BUILD_SHARED_LIB=y
> >>> +CONFIG_RTE_NEXT_ABI=n
> >>> +CONFIG_RTE_EAL_IGB_UIO=n
> >>> +CONFIG_RTE_LIBRTE_KNI=n
> >>> +CONFIG_RTE_KNI_KMOD=n
> >
> >Hmm, not sure where this came from, but will remove it.
> 
> I think this was from the ABI-Checker I ran and the tool should leave the repo in its original state.

Yes you're right. The ABI checker modify the defconfig instead of modifying
the generated .config file.
Anyone for a patch?

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-09 17:30  2% ` [dpdk-dev] [PATCH v2] mempool: reduce " Keith Wiles
@ 2016-02-10 21:18  7%   ` Keith Wiles
  2016-02-12 11:23  0%     ` Panu Matilainen
    2016-02-12 18:36  3%   ` [dpdk-dev] [PATCH v4] " Keith Wiles
  2 siblings, 1 reply; 200+ results
From: Keith Wiles @ 2016-02-10 21:18 UTC (permalink / raw)
  To: dev

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.

Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
* Patch v3 fix up the ifdefs to correct some problems in removing ifdef
  lines. Added the ABI deprecation notice to the document file.
* Patch v2 to add some comments and setup for RTE_NEXT_ABI changes.

 app/test/test_mempool.c              |  5 +++
 doc/guides/rel_notes/deprecation.rst |  7 +++
 lib/librte_mempool/rte_mempool.c     | 82 +++++++++++++++++++++++++++++++++---
 lib/librte_mempool/rte_mempool.h     | 46 ++++++++++++++++----
 4 files changed, 127 insertions(+), 13 deletions(-)

diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
index f0f823b..f3fba50 100644
--- a/app/test/test_mempool.c
+++ b/app/test/test_mempool.c
@@ -122,8 +122,13 @@ test_mempool_basic(void)
 		return -1;
 
 	printf("get private data\n");
+#ifdef RTE_NEXT_ABI
+	if (rte_mempool_get_priv(mp) != (char *)mp +
+			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))
+#else
 	if (rte_mempool_get_priv(mp) !=
 			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
+#endif
 		return -1;
 
 	printf("get physical address of an object\n");
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..1b9d25e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,3 +49,10 @@ 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 change is planned for the rte_mempool structure to allow mempool
+  cache support to be dynamic depending on the mempool being created
+  needing cache support. Saves about 1.5M of memory per rte_mempool structure
+  by removing the per lcore cache memory. Change will occur after DPDK 16.04
+  release.
+
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index aff5f6d..5f21eaa 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -452,12 +452,17 @@ 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);
+#ifdef RTE_NEXT_ABI
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#else
 #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
+#endif /* RTE_NEXT_ABI */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
 			  RTE_CACHE_LINE_MASK) != 0);
@@ -527,9 +532,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 +548,12 @@ 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.
 	 */
+#ifdef RTE_NEXT_ABI
+	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
+	mempool_size += private_data_size;
+#else
 	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
+#endif /* RTE_NEXT_ABI */
 	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
 	if (vaddr == NULL)
 		mempool_size += (size_t)objsz.total_size * n;
@@ -598,9 +607,22 @@ 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;
 
+#ifdef RTE_NEXT_ABI
+	/*
+	 * 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 *)
+			((char *)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, cache_size) +
+		private_data_size;
+#else
 	/* calculate address of the first element for continuous mempool. */
 	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
 		private_data_size;
+#endif /* RTE_NEXT_ABI */
 	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
 
 	/* populate address translation fields. */
@@ -613,9 +635,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);
 	}
@@ -645,10 +666,21 @@ unsigned
 rte_mempool_count(const struct rte_mempool *mp)
 {
 	unsigned count;
+#ifdef RTE_NEXT_ABI
+	unsigned lcore_id;
 
 	count = rte_ring_count(mp->ring);
 
+	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;
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+
+	count = rte_ring_count(mp->ring);
+
 	{
 		unsigned lcore_id;
 		if (mp->cache_size == 0)
@@ -658,6 +690,7 @@ rte_mempool_count(const struct rte_mempool *mp)
 			count += mp->local_cache[lcore_id].len;
 	}
 #endif
+#endif /* RTE_NEXT_ABI */
 
 	/*
 	 * due to race condition (access to len is not locked), the
@@ -672,6 +705,24 @@ rte_mempool_count(const struct rte_mempool *mp)
 static unsigned
 rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 {
+#ifdef RTE_NEXT_ABI
+	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);
+		count += cache_count;
+	}
+	fprintf(f, "    total_cache_count=%u\n", count);
+	return count;
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	unsigned lcore_id;
 	unsigned count = 0;
@@ -691,6 +742,7 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
 	fprintf(f, "  cache disabled\n");
 	return 0;
 #endif
+#endif /* RTE_NEXT_ABI */
 }
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -755,6 +807,26 @@ mempool_audit_cookies(const struct rte_mempool *mp)
 #define mempool_audit_cookies(mp) do {} while(0)
 #endif
 
+#ifdef RTE_NEXT_ABI
+/* 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",
+				lcore_id);
+			rte_panic("MEMPOOL: invalid cache len\n");
+		}
+	}
+}
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 /* check cookies before and after objects */
 static void
@@ -773,7 +845,7 @@ mempool_audit_cache(const struct rte_mempool *mp)
 #else
 #define mempool_audit_cache(mp) do {} while(0)
 #endif
-
+#endif /* RTE_NEXT_ABI */
 
 /* 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..b12d6a9 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -95,7 +95,7 @@ struct rte_mempool_debug_stats {
 } __rte_cache_aligned;
 #endif
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
 /**
  * A structure that stores a per-core object cache.
  */
@@ -107,7 +107,7 @@ struct rte_mempool_cache {
 	 */
 	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
 } __rte_cache_aligned;
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
 
 /**
  * A structure that stores the size of mempool elements.
@@ -194,10 +194,14 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
+#ifdef RTE_NEXT_ABI
+	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
+#else
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/** Per-lcore local cache. */
 	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
 #endif
+#endif  /* RTE_NEXT_ABI */
 
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 	/** Per-lcore statistics. */
@@ -246,6 +250,26 @@ struct rte_mempool {
 #define __MEMPOOL_STAT_ADD(mp, name, n) do {} while(0)
 #endif
 
+#ifdef RTE_NEXT_ABI
+/**
+ * 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
+ *   Pointer to the memory pool.
+ * @param pgn
+ *   Number of pages used to store mempool objects.
+ */
+#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
+	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
+	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
+#else
 /**
  * Calculate the size of the mempool header.
  *
@@ -257,6 +281,7 @@ struct rte_mempool {
 #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))
+#endif /* RTE_NEXT_ABI */
 
 /**
  * Return true if the whole mempool is in contiguous memory.
@@ -755,19 +780,19 @@ 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
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
 	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 */
+#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */   /* Remove line RTE_NEXT_ABI */
 
 	/* increment stat now, adding in mempool always success */
 	__MEMPOOL_STAT_ADD(mp, put, n);
 
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
 	/* 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 +827,7 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 	return;
 
 ring_enqueue:
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
 
 	/* push remaining objects in ring */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
@@ -946,7 +971,7 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 		   unsigned n, int is_mc)
 {
 	int ret;
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
 	struct rte_mempool_cache *cache;
 	uint32_t index, len;
 	void **cache_objs;
@@ -992,7 +1017,7 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 	return 0;
 
 ring_dequeue:
-#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
+#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
 
 	/* get remaining objects from ring */
 	if (is_mc)
@@ -1293,7 +1318,12 @@ void rte_mempool_audit(const struct rte_mempool *mp);
  */
 static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
 {
+#ifdef RTE_NEXT_ABI
+	return (char *)mp +
+		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
+#else
 	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
+#endif /* RTE_NEXT_ABI */
 }
 
 /**
-- 
2.5.4 (Apple Git-61)

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v5 3/4] ethdev: redesign link speed config API
  @ 2016-02-11 15:27  3%           ` Nélio Laranjeiro
  2016-02-11 23:23  0%             ` Marc
  0 siblings, 1 reply; 200+ results
From: Nélio Laranjeiro @ 2016-02-11 15:27 UTC (permalink / raw)
  To: Marc; +Cc: dev

On Tue, Feb 02, 2016 at 11:30:59PM +0100, Marc wrote:
> On 2 February 2016 at 03:20, Stephen Hemminger <stephen@networkplumber.org>
> wrote:
> 
> > On Thu, 28 Jan 2016 17:33:20 +0000
> > Harish Patil <harish.patil@qlogic.com> wrote:
> >
> > > * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
> > >   values of all supported link speeds, in Mbps.
> >
> > I would prefer that there were no speed value macros.
> > Linux used to have these, but people kept adding new hardware speeds
> > and it soon gets out of date.
> >
> 
> I see what you mean, but I am not sure I agree. Link speeds are generally a
> reduced amount of items (~20). Though it is true it can eventually grow,
> but at small rate. Having numeric constants all over the source seems less
> readable and less maintainable (e.g. less "grepable"/"sedable") to me.
> 
> 
> >
> > If you are going to redo it, then just increase speed to 64 bit, and allow
> > any non-zero value.
> >
> 
> Value is now 32 bits, which I think is enough for future rates in mbps.
> Since these constants were there, and before doing something to have to
> revert it, can someone else give his/her opinion on this?

For non 64bit architecture it is better to keep it on 32 bit but, if this
field is only used on control plane we can afford 64 bit field and avoid
another ABI breakage (in a far future).

Even if this 32 bit field seems large enough you can already find on
Internet some reports of transmission of petabit/s [1], we can imagine a
NIC which provide this possibility by aggregating a lot of optical links
and DPDK only will see it as single one.

> If there is consensus, I've no problem on removing it for v8
> 
> Thanks
> marc

[1] http://optics.org/news/4/1/29

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3] af_packet: make the device detachable
@ 2016-02-11 16:37  3% Wojciech Zmuda
  2016-02-24 14:08  3% ` Iremonger, Bernard
  0 siblings, 1 reply; 200+ results
From: Wojciech Zmuda @ 2016-02-11 16:37 UTC (permalink / raw)
  To: dev

Allow dynamic deallocation of af_packet device through proper
API functions. To achieve this:
* set device flag to RTE_ETH_DEV_DETACHABLE
* implement rte_pmd_af_packet_devuninit() and expose it
  through rte_driver.uninit()
* copy device name to ethdev->data to make discoverable with
  rte_eth_dev_allocated()
Moreover, make af_packet init function static, as there is no
reason to keep it public.

Signed-off-by: Wojciech Zmuda <woz@semihalf.com>
---
v3:
* Rephrased feature note in release notes.
* Rephrased commit log.
* Added API change note in release notes.
* Made init function static.
* Removed af_packet header file, as it is not needed
  after init function is not public anymore.

v2:
* Fixed typo and a comment.
* Added feature to the 2.3 release notes.
* Free memory allocated for rx and tx queues.

 doc/guides/rel_notes/release_2_3.rst               |  6 +++
 drivers/net/af_packet/Makefile                     |  5 --
 drivers/net/af_packet/rte_eth_af_packet.c          | 43 ++++++++++++++++--
 drivers/net/af_packet/rte_eth_af_packet.h          | 53 ----------------------
 .../net/af_packet/rte_pmd_af_packet_version.map    |  3 --
 5 files changed, 45 insertions(+), 65 deletions(-)
 delete mode 100644 drivers/net/af_packet/rte_eth_af_packet.h

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
index 7945694..da4abc3 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -39,6 +39,9 @@ This section should contain new features added in this release. Sample format:
 
   Enabled virtio 1.0 support for virtio pmd driver.
 
+* **Added af_packet dynamic removal function.**
+
+  Af_packet device can now be detached using API, like other PMD devices.
 
 Resolved Issues
 ---------------
@@ -91,6 +94,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.
 
+* Af_packet device init function is no longer public. Device should be attached
+  with API.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/af_packet/Makefile b/drivers/net/af_packet/Makefile
index ce5d239..cb1a7ae 100644
--- a/drivers/net/af_packet/Makefile
+++ b/drivers/net/af_packet/Makefile
@@ -50,11 +50,6 @@ CFLAGS += $(WERROR_FLAGS)
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += rte_eth_af_packet.c
 
-#
-# Export include files
-#
-SYMLINK-y-include += rte_eth_af_packet.h
-
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_mbuf
 DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_ether
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..5544528 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -53,8 +53,6 @@
 #include <unistd.h>
 #include <poll.h>
 
-#include "rte_eth_af_packet.h"
-
 #define ETH_AF_PACKET_IFACE_ARG		"iface"
 #define ETH_AF_PACKET_NUM_Q_ARG		"qpairs"
 #define ETH_AF_PACKET_BLOCKSIZE_ARG	"blocksz"
@@ -65,6 +63,8 @@
 #define DFLT_FRAME_SIZE		(1 << 11)
 #define DFLT_FRAME_COUNT	(1 << 9)
 
+#define RTE_PMD_AF_PACKET_MAX_RINGS 16
+
 struct pkt_rx_queue {
 	int sockfd;
 
@@ -667,11 +667,13 @@ rte_pmd_init_internals(const char *name,
 	data->nb_tx_queues = (uint16_t)nb_queues;
 	data->dev_link = pmd_link;
 	data->mac_addrs = &(*internals)->eth_addr;
+	strncpy(data->name,
+		(*eth_dev)->data->name, strlen((*eth_dev)->data->name));
 
 	(*eth_dev)->data = data;
 	(*eth_dev)->dev_ops = &ops;
 	(*eth_dev)->driver = NULL;
-	(*eth_dev)->data->dev_flags = 0;
+	(*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
 	(*eth_dev)->data->drv_name = drivername;
 	(*eth_dev)->data->kdrv = RTE_KDRV_NONE;
 	(*eth_dev)->data->numa_node = numa_node;
@@ -798,7 +800,7 @@ rte_eth_from_packet(const char *name,
 	return 0;
 }
 
-int
+static int
 rte_pmd_af_packet_devinit(const char *name, const char *params)
 {
 	unsigned numa_node;
@@ -836,10 +838,43 @@ exit:
 	return ret;
 }
 
+static int
+rte_pmd_af_packet_devuninit(const char *name)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct pmd_internals *internals;
+	unsigned q;
+
+	RTE_LOG(INFO, PMD, "Closing AF_PACKET ethdev on numa socket %u\n",
+			rte_socket_id());
+
+	if (name == NULL)
+		return -1;
+
+	/* find the ethdev entry */
+	eth_dev = rte_eth_dev_allocated(name);
+	if (eth_dev == NULL)
+		return -1;
+
+	internals = eth_dev->data->dev_private;
+	for (q = 0; q < internals->nb_queues; q++) {
+		rte_free(internals->rx_queue[q].rd);
+		rte_free(internals->tx_queue[q].rd);
+	}
+
+	rte_free(eth_dev->data->dev_private);
+	rte_free(eth_dev->data);
+
+	rte_eth_dev_release_port(eth_dev);
+
+	return 0;
+}
+
 static struct rte_driver pmd_af_packet_drv = {
 	.name = "eth_af_packet",
 	.type = PMD_VDEV,
 	.init = rte_pmd_af_packet_devinit,
+	.uninit = rte_pmd_af_packet_devuninit,
 };
 
 PMD_REGISTER_DRIVER(pmd_af_packet_drv);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.h b/drivers/net/af_packet/rte_eth_af_packet.h
deleted file mode 100644
index 5d1bc7e..0000000
--- a/drivers/net/af_packet/rte_eth_af_packet.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef _RTE_ETH_AF_PACKET_H_
-#define _RTE_ETH_AF_PACKET_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define RTE_PMD_AF_PACKET_MAX_RINGS 16
-
-/**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
- * configured on command line.
- */
-int rte_pmd_af_packet_devinit(const char *name, const char *params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map b/drivers/net/af_packet/rte_pmd_af_packet_version.map
index de95169..ef35398 100644
--- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
+++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
@@ -1,7 +1,4 @@
 DPDK_2.0 {
-	global:
-
-	rte_pmd_af_packet_devinit;
 
 	local: *;
 };
-- 
1.9.1

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v5 3/4] ethdev: redesign link speed config API
  2016-02-11 15:27  3%           ` Nélio Laranjeiro
@ 2016-02-11 23:23  0%             ` Marc
  0 siblings, 0 replies; 200+ results
From: Marc @ 2016-02-11 23:23 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

On 11 February 2016 at 16:27, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> On Tue, Feb 02, 2016 at 11:30:59PM +0100, Marc wrote:
> > On 2 February 2016 at 03:20, Stephen Hemminger <
> stephen@networkplumber.org>
> > wrote:
> >
> > > On Thu, 28 Jan 2016 17:33:20 +0000
> > > Harish Patil <harish.patil@qlogic.com> wrote:
> > >
> > > > * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
> > > >   values of all supported link speeds, in Mbps.
> > >
> > > I would prefer that there were no speed value macros.
> > > Linux used to have these, but people kept adding new hardware speeds
> > > and it soon gets out of date.
> > >
> >
> > I see what you mean, but I am not sure I agree. Link speeds are
> generally a
> > reduced amount of items (~20). Though it is true it can eventually grow,
> > but at small rate. Having numeric constants all over the source seems
> less
> > readable and less maintainable (e.g. less "grepable"/"sedable") to me.
> >
> >
> > >
> > > If you are going to redo it, then just increase speed to 64 bit, and
> allow
> > > any non-zero value.
> > >
> >
> > Value is now 32 bits, which I think is enough for future rates in mbps.
> > Since these constants were there, and before doing something to have to
> > revert it, can someone else give his/her opinion on this?
>
> For non 64bit architecture it is better to keep it on 32 bit but, if this
> field is only used on control plane we can afford 64 bit field and avoid
> another ABI breakage (in a far future).
>
> Even if this 32 bit field seems large enough you can already find on
> Internet some reports of transmission of petabit/s [1], we can imagine a
> NIC which provide this possibility by aggregating a lot of optical links
> and DPDK only will see it as single one.
>

OK, since it is not performance critical I will change it to 64 bit value.


>
> > If there is consensus, I've no problem on removing it for v8
>

Still the question about numeric speed MACROs is open.

best
marc




> >
> > Thanks
> > marc
>
> [1] http://optics.org/news/4/1/29
>
> --
> Nélio Laranjeiro
> 6WIND
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-10 21:18  7%   ` [dpdk-dev] [PATCH v3] " Keith Wiles
@ 2016-02-12 11:23  0%     ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-02-12 11:23 UTC (permalink / raw)
  To: Keith Wiles, dev

On 02/10/2016 11:18 PM, Keith Wiles wrote:
> 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.
>
> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
> ---
> * Patch v3 fix up the ifdefs to correct some problems in removing ifdef
>    lines. Added the ABI deprecation notice to the document file.
> * Patch v2 to add some comments and setup for RTE_NEXT_ABI changes.
>
>   app/test/test_mempool.c              |  5 +++
>   doc/guides/rel_notes/deprecation.rst |  7 +++
>   lib/librte_mempool/rte_mempool.c     | 82 +++++++++++++++++++++++++++++++++---
>   lib/librte_mempool/rte_mempool.h     | 46 ++++++++++++++++----
>   4 files changed, 127 insertions(+), 13 deletions(-)
>
> diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
> index f0f823b..f3fba50 100644
> --- a/app/test/test_mempool.c
> +++ b/app/test/test_mempool.c
> @@ -122,8 +122,13 @@ test_mempool_basic(void)
>   		return -1;
>
>   	printf("get private data\n");
> +#ifdef RTE_NEXT_ABI
> +	if (rte_mempool_get_priv(mp) != (char *)mp +
> +			MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size))
> +#else
>   	if (rte_mempool_get_priv(mp) !=
>   			(char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num))
> +#endif
>   		return -1;
>
>   	printf("get physical address of an object\n");
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index e94d4a2..1b9d25e 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -49,3 +49,10 @@ 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 change is planned for the rte_mempool structure to allow mempool
> +  cache support to be dynamic depending on the mempool being created
> +  needing cache support. Saves about 1.5M of memory per rte_mempool structure
> +  by removing the per lcore cache memory. Change will occur after DPDK 16.04
> +  release.
> +
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index aff5f6d..5f21eaa 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -452,12 +452,17 @@ 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);
> +#ifdef RTE_NEXT_ABI
> +	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
> +			  RTE_CACHE_LINE_MASK) != 0);
> +#else
>   #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
> +#endif /* RTE_NEXT_ABI */
>   #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>   	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
>   			  RTE_CACHE_LINE_MASK) != 0);
> @@ -527,9 +532,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 +548,12 @@ 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.
>   	 */
> +#ifdef RTE_NEXT_ABI
> +	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num, cache_size);
> +	mempool_size += private_data_size;
> +#else
>   	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
> +#endif /* RTE_NEXT_ABI */
>   	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
>   	if (vaddr == NULL)
>   		mempool_size += (size_t)objsz.total_size * n;
> @@ -598,9 +607,22 @@ 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;
>
> +#ifdef RTE_NEXT_ABI
> +	/*
> +	 * 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 *)
> +			((char *)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, cache_size) +
> +		private_data_size;
> +#else
>   	/* calculate address of the first element for continuous mempool. */
>   	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
>   		private_data_size;
> +#endif /* RTE_NEXT_ABI */
>   	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
>
>   	/* populate address translation fields. */
> @@ -613,9 +635,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);
>   	}
> @@ -645,10 +666,21 @@ unsigned
>   rte_mempool_count(const struct rte_mempool *mp)
>   {
>   	unsigned count;
> +#ifdef RTE_NEXT_ABI
> +	unsigned lcore_id;
>
>   	count = rte_ring_count(mp->ring);
>
> +	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;
> +#else
>   #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> +
> +	count = rte_ring_count(mp->ring);
> +
>   	{
>   		unsigned lcore_id;
>   		if (mp->cache_size == 0)
> @@ -658,6 +690,7 @@ rte_mempool_count(const struct rte_mempool *mp)
>   			count += mp->local_cache[lcore_id].len;
>   	}
>   #endif
> +#endif /* RTE_NEXT_ABI */
>
>   	/*
>   	 * due to race condition (access to len is not locked), the
> @@ -672,6 +705,24 @@ rte_mempool_count(const struct rte_mempool *mp)
>   static unsigned
>   rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
>   {
> +#ifdef RTE_NEXT_ABI
> +	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);
> +		count += cache_count;
> +	}
> +	fprintf(f, "    total_cache_count=%u\n", count);
> +	return count;
> +#else
>   #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>   	unsigned lcore_id;
>   	unsigned count = 0;
> @@ -691,6 +742,7 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
>   	fprintf(f, "  cache disabled\n");
>   	return 0;
>   #endif
> +#endif /* RTE_NEXT_ABI */
>   }
>
>   #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> @@ -755,6 +807,26 @@ mempool_audit_cookies(const struct rte_mempool *mp)
>   #define mempool_audit_cookies(mp) do {} while(0)
>   #endif
>
> +#ifdef RTE_NEXT_ABI
> +/* 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",
> +				lcore_id);
> +			rte_panic("MEMPOOL: invalid cache len\n");
> +		}
> +	}
> +}
> +#else
>   #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>   /* check cookies before and after objects */
>   static void
> @@ -773,7 +845,7 @@ mempool_audit_cache(const struct rte_mempool *mp)
>   #else
>   #define mempool_audit_cache(mp) do {} while(0)
>   #endif
> -
> +#endif /* RTE_NEXT_ABI */
>
>   /* 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..b12d6a9 100644
> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -95,7 +95,7 @@ struct rte_mempool_debug_stats {
>   } __rte_cache_aligned;
>   #endif
>
> -#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
>   /**
>    * A structure that stores a per-core object cache.
>    */
> @@ -107,7 +107,7 @@ struct rte_mempool_cache {
>   	 */
>   	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
>   } __rte_cache_aligned;
> -#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
>
>   /**
>    * A structure that stores the size of mempool elements.
> @@ -194,10 +194,14 @@ struct rte_mempool {
>
>   	unsigned private_data_size;      /**< Size of private data. */
>
> +#ifdef RTE_NEXT_ABI
> +	struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
> +#else
>   #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
>   	/** Per-lcore local cache. */
>   	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
>   #endif
> +#endif  /* RTE_NEXT_ABI */
>
>   #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
>   	/** Per-lcore statistics. */
> @@ -246,6 +250,26 @@ struct rte_mempool {
>   #define __MEMPOOL_STAT_ADD(mp, name, n) do {} while(0)
>   #endif
>
> +#ifdef RTE_NEXT_ABI
> +/**
> + * 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
> + *   Pointer to the memory pool.
> + * @param pgn
> + *   Number of pages used to store mempool objects.
> + */
> +#define MEMPOOL_HEADER_SIZE(mp, pgn, cs) \
> +	(sizeof(*(mp)) + __PA_SIZE(mp, pgn) + (((cs) == 0) ? 0 : \
> +	(sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
> +#else
>   /**
>    * Calculate the size of the mempool header.
>    *
> @@ -257,6 +281,7 @@ struct rte_mempool {
>   #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))
> +#endif /* RTE_NEXT_ABI */
>
>   /**
>    * Return true if the whole mempool is in contiguous memory.
> @@ -755,19 +780,19 @@ 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
> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
>   	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 */
> +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */   /* Remove line RTE_NEXT_ABI */
>
>   	/* increment stat now, adding in mempool always success */
>   	__MEMPOOL_STAT_ADD(mp, put, n);
>
> -#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
>   	/* 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 +827,7 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
>   	return;
>
>   ring_enqueue:
> -#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
>
>   	/* push remaining objects in ring */
>   #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
> @@ -946,7 +971,7 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
>   		   unsigned n, int is_mc)
>   {
>   	int ret;
> -#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
> +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 || defined(RTE_NEXT_ABI) /* Remove line */
>   	struct rte_mempool_cache *cache;
>   	uint32_t index, len;
>   	void **cache_objs;
> @@ -992,7 +1017,7 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
>   	return 0;
>
>   ring_dequeue:
> -#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
> +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ /* Remove line RTE_NEXT_ABI */
>
>   	/* get remaining objects from ring */
>   	if (is_mc)
> @@ -1293,7 +1318,12 @@ void rte_mempool_audit(const struct rte_mempool *mp);
>    */
>   static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
>   {
> +#ifdef RTE_NEXT_ABI
> +	return (char *)mp +
> +		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
> +#else
>   	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
> +#endif /* RTE_NEXT_ABI */
>   }
>
>   /**
>

This is not RTE_NEXT_ABI material IMO, the added ifdef clutter is just 
too much.

I'd suggest adding a deprecation notice for the change now and after 
16.04 is released, just resend the patch without messing with RTE_NEXT_ABI.

	- Pnau -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
  @ 2016-02-12 11:44  3%             ` Ananyev, Konstantin
  2016-02-12 16:40  0%               ` Ivan Boule
  0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2016-02-12 11:44 UTC (permalink / raw)
  To: Ananyev, Konstantin, Kulasek, TomaszX, dev


> 
> > -----Original Message-----
> > From: Kulasek, TomaszX
> > Sent: Tuesday, February 09, 2016 5:03 PM
> > To: Ananyev, Konstantin; dev@dpdk.org
> > Subject: RE: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
> >
> >
> >
> > > -----Original Message-----
> > > From: Ananyev, Konstantin
> > > Sent: Tuesday, February 2, 2016 14:50
> > > To: Kulasek, TomaszX <tomaszx.kulasek@intel.com>; dev@dpdk.org
> > > Subject: RE: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
> > >
> > > Hi Tomasz,
> > >
> > > > -----Original Message-----
> > > > From: Kulasek, TomaszX
> > > > Sent: Tuesday, February 02, 2016 10:01 AM
> > > > To: Ananyev, Konstantin; dev@dpdk.org
> > > > Subject: RE: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
> > > >
> > > > Hi Konstantin,
> > > >
> > > > > -----Original Message-----
> > > > > From: Ananyev, Konstantin
> > > > > Sent: Friday, January 15, 2016 19:45
> > > > > To: Kulasek, TomaszX; dev@dpdk.org
> > > > > Subject: RE: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
> > > > >
> > > > > Hi Tomasz,
> > > > >
> > > > > >
> > > > > > +		/* get new buffer space first, but keep old space around
> > > */
> > > > > > +		new_bufs = rte_zmalloc("ethdev->txq_bufs",
> > > > > > +				sizeof(*dev->data->txq_bufs) * nb_queues, 0);
> > > > > > +		if (new_bufs == NULL)
> > > > > > +			return -(ENOMEM);
> > > > > > +
> > > > >
> > > > > Why not to allocate space for txq_bufs together with tx_queues (as
> > > > > one chunk for both)?
> > > > > As I understand there is always one to one mapping between them
> > > anyway.
> > > > > Would simplify things a bit.
> > > > > Or even introduce a new struct to group with all related tx queue
> > > > > info togetehr struct rte_eth_txq_data {
> > > > > 	void *queue; /*actual pmd  queue*/
> > > > > 	struct rte_eth_dev_tx_buffer buf;
> > > > > 	uint8_t state;
> > > > > }
> > > > > And use it inside struct rte_eth_dev_data?
> > > > > Would probably give a better data locality.
> > > > >
> > > >
> > > > Introducing such a struct will require a huge rework of pmd drivers. I
> > > don't think it's worth only for this one feature.
> > >
> > > Why not?
> > > Things are getting more and more messy here: now we have a separate array
> > > of pointer to queues, Separate array of queue states, you are going to add
> > > separate array of tx buffers.
> > > For me it seems logical to unite all these 3 fields into one sub-struct.
> > >
> >
> > I agree with you, and probably such a work will be nice also for rx queues, but these two changes impacts on another part of dpdk.
> > While buffered tx API is more client application helper.
> >
> > For me these two thinks are different features and should be made separately because:
> > 1) They are independent and can be done separately,
> > 2) They can (and should) be reviewed, tested and approved separately,
> > 3) They are addressed to another type of people (tx buffering to application developers, rte_eth_dev_data to pmd developers), so
> > another people can be interested in having (or not) one or second feature
> 
> Such division seems a bit artificial to me :)
> You are making changes in rte_ethdev.[c,h]  - I think that filed regrouping would make code cleaner and easier to read/maintain.
> 
> >
> > Even for bug tracking it will be cleaner to separate these two things. And yes, it is logical to unite it, maybe also for rx queues, but
> > should be discussed separately.
> >
> > I've made a prototype with this rework, and the impact on the code not related to this particular feature is too wide and strong to
> join
> > them. I would rather to provide it as independent patch for further discussion only on it, if needed.
> 
> Sure, separate patch is fine.
> Why not to submit it as extra one is the series?
> 
> 
> >
> > > >
> > > >
> > > > > > +/**
> > > > > > + * @internal
> > > > > > + * Structure used to buffer packets for future TX
> > > > > > + * Used by APIs rte_eth_tx_buffer and rte_eth_tx_buffer_flush  */
> > > > > > +struct rte_eth_dev_tx_buffer {
> > > > > > +	struct rte_mbuf *pkts[RTE_ETHDEV_TX_BUFSIZE];
> > > > >
> > > > > I think it is better to make size of pkts[] configurable at runtime.
> > > > > There are a lot of different usage scenarios - hard to predict what
> > > > > would be an optimal buffer size for all cases.
> > > > >
> > > >
> > > > This buffer is allocated in eth_dev shared memory, so there are two
> > > scenarios:
> > > > 1) We have prealocated buffer with maximal size, and then we can set
> > > > threshold level without restarting device, or
> > > > 2) We need to set its size before starting device.
> > >
> > > >
> > > > Second one is better, I think.
> > >
> > > Yep, I was thinking about 2) too.
> > > Might be an extra parameter in struct rte_eth_txconf.
> > >
> >
> > Struct rte_eth_txconf is passed to ethdev after rte_eth_dev_tx_queue_config, so we don't know its value when buffers are
> > allocated.
> 
> Ok, and why allocation of the tx buffer can't be done at rte_eth_tx_queue_setup()?
> 
> Actually just thought why not to let rte_eth_tx_buffer() to accept struct rte_eth_dev_tx_buffer * as a parameter:
> +static inline int __attribute__((always_inline))
> +rte_eth_tx_buffer(uint8_t port_id, uint16_t queue_id,  accept struct rte_eth_dev_tx_buffer * txb, struct rte_mbuf *tx_pkt)
> ?
> 
> In that case we don't need to make any changes at rte_ethdev.[h,c] to alloc/free/maintain tx_buffer inside each queue...
> It all will be upper layer responsibility.
> So no need to modify existing rte_ethdev structures/code.
> Again, no need for error callback - caller would check return value and decide what to do with unsent packets in the tx_buffer.
> 

Just to summarise why I think it is better to have tx buffering managed on the app level:

1. avoid any ABI change.
2. Avoid extra changes in rte_ethdev.c: tx_queue_setup/tx_queue_stop.
3. Provides much more flexibility to the user:
   a) where to allocate space for tx_buffer (stack, heap, hugepages, etc).
   b) user can mix and match plain tx_burst() and   tx_buffer/tx_buffer_flush()
        in any way he fills it appropriate.
   c) user can change the size of tx_buffer without stop/re-config/start queue:
        just allocate new larger(smaller) tx_buffer & copy contents to the new one.
   d) user can preserve buffered packets through device restart circle:
        i.e if let say TX hang happened, and user has to do dev_stop/dev_start -
        contents of tx_buffer will stay unchanged and its contents could be
        (re-)transmitted after device is up again, or  through different port/queue if needed.
 
As a drawbacks mentioned - tx error handling becomes less transparent...
But we can add error handling routine and it's user provided parameter
into struct rte_eth_dev_tx_buffer', something like that:

+struct rte_eth_dev_tx_buffer {
+	buffer_tx_error_fn cbfn;
+	void *userdata;
+	unsigned nb_pkts;
+	uint64_t errors;
+	/**< Total number of queue packets to sent that are dropped. */
+	struct rte_mbuf *pkts[];
+};

Konstantin

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size
  2016-02-10 18:02  3% ` Thomas Monjalon
@ 2016-02-12 11:52  3%   ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-02-12 11:52 UTC (permalink / raw)
  To: Thomas Monjalon, Wiles, Keith; +Cc: dev, Neil Horman

On 02/10/2016 08:02 PM, Thomas Monjalon wrote:
> 2016-02-10 18:01, Wiles, Keith:
>>>>> --- a/config/defconfig_x86_64-native-linuxapp-gcc
>>>>> +++ b/config/defconfig_x86_64-native-linuxapp-gcc
>>>>> @@ -40,3 +40,8 @@ CONFIG_RTE_ARCH_64=y
>>>>>
>>>>>   CONFIG_RTE_TOOLCHAIN="gcc"
>>>>>   CONFIG_RTE_TOOLCHAIN_GCC=y
>>>>> +CONFIG_RTE_BUILD_SHARED_LIB=y
>>>>> +CONFIG_RTE_NEXT_ABI=n
>>>>> +CONFIG_RTE_EAL_IGB_UIO=n
>>>>> +CONFIG_RTE_LIBRTE_KNI=n
>>>>> +CONFIG_RTE_KNI_KMOD=n
>>>
>>> Hmm, not sure where this came from, but will remove it.
>>
>> I think this was from the ABI-Checker I ran and the tool should leave the repo in its original state.
>
> Yes you're right. The ABI checker modify the defconfig instead of modifying
> the generated .config file.

Its "by design" according to Neil (this was discussed when the abi 
checker was introduced, see 
http://dpdk.org/ml/archives/dev/2015-March/014636.html)

I actually agree with Neil that changing .config after make config seems 
counter-intuitive compared to how this works in other projects, but that 
doesn't make modifying the default templates the right thing to do in DPDK.

> Anyone for a patch?

I can add it to my TODO among a couple of other things - it should not 
leave clutter like this behind no matter what. As to how exactly it 
should be fixed, it could of course just change .config, or 
alternatively create (and later clean up) a temporary defconfig file 
with the necessary contents, which would be closer to the current 
approach I guess.

	- Panu -

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library
  @ 2016-02-12 13:45  1%   ` Ferruh Yigit
  2016-02-17 19:58  0%     ` Ananyev, Konstantin
    1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2016-02-12 13:45 UTC (permalink / raw)
  To: dev

This library gets control messages form kernelspace and forwards them to
librte_ether and returns response back to the kernelspace.

Library does:
1) Trigger Linux virtual interface creation
2) Initialize the netlink socket communication
3) Provides process() API to the application that does processing the
received messages

This library requires corresponding kernel module to be inserted.

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

---

v2:
* User rtnetlink to create interfaces.
* Add more ethtool support: get/set ringparam, set pauseparam.
* return defined error instead of hardcoded value
---
 MAINTAINERS                                |   1 +
 config/common_linuxapp                     |   3 +-
 doc/api/doxy-api-index.md                  |   3 +-
 doc/api/doxy-api.conf                      |   1 +
 doc/guides/rel_notes/release_16_04.rst     |   9 +
 lib/Makefile                               |   3 +-
 lib/librte_ctrl_if/Makefile                |  58 ++++
 lib/librte_ctrl_if/rte_ctrl_if.c           | 385 ++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           | 115 ++++++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |   9 +
 lib/librte_ctrl_if/rte_ethtool.c           | 450 +++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ethtool.h           |  54 ++++
 lib/librte_ctrl_if/rte_nl.c                | 274 ++++++++++++++++++
 lib/librte_ctrl_if/rte_nl.h                |  49 ++++
 lib/librte_eal/common/include/rte_log.h    |   3 +-
 mk/rte.app.mk                              |   3 +-
 16 files changed, 1415 insertions(+), 5 deletions(-)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
 create mode 100644 lib/librte_ctrl_if/rte_ethtool.c
 create mode 100644 lib/librte_ctrl_if/rte_ethtool.h
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 09c56c7..91c98bc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -256,6 +256,7 @@ F: doc/guides/sample_app_ug/kernel_nic_interface.rst
 Linux KCP
 M: Ferruh Yigit <ferruh.yigit@intel.com>
 F: lib/librte_eal/linuxapp/kcp/
+F: lib/librte_ctrl_if/
 
 Linux AF_PACKET
 M: John W. Linville <linville@tuxdriver.com>
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 2f4eb1d..4bcd508 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
@@ -501,6 +501,7 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 #
 CONFIG_RTE_KCP_KMOD=y
 CONFIG_RTE_KCP_KO_DEBUG=n
+CONFIG_RTE_LIBRTE_CTRL_IF=y
 
 #
 # Compile vhost library
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 7a91001..214d16e 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),
+  [control interface]  (@ref rte_ctrl_if.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 57e8b5d..fd69bf1 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -39,6 +39,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cmdline \
                           lib/librte_compat \
                           lib/librte_cryptodev \
+                          lib/librte_ctrl_if \
                           lib/librte_distributor \
                           lib/librte_ether \
                           lib/librte_hash \
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 27fc624..1b1d34c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -39,6 +39,14 @@ This section should contain new features added in this release. Sample format:
 
   Enabled virtio 1.0 support for virtio pmd driver.
 
+* **Control interface support added.**
+
+  To enable controlling DPDK ports by common Linux tools.
+  Following modules added to DPDK:
+
+  * librte_ctrl_if library
+  * librte_eal/linuxapp/kcp kernel module
+
 
 Resolved Issues
 ---------------
@@ -113,6 +121,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_acl.so.2
      librte_cfgfile.so.2
      librte_cmdline.so.1
+   + librte_ctrl_if.so.1
      librte_distributor.so.1
      librte_eal.so.2
      librte_hash.so.2
diff --git a/lib/Makefile b/lib/Makefile
index ef172ea..a50bc1e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -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
@@ -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_CTRL_IF) += librte_ctrl_if
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
new file mode 100644
index 0000000..4e82966
--- /dev/null
+++ b/lib/librte_ctrl_if/Makefile
@@ -0,0 +1,58 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_ctrl_if.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ctrl_if_version.map
+
+LIBABIVER := 1
+
+SRCS-y += rte_ctrl_if.c
+SRCS-y += rte_nl.c
+SRCS-y += rte_ethtool.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_ctrl_if.h
+
+# this lib depends upon:
+DEPDIRS-y += lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
new file mode 100644
index 0000000..d16398f
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -0,0 +1,385 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <rte_ethdev.h>
+#include "rte_ctrl_if.h"
+#include "rte_nl.h"
+
+#define NAMESZ 32
+#define IFNAME "dpdk"
+#define BUFSZ 1024
+
+static int kcp_rtnl_fd = -1;
+static int kcp_fd_ref;
+
+struct kcp_request {
+	struct nlmsghdr nlmsg;
+	char buf[BUFSZ];
+};
+
+static int
+conrol_interface_rtnl_init(void)
+{
+	struct sockaddr_nl src;
+	int ret;
+
+	kcp_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (kcp_rtnl_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "socket for create failed.\n");
+		return -1;
+	}
+
+	memset(&src, 0, sizeof(struct sockaddr_nl));
+
+	src.nl_family = AF_NETLINK;
+	src.nl_pid = getpid();
+
+	ret = bind(kcp_rtnl_fd, (struct sockaddr *)&src,
+			sizeof(struct sockaddr_nl));
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Bind for create failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+control_interface_init(void)
+{
+	int ret;
+
+	ret = conrol_interface_rtnl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink.\n");
+		return -1;
+	}
+
+	ret = control_interface_nl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink.\n");
+		close(kcp_rtnl_fd);
+		kcp_rtnl_fd = -1;
+	}
+
+	return ret;
+}
+
+static int
+control_interface_ref_get(void)
+{
+	int ret = 0;
+
+	if (kcp_fd_ref == 0)
+		ret = control_interface_init();
+
+	if (ret == 0)
+		kcp_fd_ref++;
+	else
+		RTE_LOG(ERR, CTRL_IF,
+				"Failed to initialize control interface.\n");
+
+	return kcp_fd_ref;
+}
+
+static void
+control_interface_release(void)
+{
+	close(kcp_rtnl_fd);
+	control_interface_nl_release();
+}
+
+static int
+control_interface_ref_put(void)
+{
+	if (kcp_fd_ref == 0)
+		return 0;
+
+	kcp_fd_ref--;
+
+	if (kcp_fd_ref == 0)
+		control_interface_release();
+
+	return kcp_fd_ref;
+}
+
+static int
+add_attr(struct kcp_request *req, unsigned short type, void *buf, size_t len)
+{
+	struct rtattr *rta;
+	int nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct kcp_request))
+		return -1;
+	rta->rta_type = type;
+	rta->rta_len = RTA_LENGTH(len);
+	memcpy(RTA_DATA(rta), buf, len);
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
+
+	return 0;
+}
+
+static struct
+rtattr *add_attr_nested(struct kcp_request *req, unsigned short type)
+{
+	struct rtattr *rta;
+	int nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct kcp_request))
+		return NULL;
+	rta->rta_type = type;
+	rta->rta_len = nlmsg_len;
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
+
+	return rta;
+}
+
+static void
+end_attr_nested(struct kcp_request *req, struct rtattr *rta)
+{
+	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
+}
+
+static int
+rte_eth_rtnl_create(uint8_t port_id)
+{
+	struct kcp_request req;
+	struct ifinfomsg *info;
+	struct rtattr *rta1;
+	struct rtattr *rta2;
+	unsigned int pid = getpid();
+	char name[NAMESZ];
+	char type[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+	char buf[BUFSZ];
+
+	memset(&req, 0, sizeof(struct kcp_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
+	req.nlmsg.nlmsg_type = RTM_NEWLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
+	if (rta1 == NULL)
+		return -1;
+
+	snprintf(type, NAMESZ, KCP_DEVICE);
+	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
+	if (rta2 == NULL)
+		return -1;
+
+	ret = add_attr(&req, IFLA_KCP_PORTID, &port_id, sizeof(uint8_t));
+	if (ret < 0)
+		return -1;
+
+	ret = add_attr(&req, IFLA_KCP_PID, &pid, sizeof(unsigned int));
+	if (ret < 0)
+		return -1;
+
+	end_attr_nested(&req, rta2);
+	end_attr_nested(&req, rta1);
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
+		return -1;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	iov.iov_base = buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(kcp_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Recv for create failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+rte_eth_control_interface_create_one(uint8_t port_id)
+{
+	int ret;
+
+	if (control_interface_ref_get() != 0) {
+		ret = rte_eth_rtnl_create(port_id);
+		RTE_LOG(DEBUG, CTRL_IF,
+			"Control interface %s for port:%u\n",
+			ret < 0 ? "failed" : "created", port_id);
+	}
+
+	return 0;
+}
+
+int
+rte_eth_control_interface_create(void)
+{
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_dev_is_valid_port(i)) {
+			ret = rte_eth_control_interface_create_one(i);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int
+rte_eth_rtnl_destroy(uint8_t port_id)
+{
+	struct kcp_request req;
+	struct ifinfomsg *info;
+	char name[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+
+	memset(&req, 0, sizeof(struct kcp_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
+	req.nlmsg.nlmsg_type = RTM_DELLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed.\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int
+rte_eth_control_interface_destroy_one(uint8_t port_id)
+{
+	rte_eth_rtnl_destroy(port_id);
+	control_interface_ref_put();
+	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
+			port_id);
+
+	return 0;
+}
+
+int
+rte_eth_control_interface_destroy(void)
+{
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_dev_is_valid_port(i)) {
+			ret = rte_eth_control_interface_destroy_one(i);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int
+rte_eth_control_interface_process_msg(int flag, unsigned int timeout_sec)
+{
+	return control_interface_process_msg(flag, timeout_sec);
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
new file mode 100644
index 0000000..dcaf6dd
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -0,0 +1,115 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CTRL_IF_H_
+#define _RTE_CTRL_IF_H_
+
+/**
+ * @file
+ *
+ * Control Interface Library for RTE
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <exec-env/rte_kcp_common.h>
+
+/**
+ * Flags values for rte_eth_control_interface_process_msg() API
+ */
+enum control_interface_process_flag {
+	/**< Process if msg available. */
+	RTE_ETHTOOL_CTRL_IF_PROCESS_MSG,
+
+	/**< Discard msg if available, respond with a error value. */
+	RTE_ETHTOOL_CTRL_IF_DISCARD_MSG,
+};
+
+/**
+ * Creates control interfaces (Linux virtual network interface)for
+ * each existing eal port.
+ *
+ * This API opens device created by supportive kernel module and initializes
+ * kernel communication interface.
+ *
+ * If supportive kernel module is not inserted this API will return
+ * an error.
+ *
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_create(void);
+
+/**
+ * Destroys control interfaces.
+ *
+ * This API close device created by supportive kernel module and release
+ * underlying communication interface.
+ *
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_destroy(void);
+
+/**
+ * Process if any received message is available.
+ *
+ * This function can be blocking or unblocking according timeout_sec
+ * parameter value. If function will be continuous loop, like can be
+ * called by any forwarding lcore, nonblocking mode should be preferred.
+ * If a separate thread created to handle control messages, blocking
+ * mode can be preferred to save CPU cycles.
+ *
+ * @param flag
+ *  Defines what to do with message, can be process or discard.
+ *
+ * @param timeout_sec
+ *  if 0, function is in nonblocking mode.
+ *  if > 0, blocks for given time, if there is no message available,
+ *  sleeps again same amount of time. Value is in seconds.
+ *
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_process_msg(int flag, unsigned int timeout_sec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_IF_H_ */
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
new file mode 100644
index 0000000..8b27e26
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -0,0 +1,9 @@
+DPDK_2.3 {
+	global:
+
+	rte_eth_control_interface_create;
+	rte_eth_control_interface_destroy;
+	rte_eth_control_interface_process_msg;
+
+	local: *;
+};
diff --git a/lib/librte_ctrl_if/rte_ethtool.c b/lib/librte_ctrl_if/rte_ethtool.c
new file mode 100644
index 0000000..def968a
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ethtool.c
@@ -0,0 +1,450 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <error.h>
+
+#include <linux/if_link.h>
+
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include "rte_ethtool.h"
+
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int
+get_drvinfo(int port_id, void *data, int *data_len)
+{
+	struct ethtool_drvinfo *info = data;
+	struct rte_eth_dev_info dev_info;
+	int n;
+
+	memset(&dev_info, 0, sizeof(dev_info));
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	snprintf(info->driver, sizeof(info->driver), "%s",
+		dev_info.driver_name);
+	snprintf(info->version, sizeof(info->version), "%s",
+		rte_version());
+	snprintf(info->bus_info, sizeof(info->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);
+	info->regdump_len = n < 0 ? 0 : n;
+
+	n = rte_eth_dev_get_eeprom_length(port_id);
+	info->eedump_len = n < 0 ? 0 : n;
+
+	info->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
+	info->testinfo_len = 0;
+
+	*data_len = sizeof(struct ethtool_drvinfo);
+
+	return 0;
+}
+
+static int
+get_reg_len(int port_id, void *data, int *data_len)
+{
+	int reg_length = 0;
+
+	reg_length = rte_eth_dev_get_reg_length(port_id);
+	if (reg_length < 0)
+		return reg_length;
+
+	*(int *)data = reg_length * sizeof(uint32_t);
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_reg(int port_id, void *in_data, void *out_data, int *out_data_len)
+{
+	unsigned int reg_length;
+	int reg_length_out_len;
+	struct ethtool_regs *ethtool_regs = in_data;
+	struct rte_dev_reg_info regs = {
+		.data = out_data,
+		.length = ethtool_regs->len,
+	};
+	int ret;
+
+	ret = get_reg_len(port_id, &reg_length, &reg_length_out_len);
+	if (ret < 0 || reg_length > ethtool_regs->len)
+		return -1;
+
+	ret = rte_eth_dev_get_reg_info(port_id, &regs);
+	if (ret < 0)
+		return ret;
+
+	ethtool_regs->version = regs.version;
+	*out_data_len = reg_length;
+
+	return 0;
+}
+
+static int
+get_link(int port_id, void *data, int *data_len)
+{
+	struct rte_eth_link link;
+
+	rte_eth_link_get(port_id, &link);
+
+	*(int *)data = link.link_status;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_eeprom_length(int port_id, void *data, int *data_len)
+{
+	int eeprom_length = 0;
+
+	eeprom_length = rte_eth_dev_get_eeprom_length(port_id);
+	if (eeprom_length < 0)
+		return eeprom_length;
+
+	*(int *)data = eeprom_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_eeprom(int port_id, void *in_data, void *out_data, int *out_data_len)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	struct rte_dev_eeprom_info eeprom_info = {
+		.data = out_data,
+		.offset = eeprom->offset,
+		.length = eeprom->len,
+	};
+	int ret;
+
+	ret = rte_eth_dev_get_eeprom(port_id, &eeprom_info);
+	if (ret < 0)
+		return ret;
+
+	eeprom->magic = eeprom_info.magic;
+	*out_data_len = eeprom->len;
+
+	return 0;
+}
+
+static int
+set_eeprom(int port_id, void *in_data)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	struct rte_dev_eeprom_info eeprom_info = {
+		.data = eeprom->data,
+		.offset = eeprom->offset,
+		.length = eeprom->len,
+	};
+	int ret;
+
+	ret = rte_eth_dev_set_eeprom(port_id, &eeprom_info);
+	if (ret < 0)
+		return ret;
+
+	eeprom->magic = eeprom_info.magic;
+
+	return 0;
+}
+
+static int
+get_ringparam(int port_id, void *data, int *data_len)
+{
+	struct ethtool_ringparam *ringparam = data;
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_rxq_info rx_qinfo;
+	struct rte_eth_txq_info tx_qinfo;
+	int ret;
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	ret = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
+	if (ret != 0)
+		return -1;
+
+	ret = rte_eth_tx_queue_info_get(port_id, 0, &tx_qinfo);
+	if (ret != 0)
+		return -1;
+
+	memset(ringparam, 0, sizeof(struct ethtool_ringparam));
+	ringparam->rx_pending = rx_qinfo.nb_desc;
+	ringparam->rx_max_pending = dev_info.rx_desc_lim.nb_max;
+	ringparam->tx_pending = tx_qinfo.nb_desc;
+	ringparam->tx_max_pending = dev_info.tx_desc_lim.nb_max;
+
+	*data_len = sizeof(struct ethtool_ringparam);
+
+	return 0;
+}
+
+static int
+set_ringparam(int port_id, void *data)
+{
+	struct ethtool_ringparam *ringparam = data;
+	struct rte_eth_rxq_info rx_qinfo;
+	int ret;
+
+	ret = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
+	if (ret != 0)
+		return -1;
+
+	rte_eth_dev_stop(port_id);
+
+	ret = rte_eth_tx_queue_setup(port_id, 0, ringparam->tx_pending,
+		rte_socket_id(), NULL);
+	if (ret != 0)
+		return -1;
+
+	ret = rte_eth_rx_queue_setup(port_id, 0, ringparam->rx_pending,
+		rte_socket_id(), NULL, rx_qinfo.mp);
+	if (ret != 0)
+		return -1;
+
+	return rte_eth_dev_start(port_id);
+}
+
+static int
+get_pauseparam(int port_id, void *data, int *data_len)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+	struct rte_eth_fc_conf fc_conf;
+	int ret;
+
+	ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+	if (ret)
+		return -1;
+
+	pauseparam->tx_pause = 0;
+	pauseparam->rx_pause = 0;
+
+	switch (fc_conf.mode) {
+	case RTE_FC_RX_PAUSE:
+		pauseparam->rx_pause = 1;
+		break;
+	case RTE_FC_TX_PAUSE:
+		pauseparam->tx_pause = 1;
+		break;
+	case RTE_FC_FULL:
+		pauseparam->rx_pause = 1;
+		pauseparam->tx_pause = 1;
+	default:
+		break;
+	}
+	pauseparam->autoneg = (uint32_t)fc_conf.autoneg;
+
+	*data_len = sizeof(struct ethtool_pauseparam);
+
+	return 0;
+}
+
+static int
+set_pauseparam(int port_id, void *data)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+	struct rte_eth_fc_conf fc_conf;
+	int ret;
+
+	ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
+	if (ret)
+		return -1;
+
+	fc_conf.autoneg = pauseparam->autoneg;
+
+	if (pauseparam->tx_pause) {
+		if (pauseparam->rx_pause)
+			fc_conf.mode = RTE_FC_FULL;
+		else
+			fc_conf.mode = RTE_FC_TX_PAUSE;
+	} else {
+		if (pauseparam->rx_pause)
+			fc_conf.mode = RTE_FC_RX_PAUSE;
+		else
+			fc_conf.mode = RTE_FC_NONE;
+	}
+
+	ret = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf);
+	if (ret)
+		return -1;
+
+	return 0;
+}
+
+int
+rte_eth_dev_ethtool_process(int cmd_id, int port_id, void *in_data,
+		void *out_data, int *out_data_len)
+{
+	int ret = 0;
+
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case ETHTOOL_GDRVINFO:
+		return get_drvinfo(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS_LEN:
+		return get_reg_len(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS:
+		return get_reg(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_GLINK:
+		return get_link(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM_LEN:
+		return get_eeprom_length(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM:
+		return get_eeprom(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_SEEPROM:
+		return set_eeprom(port_id, in_data);
+	case ETHTOOL_GRINGPARAM:
+		return get_ringparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SRINGPARAM:
+		return set_ringparam(port_id, in_data);
+	case ETHTOOL_GPAUSEPARAM:
+		return get_pauseparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SPAUSEPARAM:
+		return set_pauseparam(port_id, in_data);
+	default:
+		ret = EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+set_mtu(int port_id, void *in_data)
+{
+	int *mtu = in_data;
+
+	return rte_eth_dev_set_mtu(port_id, *mtu);
+}
+
+static int
+get_stats(int port_id, void *data, int *data_len)
+{
+	struct rte_eth_stats stats;
+	struct rtnl_link_stats64 *if_stats = data;
+	int ret;
+
+	ret = rte_eth_stats_get(port_id, &stats);
+	if (ret < 0)
+		return -EOPNOTSUPP;
+
+	if_stats->rx_packets = stats.ipackets;
+	if_stats->tx_packets = stats.opackets;
+	if_stats->rx_bytes = stats.ibytes;
+	if_stats->tx_bytes = stats.obytes;
+	if_stats->rx_errors = stats.ierrors;
+	if_stats->tx_errors = stats.oerrors;
+	if_stats->rx_dropped = stats.imissed;
+	if_stats->multicast = stats.imcasts;
+
+	*data_len = sizeof(struct rtnl_link_stats64);
+
+	return 0;
+}
+
+static int
+get_mac(int port_id, void *data, int *data_len)
+{
+	struct ether_addr addr;
+
+	rte_eth_macaddr_get(port_id, &addr);
+	memcpy(data, &addr, sizeof(struct ether_addr));
+
+	*data_len = sizeof(struct ether_addr);
+
+	return 0;
+}
+
+static int
+set_mac(int port_id, void *in_data)
+{
+	struct ether_addr addr;
+
+	memcpy(&addr, in_data, ETHER_ADDR_LEN);
+
+	return rte_eth_dev_default_mac_addr_set(port_id, &addr);
+}
+
+static int
+start_port(int port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return rte_eth_dev_start(port_id);
+}
+
+static int
+stop_port(int port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return 0;
+}
+
+int
+rte_eth_dev_control_process(int cmd_id, int port_id, void *in_data,
+		void *out_data, int *out_data_len)
+{
+	int ret = 0;
+
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case RTE_KCP_REQ_CHANGE_MTU:
+		return set_mtu(port_id, in_data);
+	case RTE_KCP_REQ_GET_STATS:
+		return get_stats(port_id, out_data, out_data_len);
+	case RTE_KCP_REQ_GET_MAC:
+		return get_mac(port_id, out_data, out_data_len);
+	case RTE_KCP_REQ_SET_MAC:
+		return set_mac(port_id, in_data);
+	case RTE_KCP_REQ_START_PORT:
+		return start_port(port_id);
+	case RTE_KCP_REQ_STOP_PORT:
+		return stop_port(port_id);
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
diff --git a/lib/librte_ctrl_if/rte_ethtool.h b/lib/librte_ctrl_if/rte_ethtool.h
new file mode 100644
index 0000000..19f364f
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ethtool.h
@@ -0,0 +1,54 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_ETHTOOL_H_
+#define _RTE_ETHTOOL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/ethtool.h>
+
+#include <exec-env/rte_kcp_common.h>
+
+int rte_eth_dev_ethtool_process(int cmd_id, int port_id, void *in_data,
+		void *out_data, int *out_data_len);
+int rte_eth_dev_control_process(int cmd_id, int port_id, void *in_data,
+		void *out_data, int *out_data_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETHTOOL_H_ */
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
new file mode 100644
index 0000000..adc5fa8
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -0,0 +1,274 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <rte_spinlock.h>
+#include <rte_ethdev.h>
+#include "rte_ethtool.h"
+#include "rte_nl.h"
+#include "rte_ctrl_if.h"
+
+#define MAX_PAYLOAD sizeof(struct kcp_ethtool_msg)
+
+struct ctrl_if_nl {
+	union {
+		struct nlmsghdr nlh;
+		uint8_t nlmsg[NLMSG_SPACE(MAX_PAYLOAD)];
+	};
+	struct msghdr msg;
+	struct iovec iov;
+};
+
+static int sock_fd = -1;
+pthread_t thread_id;
+
+struct sockaddr_nl dest_addr;
+
+pthread_cond_t cond  = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t msg_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static struct ctrl_if_nl nl_s;
+static struct ctrl_if_nl nl_r;
+
+static int kcp_ethtool_msg_count;
+static struct kcp_ethtool_msg msg_storage;
+
+static int
+nl_send(void *buf, size_t len)
+{
+	int ret;
+
+	if (nl_s.nlh.nlmsg_len < len) {
+		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
+		return -1;
+	}
+
+	if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) {
+		RTE_LOG(ERR, CTRL_IF, "Message is not OK\n");
+		return -1;
+	}
+
+	/* Fill in the netlink message payload */
+	memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len);
+
+	ret = sendmsg(sock_fd, &nl_s.msg, 0);
+
+	if (ret < 0)
+		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
+				ret, errno);
+	return ret;
+}
+
+static int
+nl_ethtool_msg_send(struct kcp_ethtool_msg *msg)
+{
+	return nl_send((void *)msg, sizeof(struct kcp_ethtool_msg));
+}
+
+static void
+process_msg(struct kcp_ethtool_msg *msg)
+{
+	if (msg->cmd_id > RTE_KCP_REQ_UNKNOWN) {
+		msg->err = rte_eth_dev_control_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	} else {
+		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	}
+
+	if (msg->err)
+		memset(msg->output_buffer, 0, msg->output_buffer_len);
+
+	nl_ethtool_msg_send(msg);
+}
+
+int
+control_interface_process_msg(int flag, unsigned int timeout_sec)
+{
+	int ret = 0;
+	struct timespec ts;
+
+	pthread_mutex_lock(&msg_lock);
+
+	clock_gettime(CLOCK_REALTIME, &ts);
+	ts.tv_sec += timeout_sec;
+	while (timeout_sec && !kcp_ethtool_msg_count && !ret)
+		ret = pthread_cond_timedwait(&cond, &msg_lock, &ts);
+
+	switch (flag) {
+	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
+		if (kcp_ethtool_msg_count) {
+			process_msg(&msg_storage);
+			kcp_ethtool_msg_count = 0;
+		}
+		ret = 0;
+		break;
+
+	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
+		if (kcp_ethtool_msg_count) {
+			msg_storage.err = -1;
+			nl_ethtool_msg_send(&msg_storage);
+			kcp_ethtool_msg_count = 0;
+		}
+		ret = 0;
+		break;
+
+	default:
+		ret = -1;
+		break;
+	}
+	pthread_mutex_unlock(&msg_lock);
+
+	return ret;
+}
+
+static int
+msg_add_and_signal(struct nlmsghdr *nlh)
+{
+	pthread_mutex_lock(&msg_lock);
+
+	memcpy(&msg_storage, NLMSG_DATA(nlh), sizeof(struct kcp_ethtool_msg));
+	kcp_ethtool_msg_count = 1;
+	msg_storage.flag = KCP_MSG_FLAG_RESPONSE;
+
+	pthread_cond_signal(&cond);
+
+	pthread_mutex_unlock(&msg_lock);
+
+	return 0;
+}
+
+static void *
+nl_recv(void *arg)
+{
+	int ret;
+
+	for (;;) {
+		ret = recvmsg(sock_fd, &nl_r.msg, 0);
+		if (ret < 0)
+			continue;
+
+		if ((unsigned)ret < sizeof(struct kcp_ethtool_msg)) {
+			RTE_LOG(WARNING, CTRL_IF,
+					"Received %u bytes, payload %lu\n",
+					ret, sizeof(struct kcp_ethtool_msg));
+			continue;
+		}
+
+		msg_add_and_signal(&nl_r.nlh);
+	}
+
+	return arg;
+}
+
+static void
+nl_setup_header(struct ctrl_if_nl *nl)
+{
+	dest_addr.nl_family = AF_NETLINK;
+	dest_addr.nl_pid = 0;   /*  For Linux Kernel */
+	dest_addr.nl_groups = 0;
+
+	memset(nl->nlmsg, 0, NLMSG_SPACE(MAX_PAYLOAD));
+
+	/* Fill the netlink message header */
+	nl->nlh.nlmsg_len = NLMSG_LENGTH(MAX_PAYLOAD);
+	nl->nlh.nlmsg_pid = getpid();  /* self pid */
+	nl->nlh.nlmsg_flags = 0;
+
+	nl->iov.iov_base = (void *)nl->nlmsg;
+	nl->iov.iov_len = nl->nlh.nlmsg_len;
+	memset(&nl->msg, 0, sizeof(struct msghdr));
+	nl->msg.msg_name = (void *)&dest_addr;
+	nl->msg.msg_namelen = sizeof(struct sockaddr_nl);
+	nl->msg.msg_iov = &nl->iov;
+	nl->msg.msg_iovlen = 1;
+}
+
+static int
+nl_socket_init(void)
+{
+	struct sockaddr_nl src_addr;
+	int fd;
+	int ret;
+
+	fd = socket(PF_NETLINK, SOCK_RAW, KCP_NL_GRP);
+	if (fd < 0)
+		return -1;
+
+	src_addr.nl_family = AF_NETLINK;
+	src_addr.nl_pid = getpid();
+	ret = bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
+	if (ret) {
+		close(fd);
+		return -1;
+	}
+
+	nl_setup_header(&nl_s);
+	nl_setup_header(&nl_r);
+
+	return fd;
+}
+
+int
+control_interface_nl_init(void)
+{
+	int ret;
+
+	sock_fd = nl_socket_init();
+	if (sock_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink socket\n");
+		return -1;
+	}
+
+	ret = pthread_create(&thread_id, NULL, nl_recv, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to create receive thread.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void
+control_interface_nl_release(void)
+{
+	pthread_cancel(thread_id);
+	pthread_join(thread_id, NULL);
+	close(sock_fd);
+}
diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h
new file mode 100644
index 0000000..ee06d90
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.h
@@ -0,0 +1,49 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_NL_H_
+#define _RTE_NL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int control_interface_nl_init(void);
+void control_interface_nl_release(void);
+int control_interface_process_msg(int flag, unsigned int timeout_sec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NL_H_ */
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 2e47e7f..a0a2c9f 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.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
@@ -79,6 +79,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
 #define RTE_LOGTYPE_MBUF    0x00010000 /**< Log related to mbuf. */
 #define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to cryptodev. */
+#define RTE_LOGTYPE_CTRL_IF 0x00040000 /**< Log related to control interface. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1   0x01000000 /**< User-defined log type 1. */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8ecab41..e1638f0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   Copyright(c) 2014-2015 6WIND S.A.
 #   All rights reserved.
 #
@@ -122,6 +122,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_CTRL_IF)        += -lrte_ctrl_if
 _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] mempool: reduce rte_mempool structure size
  @ 2016-02-12 15:38  4%       ` Thomas Monjalon
  2016-02-12 15:50  0%         ` Olivier MATZ
  2016-02-12 15:54  0%         ` Wiles, Keith
  0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2016-02-12 15:38 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dev

2016-02-12 15:07, Wiles, Keith:
> >On 02/12/2016 03:57 PM, Thomas Monjalon wrote:
> >> 2016-02-12 13:23, Panu Matilainen:
> >>> On 02/10/2016 11:18 PM, Keith Wiles wrote:
> >>>>    static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
> >>>>    {
> >>>> +#ifdef RTE_NEXT_ABI
> >>>> +	return (char *)mp +
> >>>> +		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
> >>>> +#else
> >>>>    	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
> >>>> +#endif /* RTE_NEXT_ABI */
> >>>>    }
> >>>
> >>> This is not RTE_NEXT_ABI material IMO, the added ifdef clutter is just
> >>> too much.
> >>
> >> The changes are restricted to the mempool files.
> >> I think it is not so much. However I wonder how much the feature is important
> >> to justify the use of NEXT_ABI.
> >
> >Well yes, to be precise: for the benefit of this patch, the ifdef 
> >clutter seems too much.
> >
> >Its not as if every change is expected to go through a NEXT_ABI phase, 
> >based on http://dpdk.org/ml/archives/dev/2016-February/032866.html there 
> >might be some confusion regarding that.
> 
> I think the NEXT_ABI is reasonable in this case as it does change a structure everyone uses and the ifdef clutter is caused by having to remove old ifdefs, which is a good thing for DPDK. The NEXT_ABI ifdefs only exist for one release and then they will disappear, which I think is more then reasonable.

OK, I'm going to sum it up with new words and let the conclusion comes
from Keith, Panu and Olivier.

We agreed to allow ABI breaking if a notification was done in the
previous release.
Keith has sent a notification for 16.04 so the "official" ABI will be
changed in 16.07.
It is also encouraged to show how the ABI will be broken when sending
a notification. It allows to give an informed opinion before ack'ing.
The code snippet will also be useful to app developpers when preparing
a future upgrade.
Keith has sent the whole code change.
This code change may be submitted in the current release without waiting
the deprecation time if gated in the NEXT_ABI ifdefs.
It allows to provide the feature to app developpers who don't care about
versioning. But the price is a more complicated code to read and manage.

To make it short, the rules to use NEXT_ABI are not strict and may change.
So now you have to decide if this change can be integrated in 16.04
as NEXT_ABI.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-12 15:38  4%       ` Thomas Monjalon
@ 2016-02-12 15:50  0%         ` Olivier MATZ
  2016-02-12 15:58  0%           ` Wiles, Keith
    2016-02-12 15:54  0%         ` Wiles, Keith
  1 sibling, 2 replies; 200+ results
From: Olivier MATZ @ 2016-02-12 15:50 UTC (permalink / raw)
  To: Thomas Monjalon, Wiles, Keith; +Cc: dev

Hi,

On 02/12/2016 04:38 PM, Thomas Monjalon wrote:
> OK, I'm going to sum it up with new words and let the conclusion comes
> from Keith, Panu and Olivier.
> 
> We agreed to allow ABI breaking if a notification was done in the
> previous release.
> Keith has sent a notification for 16.04 so the "official" ABI will be
> changed in 16.07.
> It is also encouraged to show how the ABI will be broken when sending
> a notification. It allows to give an informed opinion before ack'ing.
> The code snippet will also be useful to app developpers when preparing
> a future upgrade.
> Keith has sent the whole code change.
> This code change may be submitted in the current release without waiting
> the deprecation time if gated in the NEXT_ABI ifdefs.
> It allows to provide the feature to app developpers who don't care about
> versioning. But the price is a more complicated code to read and manage.
> 
> To make it short, the rules to use NEXT_ABI are not strict and may change.
> So now you have to decide if this change can be integrated in 16.04
> as NEXT_ABI.

Thank you Thomas for this summary. Then my vote would be in favor of
only keep the deprecation notice for 16.04 and push the code without
the NEXT_ABI ifdefs for 16.07 because:

- although it's a valuable patch, there is no urgency in having if for
  the next release
- NEXT_ABI does make the code harder to read in this case, and I'm
  thinking about the patchset from David Hunt (external mempool handler)
  that will be in the same situation, and maybe also another patchset
  I'm working on.

Regards,
Olivier

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-12 15:38  4%       ` Thomas Monjalon
  2016-02-12 15:50  0%         ` Olivier MATZ
@ 2016-02-12 15:54  0%         ` Wiles, Keith
  1 sibling, 0 replies; 200+ results
From: Wiles, Keith @ 2016-02-12 15:54 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

>2016-02-12 15:07, Wiles, Keith:
>> >On 02/12/2016 03:57 PM, Thomas Monjalon wrote:
>> >> 2016-02-12 13:23, Panu Matilainen:
>> >>> On 02/10/2016 11:18 PM, Keith Wiles wrote:
>> >>>>    static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
>> >>>>    {
>> >>>> +#ifdef RTE_NEXT_ABI
>> >>>> +	return (char *)mp +
>> >>>> +		MEMPOOL_HEADER_SIZE(mp, mp->pg_num, mp->cache_size);
>> >>>> +#else
>> >>>>    	return (char *)mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num);
>> >>>> +#endif /* RTE_NEXT_ABI */
>> >>>>    }
>> >>>
>> >>> This is not RTE_NEXT_ABI material IMO, the added ifdef clutter is just
>> >>> too much.
>> >>
>> >> The changes are restricted to the mempool files.
>> >> I think it is not so much. However I wonder how much the feature is important
>> >> to justify the use of NEXT_ABI.
>> >
>> >Well yes, to be precise: for the benefit of this patch, the ifdef 
>> >clutter seems too much.
>> >
>> >Its not as if every change is expected to go through a NEXT_ABI phase, 
>> >based on http://dpdk.org/ml/archives/dev/2016-February/032866.html there 
>> >might be some confusion regarding that.
>> 
>> I think the NEXT_ABI is reasonable in this case as it does change a structure everyone uses and the ifdef clutter is caused by having to remove old ifdefs, which is a good thing for DPDK. The NEXT_ABI ifdefs only exist for one release and then they will disappear, which I think is more then reasonable.
>
>OK, I'm going to sum it up with new words and let the conclusion comes
>from Keith, Panu and Olivier.
>
>We agreed to allow ABI breaking if a notification was done in the
>previous release.
>Keith has sent a notification for 16.04 so the "official" ABI will be
>changed in 16.07.
>It is also encouraged to show how the ABI will be broken when sending
>a notification. It allows to give an informed opinion before ack'ing.
>The code snippet will also be useful to app developpers when preparing
>a future upgrade.
>Keith has sent the whole code change.
>This code change may be submitted in the current release without waiting
>the deprecation time if gated in the NEXT_ABI ifdefs.
>It allows to provide the feature to app developpers who don't care about
>versioning. But the price is a more complicated code to read and manage.
>
>To make it short, the rules to use NEXT_ABI are not strict and may change.
>So now you have to decide if this change can be integrated in 16.04
>as NEXT_ABI.

I would personally go ahead with the NEXT_ABI in 16.04 as it seems more reasonable for developers. I do not know if we made this patch in 16.04 without NEXT_ABI what would break in a developers project, which to me means we need to error on the side of caution by using NEXT_ABI.

I am willing to submit a v4 patch without the NEXT_API ifdefs, but that is something everyone needs to agree on.
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-12 15:50  0%         ` Olivier MATZ
@ 2016-02-12 15:58  0%           ` Wiles, Keith
    1 sibling, 0 replies; 200+ results
From: Wiles, Keith @ 2016-02-12 15:58 UTC (permalink / raw)
  To: Olivier MATZ, Thomas Monjalon; +Cc: dev

>Hi,
>
>On 02/12/2016 04:38 PM, Thomas Monjalon wrote:
>> OK, I'm going to sum it up with new words and let the conclusion comes
>> from Keith, Panu and Olivier.
>> 
>> We agreed to allow ABI breaking if a notification was done in the
>> previous release.
>> Keith has sent a notification for 16.04 so the "official" ABI will be
>> changed in 16.07.
>> It is also encouraged to show how the ABI will be broken when sending
>> a notification. It allows to give an informed opinion before ack'ing.
>> The code snippet will also be useful to app developpers when preparing
>> a future upgrade.
>> Keith has sent the whole code change.
>> This code change may be submitted in the current release without waiting
>> the deprecation time if gated in the NEXT_ABI ifdefs.
>> It allows to provide the feature to app developpers who don't care about
>> versioning. But the price is a more complicated code to read and manage.
>> 
>> To make it short, the rules to use NEXT_ABI are not strict and may change.
>> So now you have to decide if this change can be integrated in 16.04
>> as NEXT_ABI.
>
>Thank you Thomas for this summary. Then my vote would be in favor of
>only keep the deprecation notice for 16.04 and push the code without
>the NEXT_ABI ifdefs for 16.07 because:
>
>- although it's a valuable patch, there is no urgency in having if for
>  the next release
>- NEXT_ABI does make the code harder to read in this case, and I'm
>  thinking about the patchset from David Hunt (external mempool handler)
>  that will be in the same situation, and maybe also another patchset
>  I'm working on.

As I stated in my previous email, I can submit v4 patch. Do you need two patches one for the notice in 16.04 and then one for 16.07?
>
>Regards,
>Olivier
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
  2016-02-12 11:44  3%             ` Ananyev, Konstantin
@ 2016-02-12 16:40  0%               ` Ivan Boule
  2016-02-12 17:33  0%                 ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Ivan Boule @ 2016-02-12 16:40 UTC (permalink / raw)
  To: Ananyev, Konstantin, Kulasek, TomaszX, dev

On 02/12/2016 12:44 PM, Ananyev, Konstantin wrote:
>
>>
>>> -----Original Message-----
...
>>
>> In that case we don't need to make any changes at rte_ethdev.[h,c] to alloc/free/maintain tx_buffer inside each queue...
>> It all will be upper layer responsibility.
>> So no need to modify existing rte_ethdev structures/code.
>> Again, no need for error callback - caller would check return value and decide what to do with unsent packets in the tx_buffer.
>>
>
> Just to summarise why I think it is better to have tx buffering managed on the app level:
>
> 1. avoid any ABI change.
> 2. Avoid extra changes in rte_ethdev.c: tx_queue_setup/tx_queue_stop.
> 3. Provides much more flexibility to the user:
>     a) where to allocate space for tx_buffer (stack, heap, hugepages, etc).
>     b) user can mix and match plain tx_burst() and   tx_buffer/tx_buffer_flush()
>          in any way he fills it appropriate.
>     c) user can change the size of tx_buffer without stop/re-config/start queue:
>          just allocate new larger(smaller) tx_buffer & copy contents to the new one.
>     d) user can preserve buffered packets through device restart circle:
>          i.e if let say TX hang happened, and user has to do dev_stop/dev_start -
>          contents of tx_buffer will stay unchanged and its contents could be
>          (re-)transmitted after device is up again, or  through different port/queue if needed.
>
> As a drawbacks mentioned - tx error handling becomes less transparent...
> But we can add error handling routine and it's user provided parameter
> into struct rte_eth_dev_tx_buffer', something like that:
>
> +struct rte_eth_dev_tx_buffer {
> +	buffer_tx_error_fn cbfn;
> +	void *userdata;
> +	unsigned nb_pkts;
> +	uint64_t errors;
> +	/**< Total number of queue packets to sent that are dropped. */
> +	struct rte_mbuf *pkts[];
> +};
>
> Konstantin
>

Just to enforce Konstantin's comments.
As a very basic - not to say fundamental - rule, one should avoid adding 
in the PMD RX/TX API any extra processing that can be handled at a 
higher level.
The only and self-sufficient reason is that we must avoid impacting 
performances on the critical path, in particular for those - usually the 
majority of - applications that do not need such extra operations, or 
better implement them at upper level.

Maybe in a not so far future will come a proposal for forking a new open 
source fast-dpdk project aiming at providing API simplicity, 
zero-overhead, modular design, and all those nice properties that every 
one claims to seek :-)

Ivan

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api
  2016-02-12 16:40  0%               ` Ivan Boule
@ 2016-02-12 17:33  0%                 ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2016-02-12 17:33 UTC (permalink / raw)
  To: Ivan Boule; +Cc: dev

On Fri, Feb 12, 2016 at 05:40:02PM +0100, Ivan Boule wrote:
> On 02/12/2016 12:44 PM, Ananyev, Konstantin wrote:
> >
> >>
> >>>-----Original Message-----
> ...
> >>
> >>In that case we don't need to make any changes at rte_ethdev.[h,c] to alloc/free/maintain tx_buffer inside each queue...
> >>It all will be upper layer responsibility.
> >>So no need to modify existing rte_ethdev structures/code.
> >>Again, no need for error callback - caller would check return value and decide what to do with unsent packets in the tx_buffer.
> >>
> >
> >Just to summarise why I think it is better to have tx buffering managed on the app level:
> >
> >1. avoid any ABI change.
> >2. Avoid extra changes in rte_ethdev.c: tx_queue_setup/tx_queue_stop.
> >3. Provides much more flexibility to the user:
> >    a) where to allocate space for tx_buffer (stack, heap, hugepages, etc).
> >    b) user can mix and match plain tx_burst() and   tx_buffer/tx_buffer_flush()
> >         in any way he fills it appropriate.
> >    c) user can change the size of tx_buffer without stop/re-config/start queue:
> >         just allocate new larger(smaller) tx_buffer & copy contents to the new one.
> >    d) user can preserve buffered packets through device restart circle:
> >         i.e if let say TX hang happened, and user has to do dev_stop/dev_start -
> >         contents of tx_buffer will stay unchanged and its contents could be
> >         (re-)transmitted after device is up again, or  through different port/queue if needed.
> >
> >As a drawbacks mentioned - tx error handling becomes less transparent...
> >But we can add error handling routine and it's user provided parameter
> >into struct rte_eth_dev_tx_buffer', something like that:
> >
> >+struct rte_eth_dev_tx_buffer {
> >+	buffer_tx_error_fn cbfn;
> >+	void *userdata;
> >+	unsigned nb_pkts;
> >+	uint64_t errors;
> >+	/**< Total number of queue packets to sent that are dropped. */
> >+	struct rte_mbuf *pkts[];
> >+};
> >
> >Konstantin
> >
> 
> Just to enforce Konstantin's comments.
> As a very basic - not to say fundamental - rule, one should avoid adding in
> the PMD RX/TX API any extra processing that can be handled at a higher
> level.
> The only and self-sufficient reason is that we must avoid impacting
> performances on the critical path, in particular for those - usually the
> majority of - applications that do not need such extra operations, or better
> implement them at upper level.
> 
> Maybe in a not so far future will come a proposal for forking a new open
> source fast-dpdk project aiming at providing API simplicity, zero-overhead,
> modular design, and all those nice properties that every one claims to seek
> :-)
> 
> Ivan
> 
Hi Ivan,

I completely agree with your comments. However, none of the proposals for TX 
buffering would impact the existing fast-path processing paths. They simply add
an optional buffering layer above it - as is done by a very large number of our
sample apps. The point of this patchset is to reduce or eliminate this duplication
of code by centralising it in the libs.

Of the different ways of doing this proposed, my slight preference is for the
original one due to the simplicity of the APIs it provides, but the advantages
in flexibility provided by Konstantin's proposals may outway the additional 
"ugliness" in the APIs.

Regards,
/Bruce

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4] mempool: reduce rte_mempool structure size
  2016-02-09 17:30  2% ` [dpdk-dev] [PATCH v2] mempool: reduce " Keith Wiles
  2016-02-10 21:18  7%   ` [dpdk-dev] [PATCH v3] " Keith Wiles
  @ 2016-02-12 18:36  3%   ` Keith Wiles
  2016-02-15  9:20  0%     ` Olivier MATZ
  2 siblings, 1 reply; 200+ results
From: Keith Wiles @ 2016-02-12 18:36 UTC (permalink / raw)
  To: dev

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>
---
* Patch v4 remove RTE_NEXT_ABI ifdefs for 16.07 integration, plus split
  out the deprecation notice into another patch email for 16.04 release.
* Patch v3 fix up the ifdefs to correct some problems in removing ifdef
  lines. Added the ABI deprecation notice to the document file.
* Patch v2 to add some comments and setup for RTE_NEXT_ABI changes.

 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 aff5f6d..6f067f3 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;
@@ -598,8 +594,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 *)
+			((char *)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);
 
@@ -613,9 +616,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);
 	}
@@ -645,19 +647,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
@@ -672,13 +670,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);
@@ -686,11 +687,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
@@ -755,13 +751,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",
@@ -770,10 +769,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.5.4 (Apple Git-61)

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] doc: deprecation notice in 16.04 for rte_mempool changes
@ 2016-02-12 18:38  5% Keith Wiles
  0 siblings, 0 replies; 200+ results
From: Keith Wiles @ 2016-02-12 18:38 UTC (permalink / raw)
  To: dev

Deprecation notice for 16.04 for changes to occur in
release 16.07 for rte_mempool memory reduction.

Signed-off-by: Keith Wiles <keith.wiles@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 e94d4a2..748a48d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,3 +49,13 @@ 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 change is planned for the rte_mempool structure to allow mempool
+  cache support to be dynamic depending on the mempool being created
+  needing cache support. Saves about 1.5M of memory per rte_mempool structure
+  by removing the per lcore cache memory. Change will occur in DPDK 16.07
+  release and will skip the define RTE_NEXT_ABI in DPDK 16.04 release. The
+  code effected is app/test/test_mempool.c and librte_mempool/rte_mempool.[ch].
+  The rte_mempool.local_cache will be converted from an array to a pointer to
+  allow for dynamic allocation of the per lcore cache memory.
+
-- 
2.5.4 (Apple Git-61)

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
  @ 2016-02-14 22:17  8%   ` Marc Sune
  2016-02-18 18:14  0%     ` Mcnamara, John
    1 sibling, 1 reply; 200+ results
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/rel_notes/release_2_3.rst | 102 +++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 doc/guides/rel_notes/release_2_3.rst

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
new file mode 100644
index 0000000..b10c3bb
--- /dev/null
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -0,0 +1,102 @@
+DPDK Release 2.3
+================
+
+New Features
+------------
+
+* **ethdev: define a set of advertised link speeds.**
+
+  Allowing to define a set of advertised speeds for auto-negociation,
+  explicitely disable link auto-negociation (single speed) and full
+  auto-negociation.
+
+* **ethdev: add speed_cap bitmap to recover eth device link speed capabilities
+  define a set of advertised link speeds.**
+
+  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
+
+
+Resolved Issues
+---------------
+
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical speeds
+  to bitmap fields.
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+
+API Changes
+-----------
+
+
+ABI Changes
+-----------
+
+* The ethdev rte_eth_link and rte_eth_conf structures were changed to
+  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
+
+* The ethdev rte_eth_dev_info was changed to support device speed capabilities.
+
+
+Shared Library Versions
+-----------------------
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     libethdev.so.2
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.1
+     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.2
+     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
-- 
2.1.4

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH v4] mempool: reduce rte_mempool structure size
  2016-02-12 18:36  3%   ` [dpdk-dev] [PATCH v4] " Keith Wiles
@ 2016-02-15  9:20  0%     ` Olivier MATZ
  0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2016-02-15  9:20 UTC (permalink / raw)
  To: Keith Wiles, dev



On 02/12/2016 07:36 PM, Keith Wiles wrote:
> 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 16.07)

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  @ 2016-02-15 10:15  4%             ` Olivier MATZ
  2016-02-15 10:21  0%               ` Hunt, David
  0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2016-02-15 10:15 UTC (permalink / raw)
  To: Hunt, David, Thomas Monjalon, Wiles, Keith; +Cc: dev

Hi David,

On 02/15/2016 10:58 AM, Hunt, David wrote:
> On 12/02/2016 15:50, Olivier MATZ wrote:
>> - NEXT_ABI does make the code harder to read in this case, and I'm
>>    thinking about the patchset from David Hunt (external mempool handler)
>>    that will be in the same situation, and maybe also another patchset
>>    I'm working on.
> 
> Olivier,
>     I'm working on that at the moment with the external mempool handler
> code. However, it crossed my mind that we have a choice to use symbol
> versioning OR use NEXT_ABI. Would one method be preferred over the other?

I think symbol versioning should always be preferred when possible.

In your case, as far as I remember, your are updating the rte_mempool
structure, which is accessed by static inline functions. I don't think
it is easily manageable with symbol versioning. Moreover, the ABI will
already be broken by Keith's patch, so I think it's less problematic
to have other patches breaking the ABI at the same time.

Regards,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-15 10:15  4%             ` Olivier MATZ
@ 2016-02-15 10:21  0%               ` Hunt, David
  2016-02-15 12:31  0%                 ` Olivier MATZ
  0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2016-02-15 10:21 UTC (permalink / raw)
  To: Olivier MATZ, Thomas Monjalon, Wiles, Keith; +Cc: dev

On 15/02/2016 10:15, Olivier MATZ wrote:
> Hi David,
>
> On 02/15/2016 10:58 AM, Hunt, David wrote:
>> On 12/02/2016 15:50, Olivier MATZ wrote:
>>> - NEXT_ABI does make the code harder to read in this case, and I'm
>>>     thinking about the patchset from David Hunt (external mempool handler)
>>>     that will be in the same situation, and maybe also another patchset
>>>     I'm working on.
>>
>> Olivier,
>>      I'm working on that at the moment with the external mempool handler
>> code. However, it crossed my mind that we have a choice to use symbol
>> versioning OR use NEXT_ABI. Would one method be preferred over the other?
>
> I think symbol versioning should always be preferred when possible.
>
> In your case, as far as I remember, your are updating the rte_mempool
> structure, which is accessed by static inline functions. I don't think
> it is easily manageable with symbol versioning. Moreover, the ABI will
> already be broken by Keith's patch, so I think it's less problematic
> to have other patches breaking the ABI at the same time.

OK, Thanks for that. I'll use NEXT_ABI in this case so. :)

Regards,
David.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] mempool: reduce rte_mempool structure size
  2016-02-15 10:21  0%               ` Hunt, David
@ 2016-02-15 12:31  0%                 ` Olivier MATZ
  0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2016-02-15 12:31 UTC (permalink / raw)
  To: Hunt, David, Thomas Monjalon, Wiles, Keith; +Cc: dev

Hi David,

On 02/15/2016 11:21 AM, Hunt, David wrote:
> On 15/02/2016 10:15, Olivier MATZ wrote:
>> On 02/15/2016 10:58 AM, Hunt, David wrote:
>>>      I'm working on that at the moment with the external mempool handler
>>> code. However, it crossed my mind that we have a choice to use symbol
>>> versioning OR use NEXT_ABI. Would one method be preferred over the
>>> other?
>>
>> I think symbol versioning should always be preferred when possible.
>>
>> In your case, as far as I remember, your are updating the rte_mempool
>> structure, which is accessed by static inline functions. I don't think
>> it is easily manageable with symbol versioning. Moreover, the ABI will
>> already be broken by Keith's patch, so I think it's less problematic
>> to have other patches breaking the ABI at the same time.
> 
> OK, Thanks for that. I'll use NEXT_ABI in this case so. :)

Just to let you know in case you missed it: Keith's patch (v3 [1] and
v4 [2]) finally does not have the NEXT_ABI ifdefs, because it was
too heavy.

So for your patches it will also depend on the complexity of the
changes. You can have a try with NEXT_ABI and see if the code is
still maintainable or not. If not, the process is to push a deprecation
notice for 16.04 and the code for 16.07.

Regards,
Olivier

[1] v3: http://dpdk.org/ml/archives/dev/2016-February/033004.html
[2] v4: http://dpdk.org/ml/archives/dev/2016-February/033102.html

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
@ 2016-02-16  3:16 15% Ziye Yang
  2016-02-16  7:38  9% ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Ziye Yang @ 2016-02-16  3:16 UTC (permalink / raw)
  To: dev; +Cc: Ziye

From: Ziye <ziye.yang@intel.com>

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>
---
 doc/guides/rel_notes/release_16_04.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 27fc624..fe843a5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -95,9 +95,10 @@ 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.
+* New field ``class`` is added into ``rte_pci_id`` structure. This new
+  added ``class`` field can be used to probe pci devices by class related
+  info. With this new field, the size of structure ``rte_pci_device`` will
+  be increased.
 
 
 Shared Library Versions
-- 
1.9.3

^ permalink raw reply	[relevance 15%]

* [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
       [not found]     <1453689419-237252>
@ 2016-02-16  4:08 15% ` Ziye Yang
  0 siblings, 0 replies; 200+ results
From: Ziye Yang @ 2016-02-16  4:08 UTC (permalink / raw)
  To: dev; +Cc: Ziye

From: Ziye <ziye.yang@intel.com>

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.

As release_2_3.rst is replaced with release_16_04.rst

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 27fc624..fe843a5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -95,9 +95,10 @@ 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.
+* New field ``class`` is added into ``rte_pci_id`` structure. This new
+  added ``class`` field can be used to probe pci devices by class related
+  info. With this new field, the size of structure ``rte_pci_device`` will
+  be increased.
 
 
 Shared Library Versions
-- 
1.9.3

^ permalink raw reply	[relevance 15%]

* [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  @ 2016-02-16  4:15 15% ` Ziye Yang
  2016-02-16 10:11  7%   ` Bruce Richardson
  2016-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
  0 siblings, 2 replies; 200+ results
From: Ziye Yang @ 2016-02-16  4:15 UTC (permalink / raw)
  To: dev; +Cc: Ziye

From: Ziye <ziye.yang@intel.com>

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.

As release_2_3.rst is replaced with release_16_04.rst.

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 27fc624..fe843a5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -95,9 +95,10 @@ 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.
+* New field ``class`` is added into ``rte_pci_id`` structure. This new
+  added ``class`` field can be used to probe pci devices by class related
+  info. With this new field, the size of structure ``rte_pci_device`` will
+  be increased.
 
 
 Shared Library Versions
-- 
1.9.3

^ permalink raw reply	[relevance 15%]

* Re: [dpdk-dev] [PATCH v2 0/5] clean-up cpuflags
  2016-02-06 22:17  3% ` [dpdk-dev] [PATCH v2 " Thomas Monjalon
  2016-02-06 22:17  1%   ` [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
@ 2016-02-16  7:30  0%   ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-02-16  7:30 UTC (permalink / raw)
  To: david.marchand; +Cc: dev, viktorin

2016-02-06 23:17, Thomas Monjalon:
> Following the work of Ferruh, I suggest this cleanup to remove as much
> as possible of the code from the cpuflags headers.
> The goal is to un-inline these functions (not performance sensitive)
> and remove the CPU flags table from the ABI (just added recently).
> The bonus is to stop mimic x86 in ARM and PPC implementations.
> 
> WARNING: it has not been tested nor compiled on Tilera and POWER8.
> 
> v2 changes:
> - fix maintainers file
> - fix include from C++ app
> - fix missing REG_PLATFORM for ARM
> - suggested ARM refactor from Jerin

Applied

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16  3:16 15% [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure Ziye Yang
@ 2016-02-16  7:38  9% ` Panu Matilainen
  2016-02-16  7:43  9%   ` Yang, Ziye
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-02-16  7:38 UTC (permalink / raw)
  To: Ziye Yang, dev

On 02/16/2016 05:16 AM, Ziye Yang wrote:
> From: Ziye <ziye.yang@intel.com>
>
> 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>
> ---
>   doc/guides/rel_notes/release_16_04.rst | 7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index 27fc624..fe843a5 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -95,9 +95,10 @@ 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.
> +* New field ``class`` is added into ``rte_pci_id`` structure. This new
> +  added ``class`` field can be used to probe pci devices by class related
> +  info. With this new field, the size of structure ``rte_pci_device`` will
> +  be increased.
>
>
>   Shared Library Versions
>

ABI breakage announcements go into doc/guides/rel_notes/deprecation.rst, 
see the examples there. Also you can't break the ABI in the version 
under development but only the next one, so right now the earliest ABI 
breakage opportunity is in the release *after* 16.04, which is supposed 
to be 16.07 according to the roadmap.

	- Panu -

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16  7:38  9% ` Panu Matilainen
@ 2016-02-16  7:43  9%   ` Yang, Ziye
  2016-02-16  7:55  7%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Yang, Ziye @ 2016-02-16  7:43 UTC (permalink / raw)
  To: Panu Matilainen, dev

Hi Panu,

" ABI breakage announcements go into doc/guides/rel_notes/deprecation.rst,
see the examples there. Also you can't break the ABI in the version under development but only the next one, so right now the earliest ABI breakage opportunity is in the release *after* 16.04, which is supposed to be 16.07 according to the roadmap."

So I only need to do the ABI breakage announcements  into doc/guides/rel_notes/deprecation.rst, right?

Thanks.

Best Regards,
Ziye Yang

-----Original Message-----
From: Panu Matilainen [mailto:pmatilai@redhat.com] 
Sent: Tuesday, February 16, 2016 3:39 PM
To: Yang, Ziye <ziye.yang@intel.com>; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure

On 02/16/2016 05:16 AM, Ziye Yang wrote:
> From: Ziye <ziye.yang@intel.com>
>
> 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>
> ---
>   doc/guides/rel_notes/release_16_04.rst | 7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/doc/guides/rel_notes/release_16_04.rst 
> b/doc/guides/rel_notes/release_16_04.rst
> index 27fc624..fe843a5 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -95,9 +95,10 @@ 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.
> +* New field ``class`` is added into ``rte_pci_id`` structure. This 
> +new
> +  added ``class`` field can be used to probe pci devices by class 
> +related
> +  info. With this new field, the size of structure ``rte_pci_device`` 
> +will
> +  be increased.
>
>
>   Shared Library Versions
>

ABI breakage announcements go into doc/guides/rel_notes/deprecation.rst,
see the examples there. Also you can't break the ABI in the version under development but only the next one, so right now the earliest ABI breakage opportunity is in the release *after* 16.04, which is supposed to be 16.07 according to the roadmap.

	- Panu -

^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16  7:43  9%   ` Yang, Ziye
@ 2016-02-16  7:55  7%     ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-02-16  7:55 UTC (permalink / raw)
  To: Yang, Ziye, dev

On 02/16/2016 09:43 AM, Yang, Ziye wrote:
> Hi Panu,
>
> " ABI breakage announcements go into doc/guides/rel_notes/deprecation.rst,
> see the examples there. Also you can't break the ABI in the version under development but only the next one, so right now the earliest ABI breakage opportunity is in the release *after* 16.04, which is supposed to be 16.07 according to the roadmap."
>
> So I only need to do the ABI breakage announcements  into doc/guides/rel_notes/deprecation.rst, right?
>

Yes.

The version-specific release notes ABI/API changes section is to be 
updated along with the actual changes to the code.

If you haven't already done so, do read
http://dpdk.org/doc/guides/contributing/versioning.html

	- Panu -

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16  4:15 15% ` [dpdk-dev] [PATCH v2] " Ziye Yang
@ 2016-02-16 10:11  7%   ` Bruce Richardson
  2016-02-16 10:34  7%     ` Thomas Monjalon
  2016-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
  1 sibling, 1 reply; 200+ results
From: Bruce Richardson @ 2016-02-16 10:11 UTC (permalink / raw)
  To: Ziye Yang; +Cc: dev

On Tue, Feb 16, 2016 at 12:15:19PM +0800, Ziye Yang wrote:
> From: Ziye <ziye.yang@intel.com>
> 
> 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.
> 
> As release_2_3.rst is replaced with release_16_04.rst.
> 
> Signed-off-by: Ziye Yang <ziye.yang@intel.com>
> ---
>  doc/guides/rel_notes/release_16_04.rst | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index 27fc624..fe843a5 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -95,9 +95,10 @@ 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.
> +* New field ``class`` is added into ``rte_pci_id`` structure. This new
> +  added ``class`` field can be used to probe pci devices by class related
> +  info. With this new field, the size of structure ``rte_pci_device`` will
> +  be increased.
>  
>  
>  Shared Library Versions
> -- 

Hi,

since this is new ABI change announcement, and not one that was previously
announced and is now being applied, this announcement should go in the 
deprecation.rst file, rather than release_16_04.rst.

Thomas, is there some reason why the deprecation notices are not called out in
the release notes for a new release? Why are they kept separately?

/Bruce

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16 10:11  7%   ` Bruce Richardson
@ 2016-02-16 10:34  7%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-02-16 10:34 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Ziye Yang, dev

2016-02-16 10:11, Bruce Richardson:
> Thomas, is there some reason why the deprecation notices are not called out in
> the release notes for a new release? Why are they kept separately?

No strong reason.
It is part of the release notes but not in the versioned section.
Probably because there is no interest in keeping the history of planned
deprecations in the release notes. When the API/ABI is changed, the deprecation
notice is replaced by an entry in the versioned section.

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH 0/6] external mempool manager
    @ 2016-02-16 14:48  3% ` David Hunt
  2016-02-16 14:48  4%   ` [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages David Hunt
  2016-03-09  9:50  3%   ` [dpdk-dev] [PATCH v3 0/4] external mempool manager David Hunt
  1 sibling, 2 replies; 200+ results
From: David Hunt @ 2016-02-16 14:48 UTC (permalink / raw)
  To: dev

Hi list.

Here's the v2 version of a proposed patch for an external mempool manager

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 (custom_mempool.c).

David Hunt (6):
  mempool: add external mempool manager support
  mempool: add stack (lifo) based external mempool handler
  mempool: adds a simple ring-based mempool handler using mallocs for
    objects
  mempool: add autotest for external mempool custom example
  mempool: allow rte_pktmbuf_pool_create switch between memool handlers
  mempool: add in the RTE_NEXT_ABI protection for ABI breakages

 app/test/Makefile                          |   3 +
 app/test/test_ext_mempool.c                | 451 +++++++++++++++++++++++++++++
 app/test/test_mempool_perf.c               |   2 +
 config/common_bsdapp                       |   2 +
 config/common_linuxapp                     |   2 +
 lib/librte_mbuf/rte_mbuf.c                 |  15 +
 lib/librte_mempool/Makefile                |   5 +
 lib/librte_mempool/custom_mempool.c        | 146 ++++++++++
 lib/librte_mempool/rte_mempool.c           | 383 ++++++++++++++++++++++--
 lib/librte_mempool/rte_mempool.h           | 213 +++++++++++++-
 lib/librte_mempool/rte_mempool_default.c   | 236 +++++++++++++++
 lib/librte_mempool/rte_mempool_internal.h  |  75 +++++
 lib/librte_mempool/rte_mempool_stack.c     | 164 +++++++++++
 lib/librte_mempool/rte_mempool_version.map |   1 +
 14 files changed, 1665 insertions(+), 33 deletions(-)
 create mode 100644 app/test/test_ext_mempool.c
 create mode 100644 lib/librte_mempool/custom_mempool.c
 create mode 100644 lib/librte_mempool/rte_mempool_default.c
 create mode 100644 lib/librte_mempool/rte_mempool_internal.h
 create mode 100644 lib/librte_mempool/rte_mempool_stack.c

-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages
  2016-02-16 14:48  3% ` [dpdk-dev] [PATCH 0/6] external mempool manager David Hunt
@ 2016-02-16 14:48  4%   ` David Hunt
  2016-02-19 13:33  7%     ` Olivier MATZ
  2016-03-09  9:50  3%   ` [dpdk-dev] [PATCH v3 0/4] external mempool manager David Hunt
  1 sibling, 1 reply; 200+ results
From: David Hunt @ 2016-02-16 14:48 UTC (permalink / raw)
  To: dev

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 | 240 ++++++++++++++++++++++++++++++++++++++-
 lib/librte_mempool/rte_mempool.h |  68 ++++++++++-
 6 files changed, 320 insertions(+), 2 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 4f72546..8038785 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -42,9 +42,11 @@ 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_default.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_stack.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  custom_mempool.c
+endif
 ifeq ($(CONFIG_RTE_LIBRTE_XEN_DOM0),y)
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_dom0_mempool.c
 endif
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 44bc92f..53e44ff 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -59,7 +59,9 @@
 #include <rte_spinlock.h>
 
 #include "rte_mempool.h"
+#ifdef RTE_NEXT_ABI
 #include "rte_mempool_internal.h"
+#endif
 
 TAILQ_HEAD(rte_mempool_list, rte_tailq_entry);
 
@@ -400,6 +402,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.
@@ -698,6 +701,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
@@ -705,7 +931,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
 	{
@@ -861,6 +1091,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);
@@ -883,7 +1116,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);
@@ -978,7 +1215,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,
@@ -1004,3 +1241,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 8d8201f..e676296 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -88,8 +88,10 @@ extern "C" {
 struct rte_mempool_debug_stats {
 	uint64_t put_bulk;         /**< Number of puts. */
 	uint64_t put_objs;         /**< Number of objects successfully put. */
+#ifdef RTE_NEXT_ABI
 	uint64_t put_pool_bulk;    /**< Number of puts into pool. */
 	uint64_t put_pool_objs;    /**< Number of objects into pool. */
+#endif
 	uint64_t get_success_bulk; /**< Successful allocation number. */
 	uint64_t get_success_objs; /**< Objects successfully allocated. */
 	uint64_t get_fail_bulk;    /**< Failed allocation number. */
@@ -177,6 +179,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);
@@ -250,12 +253,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. */
@@ -269,10 +276,12 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
+#ifdef RTE_NEXT_ABI
 	/* Common pool data structure pointer */
 	void *rt_pool;
 
 	int16_t handler_idx;
+#endif
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/** Per-lcore local cache. */
@@ -303,9 +312,10 @@ 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_USE_STACK      0x0010 /**< Use a stack for the common pool. */
 #define MEMPOOL_F_INT_HANDLER    0x0020 /**< Using internal mempool handler */
-
+#endif
 
 /**
  * @internal When debug is enabled, store some statistics.
@@ -836,7 +846,11 @@ 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,
+#ifdef RTE_NEXT_ABI
 		    unsigned n, __attribute__((unused)) int is_mp)
+#else
+		    unsigned n, int is_mp)
+#endif
 {
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	struct rte_mempool_cache *cache;
@@ -852,7 +866,12 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/* cache is not enabled or single producer or non-EAL thread */
+#ifdef RTE_NEXT_ABI
 	if (unlikely(cache_size == 0 || lcore_id >= RTE_MAX_LCORE))
+#else
+	if (unlikely(cache_size == 0 || is_mp == 0 ||
+		     lcore_id >= RTE_MAX_LCORE))
+#endif
 		goto ring_enqueue;
 
 	/* Go straight to ring if put would overflow mem allocated for cache */
@@ -875,9 +894,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;
 	}
 
@@ -886,10 +911,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
 }
 
 
@@ -1013,7 +1056,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
@@ -1024,8 +1071,13 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 	uint32_t cache_size = mp->cache_size;
 
 	/* cache is not enabled or single consumer */
+#ifdef RTE_NEXT_ABI
 	if (unlikely(cache_size == 0 || n >= cache_size ||
 						lcore_id >= RTE_MAX_LCORE))
+#else
+	if (unlikely(cache_size == 0 || is_mc == 0 ||
+		     n >= cache_size || lcore_id >= RTE_MAX_LCORE))
+#endif
 		goto ring_dequeue;
 
 	cache = &mp->local_cache[lcore_id];
@@ -1037,8 +1089,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,
@@ -1066,7 +1123,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);
@@ -1468,6 +1532,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
@@ -1541,6 +1606,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] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-16  4:15 15% ` [dpdk-dev] [PATCH v2] " Ziye Yang
  2016-02-16 10:11  7%   ` Bruce Richardson
@ 2016-02-17  1:54 11%   ` Ziye Yang
  2016-02-17 10:14  4%     ` Bruce Richardson
                       ` (2 more replies)
  1 sibling, 3 replies; 200+ results
From: Ziye Yang @ 2016-02-17  1:54 UTC (permalink / raw)
  To: dev; +Cc: Ziye

From: Ziye <ziye.yang@intel.com>

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>
---
 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 e94d4a2..9fa2433 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 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
+  rte_pci_device. The release 16.04 does not contain these ABI changes, but
+  release 16.07 will.
-- 
1.9.3

^ permalink raw reply	[relevance 11%]

* Re: [dpdk-dev] [PATCH v3] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
@ 2016-02-17 10:14  4%     ` Bruce Richardson
  2016-02-18  1:57  4%     ` Zhang, Helin
  2016-02-18  2:46  4%     ` Liang, Cunming
  2 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2016-02-17 10:14 UTC (permalink / raw)
  To: Ziye Yang; +Cc: dev

On Wed, Feb 17, 2016 at 09:54:33AM +0800, Ziye Yang wrote:
> From: Ziye <ziye.yang@intel.com>
> 
> 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>

^ permalink raw reply	[relevance 4%]

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

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.

Ferruh Yigit (3):
  ethdev: add helper functions to get eth_dev and dev private data
  app/test: use ethdev helper functions
  bonding: use ethdev helper functions

 app/test/test_link_bonding.c              | 35 ++++++++------
 app/test/virtual_pmd.c                    | 51 +++++++++------------
 drivers/net/bonding/rte_eth_bond_8023ad.c | 10 ++--
 drivers/net/bonding/rte_eth_bond_api.c    | 76 +++++++++++++++----------------
 drivers/net/bonding/rte_eth_bond_args.c   | 13 ++++--
 drivers/net/bonding/rte_eth_bond_pmd.c    | 47 +++++++++++--------
 lib/librte_ether/rte_ethdev.h             | 44 ++++++++++++++++++
 7 files changed, 167 insertions(+), 109 deletions(-)

-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/3] ethdev: add helper functions to get eth_dev and dev private data
  2016-02-17 14:20  3% [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data Ferruh Yigit
@ 2016-02-17 14:20  3% ` Ferruh Yigit
  2016-03-10  0:00  0% ` [dpdk-dev] [PATCH 0/3] " Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-02-17 14:20 UTC (permalink / raw)
  To: dev

This is to provide abstraction and reduce global variable access.

Global variable rte_eth_devices kept exported to not break ABI.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ether/rte_ethdev.h | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 6afb5a9..7209b83 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3881,6 +3881,50 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *eth_dev, const char *name,
 			 uint16_t queue_id, size_t size,
 			 unsigned align, int socket_id);
 
+/**
+ * Return rte_eth_dev by port id
+ *
+ * This is to abstract device access and limit global variable access.
+ *
+ * @param port_id
+ *   port_id of the device to return.
+ */
+static inline struct rte_eth_dev *
+rte_eth_by_port(uint16_t port_id)
+{
+	return &rte_eth_devices[port_id];
+}
+
+/**
+ * Return rte_eth_dev private data structure by port id
+ *
+ * This is to abstract device private data access and
+ * limit global variable access.
+ *
+ * @param port_id
+ *   port_id of the device to return.
+ */
+static inline void *
+rte_eth_private_by_port(uint16_t port_id)
+{
+	return rte_eth_devices[port_id].data->dev_private;
+}
+
+/**
+ * Return rte_eth_dev private data structure by rte_eth_dev
+ *
+ * This is helper function to access device private data, also
+ * provides some abstraction on how private data kept.
+ *
+ * @param dev
+ *   rte_eth_dev
+ */
+static inline void *
+rte_eth_private_by_dev(struct rte_eth_dev *dev)
+{
+	return dev->data->dev_private;
+}
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library
  2016-02-12 13:45  1%   ` [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library Ferruh Yigit
@ 2016-02-17 19:58  0%     ` Ananyev, Konstantin
  2016-02-18 10:43  0%       ` Yigit, Ferruh
  0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2016-02-17 19:58 UTC (permalink / raw)
  To: Yigit, Ferruh, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Friday, February 12, 2016 1:46 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library
> 
> This library gets control messages form kernelspace and forwards them to
> librte_ether and returns response back to the kernelspace.
> 
> Library does:
> 1) Trigger Linux virtual interface creation
> 2) Initialize the netlink socket communication
> 3) Provides process() API to the application that does processing the
> received messages
> 
> This library requires corresponding kernel module to be inserted.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
> ---
> 
> v2:
> * User rtnetlink to create interfaces.
> * Add more ethtool support: get/set ringparam, set pauseparam.
> * return defined error instead of hardcoded value
> ---
>  MAINTAINERS                                |   1 +
>  config/common_linuxapp                     |   3 +-
>  doc/api/doxy-api-index.md                  |   3 +-
>  doc/api/doxy-api.conf                      |   1 +
>  doc/guides/rel_notes/release_16_04.rst     |   9 +
>  lib/Makefile                               |   3 +-
>  lib/librte_ctrl_if/Makefile                |  58 ++++
>  lib/librte_ctrl_if/rte_ctrl_if.c           | 385 ++++++++++++++++++++++++
>  lib/librte_ctrl_if/rte_ctrl_if.h           | 115 ++++++++
>  lib/librte_ctrl_if/rte_ctrl_if_version.map |   9 +
>  lib/librte_ctrl_if/rte_ethtool.c           | 450 +++++++++++++++++++++++++++++
>  lib/librte_ctrl_if/rte_ethtool.h           |  54 ++++
>  lib/librte_ctrl_if/rte_nl.c                | 274 ++++++++++++++++++
>  lib/librte_ctrl_if/rte_nl.h                |  49 ++++
>  lib/librte_eal/common/include/rte_log.h    |   3 +-
>  mk/rte.app.mk                              |   3 +-
>  16 files changed, 1415 insertions(+), 5 deletions(-)
>  create mode 100644 lib/librte_ctrl_if/Makefile
>  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
>  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
>  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
>  create mode 100644 lib/librte_ctrl_if/rte_ethtool.c
>  create mode 100644 lib/librte_ctrl_if/rte_ethtool.h
>  create mode 100644 lib/librte_ctrl_if/rte_nl.c
>  create mode 100644 lib/librte_ctrl_if/rte_nl.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 09c56c7..91c98bc 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -256,6 +256,7 @@ F: doc/guides/sample_app_ug/kernel_nic_interface.rst
>  Linux KCP
>  M: Ferruh Yigit <ferruh.yigit@intel.com>
>  F: lib/librte_eal/linuxapp/kcp/
> +F: lib/librte_ctrl_if/
> 
>  Linux AF_PACKET
>  M: John W. Linville <linville@tuxdriver.com>
> diff --git a/config/common_linuxapp b/config/common_linuxapp
> index 2f4eb1d..4bcd508 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
> @@ -501,6 +501,7 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
>  #
>  CONFIG_RTE_KCP_KMOD=y
>  CONFIG_RTE_KCP_KO_DEBUG=n
> +CONFIG_RTE_LIBRTE_CTRL_IF=y
> 
>  #
>  # Compile vhost library
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 7a91001..214d16e 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),
> +  [control interface]  (@ref rte_ctrl_if.h)
> diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
> index 57e8b5d..fd69bf1 100644
> --- a/doc/api/doxy-api.conf
> +++ b/doc/api/doxy-api.conf
> @@ -39,6 +39,7 @@ INPUT                   = doc/api/doxy-api-index.md \
>                            lib/librte_cmdline \
>                            lib/librte_compat \
>                            lib/librte_cryptodev \
> +                          lib/librte_ctrl_if \
>                            lib/librte_distributor \
>                            lib/librte_ether \
>                            lib/librte_hash \
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index 27fc624..1b1d34c 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -39,6 +39,14 @@ This section should contain new features added in this release. Sample format:
> 
>    Enabled virtio 1.0 support for virtio pmd driver.
> 
> +* **Control interface support added.**
> +
> +  To enable controlling DPDK ports by common Linux tools.
> +  Following modules added to DPDK:
> +
> +  * librte_ctrl_if library
> +  * librte_eal/linuxapp/kcp kernel module
> +
> 
>  Resolved Issues
>  ---------------
> @@ -113,6 +121,7 @@ The libraries prepended with a plus sign were incremented in this version.
>       librte_acl.so.2
>       librte_cfgfile.so.2
>       librte_cmdline.so.1
> +   + librte_ctrl_if.so.1
>       librte_distributor.so.1
>       librte_eal.so.2
>       librte_hash.so.2
> diff --git a/lib/Makefile b/lib/Makefile
> index ef172ea..a50bc1e 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -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
> @@ -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_CTRL_IF) += librte_ctrl_if
> 
>  ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
>  DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
> diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
> new file mode 100644
> index 0000000..4e82966
> --- /dev/null
> +++ b/lib/librte_ctrl_if/Makefile
> @@ -0,0 +1,58 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2016 Intel Corporation. All rights reserved.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above copyright
> +#       notice, this list of conditions and the following disclaimer.
> +#     * Redistributions in binary form must reproduce the above copyright
> +#       notice, this list of conditions and the following disclaimer in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of Intel Corporation nor the names of its
> +#       contributors may be used to endorse or promote products derived
> +#       from this software without specific prior written permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_ctrl_if.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +EXPORT_MAP := rte_ctrl_if_version.map
> +
> +LIBABIVER := 1
> +
> +SRCS-y += rte_ctrl_if.c
> +SRCS-y += rte_nl.c
> +SRCS-y += rte_ethtool.c
> +
> +#
> +# Export include files
> +#
> +SYMLINK-y-include += rte_ctrl_if.h
> +
> +# this lib depends upon:
> +DEPDIRS-y += lib/librte_ether
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
> new file mode 100644
> index 0000000..d16398f
> --- /dev/null
> +++ b/lib/librte_ctrl_if/rte_ctrl_if.c
> @@ -0,0 +1,385 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <time.h>
> +
> +#include <sys/ioctl.h>
> +#include <sys/socket.h>
> +#include <linux/netlink.h>
> +#include <linux/rtnetlink.h>
> +
> +#include <rte_ethdev.h>
> +#include "rte_ctrl_if.h"
> +#include "rte_nl.h"
> +
> +#define NAMESZ 32
> +#define IFNAME "dpdk"
> +#define BUFSZ 1024
> +
> +static int kcp_rtnl_fd = -1;
> +static int kcp_fd_ref;
> +
> +struct kcp_request {
> +	struct nlmsghdr nlmsg;
> +	char buf[BUFSZ];
> +};
> +
> +static int
> +conrol_interface_rtnl_init(void)
> +{
> +	struct sockaddr_nl src;
> +	int ret;
> +
> +	kcp_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> +	if (kcp_rtnl_fd < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "socket for create failed.\n");
> +		return -1;
> +	}
> +
> +	memset(&src, 0, sizeof(struct sockaddr_nl));
> +
> +	src.nl_family = AF_NETLINK;
> +	src.nl_pid = getpid();
> +
> +	ret = bind(kcp_rtnl_fd, (struct sockaddr *)&src,
> +			sizeof(struct sockaddr_nl));
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Bind for create failed.\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +control_interface_init(void)
> +{
> +	int ret;
> +
> +	ret = conrol_interface_rtnl_init();
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink.\n");
> +		return -1;
> +	}
> +
> +	ret = control_interface_nl_init();
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink.\n");
> +		close(kcp_rtnl_fd);
> +		kcp_rtnl_fd = -1;
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +control_interface_ref_get(void)
> +{
> +	int ret = 0;
> +
> +	if (kcp_fd_ref == 0)
> +		ret = control_interface_init();
> +
> +	if (ret == 0)
> +		kcp_fd_ref++;
> +	else
> +		RTE_LOG(ERR, CTRL_IF,
> +				"Failed to initialize control interface.\n");
> +
> +	return kcp_fd_ref;
> +}
> +
> +static void
> +control_interface_release(void)
> +{
> +	close(kcp_rtnl_fd);
> +	control_interface_nl_release();
> +}
> +
> +static int
> +control_interface_ref_put(void)
> +{
> +	if (kcp_fd_ref == 0)
> +		return 0;
> +
> +	kcp_fd_ref--;
> +
> +	if (kcp_fd_ref == 0)
> +		control_interface_release();
> +
> +	return kcp_fd_ref;
> +}
> +
> +static int
> +add_attr(struct kcp_request *req, unsigned short type, void *buf, size_t len)
> +{
> +	struct rtattr *rta;
> +	int nlmsg_len;
> +
> +	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
> +	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
> +	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct kcp_request))
> +		return -1;
> +	rta->rta_type = type;
> +	rta->rta_len = RTA_LENGTH(len);
> +	memcpy(RTA_DATA(rta), buf, len);
> +	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
> +
> +	return 0;
> +}
> +
> +static struct
> +rtattr *add_attr_nested(struct kcp_request *req, unsigned short type)
> +{
> +	struct rtattr *rta;
> +	int nlmsg_len;
> +
> +	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
> +	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
> +	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct kcp_request))
> +		return NULL;
> +	rta->rta_type = type;
> +	rta->rta_len = nlmsg_len;
> +	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
> +
> +	return rta;
> +}
> +
> +static void
> +end_attr_nested(struct kcp_request *req, struct rtattr *rta)
> +{
> +	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
> +}
> +
> +static int
> +rte_eth_rtnl_create(uint8_t port_id)
> +{
> +	struct kcp_request req;
> +	struct ifinfomsg *info;
> +	struct rtattr *rta1;
> +	struct rtattr *rta2;
> +	unsigned int pid = getpid();
> +	char name[NAMESZ];
> +	char type[NAMESZ];
> +	struct iovec iov;
> +	struct msghdr msg;
> +	struct sockaddr_nl nladdr;
> +	int ret;
> +	char buf[BUFSZ];
> +
> +	memset(&req, 0, sizeof(struct kcp_request));
> +
> +	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
> +	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
> +	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
> +	req.nlmsg.nlmsg_type = RTM_NEWLINK;
> +
> +	info = NLMSG_DATA(&req.nlmsg);
> +
> +	info->ifi_family = AF_UNSPEC;
> +	info->ifi_index = 0;
> +
> +	snprintf(name, NAMESZ, IFNAME"%u", port_id);
> +	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
> +	if (ret < 0)
> +		return -1;
> +
> +	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
> +	if (rta1 == NULL)
> +		return -1;
> +
> +	snprintf(type, NAMESZ, KCP_DEVICE);
> +	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
> +	if (ret < 0)
> +		return -1;
> +
> +	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
> +	if (rta2 == NULL)
> +		return -1;
> +
> +	ret = add_attr(&req, IFLA_KCP_PORTID, &port_id, sizeof(uint8_t));
> +	if (ret < 0)
> +		return -1;
> +
> +	ret = add_attr(&req, IFLA_KCP_PID, &pid, sizeof(unsigned int));
> +	if (ret < 0)
> +		return -1;
> +
> +	end_attr_nested(&req, rta2);
> +	end_attr_nested(&req, rta1);
> +
> +	memset(&nladdr, 0, sizeof(nladdr));
> +	nladdr.nl_family = AF_NETLINK;
> +
> +	iov.iov_base = (void *)&req.nlmsg;
> +	iov.iov_len = req.nlmsg.nlmsg_len;
> +
> +	memset(&msg, 0, sizeof(struct msghdr));
> +	msg.msg_name = &nladdr;
> +	msg.msg_namelen = sizeof(nladdr);
> +	msg.msg_iov = &iov;
> +	msg.msg_iovlen = 1;
> +
> +	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
> +		return -1;
> +	}
> +
> +	memset(buf, 0, sizeof(buf));
> +	iov.iov_base = buf;
> +	iov.iov_len = sizeof(buf);
> +
> +	ret = recvmsg(kcp_rtnl_fd, &msg, 0);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Recv for create failed.\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +

It is probably would be good to make
rte_eth_control_interface_create_one()/rte_eth_control_interface_destroy_one()
a public API, so the user can decide which ports to expose to KCP, which not.
If that is not possible by some reason - then seems no reason to keep 
control_interface_ref_get/ control_interface_ref_put.

> +static int
> +rte_eth_control_interface_create_one(uint8_t port_id)
> +{
> +	int ret;
> +
> +	if (control_interface_ref_get() != 0) {
> +		ret = rte_eth_rtnl_create(port_id);
> +		RTE_LOG(DEBUG, CTRL_IF,
> +			"Control interface %s for port:%u\n",
> +			ret < 0 ? "failed" : "created", port_id);
> +	}
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_control_interface_create(void)
> +{
> +	int i;
> +	int ret = 0;
> +
> +	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> +		if (rte_eth_dev_is_valid_port(i)) {
> +			ret = rte_eth_control_interface_create_one(i);
> +			if (ret < 0)
> +				return ret;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +rte_eth_rtnl_destroy(uint8_t port_id)
> +{
> +	struct kcp_request req;
> +	struct ifinfomsg *info;
> +	char name[NAMESZ];
> +	struct iovec iov;
> +	struct msghdr msg;
> +	struct sockaddr_nl nladdr;
> +	int ret;
> +
> +	memset(&req, 0, sizeof(struct kcp_request));
> +
> +	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
> +	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
> +	req.nlmsg.nlmsg_type = RTM_DELLINK;
> +
> +	info = NLMSG_DATA(&req.nlmsg);
> +
> +	info->ifi_family = AF_UNSPEC;
> +	info->ifi_index = 0;
> +
> +	snprintf(name, NAMESZ, IFNAME"%u", port_id);
> +	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
> +	if (ret < 0)
> +		return -1;
> +
> +	memset(&nladdr, 0, sizeof(nladdr));
> +	nladdr.nl_family = AF_NETLINK;
> +
> +	iov.iov_base = (void *)&req.nlmsg;
> +	iov.iov_len = req.nlmsg.nlmsg_len;
> +
> +	memset(&msg, 0, sizeof(struct msghdr));
> +	msg.msg_name = &nladdr;
> +	msg.msg_namelen = sizeof(nladdr);
> +	msg.msg_iov = &iov;
> +	msg.msg_iovlen = 1;
> +
> +	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed.\n");
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +static int
> +rte_eth_control_interface_destroy_one(uint8_t port_id)
> +{
> +	rte_eth_rtnl_destroy(port_id);
> +	control_interface_ref_put();
> +	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
> +			port_id);
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_control_interface_destroy(void)
> +{
> +	int i;
> +	int ret = 0;
> +
> +	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> +		if (rte_eth_dev_is_valid_port(i)) {
> +			ret = rte_eth_control_interface_destroy_one(i);
> +			if (ret < 0)
> +				return ret;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +int
> +rte_eth_control_interface_process_msg(int flag, unsigned int timeout_sec)
> +{
> +	return control_interface_process_msg(flag, timeout_sec);
> +}
> +};
....

> diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
> new file mode 100644
> index 0000000..adc5fa8
> --- /dev/null
> +++ b/lib/librte_ctrl_if/rte_nl.c
> @@ -0,0 +1,274 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <unistd.h>
> +
> +#include <sys/socket.h>
> +#include <linux/netlink.h>
> +
> +#include <rte_spinlock.h>
> +#include <rte_ethdev.h>
> +#include "rte_ethtool.h"
> +#include "rte_nl.h"
> +#include "rte_ctrl_if.h"
> +
> +#define MAX_PAYLOAD sizeof(struct kcp_ethtool_msg)
> +
> +struct ctrl_if_nl {
> +	union {
> +		struct nlmsghdr nlh;
> +		uint8_t nlmsg[NLMSG_SPACE(MAX_PAYLOAD)];
> +	};
> +	struct msghdr msg;
> +	struct iovec iov;
> +};
> +
> +static int sock_fd = -1;
> +pthread_t thread_id;
> +
> +struct sockaddr_nl dest_addr;
> +
> +pthread_cond_t cond  = PTHREAD_COND_INITIALIZER;
> +pthread_mutex_t msg_lock = PTHREAD_MUTEX_INITIALIZER;

Could you group related global variables into some struct.
Then at least people would realise what lock and cond are supposed to synchronise.
Another good thing to do - make them static, if possible. 

> +
> +static struct ctrl_if_nl nl_s;
> +static struct ctrl_if_nl nl_r;
> +
> +static int kcp_ethtool_msg_count;
> +static struct kcp_ethtool_msg msg_storage;
> +
> +static int
> +nl_send(void *buf, size_t len)
> +{
> +	int ret;
> +
> +	if (nl_s.nlh.nlmsg_len < len) {
> +		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
> +		return -1;
> +	}
> +
> +	if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) {
> +		RTE_LOG(ERR, CTRL_IF, "Message is not OK\n");
> +		return -1;
> +	}
> +
> +	/* Fill in the netlink message payload */
> +	memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len);
> +
> +	ret = sendmsg(sock_fd, &nl_s.msg, 0);
> +
> +	if (ret < 0)
> +		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
> +				ret, errno);
> +	return ret;
> +}
> +
> +static int
> +nl_ethtool_msg_send(struct kcp_ethtool_msg *msg)
> +{
> +	return nl_send((void *)msg, sizeof(struct kcp_ethtool_msg));
> +}
> +
> +static void
> +process_msg(struct kcp_ethtool_msg *msg)
> +{
> +	if (msg->cmd_id > RTE_KCP_REQ_UNKNOWN) {
> +		msg->err = rte_eth_dev_control_process(msg->cmd_id,
> +				msg->port_id, msg->input_buffer,
> +				msg->output_buffer, &msg->output_buffer_len);
> +	} else {
> +		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
> +				msg->port_id, msg->input_buffer,
> +				msg->output_buffer, &msg->output_buffer_len);
> +	}
> +
> +	if (msg->err)
> +		memset(msg->output_buffer, 0, msg->output_buffer_len);
> +
> +	nl_ethtool_msg_send(msg);
> +}
> +
> +int
> +control_interface_process_msg(int flag, unsigned int timeout_sec)
> +{
> +	int ret = 0;
> +	struct timespec ts;
> +
> +	pthread_mutex_lock(&msg_lock);
> +
> +	clock_gettime(CLOCK_REALTIME, &ts);
> +	ts.tv_sec += timeout_sec;
> +	while (timeout_sec && !kcp_ethtool_msg_count && !ret)
> +		ret = pthread_cond_timedwait(&cond, &msg_lock, &ts);


Better to avoid holding lock while calling process_msg().
That is a good programming practice, as msg_lock protects only contents of the msg_storage.
Again if by some reason process() would take a while, wouldn't stop your control thread. 
lock(); copy_message_into_local_buffer; unlock(); process();

> +
> +	switch (flag) {
> +	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
> +		if (kcp_ethtool_msg_count) {
> +			process_msg(&msg_storage);
> +			kcp_ethtool_msg_count = 0;
> +		}
> +		ret = 0;
> +		break;
> +
> +	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
> +		if (kcp_ethtool_msg_count) {
> +			msg_storage.err = -1;
> +			nl_ethtool_msg_send(&msg_storage);
> +			kcp_ethtool_msg_count = 0;
> +		}
> +		ret = 0;
> +		break;
> +
> +	default:
> +		ret = -1;
> +		break;
> +	}
> +	pthread_mutex_unlock(&msg_lock);
> +
> +	return ret;
> +}
> +

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] PCI: ABI change request for adding new field in rte_pci_id structure
  2016-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
  2016-02-17 10:14  4%     ` Bruce Richardson
@ 2016-02-18  1:57  4%     ` Zhang, Helin
  2016-02-18  2:46  4%     ` Liang, Cunming
  2 siblings, 0 replies; 200+ results
From: Zhang, Helin @ 2016-02-18  1:57 UTC (permalink / raw)
  To: Yang, Ziye, dev; +Cc: Yang, Ziye



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ziye Yang
> Sent: Wednesday, February 17, 2016 9:55 AM
> To: dev@dpdk.org
> Cc: Yang, Ziye
> Subject: [dpdk-dev] [PATCH v3] PCI: ABI change request for adding new field
> in rte_pci_id structure
> 
> From: Ziye <ziye.yang@intel.com>
> 
> 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: Helin Zhang <helin.zhang@intel.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-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
  2016-02-17 10:14  4%     ` Bruce Richardson
  2016-02-18  1:57  4%     ` Zhang, Helin
@ 2016-02-18  2:46  4%     ` Liang, Cunming
  2 siblings, 0 replies; 200+ results
From: Liang, Cunming @ 2016-02-18  2:46 UTC (permalink / raw)
  To: Yang, Ziye, dev; +Cc: Yang, Ziye



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ziye Yang
> Sent: Wednesday, February 17, 2016 9:55 AM
> To: dev@dpdk.org
> Cc: Yang, Ziye
> Subject: [dpdk-dev] [PATCH v3] PCI: ABI change request for adding new field in
> rte_pci_id structure
> 
> From: Ziye <ziye.yang@intel.com>
> 
> 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>

It's better to use "doc:" as subject prefix, the others are good to go.
Acked-by: Cunming Liang <cunming.liang@intel.com>

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-02-18  3:17  4%   ` Wenzhuo Lu
  0 siblings, 0 replies; 200+ results
From: Wenzhuo Lu @ 2016-02-18  3:17 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>
---
 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          | 18 ++++++++++++++
 4 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 73298c9..4e71e90 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6780,9 +6780,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 ed971b4..74428f4 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1987,6 +1987,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)
 {
@@ -2010,6 +2032,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 bada8ad..2e064f4 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -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;
 };
 
 /**
@@ -3408,6 +3420,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);
+int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
  * Detete UDP tunneling port configuration of Ethernet device
@@ -3425,6 +3440,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);
 
 /**
  * Check whether the filter type is supported on an Ethernet device.
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 28/30] i40e: add/remove new device IDs
  @ 2016-02-18  6:30  4%   ` Helin Zhang
  0 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-02-18  6:30 UTC (permalink / raw)
  To: dev

It adds several new device IDs, and also removed one which is
not used at all.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/release_2_3.rst            | 91 +++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h                  |  2 +-
 drivers/net/i40e/i40e_rxtx.c                    |  8 +--
 lib/librte_eal/common/include/rte_pci_dev_ids.h |  8 ++-
 4 files changed, 102 insertions(+), 7 deletions(-)
 create mode 100644 doc/guides/rel_notes/release_2_3.rst

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
new file mode 100644
index 0000000..fec5e4d
--- /dev/null
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -0,0 +1,91 @@
+DPDK Release 2.3
+================
+
+New Features
+------------
+
+**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.
+  * Add new X722 device IDs, and removed X710 one was never used.
+  * Expose registers for HASH/FD input set configuring.
+
+
+Resolved Issues
+---------------
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+* **i40e: Fixed failure of reading/writing rx control registers.**
+
+  Fixed i40e issue failing to read/write rx control registers when
+  under stress small traffic, which will result in application launch
+  failure.
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+
+API Changes
+-----------
+
+
+ABI Changes
+-----------
+
+
+Shared Library Versions
+-----------------------
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     libethdev.so.2
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.1
+     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.2
+     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
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 6edd7dd..a5207fc 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -599,7 +599,7 @@ i40e_get_vsi_from_adapter(struct i40e_adapter *adapter)
                 return NULL;
 
 	hw = I40E_DEV_PRIVATE_TO_HW(adapter);
-	if (hw->mac.type == I40E_MAC_VF) {
+	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(adapter);
 		return &vf->vsi;
 	} else {
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 40cffc1..90ca819 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2113,7 +2113,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t base, bsf, tc_mapping;
 	int use_def_burst_func = 1;
 
-	if (hw->mac.type == I40E_MAC_VF) {
+	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		struct i40e_vf *vf =
 			I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 		vsi = &vf->vsi;
@@ -2153,7 +2153,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->nb_rx_desc = nb_desc;
 	rxq->rx_free_thresh = rx_conf->rx_free_thresh;
 	rxq->queue_id = queue_idx;
-	if (hw->mac.type == I40E_MAC_VF)
+	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF)
 		rxq->reg_idx = queue_idx;
 	else /* PF device */
 		rxq->reg_idx = vsi->base_queue +
@@ -2330,7 +2330,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
 
-	if (hw->mac.type == I40E_MAC_VF) {
+	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		struct i40e_vf *vf =
 			I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 		vsi = &vf->vsi;
@@ -2458,7 +2458,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->hthresh = tx_conf->tx_thresh.hthresh;
 	txq->wthresh = tx_conf->tx_thresh.wthresh;
 	txq->queue_id = queue_idx;
-	if (hw->mac.type == I40E_MAC_VF)
+	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF)
 		txq->reg_idx = queue_idx;
 	else /* PF device */
 		txq->reg_idx = vsi->base_queue +
diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index d088191..40ba98c 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -496,7 +496,6 @@ RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82599_BYPASS)
 
 #define I40E_DEV_ID_SFP_XL710           0x1572
 #define I40E_DEV_ID_QEMU                0x1574
-#define I40E_DEV_ID_KX_A                0x157F
 #define I40E_DEV_ID_KX_B                0x1580
 #define I40E_DEV_ID_KX_C                0x1581
 #define I40E_DEV_ID_QSFP_A              0x1583
@@ -507,13 +506,14 @@ RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82599_BYPASS)
 #define I40E_DEV_ID_20G_KR2_A           0x1588
 #define I40E_DEV_ID_10G_BASE_T4         0x1589
 #define I40E_DEV_ID_X722_A0             0x374C
+#define I40E_DEV_ID_KX_X722             0x37CE
+#define I40E_DEV_ID_QSFP_X722           0x37CF
 #define I40E_DEV_ID_SFP_X722            0x37D0
 #define I40E_DEV_ID_1G_BASE_T_X722      0x37D1
 #define I40E_DEV_ID_10G_BASE_T_X722     0x37D2
 
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_SFP_XL710)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_QEMU)
-RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_KX_A)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_KX_B)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_KX_C)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_QSFP_A)
@@ -524,6 +524,8 @@ RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_20G_KR2)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_20G_KR2_A)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_10G_BASE_T4)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_X722_A0)
+RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_KX_X722)
+RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_QSFP_X722)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_SFP_X722)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_1G_BASE_T_X722)
 RTE_PCI_DEV_ID_DECL_I40E(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_10G_BASE_T_X722)
@@ -572,11 +574,13 @@ RTE_PCI_DEV_ID_DECL_IXGBEVF(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV)
 
 #define I40E_DEV_ID_VF                  0x154C
 #define I40E_DEV_ID_VF_HV               0x1571
+#define I40E_DEV_ID_X722_A0_VF          0x374D
 #define I40E_DEV_ID_X722_VF             0x37CD
 #define I40E_DEV_ID_X722_VF_HV          0x37D9
 
 RTE_PCI_DEV_ID_DECL_I40EVF(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_VF)
 RTE_PCI_DEV_ID_DECL_I40EVF(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_VF_HV)
+RTE_PCI_DEV_ID_DECL_I40EVF(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_X722_A0_VF)
 RTE_PCI_DEV_ID_DECL_I40EVF(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_X722_VF)
 RTE_PCI_DEV_ID_DECL_I40EVF(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_X722_VF_HV)
 
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  @ 2016-02-18  9:58 17%   ` Xutao Sun
    1 sibling, 0 replies; 200+ results
From: Xutao Sun @ 2016-02-18  9:58 UTC (permalink / raw)
  To: dev

Change the fields of outer_mac and inner_mac 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 |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
 lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
 5 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..c707318 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6640,8 +6640,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 e94d4a2..a895364 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -32,11 +32,6 @@ 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 eb1b3b2..2588225 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -104,6 +104,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.
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..7c22358 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5828,10 +5828,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) {
@@ -6131,13 +6131,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 ce224ad..30cbde7 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 {
-- 
1.9.3

^ permalink raw reply	[relevance 17%]

* Re: [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library
  2016-02-17 19:58  0%     ` Ananyev, Konstantin
@ 2016-02-18 10:43  0%       ` Yigit, Ferruh
  0 siblings, 0 replies; 200+ results
From: Yigit, Ferruh @ 2016-02-18 10:43 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Wed, Feb 17, 2016 at 07:58:16PM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> > Sent: Friday, February 12, 2016 1:46 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library
> > 
> > This library gets control messages form kernelspace and forwards them to
> > librte_ether and returns response back to the kernelspace.
> > 
> > Library does:
> > 1) Trigger Linux virtual interface creation
> > 2) Initialize the netlink socket communication
> > 3) Provides process() API to the application that does processing the
> > received messages
> > 
> > This library requires corresponding kernel module to be inserted.
> > 
> > Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> > 
> > ---
> > 
> > v2:
> > * User rtnetlink to create interfaces.
> > * Add more ethtool support: get/set ringparam, set pauseparam.
> > * return defined error instead of hardcoded value
> > ---
> >  MAINTAINERS                                |   1 +
> >  config/common_linuxapp                     |   3 +-
> >  doc/api/doxy-api-index.md                  |   3 +-
> >  doc/api/doxy-api.conf                      |   1 +
> >  doc/guides/rel_notes/release_16_04.rst     |   9 +
> >  lib/Makefile                               |   3 +-
> >  lib/librte_ctrl_if/Makefile                |  58 ++++
> >  lib/librte_ctrl_if/rte_ctrl_if.c           | 385 ++++++++++++++++++++++++
> >  lib/librte_ctrl_if/rte_ctrl_if.h           | 115 ++++++++
> >  lib/librte_ctrl_if/rte_ctrl_if_version.map |   9 +
> >  lib/librte_ctrl_if/rte_ethtool.c           | 450 +++++++++++++++++++++++++++++
> >  lib/librte_ctrl_if/rte_ethtool.h           |  54 ++++
> >  lib/librte_ctrl_if/rte_nl.c                | 274 ++++++++++++++++++
> >  lib/librte_ctrl_if/rte_nl.h                |  49 ++++
> >  lib/librte_eal/common/include/rte_log.h    |   3 +-
> >  mk/rte.app.mk                              |   3 +-
> >  16 files changed, 1415 insertions(+), 5 deletions(-)
> >  create mode 100644 lib/librte_ctrl_if/Makefile
> >  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
> >  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
> >  create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
> >  create mode 100644 lib/librte_ctrl_if/rte_ethtool.c
> >  create mode 100644 lib/librte_ctrl_if/rte_ethtool.h
> >  create mode 100644 lib/librte_ctrl_if/rte_nl.c
> >  create mode 100644 lib/librte_ctrl_if/rte_nl.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 09c56c7..91c98bc 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -256,6 +256,7 @@ F: doc/guides/sample_app_ug/kernel_nic_interface.rst
> >  Linux KCP
> >  M: Ferruh Yigit <ferruh.yigit@intel.com>
> >  F: lib/librte_eal/linuxapp/kcp/
> > +F: lib/librte_ctrl_if/
> > 
> >  Linux AF_PACKET
> >  M: John W. Linville <linville@tuxdriver.com>
> > diff --git a/config/common_linuxapp b/config/common_linuxapp
> > index 2f4eb1d..4bcd508 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
> > @@ -501,6 +501,7 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
> >  #
> >  CONFIG_RTE_KCP_KMOD=y
> >  CONFIG_RTE_KCP_KO_DEBUG=n
> > +CONFIG_RTE_LIBRTE_CTRL_IF=y
> > 
> >  #
> >  # Compile vhost library
> > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> > index 7a91001..214d16e 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),
> > +  [control interface]  (@ref rte_ctrl_if.h)
> > diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
> > index 57e8b5d..fd69bf1 100644
> > --- a/doc/api/doxy-api.conf
> > +++ b/doc/api/doxy-api.conf
> > @@ -39,6 +39,7 @@ INPUT                   = doc/api/doxy-api-index.md \
> >                            lib/librte_cmdline \
> >                            lib/librte_compat \
> >                            lib/librte_cryptodev \
> > +                          lib/librte_ctrl_if \
> >                            lib/librte_distributor \
> >                            lib/librte_ether \
> >                            lib/librte_hash \
> > diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> > index 27fc624..1b1d34c 100644
> > --- a/doc/guides/rel_notes/release_16_04.rst
> > +++ b/doc/guides/rel_notes/release_16_04.rst
> > @@ -39,6 +39,14 @@ This section should contain new features added in this release. Sample format:
> > 
> >    Enabled virtio 1.0 support for virtio pmd driver.
> > 
> > +* **Control interface support added.**
> > +
> > +  To enable controlling DPDK ports by common Linux tools.
> > +  Following modules added to DPDK:
> > +
> > +  * librte_ctrl_if library
> > +  * librte_eal/linuxapp/kcp kernel module
> > +
> > 
> >  Resolved Issues
> >  ---------------
> > @@ -113,6 +121,7 @@ The libraries prepended with a plus sign were incremented in this version.
> >       librte_acl.so.2
> >       librte_cfgfile.so.2
> >       librte_cmdline.so.1
> > +   + librte_ctrl_if.so.1
> >       librte_distributor.so.1
> >       librte_eal.so.2
> >       librte_hash.so.2
> > diff --git a/lib/Makefile b/lib/Makefile
> > index ef172ea..a50bc1e 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -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
> > @@ -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_CTRL_IF) += librte_ctrl_if
> > 
> >  ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
> >  DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
> > diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
> > new file mode 100644
> > index 0000000..4e82966
> > --- /dev/null
> > +++ b/lib/librte_ctrl_if/Makefile
> > @@ -0,0 +1,58 @@
> > +#   BSD LICENSE
> > +#
> > +#   Copyright(c) 2016 Intel Corporation. All rights reserved.
> > +#   All rights reserved.
> > +#
> > +#   Redistribution and use in source and binary forms, with or without
> > +#   modification, are permitted provided that the following conditions
> > +#   are met:
> > +#
> > +#     * Redistributions of source code must retain the above copyright
> > +#       notice, this list of conditions and the following disclaimer.
> > +#     * Redistributions in binary form must reproduce the above copyright
> > +#       notice, this list of conditions and the following disclaimer in
> > +#       the documentation and/or other materials provided with the
> > +#       distribution.
> > +#     * Neither the name of Intel Corporation nor the names of its
> > +#       contributors may be used to endorse or promote products derived
> > +#       from this software without specific prior written permission.
> > +#
> > +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > +
> > +include $(RTE_SDK)/mk/rte.vars.mk
> > +
> > +#
> > +# library name
> > +#
> > +LIB = librte_ctrl_if.a
> > +
> > +CFLAGS += -O3
> > +CFLAGS += $(WERROR_FLAGS)
> > +
> > +EXPORT_MAP := rte_ctrl_if_version.map
> > +
> > +LIBABIVER := 1
> > +
> > +SRCS-y += rte_ctrl_if.c
> > +SRCS-y += rte_nl.c
> > +SRCS-y += rte_ethtool.c
> > +
> > +#
> > +# Export include files
> > +#
> > +SYMLINK-y-include += rte_ctrl_if.h
> > +
> > +# this lib depends upon:
> > +DEPDIRS-y += lib/librte_ether
> > +
> > +include $(RTE_SDK)/mk/rte.lib.mk
> > diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
> > new file mode 100644
> > index 0000000..d16398f
> > --- /dev/null
> > +++ b/lib/librte_ctrl_if/rte_ctrl_if.c
> > @@ -0,0 +1,385 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 Intel Corporation. All rights reserved.
> > + *   All rights reserved.
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of Intel Corporation nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <fcntl.h>
> > +#include <unistd.h>
> > +#include <time.h>
> > +
> > +#include <sys/ioctl.h>
> > +#include <sys/socket.h>
> > +#include <linux/netlink.h>
> > +#include <linux/rtnetlink.h>
> > +
> > +#include <rte_ethdev.h>
> > +#include "rte_ctrl_if.h"
> > +#include "rte_nl.h"
> > +
> > +#define NAMESZ 32
> > +#define IFNAME "dpdk"
> > +#define BUFSZ 1024
> > +
> > +static int kcp_rtnl_fd = -1;
> > +static int kcp_fd_ref;
> > +
> > +struct kcp_request {
> > +	struct nlmsghdr nlmsg;
> > +	char buf[BUFSZ];
> > +};
> > +
> > +static int
> > +conrol_interface_rtnl_init(void)
> > +{
> > +	struct sockaddr_nl src;
> > +	int ret;
> > +
> > +	kcp_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> > +	if (kcp_rtnl_fd < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "socket for create failed.\n");
> > +		return -1;
> > +	}
> > +
> > +	memset(&src, 0, sizeof(struct sockaddr_nl));
> > +
> > +	src.nl_family = AF_NETLINK;
> > +	src.nl_pid = getpid();
> > +
> > +	ret = bind(kcp_rtnl_fd, (struct sockaddr *)&src,
> > +			sizeof(struct sockaddr_nl));
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Bind for create failed.\n");
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +control_interface_init(void)
> > +{
> > +	int ret;
> > +
> > +	ret = conrol_interface_rtnl_init();
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink.\n");
> > +		return -1;
> > +	}
> > +
> > +	ret = control_interface_nl_init();
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink.\n");
> > +		close(kcp_rtnl_fd);
> > +		kcp_rtnl_fd = -1;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int
> > +control_interface_ref_get(void)
> > +{
> > +	int ret = 0;
> > +
> > +	if (kcp_fd_ref == 0)
> > +		ret = control_interface_init();
> > +
> > +	if (ret == 0)
> > +		kcp_fd_ref++;
> > +	else
> > +		RTE_LOG(ERR, CTRL_IF,
> > +				"Failed to initialize control interface.\n");
> > +
> > +	return kcp_fd_ref;
> > +}
> > +
> > +static void
> > +control_interface_release(void)
> > +{
> > +	close(kcp_rtnl_fd);
> > +	control_interface_nl_release();
> > +}
> > +
> > +static int
> > +control_interface_ref_put(void)
> > +{
> > +	if (kcp_fd_ref == 0)
> > +		return 0;
> > +
> > +	kcp_fd_ref--;
> > +
> > +	if (kcp_fd_ref == 0)
> > +		control_interface_release();
> > +
> > +	return kcp_fd_ref;
> > +}
> > +
> > +static int
> > +add_attr(struct kcp_request *req, unsigned short type, void *buf, size_t len)
> > +{
> > +	struct rtattr *rta;
> > +	int nlmsg_len;
> > +
> > +	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
> > +	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
> > +	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct kcp_request))
> > +		return -1;
> > +	rta->rta_type = type;
> > +	rta->rta_len = RTA_LENGTH(len);
> > +	memcpy(RTA_DATA(rta), buf, len);
> > +	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct
> > +rtattr *add_attr_nested(struct kcp_request *req, unsigned short type)
> > +{
> > +	struct rtattr *rta;
> > +	int nlmsg_len;
> > +
> > +	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
> > +	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
> > +	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct kcp_request))
> > +		return NULL;
> > +	rta->rta_type = type;
> > +	rta->rta_len = nlmsg_len;
> > +	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
> > +
> > +	return rta;
> > +}
> > +
> > +static void
> > +end_attr_nested(struct kcp_request *req, struct rtattr *rta)
> > +{
> > +	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
> > +}
> > +
> > +static int
> > +rte_eth_rtnl_create(uint8_t port_id)
> > +{
> > +	struct kcp_request req;
> > +	struct ifinfomsg *info;
> > +	struct rtattr *rta1;
> > +	struct rtattr *rta2;
> > +	unsigned int pid = getpid();
> > +	char name[NAMESZ];
> > +	char type[NAMESZ];
> > +	struct iovec iov;
> > +	struct msghdr msg;
> > +	struct sockaddr_nl nladdr;
> > +	int ret;
> > +	char buf[BUFSZ];
> > +
> > +	memset(&req, 0, sizeof(struct kcp_request));
> > +
> > +	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
> > +	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
> > +	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
> > +	req.nlmsg.nlmsg_type = RTM_NEWLINK;
> > +
> > +	info = NLMSG_DATA(&req.nlmsg);
> > +
> > +	info->ifi_family = AF_UNSPEC;
> > +	info->ifi_index = 0;
> > +
> > +	snprintf(name, NAMESZ, IFNAME"%u", port_id);
> > +	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
> > +	if (ret < 0)
> > +		return -1;
> > +
> > +	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
> > +	if (rta1 == NULL)
> > +		return -1;
> > +
> > +	snprintf(type, NAMESZ, KCP_DEVICE);
> > +	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
> > +	if (ret < 0)
> > +		return -1;
> > +
> > +	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
> > +	if (rta2 == NULL)
> > +		return -1;
> > +
> > +	ret = add_attr(&req, IFLA_KCP_PORTID, &port_id, sizeof(uint8_t));
> > +	if (ret < 0)
> > +		return -1;
> > +
> > +	ret = add_attr(&req, IFLA_KCP_PID, &pid, sizeof(unsigned int));
> > +	if (ret < 0)
> > +		return -1;
> > +
> > +	end_attr_nested(&req, rta2);
> > +	end_attr_nested(&req, rta1);
> > +
> > +	memset(&nladdr, 0, sizeof(nladdr));
> > +	nladdr.nl_family = AF_NETLINK;
> > +
> > +	iov.iov_base = (void *)&req.nlmsg;
> > +	iov.iov_len = req.nlmsg.nlmsg_len;
> > +
> > +	memset(&msg, 0, sizeof(struct msghdr));
> > +	msg.msg_name = &nladdr;
> > +	msg.msg_namelen = sizeof(nladdr);
> > +	msg.msg_iov = &iov;
> > +	msg.msg_iovlen = 1;
> > +
> > +	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
> > +		return -1;
> > +	}
> > +
> > +	memset(buf, 0, sizeof(buf));
> > +	iov.iov_base = buf;
> > +	iov.iov_len = sizeof(buf);
> > +
> > +	ret = recvmsg(kcp_rtnl_fd, &msg, 0);
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Recv for create failed.\n");
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> It is probably would be good to make
> rte_eth_control_interface_create_one()/rte_eth_control_interface_destroy_one()
> a public API, so the user can decide which ports to expose to KCP, which not.
> If that is not possible by some reason - then seems no reason to keep 
> control_interface_ref_get/ control_interface_ref_put.
> 
It is easy to make them public, they are already as seperate functions,
but my concern is to make it more complex, right now this lib has only three APIs: create, destroy, process; simple.
and there is no overhead of having all interface instead of one.
When they are added as API, it is hard to remove them, is it OK if we kept as it is, and add those APIs if there is any demand?

> > +static int
> > +rte_eth_control_interface_create_one(uint8_t port_id)
> > +{
> > +	int ret;
> > +
> > +	if (control_interface_ref_get() != 0) {
> > +		ret = rte_eth_rtnl_create(port_id);
> > +		RTE_LOG(DEBUG, CTRL_IF,
> > +			"Control interface %s for port:%u\n",
> > +			ret < 0 ? "failed" : "created", port_id);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +int
> > +rte_eth_control_interface_create(void)
> > +{
> > +	int i;
> > +	int ret = 0;
> > +
> > +	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> > +		if (rte_eth_dev_is_valid_port(i)) {
> > +			ret = rte_eth_control_interface_create_one(i);
> > +			if (ret < 0)
> > +				return ret;
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int
> > +rte_eth_rtnl_destroy(uint8_t port_id)
> > +{
> > +	struct kcp_request req;
> > +	struct ifinfomsg *info;
> > +	char name[NAMESZ];
> > +	struct iovec iov;
> > +	struct msghdr msg;
> > +	struct sockaddr_nl nladdr;
> > +	int ret;
> > +
> > +	memset(&req, 0, sizeof(struct kcp_request));
> > +
> > +	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
> > +	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
> > +	req.nlmsg.nlmsg_type = RTM_DELLINK;
> > +
> > +	info = NLMSG_DATA(&req.nlmsg);
> > +
> > +	info->ifi_family = AF_UNSPEC;
> > +	info->ifi_index = 0;
> > +
> > +	snprintf(name, NAMESZ, IFNAME"%u", port_id);
> > +	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
> > +	if (ret < 0)
> > +		return -1;
> > +
> > +	memset(&nladdr, 0, sizeof(nladdr));
> > +	nladdr.nl_family = AF_NETLINK;
> > +
> > +	iov.iov_base = (void *)&req.nlmsg;
> > +	iov.iov_len = req.nlmsg.nlmsg_len;
> > +
> > +	memset(&msg, 0, sizeof(struct msghdr));
> > +	msg.msg_name = &nladdr;
> > +	msg.msg_namelen = sizeof(nladdr);
> > +	msg.msg_iov = &iov;
> > +	msg.msg_iovlen = 1;
> > +
> > +	ret = sendmsg(kcp_rtnl_fd, &msg, 0);
> > +	if (ret < 0) {
> > +		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed.\n");
> > +		return -1;
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int
> > +rte_eth_control_interface_destroy_one(uint8_t port_id)
> > +{
> > +	rte_eth_rtnl_destroy(port_id);
> > +	control_interface_ref_put();
> > +	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
> > +			port_id);
> > +
> > +	return 0;
> > +}
> > +
> > +int
> > +rte_eth_control_interface_destroy(void)
> > +{
> > +	int i;
> > +	int ret = 0;
> > +
> > +	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> > +		if (rte_eth_dev_is_valid_port(i)) {
> > +			ret = rte_eth_control_interface_destroy_one(i);
> > +			if (ret < 0)
> > +				return ret;
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +int
> > +rte_eth_control_interface_process_msg(int flag, unsigned int timeout_sec)
> > +{
> > +	return control_interface_process_msg(flag, timeout_sec);
> > +}
> > +};
> ....
> 
> > diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
> > new file mode 100644
> > index 0000000..adc5fa8
> > --- /dev/null
> > +++ b/lib/librte_ctrl_if/rte_nl.c
> > @@ -0,0 +1,274 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 Intel Corporation. All rights reserved.
> > + *   All rights reserved.
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of Intel Corporation nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <unistd.h>
> > +
> > +#include <sys/socket.h>
> > +#include <linux/netlink.h>
> > +
> > +#include <rte_spinlock.h>
> > +#include <rte_ethdev.h>
> > +#include "rte_ethtool.h"
> > +#include "rte_nl.h"
> > +#include "rte_ctrl_if.h"
> > +
> > +#define MAX_PAYLOAD sizeof(struct kcp_ethtool_msg)
> > +
> > +struct ctrl_if_nl {
> > +	union {
> > +		struct nlmsghdr nlh;
> > +		uint8_t nlmsg[NLMSG_SPACE(MAX_PAYLOAD)];
> > +	};
> > +	struct msghdr msg;
> > +	struct iovec iov;
> > +};
> > +
> > +static int sock_fd = -1;
> > +pthread_t thread_id;
> > +
> > +struct sockaddr_nl dest_addr;
> > +
> > +pthread_cond_t cond  = PTHREAD_COND_INITIALIZER;
> > +pthread_mutex_t msg_lock = PTHREAD_MUTEX_INITIALIZER;
> 
> Could you group related global variables into some struct.
> Then at least people would realise what lock and cond are supposed to synchronise.
OK

> Another good thing to do - make them static, if possible. 
> 
Right, I will make them static.

> > +
> > +static struct ctrl_if_nl nl_s;
> > +static struct ctrl_if_nl nl_r;
> > +
> > +static int kcp_ethtool_msg_count;
> > +static struct kcp_ethtool_msg msg_storage;
> > +
> > +static int
> > +nl_send(void *buf, size_t len)
> > +{
> > +	int ret;
> > +
> > +	if (nl_s.nlh.nlmsg_len < len) {
> > +		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
> > +		return -1;
> > +	}
> > +
> > +	if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) {
> > +		RTE_LOG(ERR, CTRL_IF, "Message is not OK\n");
> > +		return -1;
> > +	}
> > +
> > +	/* Fill in the netlink message payload */
> > +	memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len);
> > +
> > +	ret = sendmsg(sock_fd, &nl_s.msg, 0);
> > +
> > +	if (ret < 0)
> > +		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
> > +				ret, errno);
> > +	return ret;
> > +}
> > +
> > +static int
> > +nl_ethtool_msg_send(struct kcp_ethtool_msg *msg)
> > +{
> > +	return nl_send((void *)msg, sizeof(struct kcp_ethtool_msg));
> > +}
> > +
> > +static void
> > +process_msg(struct kcp_ethtool_msg *msg)
> > +{
> > +	if (msg->cmd_id > RTE_KCP_REQ_UNKNOWN) {
> > +		msg->err = rte_eth_dev_control_process(msg->cmd_id,
> > +				msg->port_id, msg->input_buffer,
> > +				msg->output_buffer, &msg->output_buffer_len);
> > +	} else {
> > +		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
> > +				msg->port_id, msg->input_buffer,
> > +				msg->output_buffer, &msg->output_buffer_len);
> > +	}
> > +
> > +	if (msg->err)
> > +		memset(msg->output_buffer, 0, msg->output_buffer_len);
> > +
> > +	nl_ethtool_msg_send(msg);
> > +}
> > +
> > +int
> > +control_interface_process_msg(int flag, unsigned int timeout_sec)
> > +{
> > +	int ret = 0;
> > +	struct timespec ts;
> > +
> > +	pthread_mutex_lock(&msg_lock);
> > +
> > +	clock_gettime(CLOCK_REALTIME, &ts);
> > +	ts.tv_sec += timeout_sec;
> > +	while (timeout_sec && !kcp_ethtool_msg_count && !ret)
> > +		ret = pthread_cond_timedwait(&cond, &msg_lock, &ts);
> 
> 
> Better to avoid holding lock while calling process_msg().
> That is a good programming practice, as msg_lock protects only contents of the msg_storage.
> Again if by some reason process() would take a while, wouldn't stop your control thread. 
> lock(); copy_message_into_local_buffer; unlock(); process();
> 
OK

> > +
> > +	switch (flag) {
> > +	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
> > +		if (kcp_ethtool_msg_count) {
> > +			process_msg(&msg_storage);
> > +			kcp_ethtool_msg_count = 0;
> > +		}
> > +		ret = 0;
> > +		break;
> > +
> > +	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
> > +		if (kcp_ethtool_msg_count) {
> > +			msg_storage.err = -1;
> > +			nl_ethtool_msg_send(&msg_storage);
> > +			kcp_ethtool_msg_count = 0;
> > +		}
> > +		ret = 0;
> > +		break;
> > +
> > +	default:
> > +		ret = -1;
> > +		break;
> > +	}
> > +	pthread_mutex_unlock(&msg_lock);
> > +
> > +	return ret;
> > +}
> > +

Thanks,
ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
  2016-02-14 22:17  8%   ` [dpdk-dev] [PATCH v8 4/4] doc: update with link changes Marc Sune
@ 2016-02-18 18:14  0%     ` Mcnamara, John
  2016-02-28 22:17  0%       ` Marc
  0 siblings, 1 reply; 200+ results
From: Mcnamara, John @ 2016-02-18 18:14 UTC (permalink / raw)
  To: Marc Sune, dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Hi,

Some minor comments below in order to get a consistent set of release notes.

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
> Sent: Sunday, February 14, 2016 10:18 PM
> To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; Harish Patil <harish.patil@qlogic.com>; Chen,
> Jing D <jing.d.chen@intel.com>
> Subject: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
> 
> Add new features, ABI changes and resolved issues notice for the
> refactored link patch.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  doc/guides/rel_notes/release_2_3.rst | 102

This should be rebased and the notes added to doc/guides/rel_notes/release_16_04.rst.


> +
> +* **ethdev: define a set of advertised link speeds.**

The title and the text should be in the past tense.


See the hints/guidelines in the updated release notes:

    http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst


> +
> +  Allowing to define a set of advertised speeds for auto-negociation,

Maybe something like: Added functionality to allow the definition of advertised speeds for ...



> +* **ethdev: add speed_cap bitmap to recover eth device link speed
> +capabilities
> +  define a set of advertised link speeds.**

The title is a little long. Just give a brief overview here and more the detail
to the text sections.

> +
> +  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows
> + the  application to recover the supported speeds for that ethernet
> device.

It would be good to use ```` quotes on speed_cap as well for consistency.


+
> +Examples
> +~~~~~~~~
> +
> +* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical
> +speeds  to bitmap fields.

I don't think this should be in the "Examples" section. Maybe as a sub-item
in the "New Featrues" or in "API Changes" if it is a change.

> +
> +ABI Changes
> +-----------
> +
> +* The ethdev rte_eth_link and rte_eth_conf structures were changed to
> +  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
> +
> +* The ethdev rte_eth_dev_info was changed to support device speed
> capabilities.

Better to put the struct names and variables in ```` quotes.

Thanks,

John.
- 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH RFC 2/4] vhost: make buf vector for scatter RX local.
  @ 2016-02-19  7:06  3%   ` Yuanhan Liu
  2016-02-19  7:30  0%     ` Ilya Maximets
  0 siblings, 1 reply; 200+ results
From: Yuanhan Liu @ 2016-02-19  7:06 UTC (permalink / raw)
  To: Ilya Maximets; +Cc: dev, Dyasly Sergey

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.

	--yliu

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH RFC 2/4] vhost: make buf vector for scatter RX local.
  2016-02-19  7:06  3%   ` Yuanhan Liu
@ 2016-02-19  7:30  0%     ` Ilya Maximets
  2016-02-19  8:10  3%       ` Xie, Huawei
  0 siblings, 1 reply; 200+ results
From: Ilya Maximets @ 2016-02-19  7:30 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, Dyasly Sergey

On 19.02.2016 10:06, 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.

Should I prepare version of this patch with field above marked as
deprecated and add note to doc/guides/rel_notes/release_16_04.rst
about future deletion?

Best regards, Ilya Maximets.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v5 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  @ 2016-02-19  7:31 15%     ` Xutao Sun
    1 sibling, 0 replies; 200+ results
From: Xutao Sun @ 2016-02-19  7:31 UTC (permalink / raw)
  To: dev

Change the fields of outer_mac and inner_mac 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      |  2 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 35 +++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.c              | 12 +++++-----
 lib/librte_ether/rte_eth_ctrl.h             |  4 ++--
 6 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..c707318 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6640,8 +6640,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 e94d4a2..a895364 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -32,11 +32,6 @@ 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 eb1b3b2..2588225 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -104,6 +104,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.
 
 Shared Library Versions
 -----------------------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..3ee629a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -553,7 +553,37 @@ tunnel_filter add
 Add a tunnel filter on a port::
 
    testpmd> tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) \
-            (inner_vlan) (tunnel_type) (filter_type) (tenant_id) (queue_id)
+            (inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|\
+            imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)
+
+The available information categories are:
+
+* ``vxlan``: Set tunnel type as VXLAN.
+
+* ``nvgre``: Set tunnel type as NVGRE.
+
+* ``ipingre``: Set tunnel type as IP-in-GRE.
+
+* ``imac-ivlan``: Set filter type as Inner MAC and VLAN.
+
+* ``imac-ivlan-tenid``: Set filter type as Inner MAC, VLAN and tenant ID.
+
+* ``imac-tenid``: Set filter type as Inner MAC and tenant ID.
+
+* ``imac``: Set filter type as Inner MAC.
+
+* ``omac-imac-tenid``: Set filter type as Outer MAC, Inner MAC and tenant ID.
+
+* ``oip``: Set filter type as Outer IP.
+
+* ``iip``: Set filter type as Inner IP.
+
+Example::
+
+   testpmd> tunnel_filter add 0 68:05:CA:28:09:82 00:00:00:00:00:00 \
+            192.168.2.2 0 ipingre oip 1 1
+
+   Set an IP-in-GRE tunnel on port 0, and the filter type is Outer IP.
 
 tunnel_filter remove
 ~~~~~~~~~~~~~~~~~~~~
@@ -561,7 +591,8 @@ tunnel_filter remove
 Remove a tunnel filter on a port::
 
    testpmd> tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) \
-            (inner_vlan) (tunnel_type) (filter_type) (tenant_id) (queue_id)
+            (inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|\
+            imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)
 
 rx_vxlan_port add
 ~~~~~~~~~~~~~~~~~
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..7c22358 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5828,10 +5828,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) {
@@ -6131,13 +6131,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 ce224ad..30cbde7 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 {
-- 
1.9.3

^ permalink raw reply	[relevance 15%]

* Re: [dpdk-dev] [PATCH RFC 2/4] vhost: make buf vector for scatter RX local.
  2016-02-19  7:30  0%     ` Ilya Maximets
@ 2016-02-19  8:10  3%       ` Xie, Huawei
  0 siblings, 0 replies; 200+ results
From: Xie, Huawei @ 2016-02-19  8:10 UTC (permalink / raw)
  To: Ilya Maximets, Yuanhan Liu; +Cc: dev, Dyasly Sergey

On 2/19/2016 3:31 PM, Ilya Maximets wrote:
> On 19.02.2016 10:06, 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.
> Should I prepare version of this patch with field above marked as
> deprecated and add note to doc/guides/rel_notes/release_16_04.rst
> about future deletion?

Ilya, you could follow the ABI process:
http://dpdk.org/doc/guides/contributing/versioning.html

>
> Best regards, Ilya Maximets.
>


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH RFC v2 2/3] vhost: make buf vector for scatter RX local.
  @ 2016-02-19 10:56  4% ` Ilya Maximets
  0 siblings, 0 replies; 200+ results
From: Ilya Maximets @ 2016-02-19 10:56 UTC (permalink / raw)
  To: dev, Huawei Xie, Yuanhan Liu; +Cc: Ilya Maximets, Dyasly Sergey

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().
buf_vec field of struct vhost_virtqueue marked as deprecated.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 doc/guides/rel_notes/deprecation.rst |  1 +
 lib/librte_vhost/rte_virtio_net.h    |  2 +-
 lib/librte_vhost/vhost_rxtx.c        | 45 ++++++++++++++++++------------------
 3 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..40f350d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -7,6 +7,7 @@ API and ABI deprecation notices are to be posted here.
 
 Deprecation Notices
 -------------------
+* Field buf_vec of struct vhost_virtqueue have been deprecated.
 
 * The following fields have been deprecated in rte_eth_stats:
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
index 10dcb90..db05d68 100644
--- a/lib/librte_vhost/rte_virtio_net.h
+++ b/lib/librte_vhost/rte_virtio_net.h
@@ -91,7 +91,7 @@ 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. */
+	struct buf_vector       buf_vec[BUF_VECTOR_MAX] __rte_deprecated;        /**< @deprecated Buffer for scatter RX. */
 } __rte_cache_aligned;
 
 
diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 411dd95..9095fb1 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -295,7 +295,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 static inline uint32_t __attribute__((always_inline))
 copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 			uint16_t res_base_idx, uint16_t res_end_idx,
-			struct rte_mbuf *pkt)
+			struct rte_mbuf *pkt, struct buf_vector *buf_vec)
 {
 	uint32_t vec_idx = 0;
 	uint32_t entry_success = 0;
@@ -325,7 +325,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 	 */
 	vq = dev->virtqueue[queue_id];
 
-	vb_addr = gpa_to_vva(dev, vq->buf_vec[vec_idx].buf_addr);
+	vb_addr = gpa_to_vva(dev, buf_vec[vec_idx].buf_addr);
 	vb_hdr_addr = vb_addr;
 
 	/* Prefetch buffer address. */
@@ -345,19 +345,19 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 	seg_avail = rte_pktmbuf_data_len(pkt);
 	vb_offset = vq->vhost_hlen;
-	vb_avail = vq->buf_vec[vec_idx].buf_len - vq->vhost_hlen;
+	vb_avail = buf_vec[vec_idx].buf_len - vq->vhost_hlen;
 
 	entry_len = vq->vhost_hlen;
 
 	if (vb_avail == 0) {
 		uint32_t desc_idx =
-			vq->buf_vec[vec_idx].desc_idx;
+			buf_vec[vec_idx].desc_idx;
 
 		if ((vq->desc[desc_idx].flags
 			& VRING_DESC_F_NEXT) == 0) {
 			/* Update used ring with desc information */
 			vq->used->ring[cur_idx & (vq->size - 1)].id
-				= vq->buf_vec[vec_idx].desc_idx;
+				= buf_vec[vec_idx].desc_idx;
 			vq->used->ring[cur_idx & (vq->size - 1)].len
 				= entry_len;
 
@@ -367,12 +367,12 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 		}
 
 		vec_idx++;
-		vb_addr = gpa_to_vva(dev, vq->buf_vec[vec_idx].buf_addr);
+		vb_addr = gpa_to_vva(dev, buf_vec[vec_idx].buf_addr);
 
 		/* Prefetch buffer address. */
 		rte_prefetch0((void *)(uintptr_t)vb_addr);
 		vb_offset = 0;
-		vb_avail = vq->buf_vec[vec_idx].buf_len;
+		vb_avail = buf_vec[vec_idx].buf_len;
 	}
 
 	cpy_len = RTE_MIN(vb_avail, seg_avail);
@@ -399,11 +399,11 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 			 * entry reach to its end.
 			 * But the segment doesn't complete.
 			 */
-			if ((vq->desc[vq->buf_vec[vec_idx].desc_idx].flags &
+			if ((vq->desc[buf_vec[vec_idx].desc_idx].flags &
 				VRING_DESC_F_NEXT) == 0) {
 				/* Update used ring with desc information */
 				vq->used->ring[cur_idx & (vq->size - 1)].id
-					= vq->buf_vec[vec_idx].desc_idx;
+					= buf_vec[vec_idx].desc_idx;
 				vq->used->ring[cur_idx & (vq->size - 1)].len
 					= entry_len;
 				entry_len = 0;
@@ -413,9 +413,9 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 			vec_idx++;
 			vb_addr = gpa_to_vva(dev,
-				vq->buf_vec[vec_idx].buf_addr);
+				buf_vec[vec_idx].buf_addr);
 			vb_offset = 0;
-			vb_avail = vq->buf_vec[vec_idx].buf_len;
+			vb_avail = buf_vec[vec_idx].buf_len;
 			cpy_len = RTE_MIN(vb_avail, seg_avail);
 		} else {
 			/*
@@ -434,7 +434,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 					 * from buf_vec.
 					 */
 					uint32_t desc_idx =
-						vq->buf_vec[vec_idx].desc_idx;
+						buf_vec[vec_idx].desc_idx;
 
 					if ((vq->desc[desc_idx].flags &
 						VRING_DESC_F_NEXT) == 0) {
@@ -456,9 +456,9 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 					/* Get next buffer from buf_vec. */
 					vec_idx++;
 					vb_addr = gpa_to_vva(dev,
-						vq->buf_vec[vec_idx].buf_addr);
+						buf_vec[vec_idx].buf_addr);
 					vb_avail =
-						vq->buf_vec[vec_idx].buf_len;
+						buf_vec[vec_idx].buf_len;
 					vb_offset = 0;
 				}
 
@@ -471,7 +471,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 				 */
 				/* Update used ring with desc information */
 				vq->used->ring[cur_idx & (vq->size - 1)].id
-					= vq->buf_vec[vec_idx].desc_idx;
+					= buf_vec[vec_idx].desc_idx;
 				vq->used->ring[cur_idx & (vq->size - 1)].len
 					= entry_len;
 				entry_success++;
@@ -485,7 +485,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 static inline void __attribute__((always_inline))
 update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
-	uint32_t *secure_len, uint32_t *vec_idx)
+	uint32_t *secure_len, uint32_t *vec_idx, struct buf_vector *buf_vec)
 {
 	uint16_t wrapped_idx = id & (vq->size - 1);
 	uint32_t idx = vq->avail->ring[wrapped_idx];
@@ -496,9 +496,9 @@ update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
 	do {
 		next_desc = 0;
 		len += vq->desc[idx].len;
-		vq->buf_vec[vec_id].buf_addr = vq->desc[idx].addr;
-		vq->buf_vec[vec_id].buf_len = vq->desc[idx].len;
-		vq->buf_vec[vec_id].desc_idx = idx;
+		buf_vec[vec_id].buf_addr = vq->desc[idx].addr;
+		buf_vec[vec_id].buf_len = vq->desc[idx].len;
+		buf_vec[vec_id].desc_idx = idx;
 		vec_id++;
 
 		if (vq->desc[idx].flags & VRING_DESC_F_NEXT) {
@@ -523,6 +523,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 	uint16_t avail_idx;
 	uint16_t res_base_idx, res_cur_idx;
 	uint8_t success = 0;
+	struct buf_vector buf_vec[BUF_VECTOR_MAX];
 
 	LOG_DEBUG(VHOST_DATA, "(%"PRIu64") virtio_dev_merge_rx()\n",
 		dev->device_fh);
@@ -561,8 +562,8 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 				if (unlikely(res_cur_idx == avail_idx))
 					goto merge_rx_exit;
 
-				update_secure_len(vq, res_cur_idx,
-						  &secure_len, &vec_idx);
+				update_secure_len(vq, res_cur_idx, &secure_len,
+						  &vec_idx, buf_vec);
 				res_cur_idx++;
 			} while (pkt_len > secure_len);
 
@@ -573,7 +574,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 		} while (success == 0);
 
 		entry_success = copy_from_mbuf_to_vring(dev, queue_id,
-			res_base_idx, res_cur_idx, pkts[pkt_idx]);
+			res_base_idx, res_cur_idx, pkts[pkt_idx], buf_vec);
 
 		rte_smp_wmb();
 
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages
  2016-02-16 14:48  4%   ` [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages David Hunt
@ 2016-02-19 13:33  7%     ` Olivier MATZ
  0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2016-02-19 13:33 UTC (permalink / raw)
  To: David Hunt, dev

Hi David,

On 02/16/2016 03:48 PM, David Hunt wrote:
> 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 | 240 ++++++++++++++++++++++++++++++++++++++-
>  lib/librte_mempool/rte_mempool.h |  68 ++++++++++-
>  6 files changed, 320 insertions(+), 2 deletions(-)

Given the size of this patch, I don't think it's worth adding the
NEXT ABI in that case.

Regards,
Olivier

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e
  @ 2016-02-22  3:59  3% ` Helin Zhang
  2016-02-22  3:59  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
                     ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Helin Zhang @ 2016-02-22  3:59 UTC (permalink / raw)
  To: dev; +Cc: zhe.tag

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.

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
  eal: remove pci config of extended tag
  igb_uio: deprecate sys files

 config/common_linuxapp                    |  1 +
 doc/guides/linux_gsg/enable_func.rst      | 47 ----------------
 doc/guides/nics/i40e.rst                  | 76 ++++++++++++++++++++++++++
 doc/guides/rel_notes/deprecation.rst      |  6 +++
 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   |  2 +
 lib/librte_eal/linuxapp/eal/eal_pci.c     | 90 +++----------------------------
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 72 +++----------------------
 10 files changed, 167 insertions(+), 205 deletions(-)
 create mode 100644 doc/guides/nics/i40e.rst

-- 
1.9.3

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files
  2016-02-22  3:59  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
@ 2016-02-22  3:59  6%   ` Helin Zhang
  2016-03-08 18:02  0%     ` Thomas Monjalon
  2016-02-22  5:52  0%   ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Wu, Jingjing
  2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 " Thomas Monjalon
  2 siblings, 1 reply; 200+ results
From: Helin Zhang @ 2016-02-22  3:59 UTC (permalink / raw)
  To: dev; +Cc: zhe.tag

It deprecated sys files of 'extended_tag' and
'max_read_request_size', and announced the planned ABI changes of
them.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/linux_gsg/enable_func.rst      | 47 -------------------
 doc/guides/nics/i40e.rst                  | 76 +++++++++++++++++++++++++++++++
 doc/guides/rel_notes/deprecation.rst      |  6 +++
 lib/librte_eal/common/include/rte_pci.h   |  2 +-
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 72 ++++-------------------------
 5 files changed, 91 insertions(+), 112 deletions(-)
 create mode 100644 doc/guides/nics/i40e.rst

v2:
 - 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'.

diff --git a/doc/guides/linux_gsg/enable_func.rst b/doc/guides/linux_gsg/enable_func.rst
index c3fa6d3..f59f25c 100644
--- a/doc/guides/linux_gsg/enable_func.rst
+++ b/doc/guides/linux_gsg/enable_func.rst
@@ -176,50 +176,3 @@ Also, if ``INTEL_IOMMU_DEFAULT_ON`` is not set in the kernel, the ``intel_iommu=
 This ensures that the Intel IOMMU is being initialized as expected.
 
 Please note that while using ``iommu=pt`` is compulsory for ``igb_uio driver``, the ``vfio-pci`` driver can actually work with both ``iommu=pt`` and ``iommu=on``.
-
-High Performance of Small Packets on 40G NIC
---------------------------------------------
-
-As there might be firmware fixes for performance enhancement in latest version
-of firmware image, the firmware update might be needed for getting high performance.
-Check with the local Intel's Network Division application engineers for firmware updates.
-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 and Setting Max Read Request Size
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-PCI configurations of ``extended_tag`` and max _read_requ st_size have big impacts on performance of small packets on 40G NIC.
-Enabling extended_tag and setting ``max_read_request_size`` to small size such as 128 bytes provide great helps to high performance of small packets.
-
-*   These can be done in some BIOS implementations.
-
-*   For other BIOS implementations, PCI configurations can be changed by using command of ``setpci``, or special configurations in DPDK config file of ``common_linux``.
-
-    *   Bits 7:5 at address of 0xA8 of each PCI device is used for setting the max_read_request_size,
-        and bit 8 of 0xA8 of each PCI device is used for enabling/disabling the extended_tag.
-        lspci and setpci can be used to read the values of 0xA8 and then write it back after being changed.
-
-    *   In config file of common_linux, below three configurations can be changed for the same purpose.
-
-        ``CONFIG_RTE_PCI_CONFIG``
-
-        ``CONFIG_RTE_PCI_EXTENDED_TAG``
-
-        ``CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE``
-
-Use 16 Bytes RX Descriptor Size
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As i40e PMD supports both 16 and 32 bytes RX descriptor sizes, and 16 bytes size can provide helps to high performance of small packets.
-Configuration of ``CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC`` in config files can be changed to use 16 bytes size RX descriptors.
-
-High Performance and per Packet Latency Tradeoff
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Due to the hardware design, the interrupt signal inside NIC is needed for per
-packet descriptor write-back. The minimum interval of interrupts could be set
-at compile time by ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` in configuration files.
-Though there is a default configuration, the interval could be tuned by the
-users with that configuration item depends on what the user cares about more,
-performance or per packet latency.
diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
new file mode 100644
index 0000000..b6f089f
--- /dev/null
+++ b/doc/guides/nics/i40e.rst
@@ -0,0 +1,76 @@
+..  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.
+
+I40E Poll Mode Driver
+=====================
+
+The I40E PMD (**librte_pmd_i40e**) provides poll mode driver support
+for **Intel X710/XL710/X722** 10/40 Gbps family of adapters.
+
+High performance of small packets
+---------------------------------
+
+As there might be firmware fixes or enhancements for performance in newer
+version of firmware images, firmware update might be necessary for getting
+high performance. In addition, host driver version is also important for
+DPDK VF performance if kernel PF driver is being used. Check with the local
+Intel Network Division application engineers for helps on firmware upgrade
+and kernel driver upgrade. Release 16.04 will be validated with NVM 5.xx.
+
+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
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As i40e PMD supports both 16 and 32 bytes RX descriptor sizes, and 16 bytes
+size may help a bit for high performance of small packet size. Configuration
+of ``CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC`` in config files can be changed
+to use 16 bytes size RX descriptors.
+
+High performance and per packet latency tradeoff
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to the hardware design, the interrupt signal inside NIC is needed for per
+packet descriptor write-back. The minimum interval of interrupts could be set
+at compile time by ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` in configuration
+files. Though there is a default configuration, the interval could be tuned by
+the users with that configuration item depends on what the user cares about
+more, performance or per packet latency.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..b7e0a4f 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 release 16.07. The eal function of
+  pci_config_space_set is deprecated in release 16.04, and will be removed
+  from 16.07. Macros of CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and
+  CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE will be removed. sysfile of extended_tag
+  and max_read_request_size created by kernel module igb_uio will be removed.
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 189d509..e4fb82d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -587,7 +587,7 @@ void rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
  *   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;
+void pci_config_space_set(struct rte_pci_device *dev);
 #endif /* RTE_PCI_CONFIG */
 
 #ifdef __cplusplus
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index f5617d2..01b4ca6 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -40,15 +40,6 @@
 
 #include "compat.h"
 
-#ifdef RTE_PCI_CONFIG
-#define PCI_SYS_FILE_BUF_SIZE      10
-#define PCI_DEV_CAP_REG            0xA4
-#define PCI_DEV_CTRL_REG           0xA8
-#define PCI_DEV_CAP_EXT_TAG_MASK   0x20
-#define PCI_DEV_CTRL_EXT_TAG_SHIFT 8
-#define PCI_DEV_CTRL_EXT_TAG_MASK  (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT)
-#endif
-
 /**
  * A structure describing the private information for a uio device.
  */
@@ -94,19 +85,9 @@ store_max_vfs(struct device *dev, struct device_attribute *attr,
 static ssize_t
 show_extended_tag(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	uint32_t val = 0;
+	dev_info(dev, "Deprecated\n");
 
-	pci_read_config_dword(pci_dev, PCI_DEV_CAP_REG, &val);
-	if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) /* Not supported */
-		return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n", "invalid");
-
-	val = 0;
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, &val);
-
-	return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n",
-		(val & PCI_DEV_CTRL_EXT_TAG_MASK) ? "on" : "off");
+	return 0;
 }
 
 static ssize_t
@@ -115,36 +96,9 @@ store_extended_tag(struct device *dev,
 		   const char *buf,
 		   size_t count)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	uint32_t val = 0, enable;
-
-	if (strncmp(buf, "on", 2) == 0)
-		enable = 1;
-	else if (strncmp(buf, "off", 3) == 0)
-		enable = 0;
-	else
-		return -EINVAL;
-
-	pci_cfg_access_lock(pci_dev);
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CAP_REG, &val);
-	if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) { /* Not supported */
-		pci_cfg_access_unlock(pci_dev);
-		return -EPERM;
-	}
+	dev_info(dev, "Deprecated\n");
 
-	val = 0;
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, &val);
-	if (enable)
-		val |= PCI_DEV_CTRL_EXT_TAG_MASK;
-	else
-		val &= ~PCI_DEV_CTRL_EXT_TAG_MASK;
-	pci_bus_write_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, val);
-	pci_cfg_access_unlock(pci_dev);
-
-	return count;
+	return 0;
 }
 
 static ssize_t
@@ -152,10 +106,9 @@ show_max_read_request_size(struct device *dev,
 			   struct device_attribute *attr,
 			   char *buf)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	int val = pcie_get_readrq(pci_dev);
+	dev_info(dev, "Deprecated\n");
 
-	return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%d\n", val);
+	return 0;
 }
 
 static ssize_t
@@ -164,18 +117,9 @@ store_max_read_request_size(struct device *dev,
 			    const char *buf,
 			    size_t count)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	unsigned long size = 0;
-	int ret;
+	dev_info(dev, "Deprecated\n");
 
-	if (0 != kstrtoul(buf, 0, &size))
-		return -EINVAL;
-
-	ret = pcie_set_readrq(pci_dev, (int)size);
-	if (ret < 0)
-		return ret;
-
-	return count;
+	return 0;
 }
 #endif
 
-- 
1.9.3

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e
  2016-02-22  3:59  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
  2016-02-22  3:59  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
@ 2016-02-22  5:52  0%   ` Wu, Jingjing
  2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 " Thomas Monjalon
  2 siblings, 0 replies; 200+ results
From: Wu, Jingjing @ 2016-02-22  5:52 UTC (permalink / raw)
  To: Zhang, Helin, dev; +Cc: zhe.tag



> -----Original Message-----
> From: Zhang, Helin
> Sent: Monday, February 22, 2016 12:00 PM
> To: dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; Wu, Jingjing; zhe.tag@intel.com; Zhang,
> Helin
> Subject: [PATCH v2 0/3] enable extended tag for i40e
> 
> 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.
> 
> 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
>   eal: remove pci config of extended tag
>   igb_uio: deprecate sys files

Agree to add a doc i40e.rst to record i40e specific stuff.
I also sent a patch http://dpdk.org/dev/patchwork/patch/10173/, it will be great if they can be merged.  :)

Acked-by: Jingjing Wu <jingjing.wu@intel.com>

> 
> --
> 1.9.3

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e
  @ 2016-02-22  6:31  3% ` Helin Zhang
  2016-02-22  6:31  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
  0 siblings, 1 reply; 200+ results
From: Helin Zhang @ 2016-02-22  6:31 UTC (permalink / raw)
  To: 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.

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
  eal: remove pci config of extended tag
  igb_uio: deprecate sys files

 config/common_linuxapp                    |  1 +
 doc/guides/linux_gsg/enable_func.rst      | 47 ----------------
 doc/guides/nics/i40e.rst                  | 76 ++++++++++++++++++++++++++
 doc/guides/rel_notes/deprecation.rst      |  6 +++
 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   |  2 +
 lib/librte_eal/linuxapp/eal/eal_pci.c     | 90 +++----------------------------
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 72 +++----------------------
 10 files changed, 167 insertions(+), 205 deletions(-)
 create mode 100644 doc/guides/nics/i40e.rst

-- 
1.9.3

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files
  2016-02-22  6:31  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
@ 2016-02-22  6:31  6%   ` Helin Zhang
  0 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2016-02-22  6:31 UTC (permalink / raw)
  To: dev

It deprecated sys files of 'extended_tag' and
'max_read_request_size', and announced the planned ABI changes of
them.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/linux_gsg/enable_func.rst      | 47 -------------------
 doc/guides/nics/i40e.rst                  | 76 +++++++++++++++++++++++++++++++
 doc/guides/rel_notes/deprecation.rst      |  6 +++
 lib/librte_eal/common/include/rte_pci.h   |  2 +-
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 72 ++++-------------------------
 5 files changed, 91 insertions(+), 112 deletions(-)
 create mode 100644 doc/guides/nics/i40e.rst

v2:
 - 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'.

diff --git a/doc/guides/linux_gsg/enable_func.rst b/doc/guides/linux_gsg/enable_func.rst
index c3fa6d3..f59f25c 100644
--- a/doc/guides/linux_gsg/enable_func.rst
+++ b/doc/guides/linux_gsg/enable_func.rst
@@ -176,50 +176,3 @@ Also, if ``INTEL_IOMMU_DEFAULT_ON`` is not set in the kernel, the ``intel_iommu=
 This ensures that the Intel IOMMU is being initialized as expected.
 
 Please note that while using ``iommu=pt`` is compulsory for ``igb_uio driver``, the ``vfio-pci`` driver can actually work with both ``iommu=pt`` and ``iommu=on``.
-
-High Performance of Small Packets on 40G NIC
---------------------------------------------
-
-As there might be firmware fixes for performance enhancement in latest version
-of firmware image, the firmware update might be needed for getting high performance.
-Check with the local Intel's Network Division application engineers for firmware updates.
-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 and Setting Max Read Request Size
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-PCI configurations of ``extended_tag`` and max _read_requ st_size have big impacts on performance of small packets on 40G NIC.
-Enabling extended_tag and setting ``max_read_request_size`` to small size such as 128 bytes provide great helps to high performance of small packets.
-
-*   These can be done in some BIOS implementations.
-
-*   For other BIOS implementations, PCI configurations can be changed by using command of ``setpci``, or special configurations in DPDK config file of ``common_linux``.
-
-    *   Bits 7:5 at address of 0xA8 of each PCI device is used for setting the max_read_request_size,
-        and bit 8 of 0xA8 of each PCI device is used for enabling/disabling the extended_tag.
-        lspci and setpci can be used to read the values of 0xA8 and then write it back after being changed.
-
-    *   In config file of common_linux, below three configurations can be changed for the same purpose.
-
-        ``CONFIG_RTE_PCI_CONFIG``
-
-        ``CONFIG_RTE_PCI_EXTENDED_TAG``
-
-        ``CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE``
-
-Use 16 Bytes RX Descriptor Size
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As i40e PMD supports both 16 and 32 bytes RX descriptor sizes, and 16 bytes size can provide helps to high performance of small packets.
-Configuration of ``CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC`` in config files can be changed to use 16 bytes size RX descriptors.
-
-High Performance and per Packet Latency Tradeoff
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Due to the hardware design, the interrupt signal inside NIC is needed for per
-packet descriptor write-back. The minimum interval of interrupts could be set
-at compile time by ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` in configuration files.
-Though there is a default configuration, the interval could be tuned by the
-users with that configuration item depends on what the user cares about more,
-performance or per packet latency.
diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
new file mode 100644
index 0000000..b6f089f
--- /dev/null
+++ b/doc/guides/nics/i40e.rst
@@ -0,0 +1,76 @@
+..  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.
+
+I40E Poll Mode Driver
+=====================
+
+The I40E PMD (**librte_pmd_i40e**) provides poll mode driver support
+for **Intel X710/XL710/X722** 10/40 Gbps family of adapters.
+
+High performance of small packets
+---------------------------------
+
+As there might be firmware fixes or enhancements for performance in newer
+version of firmware images, firmware update might be necessary for getting
+high performance. In addition, host driver version is also important for
+DPDK VF performance if kernel PF driver is being used. Check with the local
+Intel Network Division application engineers for helps on firmware upgrade
+and kernel driver upgrade. Release 16.04 will be validated with NVM 5.xx.
+
+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
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As i40e PMD supports both 16 and 32 bytes RX descriptor sizes, and 16 bytes
+size may help a bit for high performance of small packet size. Configuration
+of ``CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC`` in config files can be changed
+to use 16 bytes size RX descriptors.
+
+High performance and per packet latency tradeoff
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to the hardware design, the interrupt signal inside NIC is needed for per
+packet descriptor write-back. The minimum interval of interrupts could be set
+at compile time by ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` in configuration
+files. Though there is a default configuration, the interval could be tuned by
+the users with that configuration item depends on what the user cares about
+more, performance or per packet latency.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..b7e0a4f 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 release 16.07. The eal function of
+  pci_config_space_set is deprecated in release 16.04, and will be removed
+  from 16.07. Macros of CONFIG_RTE_PCI_CONFIG, CONFIG_RTE_PCI_EXTENDED_TAG and
+  CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE will be removed. sysfile of extended_tag
+  and max_read_request_size created by kernel module igb_uio will be removed.
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 189d509..e4fb82d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -587,7 +587,7 @@ void rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
  *   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;
+void pci_config_space_set(struct rte_pci_device *dev);
 #endif /* RTE_PCI_CONFIG */
 
 #ifdef __cplusplus
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index f5617d2..01b4ca6 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -40,15 +40,6 @@
 
 #include "compat.h"
 
-#ifdef RTE_PCI_CONFIG
-#define PCI_SYS_FILE_BUF_SIZE      10
-#define PCI_DEV_CAP_REG            0xA4
-#define PCI_DEV_CTRL_REG           0xA8
-#define PCI_DEV_CAP_EXT_TAG_MASK   0x20
-#define PCI_DEV_CTRL_EXT_TAG_SHIFT 8
-#define PCI_DEV_CTRL_EXT_TAG_MASK  (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT)
-#endif
-
 /**
  * A structure describing the private information for a uio device.
  */
@@ -94,19 +85,9 @@ store_max_vfs(struct device *dev, struct device_attribute *attr,
 static ssize_t
 show_extended_tag(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	uint32_t val = 0;
+	dev_info(dev, "Deprecated\n");
 
-	pci_read_config_dword(pci_dev, PCI_DEV_CAP_REG, &val);
-	if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) /* Not supported */
-		return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n", "invalid");
-
-	val = 0;
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, &val);
-
-	return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%s\n",
-		(val & PCI_DEV_CTRL_EXT_TAG_MASK) ? "on" : "off");
+	return 0;
 }
 
 static ssize_t
@@ -115,36 +96,9 @@ store_extended_tag(struct device *dev,
 		   const char *buf,
 		   size_t count)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	uint32_t val = 0, enable;
-
-	if (strncmp(buf, "on", 2) == 0)
-		enable = 1;
-	else if (strncmp(buf, "off", 3) == 0)
-		enable = 0;
-	else
-		return -EINVAL;
-
-	pci_cfg_access_lock(pci_dev);
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CAP_REG, &val);
-	if (!(val & PCI_DEV_CAP_EXT_TAG_MASK)) { /* Not supported */
-		pci_cfg_access_unlock(pci_dev);
-		return -EPERM;
-	}
+	dev_info(dev, "Deprecated\n");
 
-	val = 0;
-	pci_bus_read_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, &val);
-	if (enable)
-		val |= PCI_DEV_CTRL_EXT_TAG_MASK;
-	else
-		val &= ~PCI_DEV_CTRL_EXT_TAG_MASK;
-	pci_bus_write_config_dword(pci_dev->bus, pci_dev->devfn,
-					PCI_DEV_CTRL_REG, val);
-	pci_cfg_access_unlock(pci_dev);
-
-	return count;
+	return 0;
 }
 
 static ssize_t
@@ -152,10 +106,9 @@ show_max_read_request_size(struct device *dev,
 			   struct device_attribute *attr,
 			   char *buf)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	int val = pcie_get_readrq(pci_dev);
+	dev_info(dev, "Deprecated\n");
 
-	return snprintf(buf, PCI_SYS_FILE_BUF_SIZE, "%d\n", val);
+	return 0;
 }
 
 static ssize_t
@@ -164,18 +117,9 @@ store_max_read_request_size(struct device *dev,
 			    const char *buf,
 			    size_t count)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	unsigned long size = 0;
-	int ret;
+	dev_info(dev, "Deprecated\n");
 
-	if (0 != kstrtoul(buf, 0, &size))
-		return -EINVAL;
-
-	ret = pcie_set_readrq(pci_dev, (int)size);
-	if (ret < 0)
-		return ret;
-
-	return count;
+	return 0;
 }
 #endif
 
-- 
1.9.3

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH v2 4/6] bond mode 4: allow external state machine
  @ 2016-02-22 13:03  4%     ` Panu Matilainen
  2016-02-25 15:22  0%       ` Iremonger, Bernard
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-02-22 13:03 UTC (permalink / raw)
  To: Eric Kinzie, dev; +Cc: Eric Kinzie

On 02/19/2016 09:17 PM, Eric Kinzie wrote:
> From: Eric Kinzie <ekinzie@brocade.com>
>
> Provide functions to allow an external 802.3ad state machine to transmit
> and recieve LACPDUs and to set the collection/distribution flags on
> slave interfaces.
>
> Signed-off-by: Eric Kinzie <ehkinzie@gmail.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Declan Doherty <declan.doherty@intel.com>
[...]
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.h b/drivers/net/bonding/rte_eth_bond_8023ad.h
> index ebd0e93..8cfa3d3 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.h
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.h
> @@ -64,6 +64,8 @@ extern "C" {
>   #define MARKER_TLV_TYPE_INFO                0x01
>   #define MARKER_TLV_TYPE_RESP                0x02
>
> +typedef void (*rte_eth_bond_8023ad_ext_slowrx_fn)(uint8_t slave_id, struct rte_mbuf *lacp_pkt);
> +
>   enum rte_bond_8023ad_selection {
>   	UNSELECTED,
>   	STANDBY,
> @@ -157,6 +159,7 @@ struct rte_eth_bond_8023ad_conf {
>   	uint32_t tx_period_ms;
>   	uint32_t rx_marker_period_ms;
>   	uint32_t update_timeout_ms;
> +	rte_eth_bond_8023ad_ext_slowrx_fn slowrx_cb;
>   };

This still is a likely an ABI break, previously discussed around here:
http://dpdk.org/ml/archives/dev/2015-November/027321.html

It might not be embedded anywhere in DPDK codebase, but there's no 
telling what others might have done with it (have an array of them, 
embed in other structs etc).

Also ultimately ABI compatibility goes both ways: when the library 
soname does not change then an application is free to assume both 
downgrading and upgrading are safe. In this case, upgrading *might* be 
okay, downgrading certainly is not. So by that measure it definitely is 
an ABI break.

[...]
> diff --git a/drivers/net/bonding/rte_eth_bond_version.map b/drivers/net/bonding/rte_eth_bond_version.map
> index 22bd920..33d73ff 100644
> --- a/drivers/net/bonding/rte_eth_bond_version.map
> +++ b/drivers/net/bonding/rte_eth_bond_version.map
> @@ -27,3 +27,9 @@ DPDK_2.1 {
>   	rte_eth_bond_free;
>
>   } DPDK_2.0;
> +
> +DPDK_2.2 {
> +	rte_eth_bond_8023ad_ext_collect;
> +	rte_eth_bond_8023ad_ext_distrib;
> +	rte_eth_bond_8023ad_ext_slowtx;
> +} DPDK_2.1;
>

These symbols are not part of DPDK 2.2, the version here is wrong. 
Technically it would not actually matter much but better not to confuse 
things unnecessarily.

	- Panu -

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] config: remove duplicate configuration information
@ 2016-02-22 13:53  6% Keith Wiles
  2016-02-22 15:09  0% ` Trahe, Fiona
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Keith Wiles @ 2016-02-22 13:53 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                          | 498 ++++++++++++++++++++++++++++
 config/common_bsdapp                        | 436 +-----------------------
 config/common_linuxapp                      | 491 +--------------------------
 config/defconfig_x86_64-native-bsdapp-clang |   1 +
 config/defconfig_x86_64-native-bsdapp-gcc   |   1 +
 5 files changed, 518 insertions(+), 909 deletions(-)
 create mode 100644 config/common_base

diff --git a/config/common_base b/config/common_base
new file mode 100644
index 0000000..91a12eb
--- /dev/null
+++ b/config/common_base
@@ -0,0 +1,498 @@
+#   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.
+#
+
+#
+# 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=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
+
+#
+# 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=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
+# 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=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
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 696382c..de0ca7d 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,74 +37,38 @@
 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
+#include "common_base"
 
 #
-# Machine forces strict alignment constraints.
+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
 #
-CONFIG_RTE_ARCH_STRICT_ALIGN=n
+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
 
 #
-# Compile to share library
+# Compile Environment Abstraction Layer
 #
-CONFIG_RTE_BUILD_SHARED_LIB=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=n
 
 #
-# Combine to one single library
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
 #
-CONFIG_RTE_BUILD_COMBINE_LIBS=n
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
 
 #
-# Use newest code breaking previous ABI
+# Compile librte_power
 #
-CONFIG_RTE_NEXT_ABI=y
+CONFIG_RTE_LIBRTE_POWER=n
 
 #
-# Machine's cache line size
+# Compile librte_kni
 #
-CONFIG_RTE_CACHE_LINE_SIZE=64
+CONFIG_RTE_LIBRTE_KNI=n
 
 #
-# Compile Environment Abstraction Layer
+# Compile vhost library
 #
-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_VHOST=n
 
 #
 # FreeBSD contiguous memory driver settings
@@ -113,373 +77,3 @@ 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 f1638db..64ddbe9 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,494 +37,9 @@
 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
-
-#
-# 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=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
+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
 #
 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
-#
-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=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
-# 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=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
diff --git a/config/defconfig_x86_64-native-bsdapp-clang b/config/defconfig_x86_64-native-bsdapp-clang
index d2baf2c..8b870b3 100644
--- a/config/defconfig_x86_64-native-bsdapp-clang
+++ b/config/defconfig_x86_64-native-bsdapp-clang
@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
 CONFIG_RTE_ARCH="x86_64"
 CONFIG_RTE_ARCH_X86_64=y
 CONFIG_RTE_ARCH_X86=y
+CONFIG_RTE_ARCH_64=y
 
 CONFIG_RTE_TOOLCHAIN="clang"
 CONFIG_RTE_TOOLCHAIN_CLANG=y
diff --git a/config/defconfig_x86_64-native-bsdapp-gcc b/config/defconfig_x86_64-native-bsdapp-gcc
index 5a6a4e8..4ea4433 100644
--- a/config/defconfig_x86_64-native-bsdapp-gcc
+++ b/config/defconfig_x86_64-native-bsdapp-gcc
@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
 CONFIG_RTE_ARCH="x86_64"
 CONFIG_RTE_ARCH_X86_64=y
 CONFIG_RTE_ARCH_X86=y
+CONFIG_RTE_ARCH_64=y
 
 CONFIG_RTE_TOOLCHAIN="gcc"
 CONFIG_RTE_TOOLCHAIN_GCC=y
-- 
2.7.0

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-03 17:23  0%       ` Olivier MATZ
@ 2016-02-22 14:49  0%         ` Xie, Huawei
  2016-02-23  5:35  0%           ` Xie, Huawei
  0 siblings, 1 reply; 200+ results
From: Xie, Huawei @ 2016-02-22 14:49 UTC (permalink / raw)
  To: Olivier MATZ, Panu Matilainen, dev; +Cc: dprovan

On 2/4/2016 1:24 AM, Olivier MATZ wrote:
> Hi,
>
> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>>
>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
>> the library ABI and should not be listed in the version map.
>>
>> I assume its inline for performance reasons, but then you lose the
>> benefits of dynamic linking such as ability to fix bugs and/or improve
>> itby just updating the library. Since the point of having a bulk API is
>> to improve performance by reducing the number of calls required, does it
>> really have to be inline? As in, have you actually measured the
>> difference between inline and non-inline and decided its worth all the
>> downsides?
>
> Agree with Panu. It would be interesting to compare the performance
> between inline and non inline to decide whether inlining it or not.

Will update after i gathered more data. inline could show obvious
performance difference in some cases.

>
> Also, it would be nice to have a simple test function in
> app/test/test_mbuf.c. For instance, you could update
> test_one_pktmbuf() to take a mbuf pointer as a parameter and remove
> the mbuf allocation from the function. Then it could be called with
> a mbuf allocated with rte_pktmbuf_alloc() (like before) and with
> all the mbufs of rte_pktmbuf_alloc_bulk().
>
> Regards,
> Olivier
>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] config: remove duplicate configuration information
  2016-02-22 13:53  6% [dpdk-dev] [PATCH] config: remove duplicate configuration information Keith Wiles
@ 2016-02-22 15:09  0% ` Trahe, Fiona
  2016-02-22 16:02  0%   ` Wiles, Keith
  2016-02-24 13:58  0% ` Wiles, Keith
  2016-03-03 14:43  0% ` Wiles, Keith
  2 siblings, 1 reply; 200+ results
From: Trahe, Fiona @ 2016-02-22 15:09 UTC (permalink / raw)
  To: Wiles, Keith, dev

Hi Keith,

What makes a param common?

e.g.  cryptodev QAT PMD is supported in linux, but currently not supported in bsd.
So typically I disable it in the bsd file and enable it in the linux file.

Couldn't the same apply to any other parameter, i.e. there may be users who want to have differences in config for different OSs?

So why not just leave as is and give users the option to choose?

Regards,
Fiona


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Keith Wiles
> Sent: Monday, February 22, 2016 1:54 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH] config: remove duplicate configuration information
> 
> 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                          | 498 ++++++++++++++++++++++++++++
>  config/common_bsdapp                        | 436 +-----------------------
>  config/common_linuxapp                      | 491 +--------------------------
>  config/defconfig_x86_64-native-bsdapp-clang |   1 +
>  config/defconfig_x86_64-native-bsdapp-gcc   |   1 +
>  5 files changed, 518 insertions(+), 909 deletions(-)  create mode 100644
> config/common_base
> 
> diff --git a/config/common_base b/config/common_base new file mode 100644
> index 0000000..91a12eb
> --- /dev/null
> +++ b/config/common_base
> @@ -0,0 +1,498 @@
> +#   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.
> +#
> +
> +#
> +# 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=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
> +
> +#
> +# 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=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
> +# 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=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
> diff --git a/config/common_bsdapp b/config/common_bsdapp index
> 696382c..de0ca7d 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,74 +37,38 @@
>  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
> +#include "common_base"
> 
>  #
> -# Machine forces strict alignment constraints.
> +# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
>  #
> -CONFIG_RTE_ARCH_STRICT_ALIGN=n
> +CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
> 
>  #
> -# Compile to share library
> +# Compile Environment Abstraction Layer
>  #
> -CONFIG_RTE_BUILD_SHARED_LIB=n
> +CONFIG_RTE_EAL_IGB_UIO=n
> +CONFIG_RTE_EAL_VFIO=n
> 
>  #
> -# Combine to one single library
> +# Compile software PMD backed by AF_PACKET sockets (Linux only)
>  #
> -CONFIG_RTE_BUILD_COMBINE_LIBS=n
> +CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
> 
>  #
> -# Use newest code breaking previous ABI
> +# Compile librte_power
>  #
> -CONFIG_RTE_NEXT_ABI=y
> +CONFIG_RTE_LIBRTE_POWER=n
> 
>  #
> -# Machine's cache line size
> +# Compile librte_kni
>  #
> -CONFIG_RTE_CACHE_LINE_SIZE=64
> +CONFIG_RTE_LIBRTE_KNI=n
> 
>  #
> -# Compile Environment Abstraction Layer
> +# Compile vhost library
>  #
> -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_VHOST=n
> 
>  #
>  # FreeBSD contiguous memory driver settings @@ -113,373 +77,3 @@
> 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
> f1638db..64ddbe9 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,494 +37,9 @@
>  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
> -
> -#
> -# 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=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
> +# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
>  #
>  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
> -#
> -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=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
> -# 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=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
> diff --git a/config/defconfig_x86_64-native-bsdapp-clang
> b/config/defconfig_x86_64-native-bsdapp-clang
> index d2baf2c..8b870b3 100644
> --- a/config/defconfig_x86_64-native-bsdapp-clang
> +++ b/config/defconfig_x86_64-native-bsdapp-clang
> @@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
>  CONFIG_RTE_ARCH="x86_64"
>  CONFIG_RTE_ARCH_X86_64=y
>  CONFIG_RTE_ARCH_X86=y
> +CONFIG_RTE_ARCH_64=y
> 
>  CONFIG_RTE_TOOLCHAIN="clang"
>  CONFIG_RTE_TOOLCHAIN_CLANG=y
> diff --git a/config/defconfig_x86_64-native-bsdapp-gcc
> b/config/defconfig_x86_64-native-bsdapp-gcc
> index 5a6a4e8..4ea4433 100644
> --- a/config/defconfig_x86_64-native-bsdapp-gcc
> +++ b/config/defconfig_x86_64-native-bsdapp-gcc
> @@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
>  CONFIG_RTE_ARCH="x86_64"
>  CONFIG_RTE_ARCH_X86_64=y
>  CONFIG_RTE_ARCH_X86=y
> +CONFIG_RTE_ARCH_64=y
> 
>  CONFIG_RTE_TOOLCHAIN="gcc"
>  CONFIG_RTE_TOOLCHAIN_GCC=y
> --
> 2.7.0

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] config: remove duplicate configuration information
  2016-02-22 15:09  0% ` Trahe, Fiona
@ 2016-02-22 16:02  0%   ` Wiles, Keith
  0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-02-22 16:02 UTC (permalink / raw)
  To: Trahe, Fiona, dev

>Hi Keith,
>
>What makes a param common?
>
>e.g.  cryptodev QAT PMD is supported in linux, but currently not supported in bsd.
>So typically I disable it in the bsd file and enable it in the linux file.
>
>Couldn't the same apply to any other parameter, i.e. there may be users who want to have differences in config for different OSs?
>
>So why not just leave as is and give users the option to choose?

The problem is the major configs are all common, in this design we have the common_base all configs are placed then as you stated they are disable in the common_OS files. Plus some are enabled/disabled in the deconfig_XXX files as well.

The goal is to move all of the configs into one file then we do not have to keep updating all of the common_OS files, but only enable/disable that option.

I have common_osxapp that I want to add later to build and run DPDK on OS X, which is another place to have these same configs. Later we may add another OS too, which means more copies :-)

>
>Regards,
>Fiona
>
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Keith Wiles
>> Sent: Monday, February 22, 2016 1:54 PM
>> To: dev@dpdk.org
>> Subject: [dpdk-dev] [PATCH] config: remove duplicate configuration information
>> 
>> 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                          | 498 ++++++++++++++++++++++++++++
>>  config/common_bsdapp                        | 436 +-----------------------
>>  config/common_linuxapp                      | 491 +--------------------------
>>  config/defconfig_x86_64-native-bsdapp-clang |   1 +
>>  config/defconfig_x86_64-native-bsdapp-gcc   |   1 +
>>  5 files changed, 518 insertions(+), 909 deletions(-)  create mode 100644
>> config/common_base
>> 
>> diff --git a/config/common_base b/config/common_base new file mode 100644
>> index 0000000..91a12eb
>> --- /dev/null
>> +++ b/config/common_base
>> @@ -0,0 +1,498 @@
>> +#   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.
>> +#
>> +
>> +#
>> +# 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=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
>> +
>> +#
>> +# 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=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
>> +# 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=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
>> diff --git a/config/common_bsdapp b/config/common_bsdapp index
>> 696382c..de0ca7d 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,74 +37,38 @@
>>  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
>> +#include "common_base"
>> 
>>  #
>> -# Machine forces strict alignment constraints.
>> +# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
>>  #
>> -CONFIG_RTE_ARCH_STRICT_ALIGN=n
>> +CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
>> 
>>  #
>> -# Compile to share library
>> +# Compile Environment Abstraction Layer
>>  #
>> -CONFIG_RTE_BUILD_SHARED_LIB=n
>> +CONFIG_RTE_EAL_IGB_UIO=n
>> +CONFIG_RTE_EAL_VFIO=n
>> 
>>  #
>> -# Combine to one single library
>> +# Compile software PMD backed by AF_PACKET sockets (Linux only)
>>  #
>> -CONFIG_RTE_BUILD_COMBINE_LIBS=n
>> +CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
>> 
>>  #
>> -# Use newest code breaking previous ABI
>> +# Compile librte_power
>>  #
>> -CONFIG_RTE_NEXT_ABI=y
>> +CONFIG_RTE_LIBRTE_POWER=n
>> 
>>  #
>> -# Machine's cache line size
>> +# Compile librte_kni
>>  #
>> -CONFIG_RTE_CACHE_LINE_SIZE=64
>> +CONFIG_RTE_LIBRTE_KNI=n
>> 
>>  #
>> -# Compile Environment Abstraction Layer
>> +# Compile vhost library
>>  #
>> -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_VHOST=n
>> 
>>  #
>>  # FreeBSD contiguous memory driver settings @@ -113,373 +77,3 @@
>> 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
>> f1638db..64ddbe9 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,494 +37,9 @@
>>  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
>> -
>> -#
>> -# 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=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
>> +# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
>>  #
>>  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
>> -#
>> -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=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
>> -# 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=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
>> diff --git a/config/defconfig_x86_64-native-bsdapp-clang
>> b/config/defconfig_x86_64-native-bsdapp-clang
>> index d2baf2c..8b870b3 100644
>> --- a/config/defconfig_x86_64-native-bsdapp-clang
>> +++ b/config/defconfig_x86_64-native-bsdapp-clang
>> @@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
>>  CONFIG_RTE_ARCH="x86_64"
>>  CONFIG_RTE_ARCH_X86_64=y
>>  CONFIG_RTE_ARCH_X86=y
>> +CONFIG_RTE_ARCH_64=y
>> 
>>  CONFIG_RTE_TOOLCHAIN="clang"
>>  CONFIG_RTE_TOOLCHAIN_CLANG=y
>> diff --git a/config/defconfig_x86_64-native-bsdapp-gcc
>> b/config/defconfig_x86_64-native-bsdapp-gcc
>> index 5a6a4e8..4ea4433 100644
>> --- a/config/defconfig_x86_64-native-bsdapp-gcc
>> +++ b/config/defconfig_x86_64-native-bsdapp-gcc
>> @@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
>>  CONFIG_RTE_ARCH="x86_64"
>>  CONFIG_RTE_ARCH_X86_64=y
>>  CONFIG_RTE_ARCH_X86=y
>> +CONFIG_RTE_ARCH_64=y
>> 
>>  CONFIG_RTE_TOOLCHAIN="gcc"
>>  CONFIG_RTE_TOOLCHAIN_GCC=y
>> --
>> 2.7.0
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-22 14:49  0%         ` Xie, Huawei
@ 2016-02-23  5:35  0%           ` Xie, Huawei
  2016-02-24 12:11  0%             ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Xie, Huawei @ 2016-02-23  5:35 UTC (permalink / raw)
  To: Olivier MATZ, Panu Matilainen, dev; +Cc: dprovan

On 2/22/2016 10:52 PM, Xie, Huawei wrote:
> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
>> Hi,
>>
>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
>>> the library ABI and should not be listed in the version map.
>>>
>>> I assume its inline for performance reasons, but then you lose the
>>> benefits of dynamic linking such as ability to fix bugs and/or improve
>>> itby just updating the library. Since the point of having a bulk API is
>>> to improve performance by reducing the number of calls required, does it
>>> really have to be inline? As in, have you actually measured the
>>> difference between inline and non-inline and decided its worth all the
>>> downsides?
>> Agree with Panu. It would be interesting to compare the performance
>> between inline and non inline to decide whether inlining it or not.
> Will update after i gathered more data. inline could show obvious
> performance difference in some cases.

Panu and Oliver:
I write a simple benchmark. This benchmark run 10M rounds, in each round
8 mbufs are allocated through bulk API, and then freed.
These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
Btw, i have removed some exceptional data, the frequency of which is
like 1/10. Sometimes observed user usage suddenly disappeared, no clue
what happened.

With 8 mbufs allocated, there is about 6% performance increase using inline.
inline            non-inline
2780738888        2950309416
2834853696        2951378072
2823015320        2954500888
2825060032        2958939912
2824499804        2898938284
2810859720        2944892796
2852229420        3014273296
2787308500        2956809852
2793337260        2958674900
2822223476        2954346352
2785455184        2925719136
2821528624        2937380416
2822922136        2974978604
2776645920        2947666548
2815952572        2952316900
2801048740        2947366984
2851462672        2946469004

With 16 mbufs allocated, we could still observe obvious performance
difference, though only 1%-2%

inline            non-inline
5519987084        5669902680
5538416096        5737646840
5578934064        5590165532
5548131972        5767926840
5625585696        5831345628
5558282876        5662223764
5445587768        5641003924
5559096320        5775258444
5656437988        5743969272
5440939404        5664882412
5498875968        5785138532
5561652808        5737123940
5515211716        5627775604
5550567140        5630790628
5665964280        5589568164
5591295900        5702697308

With 32/64 mbufs allocated, the deviation of the data itself would hide
the performance difference.

So we prefer using inline for performance.
>> Also, it would be nice to have a simple test function in
>> app/test/test_mbuf.c. For instance, you could update
>> test_one_pktmbuf() to take a mbuf pointer as a parameter and remove
>> the mbuf allocation from the function. Then it could be called with
>> a mbuf allocated with rte_pktmbuf_alloc() (like before) and with
>> all the mbufs of rte_pktmbuf_alloc_bulk().

Don't quite get you. Is it that we write two cases, one case allocate
mbuf through rte_pktmbuf_alloc_bulk and one use rte_pktmbuf_alloc? It is
good to have. I could do this after this patch.
>>
>> Regards,
>> Olivier
>>
>


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2] mk: replace the combined library with a linker script
  @ 2016-02-23 22:20  4% ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-02-23 22:20 UTC (permalink / raw)
  To: pmatilai; +Cc: dev

From: Panu Matilainen <pmatilai@redhat.com>

The physically linked-together combined library has been an increasing
source of problems, as was predicted when library and symbol versioning
was introduced. Replace the complex and fragile construction with a
simple linker script which achieves the same without all the problems,
remove the related kludges from eg mlx drivers.

Since creating the linker script is practically zero cost, remove the
config option and just create it always.

Based on a patch by Sergio Gonzales Monroy, linker script approach
initially suggested by Neil Horman.

Suggested-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
Suggested-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
v2:
- move RTE_LIBNAME assignment rte.vars.mk to rte.combinedlib.mk
- update crypto
- update doc
- update rte.app.mk
- update test-build.sh

 config/common_bsdapp                             |   5 --
 config/common_linuxapp                           |   5 --
 doc/guides/contributing/patches.rst              |  12 ++-
 doc/guides/nics/mlx4.rst                         |   5 --
 doc/guides/nics/mlx5.rst                         |   5 --
 drivers/crypto/Makefile                          |   3 +-
 drivers/net/Makefile                             |   1 -
 drivers/net/mlx4/Makefile                        |   6 --
 drivers/net/mlx5/Makefile                        |   6 --
 lib/Makefile                                     |   1 -
 mk/rte.app.mk                                    |  17 +---
 drivers/crypto/Makefile => mk/rte.combinedlib.mk |  28 +++++-
 mk/rte.lib.mk                                    |  16 ----
 mk/rte.sdkbuild.mk                               |   4 +-
 mk/rte.sharelib.mk                               | 105 -----------------------
 mk/rte.vars.mk                                   |   2 -
 scripts/test-build.sh                            |   7 +-
 17 files changed, 36 insertions(+), 192 deletions(-)
 copy drivers/crypto/Makefile => mk/rte.combinedlib.mk (81%)
 delete mode 100644 mk/rte.sharelib.mk

diff --git a/config/common_bsdapp b/config/common_bsdapp
index 696382c..7df5ac6 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -74,11 +74,6 @@ CONFIG_RTE_ARCH_STRICT_ALIGN=n
 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
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f1638db..26df137 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -74,11 +74,6 @@ CONFIG_RTE_ARCH_STRICT_ALIGN=n
 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
diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst
index 5dd8f79..3ebe95b 100644
--- a/doc/guides/contributing/patches.rst
+++ b/doc/guides/contributing/patches.rst
@@ -267,7 +267,7 @@ Checking Compilation
 Compilation of patches and changes should be tested using the the ``test-build.sh`` script in the ``scripts``
 directory of the DPDK repo::
 
-  scripts/test-build.sh x86_64-native-linuxapp-gcc+next+shared+combined
+  scripts/test-build.sh x86_64-native-linuxapp-gcc+next+shared
 
 The script usage is::
 
@@ -283,10 +283,8 @@ Where:
 Examples of configs are::
 
    x86_64-native-linuxapp-gcc
-   x86_64-native-linuxapp-gcc+next+shared+combined
-   x86_64-native-linuxapp-gcc+shared+next
-   x86_64-native-linuxapp-clang+shared+combined
-   i686-native-linuxapp-gcc+combined
+   x86_64-native-linuxapp-gcc+next+shared
+   x86_64-native-linuxapp-clang+shared
 
 The builds can be modifies via the following environmental variables:
 
@@ -302,8 +300,8 @@ These can be set from the command line or in the config files shown above in the
 The recommended configurations and options to test compilation prior to submitting patches are::
 
    x86_64-native-linuxapp-gcc+shared+next
-   x86_64-native-linuxapp-clang+shared+combined
-   i686-native-linuxapp-gcc+combined
+   x86_64-native-linuxapp-clang+shared
+   i686-native-linuxapp-gcc
 
    export DPDK_DEP_ZLIB=y
    export DPDK_DEP_PCAP=y
diff --git a/doc/guides/nics/mlx4.rst b/doc/guides/nics/mlx4.rst
index 7757013..49f4626 100644
--- a/doc/guides/nics/mlx4.rst
+++ b/doc/guides/nics/mlx4.rst
@@ -47,11 +47,6 @@ There is also a `section dedicated to this poll mode driver
    be enabled manually by setting ``CONFIG_RTE_LIBRTE_MLX4_PMD=y`` and
    recompiling DPDK.
 
-.. warning::
-
-   ``CONFIG_RTE_BUILD_COMBINE_LIBS`` with ``CONFIG_RTE_BUILD_SHARED_LIB``
-   is not supported and thus the compilation will fail with this configuration.
-
 Implementation details
 ----------------------
 
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index b2a12ce..66794e6 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -48,11 +48,6 @@ There is also a `section dedicated to this poll mode driver
    be enabled manually by setting ``CONFIG_RTE_LIBRTE_MLX5_PMD=y`` and
    recompiling DPDK.
 
-.. warning::
-
-   ``CONFIG_RTE_BUILD_COMBINE_LIBS`` with ``CONFIG_RTE_BUILD_SHARED_LIB``
-   is not supported and thus the compilation will fail with this configuration.
-
 Implementation details
 ----------------------
 
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d07ee96..d0258da 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -34,5 +34,4 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
 
-include $(RTE_SDK)/mk/rte.sharelib.mk
-include $(RTE_SDK)/mk/rte.subdir.mk
\ No newline at end of file
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6e4497e..0c3393f 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -52,5 +52,4 @@ DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
 
-include $(RTE_SDK)/mk/rte.sharelib.mk
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 23b766d..d2f5692 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -31,12 +31,6 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS)$(CONFIG_RTE_BUILD_SHARED_LIB),yy)
-all:
-	@echo 'MLX4: Not supported in a combined shared library'
-	@false
-endif
-
 # Library name.
 LIB = librte_pmd_mlx4.a
 
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index ae568e6..736d205 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -31,12 +31,6 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS)$(CONFIG_RTE_BUILD_SHARED_LIB),yy)
-all:
-	@echo 'MLX5: Not supported in a combined shared library'
-	@false
-endif
-
 # Library name.
 LIB = librte_pmd_mlx5.a
 
diff --git a/lib/Makefile b/lib/Makefile
index ef172ea..6840f87 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -64,5 +64,4 @@ DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
 DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += librte_ivshmem
 endif
 
-include $(RTE_SDK)/mk/rte.sharelib.mk
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8ecab41..daac09f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -59,10 +59,6 @@ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib
 
 _LDLIBS-y += --whole-archive
 
-_LDLIBS-$(CONFIG_RTE_BUILD_COMBINE_LIBS)    += -l$(RTE_LIBNAME)
-
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),n)
-
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR)    += -lrte_distributor
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
@@ -88,8 +84,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrt
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lrte_vhost
 
-endif # ! CONFIG_RTE_BUILD_COMBINE_LIBS
-
 ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lnuma
 endif
@@ -99,9 +93,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lfuse
 endif
 
 # The static libraries do not know their dependencies.
-# The combined library fails also to store this information.
-# So linking with static or combined library requires explicit dependencies.
-ifneq ($(CONFIG_RTE_BUILD_COMBINE_LIBS)$(CONFIG_RTE_BUILD_SHARED_LIB),ny)
+# So linking with static library requires explicit dependencies.
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lpcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD)      += -lz
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -libverbs
@@ -111,12 +104,10 @@ _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
-endif # CONFIG_RTE_BUILD_COMBINE_LIBS or not CONFIG_RTE_BUILD_SHARED_LIBS
+endif # !CONFIG_RTE_BUILD_SHARED_LIBS
 
 _LDLIBS-y += --start-group
 
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),n)
-
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF_OFFLOAD)   += -lrte_mbuf_offload
@@ -161,8 +152,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH)
 
 endif # ! $(CONFIG_RTE_BUILD_SHARED_LIB)
 
-endif # ! CONFIG_RTE_BUILD_COMBINE_LIBS
-
 _LDLIBS-y += $(EXECENV_LDLIBS)
 _LDLIBS-y += --end-group
 _LDLIBS-y += --no-whole-archive
diff --git a/drivers/crypto/Makefile b/mk/rte.combinedlib.mk
similarity index 81%
copy from drivers/crypto/Makefile
copy to mk/rte.combinedlib.mk
index d07ee96..fe4817b 100644
--- a/drivers/crypto/Makefile
+++ b/mk/rte.combinedlib.mk
@@ -31,8 +31,28 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
-DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
+default: all
 
-include $(RTE_SDK)/mk/rte.sharelib.mk
-include $(RTE_SDK)/mk/rte.subdir.mk
\ No newline at end of file
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+EXT:=.so
+else
+EXT:=.a
+endif
+
+RTE_LIBNAME := dpdk
+COMBINEDLIB := lib$(RTE_LIBNAME)$(EXT)
+
+LIBS := $(notdir $(wildcard $(RTE_OUTPUT)/lib/*$(EXT)))
+
+all: FORCE
+	$(Q)echo "GROUP ( $(LIBS) )" > $(RTE_OUTPUT)/lib/$(COMBINEDLIB)
+
+#
+# Clean all generated files
+#
+.PHONY: clean
+clean:
+	$(Q)rm -f $(RTE_OUTPUT)/lib/$(COMBINEDLIB)
+
+.PHONY: FORCE
+FORCE:
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 24c81e7..8f7e021 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -138,14 +138,6 @@ endif
 		$(depfile_newer)),\
 		$(O_TO_S_DO))
 
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS)$(EXTLIB_BUILD),yn)
-	$(if $(or \
-        $(file_missing),\
-        $(call cmdline_changed,$(O_TO_C_STR)),\
-        $(depfile_missing),\
-        $(depfile_newer)),\
-        $(O_TO_C_DO))
-endif
 else
 $(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE
 	@[ -d $(dir $@) ] || mkdir -p $(dir $@)
@@ -161,14 +153,6 @@ $(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE
 	    $(depfile_missing),\
 	    $(depfile_newer)),\
 	    $(O_TO_A_DO))
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS)$(EXTLIB_BUILD),yn)
-	$(if $(or \
-        $(file_missing),\
-        $(call cmdline_changed,$(O_TO_C_STR)),\
-        $(depfile_missing),\
-        $(depfile_newer)),\
-        $(O_TO_C_DO))
-endif
 endif
 
 #
diff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk
index 85f603c..eec5241 100644
--- a/mk/rte.sdkbuild.mk
+++ b/mk/rte.sdkbuild.mk
@@ -77,8 +77,8 @@ $(ROOTDIRS-y):
 	@[ -d $(BUILDDIR)/$@ ] || mkdir -p $(BUILDDIR)/$@
 	@echo "== Build $@"
 	$(Q)$(MAKE) S=$@ -f $(RTE_SRCDIR)/$@/Makefile -C $(BUILDDIR)/$@ all
-	@if [ $@ = drivers -a $(CONFIG_RTE_BUILD_COMBINE_LIBS) = y ]; then \
-		$(MAKE) -f $(RTE_SDK)/lib/Makefile sharelib; \
+	@if [ $@ = drivers ]; then \
+		$(MAKE) -f $(RTE_SDK)/mk/rte.combinedlib.mk; \
 	fi
 
 %_clean:
diff --git a/mk/rte.sharelib.mk b/mk/rte.sharelib.mk
deleted file mode 100644
index 70c49a8..0000000
--- a/mk/rte.sharelib.mk
+++ /dev/null
@@ -1,105 +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.
-
-include $(RTE_SDK)/mk/internal/rte.build-pre.mk
-
-# VPATH contains at least SRCDIR
-VPATH += $(SRCDIR)
-
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
-LIB_ONE := lib$(RTE_LIBNAME).so
-else
-LIB_ONE := lib$(RTE_LIBNAME).a
-endif
-COMBINED_MAP=$(BUILDDIR)/lib/libdpdk.map
-COMBINED_LDFLAGS += --version-script=$(COMBINED_MAP)
-endif
-
-.PHONY:sharelib
-sharelib: $(LIB_ONE) FORCE
-
-OBJS = $(wildcard $(RTE_OUTPUT)/build/lib/*.o)
-
-ifeq ($(LINK_USING_CC),1)
-# Override the definition of LD here, since we're linking with CC
-LD := $(CC) $(CPU_CFLAGS)
-O_TO_S = $(LD) $(call linkerprefix,$(CPU_LDFLAGS)) \
-	 $(call linkerprefix,$(COMBINED_LDFLAGS)) \
-	-shared $(OBJS) -o $(RTE_OUTPUT)/lib/$(LIB_ONE)
-else
-O_TO_S = $(LD) $(CPU_LDFLAGS) $(COMBINED_LDFLAGS) \
-	-shared $(OBJS) -o $(RTE_OUTPUT)/lib/$(LIB_ONE)
-endif
-
-O_TO_S_STR = $(subst ','\'',$(O_TO_S)) #'# fix syntax highlight
-O_TO_S_DISP = $(if $(V),"$(O_TO_S_STR)","  LD $(@)")
-O_TO_S_CMD = "cmd_$@ = $(O_TO_S_STR)"
-O_TO_S_DO = @set -e; \
-    echo $(O_TO_S_DISP); \
-    $(O_TO_S)
-
-O_TO_A =  $(AR) crus $(RTE_OUTPUT)/lib/$(LIB_ONE) $(OBJS)
-O_TO_A_STR = $(subst ','\'',$(O_TO_A)) #'# fix syntax highlight
-O_TO_A_DISP = $(if $(V),"$(O_TO_A_STR)","  LD $(@)")
-O_TO_A_CMD = "cmd_$@ = $(O_TO_A_STR)"
-O_TO_A_DO = @set -e; \
-    echo $(O_TO_A_DISP); \
-    $(O_TO_A)
-#
-# Archive objects to share library
-#
-
-ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
-$(LIB_ONE): FORCE
-	@[ -d $(dir $@) ] || mkdir -p $(dir $@)
-	@$(SRCDIR)/scripts/merge-maps.sh > $(COMBINED_MAP)
-	$(O_TO_S_DO)
-else
-$(LIB_ONE): FORCE
-	@[ -d $(dir $@) ] || mkdir -p $(dir $@)
-	$(O_TO_A_DO)
-endif
-endif
-
-#
-# Clean all generated files
-#
-.PHONY: clean
-clean: _postclean
-
-.PHONY: doclean
-doclean:
-	$(Q)rm -rf $(LIB_ONE)
-
-.PHONY: FORCE
-FORCE:
diff --git a/mk/rte.vars.mk b/mk/rte.vars.mk
index 7e7ee14..2d734bd 100644
--- a/mk/rte.vars.mk
+++ b/mk/rte.vars.mk
@@ -66,8 +66,6 @@ endif
 
 RTE_TARGET ?= $(RTE_ARCH)-$(RTE_MACHINE)-$(RTE_EXEC_ENV)-$(RTE_TOOLCHAIN)
 
-RTE_LIBNAME := dpdk
-
 ifeq ($(BUILDING_RTE_SDK),)
 # if we are building an external app/lib, include internal/rte.extvars.mk that will
 # define RTE_OUTPUT, RTE_SRCDIR, RTE_EXTMK, RTE_SDK_BIN, (etc ...)
diff --git a/scripts/test-build.sh b/scripts/test-build.sh
index 6d28c5d..ead7b47 100755
--- a/scripts/test-build.sh
+++ b/scripts/test-build.sh
@@ -55,7 +55,7 @@ print_help () {
 	        -s    short test with only first config without examples/doc
 
 	config: defconfig name followed by switches delimited with "+" sign
-	        Example: x86_64-native-linuxapp-gcc+next+shared+combined
+	        Example: x86_64-native-linuxapp-gcc+next+shared
 	        Default is to enable most of the options.
 	        The external dependencies are setup with DPDK_DEP_* variables.
 	END_OF_HELP
@@ -101,8 +101,6 @@ config () # <directory> <target> <options>
 		sed -ri           's,(NEXT_ABI=)y,\1n,' $1/.config
 		! echo $3 | grep -q shared || \
 		sed -ri         's,(SHARED_LIB=)n,\1y,' $1/.config
-		! echo $3 | grep -q combined || \
-		sed -ri       's,(COMBINE_LIBS=)n,\1y,' $1/.config
 		echo $2 | grep -q '^i686' || \
 		sed -ri               's,(NUMA=)n,\1y,' $1/.config
 		sed -ri         's,(PCI_CONFIG=)n,\1y,' $1/.config
@@ -110,7 +108,6 @@ config () # <directory> <target> <options>
 		sed -ri             's,(BYPASS=)n,\1y,' $1/.config
 		test "$DPDK_DEP_MOFED" != y || \
 		echo $2 | grep -q '^clang$' || \
-		echo $3 | grep -q 'shared.*combined' || \
 		sed -ri           's,(MLX._PMD=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SZE" != y || \
 		echo $2 | grep -q '^i686' || \
@@ -122,11 +119,9 @@ config () # <directory> <target> <options>
 		sed -ri               's,(PCAP=)n,\1y,' $1/.config
 		test -z "$AESNI_MULTI_BUFFER_LIB_PATH" || \
 		echo $2 | grep -q '^i686' || \
-		echo $3 | grep -q 'shared.*combined' || \
 		sed -ri       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SSL" != y || \
 		echo $2 | grep -q '^i686' || \
-		echo $3 | grep -q 'shared.*combined' || \
 		sed -ri            's,(PMD_QAT=)n,\1y,' $1/.config
 		sed -ri        's,(KNI_VHOST.*=)n,\1y,' $1/.config
 		sed -ri           's,(SCHED_.*=)n,\1y,' $1/.config
-- 
2.7.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH RFC v3 2/3] vhost: make buf vector for scatter RX local.
  @ 2016-02-24 11:47  4% ` Ilya Maximets
  0 siblings, 0 replies; 200+ results
From: Ilya Maximets @ 2016-02-24 11:47 UTC (permalink / raw)
  To: dev, Huawei Xie, Yuanhan Liu; +Cc: Dyasly Sergey, Ilya Maximets

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().
buf_vec field of struct vhost_virtqueue marked as deprecated.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 doc/guides/rel_notes/deprecation.rst |  1 +
 lib/librte_vhost/rte_virtio_net.h    |  2 +-
 lib/librte_vhost/vhost_rxtx.c        | 49 ++++++++++++++++++------------------
 3 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..40f350d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -7,6 +7,7 @@ API and ABI deprecation notices are to be posted here.
 
 Deprecation Notices
 -------------------
+* Field buf_vec of struct vhost_virtqueue have been deprecated.
 
 * The following fields have been deprecated in rte_eth_stats:
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
index 4a2303a..e6e5cf3 100644
--- a/lib/librte_vhost/rte_virtio_net.h
+++ b/lib/librte_vhost/rte_virtio_net.h
@@ -93,7 +93,7 @@ struct vhost_virtqueue {
 	int			enabled;
 	uint64_t		log_guest_addr;		/**< Physical address of used ring, for logging */
 	uint64_t		reserved[15];		/**< Reserve some spaces for future extension. */
-	struct buf_vector	buf_vec[BUF_VECTOR_MAX];	/**< for scatter RX. */
+	struct buf_vector       buf_vec[BUF_VECTOR_MAX] __rte_deprecated;        /**< @deprecated Buffer for scatter RX. */
 } __rte_cache_aligned;
 
 
diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 14c2159..a8e2582 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -340,7 +340,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 static inline uint32_t __attribute__((always_inline))
 copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 			uint16_t res_base_idx, uint16_t res_end_idx,
-			struct rte_mbuf *pkt)
+			struct rte_mbuf *pkt, struct buf_vector *buf_vec)
 {
 	uint32_t vec_idx = 0;
 	uint32_t entry_success = 0;
@@ -371,7 +371,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 	 */
 	vq = dev->virtqueue[queue_id];
 
-	vb_addr = gpa_to_vva(dev, vq->buf_vec[vec_idx].buf_addr);
+	vb_addr = gpa_to_vva(dev, buf_vec[vec_idx].buf_addr);
 	vb_hdr_addr = vb_addr;
 
 	/* Prefetch buffer address. */
@@ -386,24 +386,24 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 	rte_memcpy((void *)(uintptr_t)vb_hdr_addr,
 		(const void *)&virtio_hdr, vq->vhost_hlen);
-	vhost_log_write(dev, vq->buf_vec[vec_idx].buf_addr, vq->vhost_hlen);
+	vhost_log_write(dev, buf_vec[vec_idx].buf_addr, vq->vhost_hlen);
 
 	PRINT_PACKET(dev, (uintptr_t)vb_hdr_addr, vq->vhost_hlen, 1);
 
 	seg_avail = rte_pktmbuf_data_len(pkt);
 	vb_offset = vq->vhost_hlen;
-	vb_avail = vq->buf_vec[vec_idx].buf_len - vq->vhost_hlen;
+	vb_avail = buf_vec[vec_idx].buf_len - vq->vhost_hlen;
 
 	entry_len = vq->vhost_hlen;
 
 	if (vb_avail == 0) {
-		uint32_t desc_idx = vq->buf_vec[vec_idx].desc_idx;
+		uint32_t desc_idx = buf_vec[vec_idx].desc_idx;
 
 		if ((vq->desc[desc_idx].flags & VRING_DESC_F_NEXT) == 0) {
 			idx = cur_idx & (vq->size - 1);
 
 			/* Update used ring with desc information */
-			vq->used->ring[idx].id = vq->buf_vec[vec_idx].desc_idx;
+			vq->used->ring[idx].id = buf_vec[vec_idx].desc_idx;
 			vq->used->ring[idx].len = entry_len;
 
 			vhost_log_used_vring(dev, vq,
@@ -416,12 +416,12 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 		}
 
 		vec_idx++;
-		vb_addr = gpa_to_vva(dev, vq->buf_vec[vec_idx].buf_addr);
+		vb_addr = gpa_to_vva(dev, buf_vec[vec_idx].buf_addr);
 
 		/* Prefetch buffer address. */
 		rte_prefetch0((void *)(uintptr_t)vb_addr);
 		vb_offset = 0;
-		vb_avail = vq->buf_vec[vec_idx].buf_len;
+		vb_avail = buf_vec[vec_idx].buf_len;
 	}
 
 	cpy_len = RTE_MIN(vb_avail, seg_avail);
@@ -431,7 +431,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 		rte_memcpy((void *)(uintptr_t)(vb_addr + vb_offset),
 			rte_pktmbuf_mtod_offset(pkt, const void *, seg_offset),
 			cpy_len);
-		vhost_log_write(dev, vq->buf_vec[vec_idx].buf_addr + vb_offset,
+		vhost_log_write(dev, buf_vec[vec_idx].buf_addr + vb_offset,
 			cpy_len);
 
 		PRINT_PACKET(dev,
@@ -450,12 +450,12 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 			 * entry reach to its end.
 			 * But the segment doesn't complete.
 			 */
-			if ((vq->desc[vq->buf_vec[vec_idx].desc_idx].flags &
+			if ((vq->desc[buf_vec[vec_idx].desc_idx].flags &
 				VRING_DESC_F_NEXT) == 0) {
 				/* Update used ring with desc information */
 				idx = cur_idx & (vq->size - 1);
 				vq->used->ring[idx].id
-					= vq->buf_vec[vec_idx].desc_idx;
+					= buf_vec[vec_idx].desc_idx;
 				vq->used->ring[idx].len = entry_len;
 				vhost_log_used_vring(dev, vq,
 					offsetof(struct vring_used, ring[idx]),
@@ -467,9 +467,9 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 			vec_idx++;
 			vb_addr = gpa_to_vva(dev,
-				vq->buf_vec[vec_idx].buf_addr);
+				buf_vec[vec_idx].buf_addr);
 			vb_offset = 0;
-			vb_avail = vq->buf_vec[vec_idx].buf_len;
+			vb_avail = buf_vec[vec_idx].buf_len;
 			cpy_len = RTE_MIN(vb_avail, seg_avail);
 		} else {
 			/*
@@ -488,7 +488,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 					 * from buf_vec.
 					 */
 					uint32_t desc_idx =
-						vq->buf_vec[vec_idx].desc_idx;
+						buf_vec[vec_idx].desc_idx;
 
 					if ((vq->desc[desc_idx].flags &
 						VRING_DESC_F_NEXT) == 0) {
@@ -512,9 +512,9 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 					/* Get next buffer from buf_vec. */
 					vec_idx++;
 					vb_addr = gpa_to_vva(dev,
-						vq->buf_vec[vec_idx].buf_addr);
+						buf_vec[vec_idx].buf_addr);
 					vb_avail =
-						vq->buf_vec[vec_idx].buf_len;
+						buf_vec[vec_idx].buf_len;
 					vb_offset = 0;
 				}
 
@@ -528,7 +528,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 				/* Update used ring with desc information */
 				idx = cur_idx & (vq->size - 1);
 				vq->used->ring[idx].id
-					= vq->buf_vec[vec_idx].desc_idx;
+					= buf_vec[vec_idx].desc_idx;
 				vq->used->ring[idx].len = entry_len;
 				vhost_log_used_vring(dev, vq,
 					offsetof(struct vring_used, ring[idx]),
@@ -544,7 +544,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
 
 static inline void __attribute__((always_inline))
 update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
-	uint32_t *secure_len, uint32_t *vec_idx)
+	uint32_t *secure_len, uint32_t *vec_idx, struct buf_vector *buf_vec)
 {
 	uint16_t wrapped_idx = id & (vq->size - 1);
 	uint32_t idx = vq->avail->ring[wrapped_idx];
@@ -555,9 +555,9 @@ update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
 	do {
 		next_desc = 0;
 		len += vq->desc[idx].len;
-		vq->buf_vec[vec_id].buf_addr = vq->desc[idx].addr;
-		vq->buf_vec[vec_id].buf_len = vq->desc[idx].len;
-		vq->buf_vec[vec_id].desc_idx = idx;
+		buf_vec[vec_id].buf_addr = vq->desc[idx].addr;
+		buf_vec[vec_id].buf_len = vq->desc[idx].len;
+		buf_vec[vec_id].desc_idx = idx;
 		vec_id++;
 
 		if (vq->desc[idx].flags & VRING_DESC_F_NEXT) {
@@ -582,6 +582,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 	uint16_t avail_idx;
 	uint16_t res_base_idx, res_cur_idx;
 	uint8_t success = 0;
+	struct buf_vector buf_vec[BUF_VECTOR_MAX];
 
 	LOG_DEBUG(VHOST_DATA, "(%"PRIu64") virtio_dev_merge_rx()\n",
 		dev->device_fh);
@@ -620,8 +621,8 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 				if (unlikely(res_cur_idx == avail_idx))
 					goto merge_rx_exit;
 
-				update_secure_len(vq, res_cur_idx,
-						  &secure_len, &vec_idx);
+				update_secure_len(vq, res_cur_idx, &secure_len,
+						  &vec_idx, buf_vec);
 				res_cur_idx++;
 			} while (pkt_len > secure_len);
 
@@ -632,7 +633,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 		} while (success == 0);
 
 		entry_success = copy_from_mbuf_to_vring(dev, queue_id,
-			res_base_idx, res_cur_idx, pkts[pkt_idx]);
+			res_base_idx, res_cur_idx, pkts[pkt_idx], buf_vec);
 
 		rte_smp_wmb();
 
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-23  5:35  0%           ` Xie, Huawei
@ 2016-02-24 12:11  0%             ` Panu Matilainen
  2016-02-24 13:23  3%               ` Ananyev, Konstantin
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-02-24 12:11 UTC (permalink / raw)
  To: Xie, Huawei, Olivier MATZ, dev; +Cc: dprovan

On 02/23/2016 07:35 AM, Xie, Huawei wrote:
> On 2/22/2016 10:52 PM, Xie, Huawei wrote:
>> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
>>> Hi,
>>>
>>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
>>>> the library ABI and should not be listed in the version map.
>>>>
>>>> I assume its inline for performance reasons, but then you lose the
>>>> benefits of dynamic linking such as ability to fix bugs and/or improve
>>>> itby just updating the library. Since the point of having a bulk API is
>>>> to improve performance by reducing the number of calls required, does it
>>>> really have to be inline? As in, have you actually measured the
>>>> difference between inline and non-inline and decided its worth all the
>>>> downsides?
>>> Agree with Panu. It would be interesting to compare the performance
>>> between inline and non inline to decide whether inlining it or not.
>> Will update after i gathered more data. inline could show obvious
>> performance difference in some cases.
>
> Panu and Oliver:
> I write a simple benchmark. This benchmark run 10M rounds, in each round
> 8 mbufs are allocated through bulk API, and then freed.
> These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
> 2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
> Btw, i have removed some exceptional data, the frequency of which is
> like 1/10. Sometimes observed user usage suddenly disappeared, no clue
> what happened.
>
> With 8 mbufs allocated, there is about 6% performance increase using inline.
[...]
>
> With 16 mbufs allocated, we could still observe obvious performance
> difference, though only 1%-2%
>
[...]
>
> With 32/64 mbufs allocated, the deviation of the data itself would hide
> the performance difference.
> So we prefer using inline for performance.

At least I was more after real-world performance in a real-world 
use-case rather than CPU cycles in a microbenchmark, we know function 
calls have a cost but the benefits tend to outweight the cons.

Inline functions have their place and they're far less evil in project 
internal use, but in library public API they are BAD and should be ... 
well, not banned because there are exceptions to every rule, but highly 
discouraged.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-24 12:11  0%             ` Panu Matilainen
@ 2016-02-24 13:23  3%               ` Ananyev, Konstantin
  2016-02-26  7:39  0%                 ` Xie, Huawei
  2016-02-29 10:51  4%                 ` Panu Matilainen
  0 siblings, 2 replies; 200+ results
From: Ananyev, Konstantin @ 2016-02-24 13:23 UTC (permalink / raw)
  To: Panu Matilainen, Xie, Huawei, Olivier MATZ, dev; +Cc: dprovan

Hi Panu,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Panu Matilainen
> Sent: Wednesday, February 24, 2016 12:12 PM
> To: Xie, Huawei; Olivier MATZ; dev@dpdk.org
> Cc: dprovan@bivio.net
> Subject: Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
> 
> On 02/23/2016 07:35 AM, Xie, Huawei wrote:
> > On 2/22/2016 10:52 PM, Xie, Huawei wrote:
> >> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
> >>> Hi,
> >>>
> >>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
> >>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
> >>>> the library ABI and should not be listed in the version map.
> >>>>
> >>>> I assume its inline for performance reasons, but then you lose the
> >>>> benefits of dynamic linking such as ability to fix bugs and/or improve
> >>>> itby just updating the library. Since the point of having a bulk API is
> >>>> to improve performance by reducing the number of calls required, does it
> >>>> really have to be inline? As in, have you actually measured the
> >>>> difference between inline and non-inline and decided its worth all the
> >>>> downsides?
> >>> Agree with Panu. It would be interesting to compare the performance
> >>> between inline and non inline to decide whether inlining it or not.
> >> Will update after i gathered more data. inline could show obvious
> >> performance difference in some cases.
> >
> > Panu and Oliver:
> > I write a simple benchmark. This benchmark run 10M rounds, in each round
> > 8 mbufs are allocated through bulk API, and then freed.
> > These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
> > 2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
> > Btw, i have removed some exceptional data, the frequency of which is
> > like 1/10. Sometimes observed user usage suddenly disappeared, no clue
> > what happened.
> >
> > With 8 mbufs allocated, there is about 6% performance increase using inline.
> [...]
> >
> > With 16 mbufs allocated, we could still observe obvious performance
> > difference, though only 1%-2%
> >
> [...]
> >
> > With 32/64 mbufs allocated, the deviation of the data itself would hide
> > the performance difference.
> > So we prefer using inline for performance.
> 
> At least I was more after real-world performance in a real-world
> use-case rather than CPU cycles in a microbenchmark, we know function
> calls have a cost but the benefits tend to outweight the cons.
> 
> Inline functions have their place and they're far less evil in project
> internal use, but in library public API they are BAD and should be ...
> well, not banned because there are exceptions to every rule, but highly
> discouraged.

Why is that?
As you can see right now we have all mbuf alloc/free routines as static inline.
And I think we would like to keep it like that.
So why that particular function should be different?
After all that function is nothing more than a wrapper 
around rte_mempool_get_bulk()  unrolled by 4 loop {rte_pktmbuf_reset()}
So unless mempool get/put API would change, I can hardly see there could be any ABI
breakages in future. 
About 'real world' performance gain - it was a 'real world' performance problem,
that we tried to solve by introducing that function:
http://dpdk.org/ml/archives/dev/2015-May/017633.html

And according to the user feedback, it does help:  
http://dpdk.org/ml/archives/dev/2016-February/033203.html

Konstantin

> 
> 	- Panu -
> 


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] config: remove duplicate configuration information
  2016-02-22 13:53  6% [dpdk-dev] [PATCH] config: remove duplicate configuration information Keith Wiles
  2016-02-22 15:09  0% ` Trahe, Fiona
@ 2016-02-24 13:58  0% ` Wiles, Keith
  2016-03-03 14:43  0% ` Wiles, Keith
  2 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-02-24 13:58 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>

Ping, Does this patch have any more comments, do we want to use this patch?
>---
> config/common_base                          | 498 ++++++++++++++++++++++++++++
> config/common_bsdapp                        | 436 +-----------------------
> config/common_linuxapp                      | 491 +--------------------------
> config/defconfig_x86_64-native-bsdapp-clang |   1 +
> config/defconfig_x86_64-native-bsdapp-gcc   |   1 +
> 5 files changed, 518 insertions(+), 909 deletions(-)
> create mode 100644 config/common_base
>
>diff --git a/config/common_base b/config/common_base
>new file mode 100644
>index 0000000..91a12eb
>--- /dev/null
>+++ b/config/common_base
>@@ -0,0 +1,498 @@
>+#   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.
>+#
>+
>+#
>+# 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=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
>+
>+#
>+# 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=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
>+# 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=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
>diff --git a/config/common_bsdapp b/config/common_bsdapp
>index 696382c..de0ca7d 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,74 +37,38 @@
> 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
>+#include "common_base"
> 
> #
>-# Machine forces strict alignment constraints.
>+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
> #
>-CONFIG_RTE_ARCH_STRICT_ALIGN=n
>+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
> 
> #
>-# Compile to share library
>+# Compile Environment Abstraction Layer
> #
>-CONFIG_RTE_BUILD_SHARED_LIB=n
>+CONFIG_RTE_EAL_IGB_UIO=n
>+CONFIG_RTE_EAL_VFIO=n
> 
> #
>-# Combine to one single library
>+# Compile software PMD backed by AF_PACKET sockets (Linux only)
> #
>-CONFIG_RTE_BUILD_COMBINE_LIBS=n
>+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
> 
> #
>-# Use newest code breaking previous ABI
>+# Compile librte_power
> #
>-CONFIG_RTE_NEXT_ABI=y
>+CONFIG_RTE_LIBRTE_POWER=n
> 
> #
>-# Machine's cache line size
>+# Compile librte_kni
> #
>-CONFIG_RTE_CACHE_LINE_SIZE=64
>+CONFIG_RTE_LIBRTE_KNI=n
> 
> #
>-# Compile Environment Abstraction Layer
>+# Compile vhost library
> #
>-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_VHOST=n
> 
> #
> # FreeBSD contiguous memory driver settings
>@@ -113,373 +77,3 @@ 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 f1638db..64ddbe9 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,494 +37,9 @@
> 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
>-
>-#
>-# 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=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
>+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
> #
> 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
>-#
>-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=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
>-# 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=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
>diff --git a/config/defconfig_x86_64-native-bsdapp-clang b/config/defconfig_x86_64-native-bsdapp-clang
>index d2baf2c..8b870b3 100644
>--- a/config/defconfig_x86_64-native-bsdapp-clang
>+++ b/config/defconfig_x86_64-native-bsdapp-clang
>@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
> CONFIG_RTE_ARCH="x86_64"
> CONFIG_RTE_ARCH_X86_64=y
> CONFIG_RTE_ARCH_X86=y
>+CONFIG_RTE_ARCH_64=y
> 
> CONFIG_RTE_TOOLCHAIN="clang"
> CONFIG_RTE_TOOLCHAIN_CLANG=y
>diff --git a/config/defconfig_x86_64-native-bsdapp-gcc b/config/defconfig_x86_64-native-bsdapp-gcc
>index 5a6a4e8..4ea4433 100644
>--- a/config/defconfig_x86_64-native-bsdapp-gcc
>+++ b/config/defconfig_x86_64-native-bsdapp-gcc
>@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
> CONFIG_RTE_ARCH="x86_64"
> CONFIG_RTE_ARCH_X86_64=y
> CONFIG_RTE_ARCH_X86=y
>+CONFIG_RTE_ARCH_64=y
> 
> CONFIG_RTE_TOOLCHAIN="gcc"
> CONFIG_RTE_TOOLCHAIN_GCC=y
>-- 
>2.7.0
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] af_packet: make the device detachable
  2016-02-11 16:37  3% [dpdk-dev] [PATCH v3] af_packet: make the device detachable Wojciech Zmuda
@ 2016-02-24 14:08  3% ` Iremonger, Bernard
  2016-02-29 18:22  0%   ` Wojciech Żmuda
  0 siblings, 1 reply; 200+ results
From: Iremonger, Bernard @ 2016-02-24 14:08 UTC (permalink / raw)
  To: Wojciech Zmuda, dev

Hi Wojciech,
<snip>

> Subject: [PATCH v3] af_packet: make the device detachable
> 
> Allow dynamic deallocation of af_packet device through proper API
> functions. To achieve this:
> * set device flag to RTE_ETH_DEV_DETACHABLE
> * implement rte_pmd_af_packet_devuninit() and expose it
>   through rte_driver.uninit()
> * copy device name to ethdev->data to make discoverable with
>   rte_eth_dev_allocated()
> Moreover, make af_packet init function static, as there is no reason to keep
> it public.
> 
> Signed-off-by: Wojciech Zmuda <woz@semihalf.com>
> ---
> v3:
> * Rephrased feature note in release notes.
> * Rephrased commit log.
> * Added API change note in release notes.
> * Made init function static.
> * Removed af_packet header file, as it is not needed
>   after init function is not public anymore.
> 
> v2:
> * Fixed typo and a comment.
> * Added feature to the 2.3 release notes.
> * Free memory allocated for rx and tx queues.
> 
>  doc/guides/rel_notes/release_2_3.rst               |  6 +++
>  drivers/net/af_packet/Makefile                     |  5 --
>  drivers/net/af_packet/rte_eth_af_packet.c          | 43 ++++++++++++++++--
>  drivers/net/af_packet/rte_eth_af_packet.h          | 53 ----------------------
>  .../net/af_packet/rte_pmd_af_packet_version.map    |  3 --
>  5 files changed, 45 insertions(+), 65 deletions(-)  delete mode 100644
> drivers/net/af_packet/rte_eth_af_packet.h
> 
> diff --git a/doc/guides/rel_notes/release_2_3.rst
> b/doc/guides/rel_notes/release_2_3.rst
> index 7945694..da4abc3 100644
> --- a/doc/guides/rel_notes/release_2_3.rst
> +++ b/doc/guides/rel_notes/release_2_3.rst

The release_2_3.rst file has been renamed to release_16_04.rst so this patch no longer applies.

> @@ -39,6 +39,9 @@ This section should contain new features added in this
> release. Sample format:
> 
>    Enabled virtio 1.0 support for virtio pmd driver.
> 
> +* **Added af_packet dynamic removal function.**
> +
> +  Af_packet device can now be detached using API, like other PMD devices.
> 
>  Resolved Issues
>  ---------------
> @@ -91,6 +94,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.
> 
> +* Af_packet device init function is no longer public. Device should be
> +attached
> +  with API.
> +
> 
>  ABI Changes
>  -----------
> diff --git a/drivers/net/af_packet/Makefile
> b/drivers/net/af_packet/Makefile index ce5d239..cb1a7ae 100644
> --- a/drivers/net/af_packet/Makefile
> +++ b/drivers/net/af_packet/Makefile
> @@ -50,11 +50,6 @@ CFLAGS += $(WERROR_FLAGS)  #
>  SRCS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += rte_eth_af_packet.c
> 
> -#
> -# Export include files
> -#
> -SYMLINK-y-include += rte_eth_af_packet.h
> -
>  # this lib depends upon:
>  DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_mbuf
>  DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_ether diff -
> -git a/drivers/net/af_packet/rte_eth_af_packet.c
> b/drivers/net/af_packet/rte_eth_af_packet.c
> index 767f36b..5544528 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -53,8 +53,6 @@
>  #include <unistd.h>
>  #include <poll.h>
> 
> -#include "rte_eth_af_packet.h"
> -
>  #define ETH_AF_PACKET_IFACE_ARG		"iface"
>  #define ETH_AF_PACKET_NUM_Q_ARG		"qpairs"
>  #define ETH_AF_PACKET_BLOCKSIZE_ARG	"blocksz"
> @@ -65,6 +63,8 @@
>  #define DFLT_FRAME_SIZE		(1 << 11)
>  #define DFLT_FRAME_COUNT	(1 << 9)
> 
> +#define RTE_PMD_AF_PACKET_MAX_RINGS 16
> +
>  struct pkt_rx_queue {
>  	int sockfd;
> 
> @@ -667,11 +667,13 @@ rte_pmd_init_internals(const char *name,
>  	data->nb_tx_queues = (uint16_t)nb_queues;
>  	data->dev_link = pmd_link;
>  	data->mac_addrs = &(*internals)->eth_addr;
> +	strncpy(data->name,
> +		(*eth_dev)->data->name, strlen((*eth_dev)->data-
> >name));
> 
>  	(*eth_dev)->data = data;
>  	(*eth_dev)->dev_ops = &ops;
>  	(*eth_dev)->driver = NULL;
> -	(*eth_dev)->data->dev_flags = 0;
> +	(*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
>  	(*eth_dev)->data->drv_name = drivername;
>  	(*eth_dev)->data->kdrv = RTE_KDRV_NONE;
>  	(*eth_dev)->data->numa_node = numa_node; @@ -798,7 +800,7
> @@ rte_eth_from_packet(const char *name,
>  	return 0;
>  }
> 
> -int
> +static int
>  rte_pmd_af_packet_devinit(const char *name, const char *params)  {
>  	unsigned numa_node;
> @@ -836,10 +838,43 @@ exit:
>  	return ret;
>  }
> 
> +static int
> +rte_pmd_af_packet_devuninit(const char *name) {
> +	struct rte_eth_dev *eth_dev = NULL;
> +	struct pmd_internals *internals;
> +	unsigned q;
> +
> +	RTE_LOG(INFO, PMD, "Closing AF_PACKET ethdev on numa socket
> %u\n",
> +			rte_socket_id());
> +
> +	if (name == NULL)
> +		return -1;
> +
> +	/* find the ethdev entry */
> +	eth_dev = rte_eth_dev_allocated(name);
> +	if (eth_dev == NULL)
> +		return -1;
> +
> +	internals = eth_dev->data->dev_private;
> +	for (q = 0; q < internals->nb_queues; q++) {
> +		rte_free(internals->rx_queue[q].rd);
> +		rte_free(internals->tx_queue[q].rd);
> +	}
> +
> +	rte_free(eth_dev->data->dev_private);
> +	rte_free(eth_dev->data);
> +
> +	rte_eth_dev_release_port(eth_dev);
> +
> +	return 0;
> +}
> +
>  static struct rte_driver pmd_af_packet_drv = {
>  	.name = "eth_af_packet",
>  	.type = PMD_VDEV,
>  	.init = rte_pmd_af_packet_devinit,
> +	.uninit = rte_pmd_af_packet_devuninit,
>  };
> 
>  PMD_REGISTER_DRIVER(pmd_af_packet_drv);
> diff --git a/drivers/net/af_packet/rte_eth_af_packet.h
> b/drivers/net/af_packet/rte_eth_af_packet.h
> deleted file mode 100644
> index 5d1bc7e..0000000
> --- a/drivers/net/af_packet/rte_eth_af_packet.h
> +++ /dev/null
> @@ -1,53 +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.
> - */
> -
> -#ifndef _RTE_ETH_AF_PACKET_H_
> -#define _RTE_ETH_AF_PACKET_H_
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -#define RTE_PMD_AF_PACKET_MAX_RINGS 16
> -
> -/**
> - * For use by the EAL only. Called as part of EAL init to set up any dummy
> NICs
> - * configured on command line.
> - */
> -int rte_pmd_af_packet_devinit(const char *name, const char *params);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif
> diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map
> b/drivers/net/af_packet/rte_pmd_af_packet_version.map
> index de95169..ef35398 100644
> --- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
> +++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
> @@ -1,7 +1,4 @@
>  DPDK_2.0 {
> -	global:
> -
> -	rte_pmd_af_packet_devinit;
> 
>  	local: *;
>  };

Does making   rte_pmd_af_packet_devinit local result in an ABI breakage?
Should the DPDK_2.0 structure be kept and a DPDK_2.3 structure added?
A deprecation notice may need to be added to the doc/guides/rel_notes/deprecation.rst  file.

> --
> 1.9.1

Regards,

Bernard.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev
    @ 2016-02-24 17:08  4% ` Tomasz Kulasek
  2016-02-24 17:08  2%   ` [dpdk-dev] [PATCH v2 1/2] ethdev: add buffered tx api Tomasz Kulasek
  2016-02-25 16:17  0%   ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Ananyev, Konstantin
  1 sibling, 2 replies; 200+ results
From: Tomasz Kulasek @ 2016-02-24 17:08 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 callback is provided, which
frees the packets (as the default callback does), as well as updating a
user-provided counter, so that the number of dropped packets can be
tracked.

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);


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                      |   36 ++++
 lib/librte_ether/rte_ethdev.h                      |  182 +++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map             |    9 +
 13 files changed, 662 insertions(+), 542 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 1/2] ethdev: add buffered tx api
  2016-02-24 17:08  4% ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Tomasz Kulasek
@ 2016-02-24 17:08  2%   ` Tomasz Kulasek
  2016-02-25 16:17  0%   ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Ananyev, Konstantin
  1 sibling, 0 replies; 200+ results
From: Tomasz Kulasek @ 2016-02-24 17:08 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 callback is provided, which
frees the packets (as the default callback does), as well as updating a
user-provided counter, so that the number of dropped packets can be
tracked.

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

Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 lib/librte_ether/rte_ethdev.c          |   36 +++++++
 lib/librte_ether/rte_ethdev.h          |  182 +++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map |    9 ++
 3 files changed, 226 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 756b234..b8ab747 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1307,6 +1307,42 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
 }
 
 void
+rte_eth_count_unsent_packet_callback(struct rte_mbuf **pkts, uint16_t unsent,
+		void *userdata)
+{
+	uint64_t *count = userdata;
+	unsigned i;
+
+	for (i = 0; i < unsent; i++)
+		rte_pktmbuf_free(pkts[i]);
+
+	*count += unsent;
+}
+
+int
+rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
+		buffer_tx_error_fn cbfn, void *userdata)
+{
+	buffer->cbfn = cbfn;
+	buffer->userdata = userdata;
+	return 0;
+}
+
+int
+rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
+{
+	if (buffer == NULL)
+		return -EINVAL;
+
+	buffer->size = size;
+	if (buffer->cbfn == NULL)
+		rte_eth_tx_buffer_set_err_callback(buffer,
+				rte_eth_count_unsent_packet_callback, (void *)&buffer->errors);
+
+	return 0;
+}
+
+void
 rte_eth_promiscuous_enable(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..b0d4932 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.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
@@ -2655,6 +2655,186 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
 	return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
 }
 
+typedef void (*buffer_tx_error_fn)(struct rte_mbuf **unsent, uint16_t count,
+		void *userdata);
+
+/**
+ * Structure used to buffer packets for future TX
+ * Used by APIs rte_eth_tx_buffer and rte_eth_tx_buffer_flush
+ */
+struct rte_eth_dev_tx_buffer {
+	unsigned nb_pkts;
+	uint64_t errors;
+	/**< Total number of queue packets to sent that are dropped. */
+	buffer_tx_error_fn cbfn;
+	void *userdata;
+	uint16_t size;           /**< Size of buffer for buffered tx */
+	struct rte_mbuf *pkts[];
+};
+
+/**
+ * Calculate the size of the tx buffer.
+ *
+ * @param sz
+ *   Number of stored packets.
+ */
+#define RTE_ETH_TX_BUFFER_SIZE(sz) \
+	(sizeof(struct rte_eth_dev_tx_buffer) + (sz) * sizeof(struct rte_mbuf *))
+
+/**
+ * Initialize default values for buffered transmitting
+ *
+ * @param buffer
+ *   Tx buffer to be initialized.
+ * @param size
+ *   Buffer size
+ * @return
+ *   0 if no error
+ */
+int
+rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
+
+/**
+ * Send any packets queued up for transmission on a port and HW queue
+ *
+ * This causes an explicit flush of packets previously buffered via the
+ * rte_eth_tx_buffer() function. It returns the number of packets successfully
+ * sent to the NIC, and calls the error callback for any unsent packets. Unless
+ * explicitly set up otherwise, the default callback simply frees the unsent
+ * packets back to the owning mempool.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param queue_id
+ *   The index of the transmit queue through which output packets must be
+ *   sent.
+ *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
+ *   to rte_eth_dev_configure().
+ * @param buffer
+ *   Buffer of packets to be transmit.
+ * @return
+ *   The number of packets successfully sent to the Ethernet device. The error
+ *   callback is called for any packets which could not be sent.
+ */
+static inline uint16_t
+rte_eth_tx_buffer_flush(uint8_t port_id, uint16_t queue_id,
+		struct rte_eth_dev_tx_buffer *buffer)
+{
+	uint16_t sent;
+
+	uint16_t to_send = buffer->nb_pkts;
+
+	if (to_send == 0)
+		return 0;
+
+	sent = rte_eth_tx_burst(port_id, queue_id, buffer->pkts, to_send);
+
+	buffer->nb_pkts = 0;
+
+	/* All packets sent, or to be dealt with by callback below */
+	if (unlikely(sent != to_send))
+		buffer->cbfn(&buffer->pkts[sent], to_send - sent,
+				buffer->userdata);
+
+	return sent;
+}
+
+/**
+ * Buffer a single packet for future transmission on a port and queue
+ *
+ * This function takes a single mbuf/packet and buffers it for later
+ * transmission on the particular port and queue specified. Once the buffer is
+ * full of packets, an attempt will be made to transmit all the buffered
+ * packets. In case of error, where not all packets can be transmitted, a
+ * callback is called with the unsent packets as a parameter. If no callback
+ * is explicitly set up, the unsent packets are just freed back to the owning
+ * mempool. The function returns the number of packets actually sent i.e.
+ * 0 if no buffer flush occurred, otherwise the number of packets successfully
+ * flushed
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param queue_id
+ *   The index of the transmit queue through which output packets must be
+ *   sent.
+ *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
+ *   to rte_eth_dev_configure().
+ * @param buffer
+ *   Buffer used to collect packets to be sent.
+ * @param tx_pkt
+ *   Pointer to the packet mbuf to be sent.
+ * @return
+ *   0 = packet has been buffered for later transmission
+ *   N > 0 = packet has been buffered, and the buffer was subsequently flushed,
+ *     causing N packets to be sent, and the error callback to be called for
+ *     the rest.
+ */
+static inline uint16_t __attribute__((always_inline))
+rte_eth_tx_buffer(uint8_t port_id, uint16_t queue_id,
+		struct rte_eth_dev_tx_buffer *buffer, struct rte_mbuf *tx_pkt)
+{
+	buffer->pkts[buffer->nb_pkts++] = tx_pkt;
+	if (buffer->nb_pkts < buffer->size)
+		return 0;
+
+	return rte_eth_tx_buffer_flush(port_id, queue_id, buffer);
+}
+
+/**
+ * Configure a callback for buffered packets which cannot be sent
+ *
+ * Register a specific callback to be called when an attempt is made to send
+ * all packets buffered on an ethernet port, but not all packets can
+ * successfully be sent. The callback registered here will be called only
+ * from calls to rte_eth_tx_buffer() and rte_eth_tx_buffer_flush() APIs.
+ * The default callback configured for each queue by default just frees the
+ * packets back to the calling mempool. If additional behaviour is required,
+ * for example, to count dropped packets, or to retry transmission of packets
+ * which cannot be sent, this function should be used to register a suitable
+ * callback function to implement the desired behaviour.
+ * The example callback "rte_eth_count_unsent_packet_callback()" is also
+ * provided as reference.
+ *
+ * @param buffer
+ *   The port identifier of the Ethernet device.
+ * @param cbfn
+ *   The function to be used as the callback.
+ * @param userdata
+ *   Arbitrary parameter to be passed to the callback function
+ * @return
+ *   0 on success, or -1 on error with rte_errno set appropriately
+ */
+int
+rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
+		buffer_tx_error_fn cbfn, void *userdata);
+
+/**
+ * Callback function for tracking unsent buffered packets.
+ *
+ * This function can be passed to rte_eth_tx_buffer_set_err_callback() to
+ * adjust the default behaviour when buffered packets cannot be sent. This
+ * function drops any unsent packets, but also updates a user-supplied counter
+ * to track the overall number of packets dropped. The counter should be an
+ * uint64_t variable.
+ *
+ * NOTE: this function should not be called directly, instead it should be used
+ *       as a callback for packet buffering.
+ *
+ * NOTE: when configuring this function as a callback with
+ *       rte_eth_tx_buffer_set_err_callback(), the final, userdata parameter
+ *       should point to an uint64_t value.
+ *
+ * @param pkts
+ *   The previously buffered packets which could not be sent
+ * @param unsent
+ *   The number of unsent packets in the pkts array
+ * @param userdata
+ *   Pointer to an unsigned long value, which will be incremented by unsent
+ */
+void
+rte_eth_count_unsent_packet_callback(struct rte_mbuf **pkts, uint16_t unsent,
+		void *userdata);
+
 /**
  * The eth device event type for interrupt, and maybe others in the future.
  */
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..ad11c71 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,12 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_2.3 {
+	global:
+
+	rte_eth_count_unsent_packet_callback;
+	rte_eth_tx_buffer_init;
+	rte_eth_tx_buffer_set_err_callback;
+
+} DPDK_2.2;
-- 
1.7.9.5

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH 01/10] ethdev: add a generic flow and new behavior switch to fdir
  @ 2016-02-25  3:26  0%   ` Wu, Jingjing
  2016-02-25  9:11  0%     ` Rahul Lakkireddy
  0 siblings, 1 reply; 200+ results
From: Wu, Jingjing @ 2016-02-25  3:26 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: Kumar Sanghvi, Nirranjan Kirubaharan



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Rahul Lakkireddy
> Sent: Wednesday, February 03, 2016 4:32 PM
> To: dev@dpdk.org
> Cc: Kumar Sanghvi; Nirranjan Kirubaharan
> Subject: [dpdk-dev] [PATCH 01/10] ethdev: add a generic flow and new
> behavior switch to fdir
> 
> Add a new raw packet flow that allows specifying generic flow input.
> 
> Add the ability to provide masks for fields in flow to allow range of values.
> 
> Add a new behavior switch.
> 
> Add the ability to provide behavior arguments to allow rewriting matched
> fields with new values. Ex: allows to provide new ip and port addresses to
> rewrite the fields of packets matching a filter rule before NAT'ing.
> 
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> ---
>  doc/guides/rel_notes/release_2_3.rst |  3 +++
>  lib/librte_ether/rte_eth_ctrl.h      | 15 ++++++++++++++-
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/rel_notes/release_2_3.rst
> b/doc/guides/rel_notes/release_2_3.rst
> index 99de186..19ce954 100644
> --- a/doc/guides/rel_notes/release_2_3.rst
> +++ b/doc/guides/rel_notes/release_2_3.rst
> @@ -39,6 +39,9 @@ API Changes
>  ABI Changes
>  -----------
> 
> +* New flow type ``RTE_ETH_FLOW_RAW_PKT`` had been introduced and
> hence
> +  ``RTE_ETH_FLOW_MAX`` had been increased to 19.
> +
> 
Great to see a raw_pkt_flow type.
And there is already a flow type "RTE_ETH_FLOW_RAW", it's not necessary to add a new one.

>  Shared Library Versions
>  -----------------------
> diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
> index ce224ad..1bc0d03 100644
> --- a/lib/librte_ether/rte_eth_ctrl.h
> +++ b/lib/librte_ether/rte_eth_ctrl.h
> @@ -74,7 +74,8 @@ extern "C" {
>  #define RTE_ETH_FLOW_IPV6_EX            15
>  #define RTE_ETH_FLOW_IPV6_TCP_EX        16
>  #define RTE_ETH_FLOW_IPV6_UDP_EX        17
> -#define RTE_ETH_FLOW_MAX                18
> +#define RTE_ETH_FLOW_RAW_PKT            18
> +#define RTE_ETH_FLOW_MAX                19
> 
>  /**
>   * Feature filter types
> @@ -499,6 +500,9 @@ struct rte_eth_tunnel_flow {
>  	struct ether_addr mac_addr;                /**< Mac address to match. */
>  };
> 
> +/**< Max length of raw packet in bytes. */ #define
> +RTE_ETH_RAW_PKT_FLOW_MAX_LEN 256
> +
>  /**
>   * An union contains the inputs for all types of flow
>   */
> @@ -514,6 +518,7 @@ union rte_eth_fdir_flow {
>  	struct rte_eth_ipv6_flow   ipv6_flow;
>  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
>  	struct rte_eth_tunnel_flow   tunnel_flow;
> +	uint8_t raw_pkt_flow[RTE_ETH_RAW_PKT_FLOW_MAX_LEN];
>  };
> 
>  /**
> @@ -534,6 +539,8 @@ struct rte_eth_fdir_input {
>  	uint16_t flow_type;
>  	union rte_eth_fdir_flow flow;
>  	/**< Flow fields to match, dependent on flow_type */
> +	union rte_eth_fdir_flow flow_mask;
> +	/**< Mask for the fields matched, dependent on flow */
>  	struct rte_eth_fdir_flow_ext flow_ext;
>  	/**< Additional fields to match */
>  };
> @@ -545,6 +552,7 @@ enum rte_eth_fdir_behavior {
>  	RTE_ETH_FDIR_ACCEPT = 0,
>  	RTE_ETH_FDIR_REJECT,
>  	RTE_ETH_FDIR_PASSTHRU,
> +	RTE_ETH_FDIR_SWITCH,
>  };
> 
>  /**
> @@ -558,6 +566,9 @@ enum rte_eth_fdir_status {
>  	RTE_ETH_FDIR_REPORT_FLEX_8,        /**< Report 8 flex bytes. */
>  };
> 
> +/**< Max # of behavior arguments */
> +#define RTE_ETH_BEHAVIOR_ARG_MAX_LEN 256
> +
>  /**
>   * A structure used to define an action when match FDIR packet filter.
>   */
> @@ -569,6 +580,8 @@ struct rte_eth_fdir_action {
>  	/**< If report_status is RTE_ETH_FDIR_REPORT_ID_FLEX_4 or
>  	     RTE_ETH_FDIR_REPORT_FLEX_8, flex_off specifies where the
> reported
>  	     flex bytes start from in flexible payload. */
> +	uint8_t behavior_arg[RTE_ETH_BEHAVIOR_ARG_MAX_LEN];
> +	/**< Extra arguments for behavior taken */
>  };
> 
>  /**
> --
> 2.5.3

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 01/10] ethdev: add a generic flow and new behavior switch to fdir
  2016-02-25  3:26  0%   ` Wu, Jingjing
@ 2016-02-25  9:11  0%     ` Rahul Lakkireddy
  0 siblings, 0 replies; 200+ results
From: Rahul Lakkireddy @ 2016-02-25  9:11 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev, Kumar A S, Nirranjan Kirubaharan

Hi Jingjing,

On Wednesday, February 02/24/16, 2016 at 19:26:54 -0800, Wu, Jingjing wrote:
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Rahul Lakkireddy
> > Sent: Wednesday, February 03, 2016 4:32 PM
> > To: dev@dpdk.org
> > Cc: Kumar Sanghvi; Nirranjan Kirubaharan
> > Subject: [dpdk-dev] [PATCH 01/10] ethdev: add a generic flow and new
> > behavior switch to fdir
> > 
> > Add a new raw packet flow that allows specifying generic flow input.
> > 
> > Add the ability to provide masks for fields in flow to allow range of values.
> > 
> > Add a new behavior switch.
> > 
> > Add the ability to provide behavior arguments to allow rewriting matched
> > fields with new values. Ex: allows to provide new ip and port addresses to
> > rewrite the fields of packets matching a filter rule before NAT'ing.
> > 
> > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> > Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> > ---
> >  doc/guides/rel_notes/release_2_3.rst |  3 +++
> >  lib/librte_ether/rte_eth_ctrl.h      | 15 ++++++++++++++-
> >  2 files changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/doc/guides/rel_notes/release_2_3.rst
> > b/doc/guides/rel_notes/release_2_3.rst
> > index 99de186..19ce954 100644
> > --- a/doc/guides/rel_notes/release_2_3.rst
> > +++ b/doc/guides/rel_notes/release_2_3.rst
> > @@ -39,6 +39,9 @@ API Changes
> >  ABI Changes
> >  -----------
> > 
> > +* New flow type ``RTE_ETH_FLOW_RAW_PKT`` had been introduced and
> > hence
> > +  ``RTE_ETH_FLOW_MAX`` had been increased to 19.
> > +
> > 
> Great to see a raw_pkt_flow type.
> And there is already a flow type "RTE_ETH_FLOW_RAW", it's not necessary to add a new one.

I added a new type based on your feedback only
http://permalink.gmane.org/gmane.comp.networking.dpdk.devel/31386

So, do you want me to revert this change and use RTE_ETH_FLOW_RAW
instead ?


Thanks,
Rahul.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 4/6] bond mode 4: allow external state machine
  2016-02-22 13:03  4%     ` Panu Matilainen
@ 2016-02-25 15:22  0%       ` Iremonger, Bernard
  2016-03-01 17:40  0%         ` Eric Kinzie
  0 siblings, 1 reply; 200+ results
From: Iremonger, Bernard @ 2016-02-25 15:22 UTC (permalink / raw)
  To: Eric Kinzie, dev

Hi Eric,
<snip>

> > @@ -157,6 +159,7 @@ struct rte_eth_bond_8023ad_conf {
> >   	uint32_t tx_period_ms;
> >   	uint32_t rx_marker_period_ms;
> >   	uint32_t update_timeout_ms;
> > +	rte_eth_bond_8023ad_ext_slowrx_fn slowrx_cb;
> >   };
> 
> This still is a likely an ABI break, previously discussed around here:
> http://dpdk.org/ml/archives/dev/2015-November/027321.html
> 
> It might not be embedded anywhere in DPDK codebase, but there's no
> telling what others might have done with it (have an array of them, embed in
> other structs etc).
> 
> Also ultimately ABI compatibility goes both ways: when the library soname
> does not change then an application is free to assume both downgrading and
> upgrading are safe. In this case, upgrading *might* be okay, downgrading
> certainly is not. So by that measure it definitely is an ABI break.
> 
> [...]
> > diff --git a/drivers/net/bonding/rte_eth_bond_version.map
> > b/drivers/net/bonding/rte_eth_bond_version.map
> > index 22bd920..33d73ff 100644
> > --- a/drivers/net/bonding/rte_eth_bond_version.map
> > +++ b/drivers/net/bonding/rte_eth_bond_version.map
> > @@ -27,3 +27,9 @@ DPDK_2.1 {
> >   	rte_eth_bond_free;
> >
> >   } DPDK_2.0;
> > +
> > +DPDK_2.2 {
> > +	rte_eth_bond_8023ad_ext_collect;
> > +	rte_eth_bond_8023ad_ext_distrib;
> > +	rte_eth_bond_8023ad_ext_slowtx;
> > +} DPDK_2.1;
> >
> 
> These symbols are not part of DPDK 2.2, the version here is wrong.
> Technically it would not actually matter much but better not to confuse
> things unnecessarily.
> 
> 	- Panu -

It looks like Panu's points are valid, a V3 of this patch set which takes care of these issues will be needed.

Patches 1/6, 5/6 and 6/6 of the patch set are bug fixes, so each patch should contain a fixes line.
Patches 2/6, 3/6 and 4/6 are a new feature, the release notes should be updated for this feature.

Could I suggest splitting the patch set into two patch sets, a bug fix patch set and a new feature patch set.

Regards,

Bernard.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev
  2016-02-24 17:08  4% ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Tomasz Kulasek
  2016-02-24 17:08  2%   ` [dpdk-dev] [PATCH v2 1/2] ethdev: add buffered tx api Tomasz Kulasek
@ 2016-02-25 16:17  0%   ` Ananyev, Konstantin
  1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2016-02-25 16:17 UTC (permalink / raw)
  To: Kulasek, TomaszX, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Tomasz Kulasek
> Sent: Wednesday, February 24, 2016 5:09 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 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 callback is provided, which
> frees the packets (as the default callback does), as well as updating a
> user-provided counter, so that the number of dropped packets can be
> tracked.
> 
> 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);
> 
> 
> 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                      |   36 ++++
>  lib/librte_ether/rte_ethdev.h                      |  182 +++++++++++++++++++-
>  lib/librte_ether/rte_ether_version.map             |    9 +
>  13 files changed, 662 insertions(+), 542 deletions(-)
> 


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

> --
> 1.7.9.5

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-24 13:23  3%               ` Ananyev, Konstantin
@ 2016-02-26  7:39  0%                 ` Xie, Huawei
  2016-02-26  8:45  0%                   ` Olivier MATZ
  2016-02-29 10:51  4%                 ` Panu Matilainen
  1 sibling, 1 reply; 200+ results
From: Xie, Huawei @ 2016-02-26  7:39 UTC (permalink / raw)
  To: Ananyev, Konstantin, Panu Matilainen, Olivier MATZ, dev; +Cc: dprovan

On 2/24/2016 9:23 PM, Ananyev, Konstantin wrote:
> Hi Panu,
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Panu Matilainen
>> Sent: Wednesday, February 24, 2016 12:12 PM
>> To: Xie, Huawei; Olivier MATZ; dev@dpdk.org
>> Cc: dprovan@bivio.net
>> Subject: Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
>>
>> On 02/23/2016 07:35 AM, Xie, Huawei wrote:
>>> On 2/22/2016 10:52 PM, Xie, Huawei wrote:
>>>> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
>>>>> Hi,
>>>>>
>>>>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>>>>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
>>>>>> the library ABI and should not be listed in the version map.
>>>>>>
>>>>>> I assume its inline for performance reasons, but then you lose the
>>>>>> benefits of dynamic linking such as ability to fix bugs and/or improve
>>>>>> itby just updating the library. Since the point of having a bulk API is
>>>>>> to improve performance by reducing the number of calls required, does it
>>>>>> really have to be inline? As in, have you actually measured the
>>>>>> difference between inline and non-inline and decided its worth all the
>>>>>> downsides?
>>>>> Agree with Panu. It would be interesting to compare the performance
>>>>> between inline and non inline to decide whether inlining it or not.
>>>> Will update after i gathered more data. inline could show obvious
>>>> performance difference in some cases.
>>> Panu and Oliver:
>>> I write a simple benchmark. This benchmark run 10M rounds, in each round
>>> 8 mbufs are allocated through bulk API, and then freed.
>>> These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
>>> 2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
>>> Btw, i have removed some exceptional data, the frequency of which is
>>> like 1/10. Sometimes observed user usage suddenly disappeared, no clue
>>> what happened.
>>>
>>> With 8 mbufs allocated, there is about 6% performance increase using inline.
>> [...]
>>> With 16 mbufs allocated, we could still observe obvious performance
>>> difference, though only 1%-2%
>>>
>> [...]
>>> With 32/64 mbufs allocated, the deviation of the data itself would hide
>>> the performance difference.
>>> So we prefer using inline for performance.
>> At least I was more after real-world performance in a real-world
>> use-case rather than CPU cycles in a microbenchmark, we know function
>> calls have a cost but the benefits tend to outweight the cons.

It depends on what could be called the real world case. It could be
argued. I think the case Konstantin mentioned could be called a real
world one.
If your opinion on whether use benchmark or real-world use case is not
specific to this bulk API, then i have different opinion. For example,
for kernel virtio optimization, people use vring bench. We couldn't
guarantee each small optimization could bring obvious performance gain
in some big workload. The gain could be hided if bottleneck is
elsewhere, so i also plan to build such kind of virtio bench in DPDK.

Finally, i am open to inline or not, but currently priority better goes
with performance. If we make it an API now, we couldn't easily step back
in future; But we could change otherwise, after we have more confidence.
We could even check every inline "API", whether it should be inline or
be in the lib.

>>
>> Inline functions have their place and they're far less evil in project
>> internal use, but in library public API they are BAD and should be ...
>> well, not banned because there are exceptions to every rule, but highly
>> discouraged.
> Why is that?
> As you can see right now we have all mbuf alloc/free routines as static inline.
> And I think we would like to keep it like that.
> So why that particular function should be different?
> After all that function is nothing more than a wrapper 
> around rte_mempool_get_bulk()  unrolled by 4 loop {rte_pktmbuf_reset()}
> So unless mempool get/put API would change, I can hardly see there could be any ABI
> breakages in future. 
> About 'real world' performance gain - it was a 'real world' performance problem,
> that we tried to solve by introducing that function:
> http://dpdk.org/ml/archives/dev/2015-May/017633.html
>
> And according to the user feedback, it does help:  
> http://dpdk.org/ml/archives/dev/2016-February/033203.html
>
> Konstantin
>
>> 	- Panu -
>>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 0/3] support setting i40e VF MAC address from DPDK host side
  @ 2016-02-26  8:14  4% ` Pei, Yulong
  0 siblings, 0 replies; 200+ results
From: Pei, Yulong @ 2016-02-26  8:14 UTC (permalink / raw)
  To: Zhang, Helin, dev

Tested-by: yulong.pei@intel.com

-----Original Message-----
From: Zhang, Helin 
Sent: Thursday, January 28, 2016 4:40 PM
To: dev@dpdk.org
Cc: Pei, Yulong <yulong.pei@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Tao, Zhe <zhe.tao@intel.com>; Xu, Qian Q <qian.q.xu@intel.com>; Zhang, Helin <helin.zhang@intel.com>
Subject: [PATCH 0/3] support setting i40e VF MAC address from DPDK host side

It adds pre-setting i40e VF MAC addresses from DPDK PF host side, during host port initialization, by introduing a new port configuration element. It then can pre-set VF MAC addresses before any launching VFs, and the VF MAC addresses will not be random each time launching a VF.
There should be no ABI broken, as ABI changes in 'struct rte_eth_conf' has already been announced in R2.2.

Helin Zhang (3):
  i40e: add setting VF MAC address in DPDK PF host
  i40evf: use ether interface for validating MAC address
  app/testpmd: set default MAC addresses for each VF

 app/test-pmd/testpmd.c               | 19 +++++++++++++++++++
 doc/guides/rel_notes/release_2_3.rst |  9 +++++++++
 drivers/net/i40e/i40e_ethdev.c       | 21 +++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h       |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c    | 14 +++++++-------
 drivers/net/i40e/i40e_pf.c           |  2 ++
 lib/librte_ether/rte_ethdev.h        | 10 ++++++++++
 7 files changed, 69 insertions(+), 7 deletions(-)

--
2.5.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-02-26  8:35  4%   ` Wenzhuo Lu
  0 siblings, 0 replies; 200+ results
From: Wenzhuo Lu @ 2016-02-26  8: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>
---
 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          | 18 ++++++++++++++
 4 files changed, 68 insertions(+), 3 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..f1f96c1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -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;
 };
 
 /**
@@ -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);
+int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
  * 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);
 
 /**
  * Check whether the filter type is supported on an Ethernet device.
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-26  7:39  0%                 ` Xie, Huawei
@ 2016-02-26  8:45  0%                   ` Olivier MATZ
  0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2016-02-26  8:45 UTC (permalink / raw)
  To: Xie, Huawei, Ananyev, Konstantin, Panu Matilainen, dev; +Cc: dprovan



On 02/26/2016 08:39 AM, Xie, Huawei wrote:
>>>> With 8 mbufs allocated, there is about 6% performance increase using inline.
>>>> With 16 mbufs allocated, we could still observe obvious performance
>>>> difference, though only 1%-2%
> 

> On 2/24/2016 9:23 PM, Ananyev, Konstantin wrote:
>> As you can see right now we have all mbuf alloc/free routines as static inline.
>> And I think we would like to keep it like that.
>> So why that particular function should be different?
>> After all that function is nothing more than a wrapper 
>> around rte_mempool_get_bulk()  unrolled by 4 loop {rte_pktmbuf_reset()}
>> So unless mempool get/put API would change, I can hardly see there could be any ABI
>> breakages in future. 
>> About 'real world' performance gain - it was a 'real world' performance problem,
>> that we tried to solve by introducing that function:
>> http://dpdk.org/ml/archives/dev/2015-May/017633.html
>>
>> And according to the user feedback, it does help:  
>> http://dpdk.org/ml/archives/dev/2016-February/033203.html

For me, there's no doubt this function will help in real world use
cases. That's also true that today most (oh no, all) datapath mbuf
functions are inline. Although I understand Panu's point of view
about the use of inline functions, trying to de-inline some functions
of the mbuf API (and others APIs like mempool or ring) would require
a deep analysis first to check the performance impact. And I think there
would be an impact for most of them.

In this particular case, as the function does bulk allocations, it
probably tempers the cost of the function call, and that's why I
was curious of any comparison with/without inlining. But I'm not
sure having this only function as non-inline makes a lot of sense.

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

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder
  @ 2016-02-26 14:10  1%     ` Ferruh Yigit
    1 sibling, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-02-26 14:10 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>
---
 config/common_linuxapp                     |   5 +
 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 +
 25 files changed, 2236 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_linuxapp b/config/common_linuxapp
index f1638db..960dde4 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -497,6 +497,11 @@ CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
 CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=y
+
+#
 # Compile vhost library
 # fuse-devel is needed to run vhost-cuse.
 # fuse-devel enables user space char driver development
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 8273817..70338f1 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -129,6 +129,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 ef172ea..ce8f0f9 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..4544c3a
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,28 @@
+DPDK_2.3 {
+	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 8ecab41..32f76b1 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -122,6 +122,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 v2 1/3] cmdline: increase command line buffer
  @ 2016-02-26 15:16  0%             ` Nélio Laranjeiro
  0 siblings, 0 replies; 200+ results
From: Nélio Laranjeiro @ 2016-02-26 15:16 UTC (permalink / raw)
  To: john.mcnamara; +Cc: dev

On Mon, Jan 18, 2016 at 03:38:43PM +0100, Olivier MATZ wrote:
> Hi,
> 
> On 01/15/2016 10:00 AM, Panu Matilainen wrote:
> >>>> diff --git a/lib/librte_cmdline/cmdline_rdline.h
> >>>> b/lib/librte_cmdline/cmdline_rdline.h
> >>>> index b9aad9b..72e2dad 100644
> >>>> --- a/lib/librte_cmdline/cmdline_rdline.h
> >>>> +++ b/lib/librte_cmdline/cmdline_rdline.h
> >>>> @@ -93,7 +93,7 @@ extern "C" {
> >>>>   #endif
> >>>>
> >>>>   /* configuration */
> >>>> -#define RDLINE_BUF_SIZE 256
> >>>> +#define RDLINE_BUF_SIZE 512
> >>>>   #define RDLINE_PROMPT_SIZE  32
> >>>>   #define RDLINE_VT100_BUF_SIZE  8
> >>>>   #define RDLINE_HISTORY_BUF_SIZE BUFSIZ
> >>>
> >>> Having to break a library ABI for a change like this is a bit
> >>> ridiculous.
> >>
> >> Sure, but John McNamara needed it to handle flow director with IPv6[1].
> >>
> >> For my part, I was needing it to manipulate the RETA table, but as I
> >> wrote in the cover letter, it ends by breaking other commands.
> >> Olivier Matz, has proposed another way to handle long commands lines[2],
> >> it could be a good idea to go on this direction.
> >>
> >> For RETA situation, we already discussed on a new API, but for now, I
> >> do not have time for it (and as it is another ABI breakage it could only
> >> be done for 16.07 or 2.4)[3].
> >>
> >> If this patch is no more needed we can just drop it, for that I would
> >> like to have the point of view from John.
> > 
> > Note that I was not objecting to the patch as such, I can easily see 256
> > characters not being enough for commandline buffer.
> > 
> > I was merely noting that having to break an ABI to increase an
> > effectively internal buffer size is a sign of a, um, less-than-optimal
> > library design.
> 
> You are right about the cmdline ABI. Changing this buffer size
> should not imply an ABI change. I'll try to find some time to
> investigate this issue.
> 
> Another question we could raise is: should we export the API of
> librte_cmdline to external applications? Now that baremetal dpdk is
> not supported, having this library in dpdk is probably useless as
> we can surely find standard replacements for it. A first step could
> be to mark it as "internal".
> 
> About the patch Nélio's patch itself, I'm not so convinced having more
> than 256 characters is absolutely required, and I would prefer to see
> the commands beeing reworked to be more human-readable. On the other
> hand, the ABI breakage was announced so there is no reason to nack
> this patch now.
> 
> Regards,
> Olivier

John,

What is your position about this patch?
Is it still needed?

Regards,

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
  2016-02-18 18:14  0%     ` Mcnamara, John
@ 2016-02-28 22:17  0%       ` Marc
  0 siblings, 0 replies; 200+ results
From: Marc @ 2016-02-28 22:17 UTC (permalink / raw)
  To: Mcnamara, John; +Cc: dev

On 18 February 2016 at 19:14, Mcnamara, John <john.mcnamara@intel.com>
wrote:

> Hi,
>
> Some minor comments below in order to get a consistent set of release
> notes.
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
> > Sent: Sunday, February 14, 2016 10:18 PM
> > To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Zhang, Helin
> > <helin.zhang@intel.com>; Harish Patil <harish.patil@qlogic.com>; Chen,
> > Jing D <jing.d.chen@intel.com>
> > Subject: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
> >
> > Add new features, ABI changes and resolved issues notice for the
> > refactored link patch.
> >
> > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > ---
> >  doc/guides/rel_notes/release_2_3.rst | 102
>
> This should be rebased and the notes added to
> doc/guides/rel_notes/release_16_04.rst.
>
>
> > +
> > +* **ethdev: define a set of advertised link speeds.**
>
> The title and the text should be in the past tense.
>
>
> See the hints/guidelines in the updated release notes:
>
>
> http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst
>
>
> > +
> > +  Allowing to define a set of advertised speeds for auto-negociation,
>
> Maybe something like: Added functionality to allow the definition of
> advertised speeds for ...
>
>
>
> > +* **ethdev: add speed_cap bitmap to recover eth device link speed
> > +capabilities
> > +  define a set of advertised link speeds.**
>
> The title is a little long. Just give a brief overview here and more the
> detail
> to the text sections.
>
> > +
> > +  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows
> > + the  application to recover the supported speeds for that ethernet
> > device.
>
> It would be good to use ```` quotes on speed_cap as well for consistency.
>
>
> +
> > +Examples
> > +~~~~~~~~
> > +
> > +* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical
> > +speeds  to bitmap fields.
>
> I don't think this should be in the "Examples" section. Maybe as a sub-item
> in the "New Featrues" or in "API Changes" if it is a change.
>
> > +
> > +ABI Changes
> > +-----------
> > +
> > +* The ethdev rte_eth_link and rte_eth_conf structures were changed to
> > +  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
> > +
> > +* The ethdev rte_eth_dev_info was changed to support device speed
> > capabilities.
>
> Better to put the struct names and variables in ```` quotes.
>
> Thanks,
>

Noted and fixed in v9.

Thanks
marc


>
> John.
> -
>
>
>
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-24 13:23  3%               ` Ananyev, Konstantin
  2016-02-26  7:39  0%                 ` Xie, Huawei
@ 2016-02-29 10:51  4%                 ` Panu Matilainen
  2016-02-29 16:14  0%                   ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Panu Matilainen @ 2016-02-29 10:51 UTC (permalink / raw)
  To: Ananyev, Konstantin, Xie, Huawei, Olivier MATZ, dev; +Cc: dprovan

On 02/24/2016 03:23 PM, Ananyev, Konstantin wrote:
> Hi Panu,
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Panu Matilainen
>> Sent: Wednesday, February 24, 2016 12:12 PM
>> To: Xie, Huawei; Olivier MATZ; dev@dpdk.org
>> Cc: dprovan@bivio.net
>> Subject: Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
>>
>> On 02/23/2016 07:35 AM, Xie, Huawei wrote:
>>> On 2/22/2016 10:52 PM, Xie, Huawei wrote:
>>>> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
>>>>> Hi,
>>>>>
>>>>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
>>>>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
>>>>>> the library ABI and should not be listed in the version map.
>>>>>>
>>>>>> I assume its inline for performance reasons, but then you lose the
>>>>>> benefits of dynamic linking such as ability to fix bugs and/or improve
>>>>>> itby just updating the library. Since the point of having a bulk API is
>>>>>> to improve performance by reducing the number of calls required, does it
>>>>>> really have to be inline? As in, have you actually measured the
>>>>>> difference between inline and non-inline and decided its worth all the
>>>>>> downsides?
>>>>> Agree with Panu. It would be interesting to compare the performance
>>>>> between inline and non inline to decide whether inlining it or not.
>>>> Will update after i gathered more data. inline could show obvious
>>>> performance difference in some cases.
>>>
>>> Panu and Oliver:
>>> I write a simple benchmark. This benchmark run 10M rounds, in each round
>>> 8 mbufs are allocated through bulk API, and then freed.
>>> These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
>>> 2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
>>> Btw, i have removed some exceptional data, the frequency of which is
>>> like 1/10. Sometimes observed user usage suddenly disappeared, no clue
>>> what happened.
>>>
>>> With 8 mbufs allocated, there is about 6% performance increase using inline.
>> [...]
>>>
>>> With 16 mbufs allocated, we could still observe obvious performance
>>> difference, though only 1%-2%
>>>
>> [...]
>>>
>>> With 32/64 mbufs allocated, the deviation of the data itself would hide
>>> the performance difference.
>>> So we prefer using inline for performance.
>>
>> At least I was more after real-world performance in a real-world
>> use-case rather than CPU cycles in a microbenchmark, we know function
>> calls have a cost but the benefits tend to outweight the cons.
>>
>> Inline functions have their place and they're far less evil in project
>> internal use, but in library public API they are BAD and should be ...
>> well, not banned because there are exceptions to every rule, but highly
>> discouraged.
>
> Why is that?

For all the reasons static linking is bad, and what's worse it forces 
the static linking badness into dynamically linked builds.

If there's a bug (security or otherwise) in a library, a distro wants to 
supply an updated package which fixes that bug and be done with it. But 
if that bug is in an inlined code, supplying an update is not enough, 
you also need to recompile everything using that code, and somehow 
inform customers possibly using that code that they need to not only 
update the library but to recompile their apps as well. That is 
precisely the reason distros go to great lenghts to avoid *any* 
statically linked apps and libs in the distro, completely regardless of 
the performance overhead.

In addition, inlined code complicates ABI compatibility issues because 
some of the code is one the "wrong" side, and worse, it bypasses all the 
other ABI compatibility safeguards like soname and symbol versioning.

Like said, inlined code is fine for internal consumption, but incredibly 
bad for public interfaces. And of course, the more complicated a 
function is, greater the potential of needing bugfixes.

Mind you, none of this is magically specific to this particular 
function. Except in the sense that bulk operations offer a better way of 
performance improvements than just inlining everything.

> As you can see right now we have all mbuf alloc/free routines as static inline.
> And I think we would like to keep it like that.
> So why that particular function should be different?

Because there's much less need to have it inlined since the function 
call overhead is "amortized" by the fact its doing bulk operations. "We 
always did it that way" is not a very good reason :)

> After all that function is nothing more than a wrapper
> around rte_mempool_get_bulk()  unrolled by 4 loop {rte_pktmbuf_reset()}
> So unless mempool get/put API would change, I can hardly see there could be any ABI
> breakages in future.
> About 'real world' performance gain - it was a 'real world' performance problem,
> that we tried to solve by introducing that function:
> http://dpdk.org/ml/archives/dev/2015-May/017633.html
>
> And according to the user feedback, it does help:
> http://dpdk.org/ml/archives/dev/2016-February/033203.html

The question is not whether the function is useful, not at all. The 
question is whether the real-world case sees any measurable difference 
in performance if the function is made non-inline.

	- Panu -

> Konstantin
>
>>
>> 	- Panu -
>>
>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v5 01/11] ethdev: add API to query packet type filling info
  @ 2016-02-29 11:34  3%     ` Panu Matilainen
  2016-02-29 16:41  0%       ` Tan, Jianfeng
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-02-29 11:34 UTC (permalink / raw)
  To: dev, Jianfeng Tan

On 02/26/2016 09:34 AM, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> type can be filled by given pmd rx burst function.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>   lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
>   lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
>   2 files changed, 52 insertions(+)
>
[...]
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..16f32a0 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 eth_rx_burst_t. */
> +
>   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,28 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);

Technically this is an ABI break but its marked internal and I guess it 
falls into the "drivers only" territory similar to what was discussed in 
this thead: http://dpdk.org/ml/archives/dev/2016-January/032348.html so 
its probably ok.

>   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.
> + *
> + * @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.
> + */
> +extern 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
>

"extern" is redundant in headers. We just saw a round of removing them 
(commit dd34ff1f0e03b2c5e4a97e9fbcba5c8238aac573), lets not add them back :)

More importantly, to export a function you need to add an entry for it 
in rte_ether_version.map.

	- Panu -

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 1/2] librte_pipeline: add support for packet redirection at action handlers
  @ 2016-02-29 14:50  4% ` Jasvinder Singh
  2016-03-02 20:41  4%   ` [dpdk-dev] [PATCH v3 " Jasvinder Singh
  0 siblings, 1 reply; 200+ results
From: Jasvinder Singh @ 2016-02-29 14:50 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). Therefore, new
pipeline API functions have been added which allows action handlers to
hijack packets and remove them from the pipeline processing, and then either
drop them or send them out of the pipeline on any output port. The port
(in/out) and table action handler prototypes have been changed for making
use of these new API functions. 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>
---
v2:
* rebased on master

 doc/guides/rel_notes/deprecation.rst         |   5 -
 doc/guides/rel_notes/release_16_04.rst       |   6 +-
 lib/librte_pipeline/Makefile                 |   4 +-
 lib/librte_pipeline/rte_pipeline.c           | 461 ++++++++++++++-------------
 lib/librte_pipeline/rte_pipeline.h           |  98 +++---
 lib/librte_pipeline/rte_pipeline_version.map |   8 +
 6 files changed, 308 insertions(+), 274 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..1a7d660 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -40,11 +40,6 @@ 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.
-
 * ABI changes are planned in cmdline buffer size to allow the use of long
   commands (such as RETA update in testpmd).  This should impact
   CMDLINE_PARSE_RESULT_BUFSIZE, STR_TOKEN_SIZE and RDLINE_BUF_SIZE.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index e2219d0..bbfd248 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -118,6 +118,10 @@ 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.
 
+* 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
 -----------------------
@@ -144,7 +148,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/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..87f7634 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;
 
-		/* Input port user actions */
-		if (port_in->f_action != NULL) {
-			uint64_t mask = pkts_mask;
+	if (port_in == NULL)
+		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);
-		}
+	/* 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;
+	}
 
-		/* 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);
-					}
-				}
-			}
+	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;
+
+	/* 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 */
+		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;
 
-			/* 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]);
+			/* 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 reserved action PORT META */
-		rte_pipeline_action_handler_port_meta(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
+			/* Table user actions */
+			if (table->f_action_hit != NULL) {
+				table->f_action_hit(p,
+					p->pkts,
+					lookup_hit_mask,
+					p->entries,
+					table->arg_ah);
 
-		/* Table reserved action DROP */
-		rte_pipeline_action_handler_drop(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					table->n_pkts_dropped_by_lkp_hit_ah);
+			}
+
+			/* 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);
+		}
+
+		/* 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 n_pkts;
 }
 
 int
@@ -1498,26 +1503,32 @@ 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;
+}
+
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+
+	return 0;
+}
+
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+	p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
 
+	RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
 	return 0;
 }
 
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 7302a62..f25ef69 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
@@ -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,29 +696,6 @@ 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
  *
  * The action handler can decide to drop packets by resetting the associated
@@ -722,22 +703,21 @@ typedef int (*rte_pipeline_port_out_action_handler)(
  * 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 pkts_mask
- *   64-bit bitmask specifying which packets in the input burst are valid. When
- *   pkts_mask bit n is set, then element n of pkts array is pointing to a
- *   valid packet. Otherwise, element n of pkts array will not be accessed.
  * @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_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 +730,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;
 };
@@ -802,6 +779,45 @@ int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
 	struct rte_mbuf *pkt);
 
 /**
+ * Pipeline packet hijack
+ *
+ * This function is called by the pipeline action handlers (port in/out, table)
+ * to hijack the packets selected using packet mask. The hijacked packets will
+ * no longer bethe part of the burst of packets undergoing pipeline processing.
+ * The hijacked packets can either be dropped or sent out of the pipeline on
+ * any output port by the action handler.
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param pkt_mask
+ *  64-bit bitmask specifying which packets in the input burst are valid. When
+ *  pkts_mask bit n is set, then element n of pkts array is pointing to a
+ *  valid packet. Otherwise, element n of pkts array will not be accessed.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
+/**
+ * Pipeline packet drop
+ *
+ * This function is called by the pipeline action handlers (port in/out, table)
+ * to drop the packets selected using packet mask.
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which packets in the input burst are valid. When
+ *   pkts_mask bit n is set, then element n of pkts array is pointing to a
+ *   valid packet. Otherwise, element n of pkts array will not be accessed.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
+/**
  * Read pipeline port out stats.
  *
  * This function reads port out statistics identified by *port_id* of given
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 4cc86f6..e4ee154 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -37,3 +37,11 @@ DPDK_2.2 {
 	rte_pipeline_table_entry_delete_bulk;
 
 } DPDK_2.1;
+
+DPDK_16.04 {
+	global:
+
+	rte_pipeline_ah_packet_hijack;
+	rte_pipeline_ah_packet_drop;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API
  2016-02-29 10:51  4%                 ` Panu Matilainen
@ 2016-02-29 16:14  0%                   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-02-29 16:14 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: dev, dprovan

2016-02-29 12:51, Panu Matilainen:
> On 02/24/2016 03:23 PM, Ananyev, Konstantin wrote:
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Panu Matilainen
> >> On 02/23/2016 07:35 AM, Xie, Huawei wrote:
> >>> On 2/22/2016 10:52 PM, Xie, Huawei wrote:
> >>>> On 2/4/2016 1:24 AM, Olivier MATZ wrote:
> >>>>> On 01/27/2016 02:56 PM, Panu Matilainen wrote:
> >>>>>> Since rte_pktmbuf_alloc_bulk() is an inline function, it is not part of
> >>>>>> the library ABI and should not be listed in the version map.
> >>>>>>
> >>>>>> I assume its inline for performance reasons, but then you lose the
> >>>>>> benefits of dynamic linking such as ability to fix bugs and/or improve
> >>>>>> itby just updating the library. Since the point of having a bulk API is
> >>>>>> to improve performance by reducing the number of calls required, does it
> >>>>>> really have to be inline? As in, have you actually measured the
> >>>>>> difference between inline and non-inline and decided its worth all the
> >>>>>> downsides?
> >>>>> Agree with Panu. It would be interesting to compare the performance
> >>>>> between inline and non inline to decide whether inlining it or not.
> >>>> Will update after i gathered more data. inline could show obvious
> >>>> performance difference in some cases.
> >>>
> >>> Panu and Oliver:
> >>> I write a simple benchmark. This benchmark run 10M rounds, in each round
> >>> 8 mbufs are allocated through bulk API, and then freed.
> >>> These are the CPU cycles measured(Intel(R) Xeon(R) CPU E5-2680 0 @
> >>> 2.70GHz, CPU isolated, timer interrupt disabled, rcu offloaded).
> >>> Btw, i have removed some exceptional data, the frequency of which is
> >>> like 1/10. Sometimes observed user usage suddenly disappeared, no clue
> >>> what happened.
> >>>
> >>> With 8 mbufs allocated, there is about 6% performance increase using inline.
> >> [...]
> >>>
> >>> With 16 mbufs allocated, we could still observe obvious performance
> >>> difference, though only 1%-2%
> >>>
> >> [...]
> >>>
> >>> With 32/64 mbufs allocated, the deviation of the data itself would hide
> >>> the performance difference.
> >>> So we prefer using inline for performance.
> >>
> >> At least I was more after real-world performance in a real-world
> >> use-case rather than CPU cycles in a microbenchmark, we know function
> >> calls have a cost but the benefits tend to outweight the cons.
> >>
> >> Inline functions have their place and they're far less evil in project
> >> internal use, but in library public API they are BAD and should be ...
> >> well, not banned because there are exceptions to every rule, but highly
> >> discouraged.
> >
> > Why is that?
> 
> For all the reasons static linking is bad, and what's worse it forces 
> the static linking badness into dynamically linked builds.
> 
> If there's a bug (security or otherwise) in a library, a distro wants to 
> supply an updated package which fixes that bug and be done with it. But 
> if that bug is in an inlined code, supplying an update is not enough, 
> you also need to recompile everything using that code, and somehow 
> inform customers possibly using that code that they need to not only 
> update the library but to recompile their apps as well. That is 
> precisely the reason distros go to great lenghts to avoid *any* 
> statically linked apps and libs in the distro, completely regardless of 
> the performance overhead.
> 
> In addition, inlined code complicates ABI compatibility issues because 
> some of the code is one the "wrong" side, and worse, it bypasses all the 
> other ABI compatibility safeguards like soname and symbol versioning.
> 
> Like said, inlined code is fine for internal consumption, but incredibly 
> bad for public interfaces. And of course, the more complicated a 
> function is, greater the potential of needing bugfixes.
> 
> Mind you, none of this is magically specific to this particular 
> function. Except in the sense that bulk operations offer a better way of 
> performance improvements than just inlining everything.
> 
> > As you can see right now we have all mbuf alloc/free routines as static inline.
> > And I think we would like to keep it like that.
> > So why that particular function should be different?
> 
> Because there's much less need to have it inlined since the function 
> call overhead is "amortized" by the fact its doing bulk operations. "We 
> always did it that way" is not a very good reason :)
> 
> > After all that function is nothing more than a wrapper
> > around rte_mempool_get_bulk()  unrolled by 4 loop {rte_pktmbuf_reset()}
> > So unless mempool get/put API would change, I can hardly see there could be any ABI
> > breakages in future.
> > About 'real world' performance gain - it was a 'real world' performance problem,
> > that we tried to solve by introducing that function:
> > http://dpdk.org/ml/archives/dev/2015-May/017633.html
> >
> > And according to the user feedback, it does help:
> > http://dpdk.org/ml/archives/dev/2016-February/033203.html
> 
> The question is not whether the function is useful, not at all. The 
> question is whether the real-world case sees any measurable difference 
> in performance if the function is made non-inline.

This is a valid question, and it applies to a large part of DPDK.
But it's something to measure and change more globally than just
a new function.
Generally speaking, any effort to reduce the size of the exported headers
will be welcome.

That said, this patch won't be blocked.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-02-29 11:34  3%     ` Panu Matilainen
@ 2016-02-29 16:41  0%       ` Tan, Jianfeng
  0 siblings, 0 replies; 200+ results
From: Tan, Jianfeng @ 2016-02-29 16:41 UTC (permalink / raw)
  To: Panu Matilainen, dev

Hi Panu,

On 2/29/2016 7:34 PM, Panu Matilainen wrote:
> On 02/26/2016 09:34 AM, Jianfeng Tan wrote:
>> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
>> type can be filled by given pmd rx burst function.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
>>   lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
>>   2 files changed, 52 insertions(+)
>>
> [...]
>> diff --git a/lib/librte_ether/rte_ethdev.h 
>> b/lib/librte_ether/rte_ethdev.h
>> index 16da821..16f32a0 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 eth_rx_burst_t. */
>> +
>>   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,28 @@ void rte_eth_macaddr_get(uint8_t port_id, 
>> struct ether_addr *mac_addr);
>
> Technically this is an ABI break but its marked internal and I guess 
> it falls into the "drivers only" territory similar to what was 
> discussed in this thead: 
> http://dpdk.org/ml/archives/dev/2016-January/032348.html so its 
> probably ok.

Yes, I think so too.

>
>>   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.
>> + *
>> + * @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.
>> + */
>> +extern 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
>>
>
> "extern" is redundant in headers. We just saw a round of removing them 
> (commit dd34ff1f0e03b2c5e4a97e9fbcba5c8238aac573), lets not add them 
> back :)
>
> More importantly, to export a function you need to add an entry for it 
> in rte_ether_version.map.

Oh, yes, thanks for pointing out this, I'll change this and update 
rte_ether_version.map.

Is it like this? Before or after DPDK_2.2 {}?
DPDK_2.3 {
     global:

     rte_eth_dev_get_ptype_info;

     local: *;
};

Thanks,
Jianfeng

>
>     - Panu -
>
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] af_packet: make the device detachable
  2016-02-24 14:08  3% ` Iremonger, Bernard
@ 2016-02-29 18:22  0%   ` Wojciech Żmuda
  2016-03-01  9:43  3%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Wojciech Żmuda @ 2016-02-29 18:22 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev

Hi Bernard,

> Does making   rte_pmd_af_packet_devinit local result in an ABI breakage?
If someone uses it in their app, they'll be forced to change it.
However, as this function is not intentionally public and there is API
to create devices that finally calls rte_pmd_af_packet_devinit(), I'm
not sure if any special caution is needed here.

> Should the DPDK_2.0 structure be kept and a DPDK_2.3 structure added?
Should it be just `DPDK_2.3 { local: *} DPDK_2.0`? Doesn't inheritance
of DPDK_2.0 make the symbol also global in 2.3?

> A deprecation notice may need to be added to the doc/guides/rel_notes/deprecation.rst  file.
As far as I understand, deprecation.rst is used to announce something
will be removed in the future release. Changes already done should be
moved from deprecation.rst to the release's .rst file. At least, this
is what I see in commit logs. If this change should be announced in
deprecation.rst, does this mean there should be another patch in the
future (after 2.3 release?) making this function static? And that
future patch will add DPDK_2.3 structure in the map file?

Thank you for your time,
Wojtek

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v9 4/4] doc: update with link changes
  @ 2016-03-01  0:45  9%     ` Marc Sune
  0 siblings, 0 replies; 200+ results
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst | 27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index d4c6ff4..6c1ae33 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -88,6 +88,7 @@ Most of these differences are summarized below.
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    link status
    link status event
+   Speed capabilities
    Rx interrupt
    queue start/stop
    MTU update
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 64e913d..fd2d3cc 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -20,6 +20,18 @@ Build the docs and view the output file to ensure the changes are correct::
 New Features
 ------------
 
+* **ethdev: define a set of advertised link speeds.**
+
+  Added functionality to Allow defining a set of advertised speeds for
+  auto-negociation, explicitely disabling link auto-negociation (single speed)
+  and full auto-negociation.
+
+* **ethdev: add speed_cap bitmap for link speed capabilities.**
+
+  ``struct rte_eth_dev_info`` has now ``speed_cap`` bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
+
+
 This section should contain new features added in this release. Sample format:
 
 * **Add a title in the past tense with a full stop.**
@@ -55,6 +67,11 @@ This section should contain new features added in this release. Sample format:
 Resolved Issues
 ---------------
 
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
 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.**
@@ -87,6 +104,9 @@ Drivers
 Libraries
 ~~~~~~~~~
 
+* New API call, ``rte_eth_speed_to_bm_flag`` in ethdev to, map numerical speeds
+  to bitmap fields.
+
 
 Examples
 ~~~~~~~~
@@ -119,6 +139,13 @@ This section should contain API changes. Sample format:
 ABI Changes
 -----------
 
+* The ethdev ``rte_eth_link`` and ``rte_eth_conf`` structures were changed to
+  support the new link API, as well as ``ETH_LINK_HALF``/``FULL_DUPLEX``.
+
+* The ethdev ``rte_eth_dev_info`` was changed to support device speed
+  capabilities.
+
+
 * 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.
-- 
2.1.4

^ permalink raw reply	[relevance 9%]

* [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  @ 2016-03-01  3:47 17%       ` Xutao Sun
  2016-03-01  8:53  3%         ` Panu Matilainen
    1 sibling, 1 reply; 200+ results
From: Xutao Sun @ 2016-03-01  3:47 UTC (permalink / raw)
  To: dev

Change the fields of outer_mac and inner_mac 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 |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
 lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
 5 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..c707318 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6640,8 +6640,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 e94d4a2..a895364 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -32,11 +32,6 @@ 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 64e913d..704d0f6 100644
--- 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.
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..7c22358 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5828,10 +5828,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) {
@@ -6131,13 +6131,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 ce224ad..30cbde7 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 {
-- 
1.9.3

^ permalink raw reply	[relevance 17%]

* [dpdk-dev] [PATCH v7 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  @ 2016-03-01  8:41 17%         ` Xutao Sun
  2016-03-08 23:08  0%           ` Thomas Monjalon
    1 sibling, 1 reply; 200+ results
From: Xutao Sun @ 2016-03-01  8:41 UTC (permalink / raw)
  To: dev

Change the fields of outer_mac and inner_mac 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 |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
 lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
 5 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..c707318 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6640,8 +6640,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 e94d4a2..a895364 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -32,11 +32,6 @@ 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 64e913d..704d0f6 100644
--- 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.
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..7c22358 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5828,10 +5828,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) {
@@ -6131,13 +6131,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 ce224ad..30cbde7 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 {
-- 
1.9.3

^ permalink raw reply	[relevance 17%]

* Re: [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  2016-03-01  3:47 17%       ` [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure Xutao Sun
@ 2016-03-01  8:53  3%         ` Panu Matilainen
  2016-03-02  3:10  3%           ` Sun, Xutao
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-01  8:53 UTC (permalink / raw)
  To: Xutao Sun, dev

On 03/01/2016 05:47 AM, Xutao Sun wrote:
> Change the fields of outer_mac and inner_mac 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 |  2 ++
>   drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
>   lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
>   5 files changed, 14 insertions(+), 15 deletions(-)
>

Since this is the commit actually changing the ABI, its best to actually 
bump LIBABIVER right here as well lest it go forgotten, and also update 
the list of shared library versions in release notes.
See commit d8c4ae275582784ec0ff3b2c54a4c861b55bc056 for an example.

Oh and sorry for not noticing this earlier.

	- Panu -

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v3] af_packet: make the device detachable
  2016-02-29 18:22  0%   ` Wojciech Żmuda
@ 2016-03-01  9:43  3%     ` Panu Matilainen
  2016-03-02 11:47  0%       ` Wojciech Żmuda
  0 siblings, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-01  9:43 UTC (permalink / raw)
  To: Wojciech Żmuda, Iremonger, Bernard; +Cc: dev

On 02/29/2016 08:22 PM, Wojciech Żmuda wrote:
> Hi Bernard,
>
>> Does making   rte_pmd_af_packet_devinit local result in an ABI breakage?
> If someone uses it in their app, they'll be forced to change it.
> However, as this function is not intentionally public and there is API
> to create devices that finally calls rte_pmd_af_packet_devinit(), I'm
> not sure if any special caution is needed here.

Yeah this is a bit of a gray area. Strictly speaking it certainly is an 
ABI break, but given that the function is documented as internal-only 
and there's a proper, public way to create the device, there's no good 
excuse for anybody to be using it. I think its okay to remove without 
going through the deprecation process.

>
>> Should the DPDK_2.0 structure be kept and a DPDK_2.3 structure added?
> Should it be just `DPDK_2.3 { local: *} DPDK_2.0`? Doesn't inheritance
> of DPDK_2.0 make the symbol also global in 2.3?

Since there are no symbols being exported I dont see any point in 
changing the version, just drop the accidentally exported symbol from 
the 2.0 definition.

	- Panu -

>> A deprecation notice may need to be added to the doc/guides/rel_notes/deprecation.rst  file.
> As far as I understand, deprecation.rst is used to announce something
> will be removed in the future release. Changes already done should be
> moved from deprecation.rst to the release's .rst file. At least, this
> is what I see in commit logs. If this change should be announced in
> deprecation.rst, does this mean there should be another patch in the
> future (after 2.3 release?) making this function static? And that
> future patch will add DPDK_2.3 structure in the map file?
>
> Thank you for your time,
> Wojtek
>

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v4 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder
  @ 2016-03-01 15:41  1%       ` Ferruh Yigit
    1 sibling, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-01 15: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:
* No update
---
 config/common_linuxapp                     |   5 +
 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 +
 25 files changed, 2236 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_linuxapp b/config/common_linuxapp
index f1638db..960dde4 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -497,6 +497,11 @@ CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
 CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=y
+
+#
 # Compile vhost library
 # fuse-devel is needed to run vhost-cuse.
 # fuse-devel enables user space char driver development
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 fd7dd1a..082e0b8 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -144,6 +144,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 ef172ea..ce8f0f9 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 8ecab41..32f76b1 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -122,6 +122,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 v2 4/6] bond mode 4: allow external state machine
  2016-02-25 15:22  0%       ` Iremonger, Bernard
@ 2016-03-01 17:40  0%         ` Eric Kinzie
  2016-03-02  9:49  0%           ` Iremonger, Bernard
  0 siblings, 1 reply; 200+ results
From: Eric Kinzie @ 2016-03-01 17:40 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev

On Thu Feb 25 15:22:35 +0000 2016, Iremonger, Bernard wrote:
> Hi Eric,
> <snip>
> 
> > > @@ -157,6 +159,7 @@ struct rte_eth_bond_8023ad_conf {
> > >   	uint32_t tx_period_ms;
> > >   	uint32_t rx_marker_period_ms;
> > >   	uint32_t update_timeout_ms;
> > > +	rte_eth_bond_8023ad_ext_slowrx_fn slowrx_cb;
> > >   };
> > 
> > This still is a likely an ABI break, previously discussed around here:
> > http://dpdk.org/ml/archives/dev/2015-November/027321.html
> > 
> > It might not be embedded anywhere in DPDK codebase, but there's no
> > telling what others might have done with it (have an array of them, embed in
> > other structs etc).
> > 
> > Also ultimately ABI compatibility goes both ways: when the library soname
> > does not change then an application is free to assume both downgrading and
> > upgrading are safe. In this case, upgrading *might* be okay, downgrading
> > certainly is not. So by that measure it definitely is an ABI break.
> > 
> > [...]
> > > diff --git a/drivers/net/bonding/rte_eth_bond_version.map
> > > b/drivers/net/bonding/rte_eth_bond_version.map
> > > index 22bd920..33d73ff 100644
> > > --- a/drivers/net/bonding/rte_eth_bond_version.map
> > > +++ b/drivers/net/bonding/rte_eth_bond_version.map
> > > @@ -27,3 +27,9 @@ DPDK_2.1 {
> > >   	rte_eth_bond_free;
> > >
> > >   } DPDK_2.0;
> > > +
> > > +DPDK_2.2 {
> > > +	rte_eth_bond_8023ad_ext_collect;
> > > +	rte_eth_bond_8023ad_ext_distrib;
> > > +	rte_eth_bond_8023ad_ext_slowtx;
> > > +} DPDK_2.1;
> > >
> > 
> > These symbols are not part of DPDK 2.2, the version here is wrong.
> > Technically it would not actually matter much but better not to confuse
> > things unnecessarily.
> > 
> > 	- Panu -
> 
> It looks like Panu's points are valid, a V3 of this patch set which takes care of these issues will be needed.
> 
> Patches 1/6, 5/6 and 6/6 of the patch set are bug fixes, so each patch should contain a fixes line.
> Patches 2/6, 3/6 and 4/6 are a new feature, the release notes should be updated for this feature.
> 
> Could I suggest splitting the patch set into two patch sets, a bug fix patch set and a new feature patch set.
> 
> Regards,
> 
> Bernard.

Bernard, a v3 is on the way.  I included only things that are fixes,
but the patch set doesn't quite match the set of patch numbers you listed
above.  1/6 (bond: use existing enslaved device queues) is an improvement,
but doesn't really fix anything that was broken, so I left that out.
2/6 (bond mode 4: copy entire config structure) and 3/6 (bond mode 4:
do not ignore multicast) fix bugs and are included.


Eric

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  @ 2016-03-02  2:02  3%         ` Stephen Hemminger
  2016-03-02  8:27  0%           ` Panu Matilainen
  2016-03-02 22:18  0%           ` Jay Rolette
  0 siblings, 2 replies; 200+ results
From: Stephen Hemminger @ 2016-03-02  2:02 UTC (permalink / raw)
  To: Jay Rolette; +Cc: DPDK, Avi Kivity

On Mon, 29 Feb 2016 08:33:25 -0600
Jay Rolette <rolette@infiniteio.com> wrote:

> On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon <thomas.monjalon@6wind.com>
> wrote:
> 
> > Hi,
> > I totally agree with Avi's comments.
> > This topic is really important for the future of DPDK.
> > So I think we must give some time to continue the discussion
> > and have netdev involved in the choices done.
> > As a consequence, these series should not be merged in the release 16.04.
> > Thanks for continuing the work.
> >
> 
> I know you guys are very interested in getting rid of the out-of-tree
> drivers, but please do not block incremental improvements to DPDK in the
> meantime. Ferruh's patch improves the usability of KNI. Don't throw out
> good and useful enhancements just because it isn't where you want to be in
> the end.
> 
> 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.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  2016-03-01  8:53  3%         ` Panu Matilainen
@ 2016-03-02  3:10  3%           ` Sun, Xutao
  2016-03-02  7:12  0%             ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Sun, Xutao @ 2016-03-02  3:10 UTC (permalink / raw)
  To: Panu Matilainen, dev

Hi, Panu

> -----Original Message-----
> From: Panu Matilainen [mailto:pmatilai@redhat.com]
> Sent: Tuesday, March 01, 2016 4:54 PM
> To: Sun, Xutao <xutao.sun@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize
> the'rte_eth_tunnel_filter_conf' structure
> 
> On 03/01/2016 05:47 AM, Xutao Sun wrote:
> > Change the fields of outer_mac and inner_mac 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 |  2 ++
> >   drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
> >   lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
> >   5 files changed, 14 insertions(+), 15 deletions(-)
> >
> 
> Since this is the commit actually changing the ABI, its best to actually bump
> LIBABIVER right here as well lest it go forgotten, and also update the list of
> shared library versions in release notes.
> See commit d8c4ae275582784ec0ff3b2c54a4c861b55bc056 for an example.
> 
> Oh and sorry for not noticing this earlier.
> 
> 	- Panu -

I didn't use the Macro "RTE_NEXT_ABI", so I think I don't need to update the shared library verisons.
And I also updated the doc about ABI change in the deprecation.rst and release notes.

Thanks,
Xutao

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v5 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-03-02  6:45  4%   ` Wenzhuo Lu
  2016-03-02  8:56  0%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Wenzhuo Lu @ 2016-03-02  6:45 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>
---
 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          | 18 ++++++++++++++
 4 files changed, 68 insertions(+), 3 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..f1f96c1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -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;
 };
 
 /**
@@ -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);
+int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
  * 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);
 
 /**
  * Check whether the filter type is supported on an Ethernet device.
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  2016-03-02  3:10  3%           ` Sun, Xutao
@ 2016-03-02  7:12  0%             ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-02  7:12 UTC (permalink / raw)
  To: Sun, Xutao, dev

On 03/02/2016 05:10 AM, Sun, Xutao wrote:
> Hi, Panu
>
>> -----Original Message-----
>> From: Panu Matilainen [mailto:pmatilai@redhat.com]
>> Sent: Tuesday, March 01, 2016 4:54 PM
>> To: Sun, Xutao <xutao.sun@intel.com>; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize
>> the'rte_eth_tunnel_filter_conf' structure
>>
>> On 03/01/2016 05:47 AM, Xutao Sun wrote:
>>> Change the fields of outer_mac and inner_mac 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 |  2 ++
>>>    drivers/net/i40e/i40e_ethdev.c         | 12 ++++++------
>>>    lib/librte_ether/rte_eth_ctrl.h        |  4 ++--
>>>    5 files changed, 14 insertions(+), 15 deletions(-)
>>>
>>
>> Since this is the commit actually changing the ABI, its best to actually bump
>> LIBABIVER right here as well lest it go forgotten, and also update the list of
>> shared library versions in release notes.
>> See commit d8c4ae275582784ec0ff3b2c54a4c861b55bc056 for an example.
>>
>> Oh and sorry for not noticing this earlier.
>>
>> 	- Panu -
>
> I didn't use the Macro "RTE_NEXT_ABI", so I think I don't need to update the shared library verisons.
> And I also updated the doc about ABI change in the deprecation.rst and release notes.

Shared library version MUST change when there's an incompatible change 
to prevent programs/libraries linked against the older version to be 
used with the incompatible version, that is the sole reason for 
versioning the libraries in the first place. Whether RTE_NEXT_ABI is 
used or not is not relevant.

In fact RTE_NEXT_ABI creates a shared library version of its own, sort 
of parallel to the current one. The basic idea remains the same though: 
shared library version has to change when an incompatible change goes in.

	- Panu -

	- Panu -





	- Panu -



	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02  2:02  3%         ` Stephen Hemminger
@ 2016-03-02  8:27  0%           ` Panu Matilainen
  2016-03-02 10:47  0%             ` Vincent JARDIN
  2016-03-02 22:18  0%           ` Jay Rolette
  1 sibling, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-02  8:27 UTC (permalink / raw)
  To: Stephen Hemminger, Jay Rolette; +Cc: DPDK, Avi Kivity

On 03/02/2016 04:02 AM, Stephen Hemminger wrote:
> On Mon, 29 Feb 2016 08:33:25 -0600
> Jay Rolette <rolette@infiniteio.com> wrote:
>
>> On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon <thomas.monjalon@6wind.com>
>> wrote:
>>
>>> Hi,
>>> I totally agree with Avi's comments.
>>> This topic is really important for the future of DPDK.
>>> So I think we must give some time to continue the discussion
>>> and have netdev involved in the choices done.
>>> As a consequence, these series should not be merged in the release 16.04.
>>> Thanks for continuing the work.
>>>
>>
>> I know you guys are very interested in getting rid of the out-of-tree
>> drivers, but please do not block incremental improvements to DPDK in the
>> meantime. Ferruh's patch improves the usability of KNI. Don't throw out
>> good and useful enhancements just because it isn't where you want to be in
>> the end.
>>
>> 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.

If a venturous vendor wants to go and build a product based on something 
in a staging tree there's nothing stopping them from doing that, but at 
least it should set the expectations straight.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-02  6:45  4%   ` [dpdk-dev] [PATCH v5 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
@ 2016-03-02  8:56  0%     ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-02  8:56 UTC (permalink / raw)
  To: Wenzhuo Lu, dev

On 03/02/2016 08:45 AM, Wenzhuo Lu wrote:
> 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>
> ---
>   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          | 18 ++++++++++++++
>   4 files changed, 68 insertions(+), 3 deletions(-)
>
[...]
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..f1f96c1 100644
> --- 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);
> +int
> +rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
> +				struct rte_eth_udp_tunnel *tunnel_udp);
>
>    /**
>    * 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);
>
>   /**
>    * Check whether the filter type is supported on an Ethernet device.
>

You need to add these functions to rte_ether_version.map in order to 
export them.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 4/6] bond mode 4: allow external state machine
  2016-03-01 17:40  0%         ` Eric Kinzie
@ 2016-03-02  9:49  0%           ` Iremonger, Bernard
  0 siblings, 0 replies; 200+ results
From: Iremonger, Bernard @ 2016-03-02  9:49 UTC (permalink / raw)
  To: Eric Kinzie; +Cc: dev

Hi Eric,

<snip>

> > > > @@ -157,6 +159,7 @@ struct rte_eth_bond_8023ad_conf {
> > > >   	uint32_t tx_period_ms;
> > > >   	uint32_t rx_marker_period_ms;
> > > >   	uint32_t update_timeout_ms;
> > > > +	rte_eth_bond_8023ad_ext_slowrx_fn slowrx_cb;
> > > >   };
> > >
> > > This still is a likely an ABI break, previously discussed around here:
> > > http://dpdk.org/ml/archives/dev/2015-November/027321.html
> > >
> > > It might not be embedded anywhere in DPDK codebase, but there's no
> > > telling what others might have done with it (have an array of them,
> > > embed in other structs etc).
> > >
> > > Also ultimately ABI compatibility goes both ways: when the library
> > > soname does not change then an application is free to assume both
> > > downgrading and upgrading are safe. In this case, upgrading *might*
> > > be okay, downgrading certainly is not. So by that measure it definitely is
> an ABI break.
> > >
> > > [...]
> > > > diff --git a/drivers/net/bonding/rte_eth_bond_version.map
> > > > b/drivers/net/bonding/rte_eth_bond_version.map
> > > > index 22bd920..33d73ff 100644
> > > > --- a/drivers/net/bonding/rte_eth_bond_version.map
> > > > +++ b/drivers/net/bonding/rte_eth_bond_version.map
> > > > @@ -27,3 +27,9 @@ DPDK_2.1 {
> > > >   	rte_eth_bond_free;
> > > >
> > > >   } DPDK_2.0;
> > > > +
> > > > +DPDK_2.2 {
> > > > +	rte_eth_bond_8023ad_ext_collect;
> > > > +	rte_eth_bond_8023ad_ext_distrib;
> > > > +	rte_eth_bond_8023ad_ext_slowtx;
> > > > +} DPDK_2.1;
> > > >
> > >
> > > These symbols are not part of DPDK 2.2, the version here is wrong.
> > > Technically it would not actually matter much but better not to
> > > confuse things unnecessarily.
> > >
> > > 	- Panu -
> >
> > It looks like Panu's points are valid, a V3 of this patch set which takes care of
> these issues will be needed.
> >
> > Patches 1/6, 5/6 and 6/6 of the patch set are bug fixes, so each patch
> should contain a fixes line.
> > Patches 2/6, 3/6 and 4/6 are a new feature, the release notes should be
> updated for this feature.
> >
> > Could I suggest splitting the patch set into two patch sets, a bug fix patch
> set and a new feature patch set.
> >
> > Regards,
> >
> > Bernard.
> 
> Bernard, a v3 is on the way.  I included only things that are fixes, but the
> patch set doesn't quite match the set of patch numbers you listed above.
> 1/6 (bond: use existing enslaved device queues) is an improvement, but
> doesn't really fix anything that was broken, so I left that out.
> 2/6 (bond mode 4: copy entire config structure) and 3/6 (bond mode 4:
> do not ignore multicast) fix bugs and are included.
> 
> 
> Eric

Thanks for the V3 patchset and clarifying which patches in the V2 patchset were fixes.

Regards,

Bernard.

  

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02  8:27  0%           ` Panu Matilainen
@ 2016-03-02 10:47  0%             ` Vincent JARDIN
  2016-03-02 10:51  0%               ` Jim Thompson
  2016-03-02 11:21  3%               ` Thomas Monjalon
  0 siblings, 2 replies; 200+ results
From: Vincent JARDIN @ 2016-03-02 10:47 UTC (permalink / raw)
  To: Panu Matilainen, Stephen Hemminger, Jay Rolette, thomas.monjalon
  Cc: DPDK, Avi Kivity

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?

Thank you,
   Vincent

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02 10:47  0%             ` Vincent JARDIN
@ 2016-03-02 10:51  0%               ` Jim Thompson
  2016-03-02 11:21  3%               ` Thomas Monjalon
  1 sibling, 0 replies; 200+ results
From: Jim Thompson @ 2016-03-02 10:51 UTC (permalink / raw)
  To: Vincent JARDIN; +Cc: Avi Kivity, DPDK


> On Mar 2, 2016, at 4:47 AM, Vincent JARDIN <vincent.jardin@6wind.com> wrote:
> 
> 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?

Can we take it as a requirement to support FreeBSD this time around?

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02 10:47  0%             ` Vincent JARDIN
  2016-03-02 10:51  0%               ` Jim Thompson
@ 2016-03-02 11:21  3%               ` Thomas Monjalon
  2016-03-02 22:35  0%                 ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2016-03-02 11:21 UTC (permalink / raw)
  To: Vincent JARDIN, Stephen Hemminger, Jay Rolette; +Cc: dev, Avi Kivity

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.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 00/12] extend flow director's fields in i40e driver
  @ 2016-03-02 11:29  4% ` Jingjing Wu
  2016-03-02 11:30 18%   ` [dpdk-dev] [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
  2016-03-09  5:42  4%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  0 siblings, 2 replies; 200+ results
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

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 hash/fdir input sets for tunnels

Jingjing Wu (11):
  ethdev: extend flow director to support input set selection
  i40e: split function for input set change of hash and fdir
  i40e: remove flex payload from INPUT_SET_SELECT operation
  i40e: restore default setting on input set of filters
  i40e: extend flow director to filter by more IP Header fields
  testpmd: extend commands for filter's input set changing
  librte_ether: extend rte_eth_fdir_flow to support tunnel format
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend commands for fdir's tunnel id input set
  i40e: extend flow director to filter by vlan id
  testpmd: extend commands for fdir's vlan input set

 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              | 401 +++++++++++++++++-----------
 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(+), 269 deletions(-)

-- 
2.4.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format
  2016-03-02 11:29  4% ` [dpdk-dev] [PATCH v2 " Jingjing Wu
@ 2016-03-02 11:30 18%   ` Jingjing Wu
  2016-03-09  5:42  4%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  1 sibling, 0 replies; 200+ results
From: Jingjing Wu @ 2016-03-02 11:30 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 73494f9..1d784d3 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -183,6 +183,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%]

* Re: [dpdk-dev] [PATCH v3] af_packet: make the device detachable
  2016-03-01  9:43  3%     ` Panu Matilainen
@ 2016-03-02 11:47  0%       ` Wojciech Żmuda
  0 siblings, 0 replies; 200+ results
From: Wojciech Żmuda @ 2016-03-02 11:47 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: dev

Hi Panu,

>I think its okay to remove without going through the deprecation process.
> just drop the accidentally exported symbol from the 2.0 definition.
Well, this is what I've done so far. I'm going to post v4 patch
modifying release_16_04.rst  instead of release_2_3.rst, then. Thank
you for sharing your opinion on this topic.

Wojtek

2016-03-01 10:43 GMT+01:00 Panu Matilainen <pmatilai@redhat.com>:
> On 02/29/2016 08:22 PM, Wojciech Żmuda wrote:
>>
>> Hi Bernard,
>>
>>> Does making   rte_pmd_af_packet_devinit local result in an ABI breakage?
>>
>> If someone uses it in their app, they'll be forced to change it.
>> However, as this function is not intentionally public and there is API
>> to create devices that finally calls rte_pmd_af_packet_devinit(), I'm
>> not sure if any special caution is needed here.
>
>
> Yeah this is a bit of a gray area. Strictly speaking it certainly is an ABI
> break, but given that the function is documented as internal-only and
> there's a proper, public way to create the device, there's no good excuse
> for anybody to be using it. I think its okay to remove without going through
> the deprecation process.
>
>>
>>> Should the DPDK_2.0 structure be kept and a DPDK_2.3 structure added?
>>
>> Should it be just `DPDK_2.3 { local: *} DPDK_2.0`? Doesn't inheritance
>> of DPDK_2.0 make the symbol also global in 2.3?
>
>
> Since there are no symbols being exported I dont see any point in changing
> the version, just drop the accidentally exported symbol from the 2.0
> definition.
>
>         - Panu -
>
>
>>> A deprecation notice may need to be added to the
>>> doc/guides/rel_notes/deprecation.rst  file.
>>
>> As far as I understand, deprecation.rst is used to announce something
>> will be removed in the future release. Changes already done should be
>> moved from deprecation.rst to the release's .rst file. At least, this
>> is what I see in commit logs. If this change should be announced in
>> deprecation.rst, does this mean there should be another patch in the
>> future (after 2.3 release?) making this function static? And that
>> future patch will add DPDK_2.3 structure in the map file?
>>
>> Thank you for your time,
>> Wojtek
>>
>

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4] af_packet: make the device detachable
@ 2016-03-02 11:55  3% Wojciech Zmuda
  0 siblings, 0 replies; 200+ results
From: Wojciech Zmuda @ 2016-03-02 11:55 UTC (permalink / raw)
  To: dev

Allow dynamic deallocation of af_packet device through proper
API functions. To achieve this:
* set device flag to RTE_ETH_DEV_DETACHABLE
* implement rte_pmd_af_packet_devuninit() and expose it
  through rte_driver.uninit()
* copy device name to ethdev->data to make discoverable with
  rte_eth_dev_allocated()
Moreover, make af_packet init function static, as there is no
reason to keep it public.

Signed-off-by: Wojciech Zmuda <woz@semihalf.com>
---
v4:
* Rebased against current master branch

v3:
* Rephrased feature note in release notes.
* Rephrased commit log.
* Added API change note in release notes.
* Made init function static.
* Removed af_packet header file, as it is not needed
  after init function is not public anymore.

v2:
* Fixed typo and a comment.
* Added feature to the 2.3 release notes.
* Free memory allocated for rx and tx queues.

 doc/guides/rel_notes/release_16_04.rst             |  6 +++
 drivers/net/af_packet/Makefile                     |  5 --
 drivers/net/af_packet/rte_eth_af_packet.c          | 43 ++++++++++++++++--
 drivers/net/af_packet/rte_eth_af_packet.h          | 53 ----------------------
 .../net/af_packet/rte_pmd_af_packet_version.map    |  3 --
 5 files changed, 45 insertions(+), 65 deletions(-)
 delete mode 100644 drivers/net/af_packet/rte_eth_af_packet.h

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index fd7dd1a..475acea 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -51,6 +51,9 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added af_packet dynamic removal function.**
+
+  Af_packet device can now be detached using API, like other PMD devices.
 
 Resolved Issues
 ---------------
@@ -120,6 +123,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.
 
+* Af_packet device init function is no longer public. Device should be attached
+  with API.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/af_packet/Makefile b/drivers/net/af_packet/Makefile
index ce5d239..cb1a7ae 100644
--- a/drivers/net/af_packet/Makefile
+++ b/drivers/net/af_packet/Makefile
@@ -50,11 +50,6 @@ CFLAGS += $(WERROR_FLAGS)
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += rte_eth_af_packet.c
 
-#
-# Export include files
-#
-SYMLINK-y-include += rte_eth_af_packet.h
-
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_mbuf
 DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_ether
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..5544528 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -53,8 +53,6 @@
 #include <unistd.h>
 #include <poll.h>
 
-#include "rte_eth_af_packet.h"
-
 #define ETH_AF_PACKET_IFACE_ARG		"iface"
 #define ETH_AF_PACKET_NUM_Q_ARG		"qpairs"
 #define ETH_AF_PACKET_BLOCKSIZE_ARG	"blocksz"
@@ -65,6 +63,8 @@
 #define DFLT_FRAME_SIZE		(1 << 11)
 #define DFLT_FRAME_COUNT	(1 << 9)
 
+#define RTE_PMD_AF_PACKET_MAX_RINGS 16
+
 struct pkt_rx_queue {
 	int sockfd;
 
@@ -667,11 +667,13 @@ rte_pmd_init_internals(const char *name,
 	data->nb_tx_queues = (uint16_t)nb_queues;
 	data->dev_link = pmd_link;
 	data->mac_addrs = &(*internals)->eth_addr;
+	strncpy(data->name,
+		(*eth_dev)->data->name, strlen((*eth_dev)->data->name));
 
 	(*eth_dev)->data = data;
 	(*eth_dev)->dev_ops = &ops;
 	(*eth_dev)->driver = NULL;
-	(*eth_dev)->data->dev_flags = 0;
+	(*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
 	(*eth_dev)->data->drv_name = drivername;
 	(*eth_dev)->data->kdrv = RTE_KDRV_NONE;
 	(*eth_dev)->data->numa_node = numa_node;
@@ -798,7 +800,7 @@ rte_eth_from_packet(const char *name,
 	return 0;
 }
 
-int
+static int
 rte_pmd_af_packet_devinit(const char *name, const char *params)
 {
 	unsigned numa_node;
@@ -836,10 +838,43 @@ exit:
 	return ret;
 }
 
+static int
+rte_pmd_af_packet_devuninit(const char *name)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct pmd_internals *internals;
+	unsigned q;
+
+	RTE_LOG(INFO, PMD, "Closing AF_PACKET ethdev on numa socket %u\n",
+			rte_socket_id());
+
+	if (name == NULL)
+		return -1;
+
+	/* find the ethdev entry */
+	eth_dev = rte_eth_dev_allocated(name);
+	if (eth_dev == NULL)
+		return -1;
+
+	internals = eth_dev->data->dev_private;
+	for (q = 0; q < internals->nb_queues; q++) {
+		rte_free(internals->rx_queue[q].rd);
+		rte_free(internals->tx_queue[q].rd);
+	}
+
+	rte_free(eth_dev->data->dev_private);
+	rte_free(eth_dev->data);
+
+	rte_eth_dev_release_port(eth_dev);
+
+	return 0;
+}
+
 static struct rte_driver pmd_af_packet_drv = {
 	.name = "eth_af_packet",
 	.type = PMD_VDEV,
 	.init = rte_pmd_af_packet_devinit,
+	.uninit = rte_pmd_af_packet_devuninit,
 };
 
 PMD_REGISTER_DRIVER(pmd_af_packet_drv);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.h b/drivers/net/af_packet/rte_eth_af_packet.h
deleted file mode 100644
index 5d1bc7e..0000000
--- a/drivers/net/af_packet/rte_eth_af_packet.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef _RTE_ETH_AF_PACKET_H_
-#define _RTE_ETH_AF_PACKET_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define RTE_PMD_AF_PACKET_MAX_RINGS 16
-
-/**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
- * configured on command line.
- */
-int rte_pmd_af_packet_devinit(const char *name, const char *params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map b/drivers/net/af_packet/rte_pmd_af_packet_version.map
index de95169..ef35398 100644
--- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
+++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
@@ -1,7 +1,4 @@
 DPDK_2.0 {
-	global:
-
-	rte_pmd_af_packet_devinit;
 
 	local: *;
 };
-- 
1.9.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3 1/2] librte_pipeline: add support for packet redirection at action handlers
  2016-02-29 14:50  4% ` [dpdk-dev] [PATCH v2 " Jasvinder Singh
@ 2016-03-02 20:41  4%   ` Jasvinder Singh
  2016-03-03 11:01  3%     ` [dpdk-dev] [PATCH v4] " Jasvinder Singh
  0 siblings, 1 reply; 200+ results
From: Jasvinder Singh @ 2016-03-02 20:41 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). Therefore, new
pipeline API functions have been added which allows action handlers to
hijack packets and remove them from the pipeline processing, and then either
drop them or send them out of the pipeline on any output port. The port
(in/out) and table action handler prototypes have been changed for making
use of these new API functions. 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>
---
v3
* improved comments in "rte_pipeline.h"

v2
* rebased on master

 doc/guides/rel_notes/deprecation.rst         |   5 -
 doc/guides/rel_notes/release_16_04.rst       |   6 +-
 lib/librte_pipeline/Makefile                 |   4 +-
 lib/librte_pipeline/rte_pipeline.c           | 461 ++++++++++++++-------------
 lib/librte_pipeline/rte_pipeline.h           | 174 ++++++----
 lib/librte_pipeline/rte_pipeline_version.map |   8 +
 6 files changed, 362 insertions(+), 296 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..1a7d660 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -40,11 +40,6 @@ 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.
-
 * ABI changes are planned in cmdline buffer size to allow the use of long
   commands (such as RETA update in testpmd).  This should impact
   CMDLINE_PARSE_RESULT_BUFSIZE, STR_TOKEN_SIZE and RDLINE_BUF_SIZE.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index fd7dd1a..bd180ee 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -128,6 +128,10 @@ 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.
 
+* 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
 -----------------------
@@ -154,7 +158,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/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..7f8fbac 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;
 
-		/* Input port user actions */
-		if (port_in->f_action != NULL) {
-			uint64_t mask = pkts_mask;
+	if (port_in == NULL)
+		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);
-		}
+	/* 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;
+	}
 
-		/* 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);
-					}
-				}
-			}
+	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;
+
+	/* 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 */
+		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;
 
-			/* 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]);
+			/* 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 reserved action PORT META */
-		rte_pipeline_action_handler_port_meta(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
+			/* Table user actions */
+			if (table->f_action_hit != NULL) {
+				table->f_action_hit(p,
+					p->pkts,
+					lookup_hit_mask,
+					p->entries,
+					table->arg_ah);
 
-		/* Table reserved action DROP */
-		rte_pipeline_action_handler_drop(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					table->n_pkts_dropped_by_lkp_hit_ah);
+			}
+
+			/* 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);
+		}
+
+		/* 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,26 +1503,32 @@ 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;
+}
+
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+
+	return 0;
+}
+
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+	p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
 
+	RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
 	return 0;
 }
 
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 7302a62..84d1802 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;
 };
@@ -778,14 +759,38 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
 	uint32_t *port_id);
 
 /**
- * Pipeline output port packet insert
+ * Read pipeline port out stats.
+ *
+ * This function reads port out statistics identified by *port_id* of given
+ * pipeline *p*.
+ *
+ * @param p
+ *   Handle to pipeline instance.
+ * @param port_id
+ *   Port ID what stats will be returned.
+ * @param stats
+ *   Statistics buffer.
+ * @param clear
+ *   If not 0 clear stats after reading.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
+	struct rte_pipeline_port_out_stats *stats, int clear);
+
+/*
+ * Functions to be called as part of the port IN/OUT or table action handlers
+ *
+ */
+/**
+ * Action handler packet insert to output port
  *
- * This function is called by the table action handler whenever it generates a
- * new packet to be sent out though one of the pipeline output ports. This
- * packet is not part of the burst of input packets read from any of the
- * pipeline input ports, so it is not an element of the pkts array input
- * parameter of the table action handler. This packet can be dropped by the
- * output port action handler.
+ * This function can be called by any input/output port or table action handler
+ * to send a packet out through one of the pipeline output ports. This packet is
+ * generated by the action handler, i.e. this packet is not part of the burst of
+ * packets read from one of the pipeline input ports and currently processed by
+ * the pipeline (this packet is not an element of the pkts array input parameter
+ * of the action handler).
  *
  * @param p
  *   Handle to pipeline instance
@@ -793,7 +798,7 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
  *   Output port ID (returned by previous invocation of pipeline output port
  *   create) to send the packet specified by pkt
  * @param pkt
- *   New packet generated by the table action handler
+ *   New packet generated by the action handler
  * @return
  *   0 on success, error code otherwise
  */
@@ -801,25 +806,68 @@ int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
 	uint32_t port_id,
 	struct rte_mbuf *pkt);
 
+#define rte_pipeline_ah_port_out_packet_insert \
+	rte_pipeline_port_out_packet_insert
+
 /**
- * Read pipeline port out stats.
+ * Action handler packet hijack
  *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
+ * This function can be called by any input/output port or table action handler
+ * to hijack selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The hijacked
+ * packets are removed from any further pipeline processing, with the action
+ * handler now having the full ownership for these packets.
+ *
+ * The action handler can further send the hijacked packets out through any
+ * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
+ * function. The action handler can also drop these packets by calling the
+ * rte_pktmbuf_free() function, although a better alternative is provided by
+ * the action handler using the rte_pipeline_ah_packet_drop() function.
  *
  * @param p
- *   Handle to pipeline instance.
- * @param port_id
- *   Port ID what stats will be returned.
- * @param stats
- *   Statistics buffer.
- * @param clear
- *   If not 0 clear stats after reading.
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be hijacked by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is hijacked.
  * @return
  *   0 on success, error code otherwise
  */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
-	struct rte_pipeline_port_out_stats *stats, int clear);
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
+/**
+ * Action handler packet drop
+ *
+ * This function is called by the pipeline action handlers (port in/out, table)
+ * to drop the packets selected using packet mask.
+ *
+ * This function can be called by any input/output port or table action handler
+ * to drop selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The dropped
+ * packets are removed from any further pipeline processing and the packet
+ * buffers are eventually freed to their buffer pool.
+ *
+ * This function updates the drop statistics counters correctly, therefore the
+ * recommended approach for dropping packets by the action handlers is to call
+ * this function as opposed to the action handler hijacking the packets first
+ * and then dropping them invisibly to the pipeline (by using the
+ * rte_pktmbuf_free() function).
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be dropped by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is dropped.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 4cc86f6..e4ee154 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -37,3 +37,11 @@ DPDK_2.2 {
 	rte_pipeline_table_entry_delete_bulk;
 
 } DPDK_2.1;
+
+DPDK_16.04 {
+	global:
+
+	rte_pipeline_ah_packet_hijack;
+	rte_pipeline_ah_packet_drop;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02  2:02  3%         ` Stephen Hemminger
  2016-03-02  8:27  0%           ` Panu Matilainen
@ 2016-03-02 22:18  0%           ` Jay Rolette
  2016-03-03 10:11  0%             ` Ferruh Yigit
  1 sibling, 1 reply; 200+ results
From: Jay Rolette @ 2016-03-02 22:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: DPDK, Avi Kivity

On Tue, Mar 1, 2016 at 8:02 PM, Stephen Hemminger <
stephen@networkplumber.org> wrote:

> On Mon, 29 Feb 2016 08:33:25 -0600
> Jay Rolette <rolette@infiniteio.com> wrote:
>
> > On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon <
> thomas.monjalon@6wind.com>
> > wrote:
> >
> > > Hi,
> > > I totally agree with Avi's comments.
> > > This topic is really important for the future of DPDK.
> > > So I think we must give some time to continue the discussion
> > > and have netdev involved in the choices done.
> > > As a consequence, these series should not be merged in the release
> 16.04.
> > > Thanks for continuing the work.
> > >
> >
> > I know you guys are very interested in getting rid of the out-of-tree
> > drivers, but please do not block incremental improvements to DPDK in the
> > meantime. Ferruh's patch improves the usability of KNI. Don't throw out
> > good and useful enhancements just because it isn't where you want to be
> in
> > the end.
> >
> > 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.
>

That's fair. To be clear, it wasn't my intent for code that wasn't baked
yet to be merged.

The main point of my comment was that I think it is important not to halt
incremental improvements to existing capabilities (KNI in this case) just
because there are philosophical or directional changes that the community
would like to make longer-term.

Bird in the hand vs. two in the bush...

Jay

^ permalink raw reply	[relevance 0%]

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

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

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v6 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-03-03  1:22  4%   ` Wenzhuo Lu
  2016-03-03  9:51  0%     ` Panu Matilainen
  0 siblings, 1 reply; 200+ results
From: Wenzhuo Lu @ 2016-03-03  1:22 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>
---
 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          | 18 ++++++++++++++
 lib/librte_ether/rte_ether_version.map |  2 ++
 5 files changed, 70 insertions(+), 3 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..f1f96c1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -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;
 };
 
 /**
@@ -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);
+int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
  * 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);
 
 /**
  * Check whether the filter type is supported on an Ethernet device.
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..5122217 100644
--- 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: *;
 };
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02 22:35  0%                 ` Thomas Monjalon
@ 2016-03-03  8:31  0%                   ` Panu Matilainen
  2016-03-03 10:05  0%                     ` Ferruh Yigit
  2016-03-10  0:04  0%                   ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Panu Matilainen @ 2016-03-03  8:31 UTC (permalink / raw)
  To: Thomas Monjalon, Vincent JARDIN; +Cc: dev, Avi Kivity

On 03/03/2016 12:35 AM, Thomas Monjalon wrote:
> 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

To answer this, I think we need to start by clarifying the kernel module 
situation. Quoting your from 
http://dpdk.org/ml/archives/dev/2016-January/032263.html:

> Sorry the kernel module party is over.
> One day, igb_uio will be removed.
> I suggest to make a first version without interrupt support
> and work with Linux community to fix your issues.

This to me reads "no more out-of-tree kernel modules, period" but here 
we are discussing the fate of another one.

If the policy truly is "no more kernel modules" (which I would fully 
back and applaud) then I think there's little to discuss - if the 
destination is kernel upstream then why should the modules pass through 
the dpdk codebase? Put it in another repo on dpdk.org, advertise it, 
make testing it as easy as possible and all (like have it integrate with 
dpdk makefiles if needed) instead.

The difference with crypto API and ethtool is different in that the 
destination for them clearly is dpdk itself. I would like to see 
experimental code moved to a separate (staging or whatever) directory 
(or a repo/git submodule) to make the situation absolutely clear. Or a 
repo/git submodule or such. I also still think experimental features 
should not be enabled by default in the configs, no other project that I 
know of does that, but that's another discussion.

	- Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-03  1:22  4%   ` [dpdk-dev] [PATCH v6 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
@ 2016-03-03  9:51  0%     ` Panu Matilainen
  0 siblings, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-03  9:51 UTC (permalink / raw)
  To: Wenzhuo Lu, dev

On 03/03/2016 03:22 AM, Wenzhuo Lu wrote:
> 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>
> ---
[...]
> diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
> index d8db24d..5122217 100644
> --- 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: *;
>   };

These symbols were not present in DPDK 2.2, hence they dont belong in 
that section. You need to declare a new version section, see 
http://dpdk.org/browse/dpdk/commit/?id=c2189745c38d944e3b0e0c99066d67d7bc7e7744 
for an example.

	- Panu -

^ permalink raw reply	[relevance 0%]

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

On 3/3/2016 8:31 AM, Panu Matilainen wrote:
> On 03/03/2016 12:35 AM, Thomas Monjalon wrote:
>> 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
> 
> To answer this, I think we need to start by clarifying the kernel module
> situation. Quoting your from
> http://dpdk.org/ml/archives/dev/2016-January/032263.html:
> 
>> Sorry the kernel module party is over.
>> One day, igb_uio will be removed.
>> I suggest to make a first version without interrupt support
>> and work with Linux community to fix your issues.
> 
> This to me reads "no more out-of-tree kernel modules, period" but here
> we are discussing the fate of another one.
> 
> If the policy truly is "no more kernel modules" (which I would fully
> back and applaud) then I think there's little to discuss - if the
> destination is kernel upstream then why should the modules pass through
> the dpdk codebase? Put it in another repo on dpdk.org, advertise it,
> make testing it as easy as possible and all (like have it integrate with
> dpdk makefiles if needed) instead.
> 
Hi Panu,

I just want to remind that these modules are to replace existing KNI
kernel module, and to reduce it's maintenance cost.
We are not adding new kernel modules for new features.

I believe replacing KNI module with new code in DPDK is a required
improvement step. But to replace, KNI users should verify the new codes.

Going directly from KNI to Linux upstream, if possible, is not easy.
Upstreaming should be done in incremental steps.

How about following steps:
1- Add KCP/KDP with an EXPERIMENTAL flag.
2- When they are mature enough, remove KNI, remove EXPERIMENTAL from
KCP/KDP.
3- Work on upstreaming

Thanks,
ferruh

> The difference with crypto API and ethtool is different in that the
> destination for them clearly is dpdk itself. I would like to see
> experimental code moved to a separate (staging or whatever) directory
> (or a repo/git submodule) to make the situation absolutely clear. Or a
> repo/git submodule or such. I also still think experimental features
> should not be enabled by default in the configs, no other project that I
> know of does that, but that's another discussion.
> 
>     - Panu -

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-02 22:18  0%           ` Jay Rolette
@ 2016-03-03 10:11  0%             ` Ferruh Yigit
  2016-03-03 16:59  0%               ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2016-03-03 10:11 UTC (permalink / raw)
  To: Jay Rolette, Stephen Hemminger; +Cc: DPDK, Avi Kivity

On 3/2/2016 10:18 PM, Jay Rolette wrote:
> 
> On Tue, Mar 1, 2016 at 8:02 PM, Stephen Hemminger
> <stephen@networkplumber.org <mailto:stephen@networkplumber.org>> wrote:
> 
>     On Mon, 29 Feb 2016 08:33:25 -0600
>     Jay Rolette <rolette@infiniteio.com <mailto:rolette@infiniteio.com>>
>     wrote:
> 
>     > On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon
>     <thomas.monjalon@6wind.com <mailto:thomas.monjalon@6wind.com>>
>     > wrote:
>     >
>     > > Hi,
>     > > I totally agree with Avi's comments.
>     > > This topic is really important for the future of DPDK.
>     > > So I think we must give some time to continue the discussion
>     > > and have netdev involved in the choices done.
>     > > As a consequence, these series should not be merged in the
>     release 16.04.
>     > > Thanks for continuing the work.
>     > >
>     >
>     > I know you guys are very interested in getting rid of the out-of-tree
>     > drivers, but please do not block incremental improvements to DPDK
>     in the
>     > meantime. Ferruh's patch improves the usability of KNI. Don't
>     throw out
>     > good and useful enhancements just because it isn't where you want
>     to be in
>     > the end.
>     >
>     > 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.
> 
> 
> That's fair. To be clear, it wasn't my intent for code that wasn't baked
> yet to be merged. 
> 
> The main point of my comment was that I think it is important not to
> halt incremental improvements to existing capabilities (KNI in this
> case) just because there are philosophical or directional changes that
> the community would like to make longer-term.
> 
> Bird in the hand vs. two in the bush...
> 

There are two different statements, first, code being not ready, I agree
a fair point (although there is no argument to that statement, it makes
hard to discuss this, I will put aside this), this implies when code is
ready it can go in to repo.

But not having kernel module, independent from their state against what
they are trying to replace is something else. And this won't help on KNI
related problems.

Thanks,
ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-03 10:05  0%                     ` Ferruh Yigit
@ 2016-03-03 10:11  0%                       ` Thomas Monjalon
  2016-03-03 10:51  0%                       ` Panu Matilainen
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-03 10:11 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Avi Kivity

2016-03-03 10:05, Ferruh Yigit:
> On 3/3/2016 8:31 AM, Panu Matilainen wrote:
> > On 03/03/2016 12:35 AM, Thomas Monjalon wrote:
> >> 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
> > 
> > To answer this, I think we need to start by clarifying the kernel module
> > situation. Quoting your from
> > http://dpdk.org/ml/archives/dev/2016-January/032263.html:
> > 
> >> Sorry the kernel module party is over.
> >> One day, igb_uio will be removed.
> >> I suggest to make a first version without interrupt support
> >> and work with Linux community to fix your issues.
> > 
> > This to me reads "no more out-of-tree kernel modules, period" but here
> > we are discussing the fate of another one.
> > 
> > If the policy truly is "no more kernel modules" (which I would fully
> > back and applaud) then I think there's little to discuss - if the
> > destination is kernel upstream then why should the modules pass through
> > the dpdk codebase? Put it in another repo on dpdk.org, advertise it,
> > make testing it as easy as possible and all (like have it integrate with
> > dpdk makefiles if needed) instead.
> > 
> Hi Panu,
> 
> I just want to remind that these modules are to replace existing KNI
> kernel module, and to reduce it's maintenance cost.
> We are not adding new kernel modules for new features.
> 
> I believe replacing KNI module with new code in DPDK is a required
> improvement step. But to replace, KNI users should verify the new codes.
> 
> Going directly from KNI to Linux upstream, if possible, is not easy.
> Upstreaming should be done in incremental steps.
> 
> How about following steps:
> 1- Add KCP/KDP with an EXPERIMENTAL flag.
> 2- When they are mature enough, remove KNI, remove EXPERIMENTAL from
> KCP/KDP.
> 3- Work on upstreaming

What about working with upstream early (step 3 before 2)?
KNI is not so nice but it was advertised and used.
If we want to advertise a replacement, it must be approved by upstream.
We need some stable and widely adopted interfaces to bring more confidence
in the project.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-03 10:05  0%                     ` Ferruh Yigit
  2016-03-03 10:11  0%                       ` Thomas Monjalon
@ 2016-03-03 10:51  0%                       ` Panu Matilainen
  1 sibling, 0 replies; 200+ results
From: Panu Matilainen @ 2016-03-03 10:51 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon, Vincent JARDIN; +Cc: dev, Avi Kivity

On 03/03/2016 12:05 PM, Ferruh Yigit wrote:
> On 3/3/2016 8:31 AM, Panu Matilainen wrote:
>> On 03/03/2016 12:35 AM, Thomas Monjalon wrote:
>>> 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
>>
>> To answer this, I think we need to start by clarifying the kernel module
>> situation. Quoting your from
>> http://dpdk.org/ml/archives/dev/2016-January/032263.html:
>>
>>> Sorry the kernel module party is over.
>>> One day, igb_uio will be removed.
>>> I suggest to make a first version without interrupt support
>>> and work with Linux community to fix your issues.
>>
>> This to me reads "no more out-of-tree kernel modules, period" but here
>> we are discussing the fate of another one.
>>
>> If the policy truly is "no more kernel modules" (which I would fully
>> back and applaud) then I think there's little to discuss - if the
>> destination is kernel upstream then why should the modules pass through
>> the dpdk codebase? Put it in another repo on dpdk.org, advertise it,
>> make testing it as easy as possible and all (like have it integrate with
>> dpdk makefiles if needed) instead.
>>
> Hi Panu,
>
> I just want to remind that these modules are to replace existing KNI
> kernel module, and to reduce it's maintenance cost.
> We are not adding new kernel modules for new features.
>
> I believe replacing KNI module with new code in DPDK is a required
> improvement step. But to replace, KNI users should verify the new codes.
>
> Going directly from KNI to Linux upstream, if possible, is not easy.
> Upstreaming should be done in incremental steps.
>
> How about following steps:
> 1- Add KCP/KDP with an EXPERIMENTAL flag.
> 2- When they are mature enough, remove KNI, remove EXPERIMENTAL from
> KCP/KDP.
> 3- Work on upstreaming

And if upstream says no, as they just as well might? You're one step 
forward, two steps back.

You need to engage upstream NOW, as has been suggested in this thread 
several times already.

	- Panu -

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v4] librte_pipeline: add support for packet redirection at action handlers
  2016-03-02 20:41  4%   ` [dpdk-dev] [PATCH v3 " Jasvinder Singh
@ 2016-03-03 11:01  3%     ` Jasvinder Singh
  2016-03-08 18:07  2%       ` [dpdk-dev] [PATCH v5 1/2] " Jasvinder Singh
  0 siblings, 1 reply; 200+ results
From: Jasvinder Singh @ 2016-03-03 11:01 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). Therefore, new
pipeline API functions have been added which allows action handlers to
hijack packets and remove them from the pipeline processing, and then either
drop them or send them out of the pipeline on any output port. The port
(in/out) and table action handler prototypes have been changed for making
use of these new API functions. This feature will be helpful to implement
functions such as exception handling (e.g. TTL =0), load balancing etc.
Changes are made to the ports and table action handlers defined in
app/test_pipeline and ip_pipeline sample application.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
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 +-
 doc/guides/rel_notes/deprecation.rst               |   5 -
 doc/guides/rel_notes/release_16_04.rst             |   6 +-
 .../ip_pipeline/pipeline/pipeline_actions_common.h |  47 ++-
 .../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                 | 461 +++++++++++----------
 lib/librte_pipeline/rte_pipeline.h                 | 174 +++++---
 lib/librte_pipeline/rte_pipeline_version.map       |   8 +
 17 files changed, 399 insertions(+), 336 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/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..1a7d660 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -40,11 +40,6 @@ 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.
-
 * ABI changes are planned in cmdline buffer size to allow the use of long
   commands (such as RETA update in testpmd).  This should impact
   CMDLINE_PARSE_RESULT_BUFSIZE, STR_TOKEN_SIZE and RDLINE_BUF_SIZE.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index fd7dd1a..bd180ee 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -128,6 +128,10 @@ 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.
 
+* 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
 -----------------------
@@ -154,7 +158,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..9958758 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(									\
+	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,22 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
-	*pkts_mask = pkts_out_mask;					\
+	rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);	\
+									\
 	return 0;							\
 }
 
 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)	\
 static int								\
 f_ah(									\
+	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 +201,8 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
-	*pkts_mask = pkts_out_mask;					\
+	rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);	\
+									\
 	return 0;							\
 }
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
index 1c376f7..0e8da94 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
@@ -439,7 +439,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 ec149c8..8244a5c 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
@@ -585,7 +585,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 ac80fc6..81b6454 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
@@ -414,7 +414,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 a898f7d..7642462 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
@@ -451,7 +451,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 9baabd0..a207286 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
@@ -1192,7 +1192,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..7f8fbac 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;
 
-		/* Input port user actions */
-		if (port_in->f_action != NULL) {
-			uint64_t mask = pkts_mask;
+	if (port_in == NULL)
+		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);
-		}
+	/* 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;
+	}
 
-		/* 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);
-					}
-				}
-			}
+	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;
+
+	/* 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 */
+		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;
 
-			/* 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]);
+			/* 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 reserved action PORT META */
-		rte_pipeline_action_handler_port_meta(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
+			/* Table user actions */
+			if (table->f_action_hit != NULL) {
+				table->f_action_hit(p,
+					p->pkts,
+					lookup_hit_mask,
+					p->entries,
+					table->arg_ah);
 
-		/* Table reserved action DROP */
-		rte_pipeline_action_handler_drop(p,
-				p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
+				RTE_PIPELINE_STATS_AH_DROP_READ(p,
+					table->n_pkts_dropped_by_lkp_hit_ah);
+			}
+
+			/* 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);
+		}
+
+		/* 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,26 +1503,32 @@ 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;
+}
+
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+
+	return 0;
+}
+
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+	p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
 
+	RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
 	return 0;
 }
 
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 7302a62..84d1802 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;
 };
@@ -778,14 +759,38 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
 	uint32_t *port_id);
 
 /**
- * Pipeline output port packet insert
+ * Read pipeline port out stats.
+ *
+ * This function reads port out statistics identified by *port_id* of given
+ * pipeline *p*.
+ *
+ * @param p
+ *   Handle to pipeline instance.
+ * @param port_id
+ *   Port ID what stats will be returned.
+ * @param stats
+ *   Statistics buffer.
+ * @param clear
+ *   If not 0 clear stats after reading.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
+	struct rte_pipeline_port_out_stats *stats, int clear);
+
+/*
+ * Functions to be called as part of the port IN/OUT or table action handlers
+ *
+ */
+/**
+ * Action handler packet insert to output port
  *
- * This function is called by the table action handler whenever it generates a
- * new packet to be sent out though one of the pipeline output ports. This
- * packet is not part of the burst of input packets read from any of the
- * pipeline input ports, so it is not an element of the pkts array input
- * parameter of the table action handler. This packet can be dropped by the
- * output port action handler.
+ * This function can be called by any input/output port or table action handler
+ * to send a packet out through one of the pipeline output ports. This packet is
+ * generated by the action handler, i.e. this packet is not part of the burst of
+ * packets read from one of the pipeline input ports and currently processed by
+ * the pipeline (this packet is not an element of the pkts array input parameter
+ * of the action handler).
  *
  * @param p
  *   Handle to pipeline instance
@@ -793,7 +798,7 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
  *   Output port ID (returned by previous invocation of pipeline output port
  *   create) to send the packet specified by pkt
  * @param pkt
- *   New packet generated by the table action handler
+ *   New packet generated by the action handler
  * @return
  *   0 on success, error code otherwise
  */
@@ -801,25 +806,68 @@ int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
 	uint32_t port_id,
 	struct rte_mbuf *pkt);
 
+#define rte_pipeline_ah_port_out_packet_insert \
+	rte_pipeline_port_out_packet_insert
+
 /**
- * Read pipeline port out stats.
+ * Action handler packet hijack
  *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
+ * This function can be called by any input/output port or table action handler
+ * to hijack selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The hijacked
+ * packets are removed from any further pipeline processing, with the action
+ * handler now having the full ownership for these packets.
+ *
+ * The action handler can further send the hijacked packets out through any
+ * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
+ * function. The action handler can also drop these packets by calling the
+ * rte_pktmbuf_free() function, although a better alternative is provided by
+ * the action handler using the rte_pipeline_ah_packet_drop() function.
  *
  * @param p
- *   Handle to pipeline instance.
- * @param port_id
- *   Port ID what stats will be returned.
- * @param stats
- *   Statistics buffer.
- * @param clear
- *   If not 0 clear stats after reading.
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be hijacked by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is hijacked.
  * @return
  *   0 on success, error code otherwise
  */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
-	struct rte_pipeline_port_out_stats *stats, int clear);
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
+/**
+ * Action handler packet drop
+ *
+ * This function is called by the pipeline action handlers (port in/out, table)
+ * to drop the packets selected using packet mask.
+ *
+ * This function can be called by any input/output port or table action handler
+ * to drop selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The dropped
+ * packets are removed from any further pipeline processing and the packet
+ * buffers are eventually freed to their buffer pool.
+ *
+ * This function updates the drop statistics counters correctly, therefore the
+ * recommended approach for dropping packets by the action handlers is to call
+ * this function as opposed to the action handler hijacking the packets first
+ * and then dropping them invisibly to the pipeline (by using the
+ * rte_pktmbuf_free() function).
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be dropped by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is dropped.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 4cc86f6..e4ee154 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -37,3 +37,11 @@ DPDK_2.2 {
 	rte_pipeline_table_entry_delete_bulk;
 
 } DPDK_2.1;
+
+DPDK_16.04 {
+	global:
+
+	rte_pipeline_ah_packet_hijack;
+	rte_pipeline_ah_packet_drop;
+
+} DPDK_2.2;
-- 
2.5.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] config: remove duplicate configuration information
  2016-02-22 13:53  6% [dpdk-dev] [PATCH] config: remove duplicate configuration information Keith Wiles
  2016-02-22 15:09  0% ` Trahe, Fiona
  2016-02-24 13:58  0% ` Wiles, Keith
@ 2016-03-03 14:43  0% ` Wiles, Keith
  2 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2016-03-03 14:43 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.

Ping. I got a +1 for this patch just trying to get someone else to agree and ack. I know the current stuff kind of works, but it does require modifying multiple files and while moving this to a single place to modify I did find at least on different.

I would like to see this one go in unless it just does not make any sense.

Thanks
++Keith

>
>Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>---
> config/common_base                          | 498 ++++++++++++++++++++++++++++
> config/common_bsdapp                        | 436 +-----------------------
> config/common_linuxapp                      | 491 +--------------------------
> config/defconfig_x86_64-native-bsdapp-clang |   1 +
> config/defconfig_x86_64-native-bsdapp-gcc   |   1 +
> 5 files changed, 518 insertions(+), 909 deletions(-)
> create mode 100644 config/common_base
>
>diff --git a/config/common_base b/config/common_base
>new file mode 100644
>index 0000000..91a12eb
>--- /dev/null
>+++ b/config/common_base
>@@ -0,0 +1,498 @@
>+#   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.
>+#
>+
>+#
>+# 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=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
>+
>+#
>+# 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=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
>+# 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=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
>diff --git a/config/common_bsdapp b/config/common_bsdapp
>index 696382c..de0ca7d 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,74 +37,38 @@
> 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
>+#include "common_base"
> 
> #
>-# Machine forces strict alignment constraints.
>+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
> #
>-CONFIG_RTE_ARCH_STRICT_ALIGN=n
>+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
> 
> #
>-# Compile to share library
>+# Compile Environment Abstraction Layer
> #
>-CONFIG_RTE_BUILD_SHARED_LIB=n
>+CONFIG_RTE_EAL_IGB_UIO=n
>+CONFIG_RTE_EAL_VFIO=n
> 
> #
>-# Combine to one single library
>+# Compile software PMD backed by AF_PACKET sockets (Linux only)
> #
>-CONFIG_RTE_BUILD_COMBINE_LIBS=n
>+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
> 
> #
>-# Use newest code breaking previous ABI
>+# Compile librte_power
> #
>-CONFIG_RTE_NEXT_ABI=y
>+CONFIG_RTE_LIBRTE_POWER=n
> 
> #
>-# Machine's cache line size
>+# Compile librte_kni
> #
>-CONFIG_RTE_CACHE_LINE_SIZE=64
>+CONFIG_RTE_LIBRTE_KNI=n
> 
> #
>-# Compile Environment Abstraction Layer
>+# Compile vhost library
> #
>-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_VHOST=n
> 
> #
> # FreeBSD contiguous memory driver settings
>@@ -113,373 +77,3 @@ 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 f1638db..64ddbe9 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,494 +37,9 @@
> 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
>-
>-#
>-# 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=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
>+# Compile Environment Abstraction Layer for linux, FreeBSD, OS X, ...
> #
> 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
>-#
>-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=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
>-# 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=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
>diff --git a/config/defconfig_x86_64-native-bsdapp-clang b/config/defconfig_x86_64-native-bsdapp-clang
>index d2baf2c..8b870b3 100644
>--- a/config/defconfig_x86_64-native-bsdapp-clang
>+++ b/config/defconfig_x86_64-native-bsdapp-clang
>@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
> CONFIG_RTE_ARCH="x86_64"
> CONFIG_RTE_ARCH_X86_64=y
> CONFIG_RTE_ARCH_X86=y
>+CONFIG_RTE_ARCH_64=y
> 
> CONFIG_RTE_TOOLCHAIN="clang"
> CONFIG_RTE_TOOLCHAIN_CLANG=y
>diff --git a/config/defconfig_x86_64-native-bsdapp-gcc b/config/defconfig_x86_64-native-bsdapp-gcc
>index 5a6a4e8..4ea4433 100644
>--- a/config/defconfig_x86_64-native-bsdapp-gcc
>+++ b/config/defconfig_x86_64-native-bsdapp-gcc
>@@ -37,6 +37,7 @@ CONFIG_RTE_MACHINE="native"
> CONFIG_RTE_ARCH="x86_64"
> CONFIG_RTE_ARCH_X86_64=y
> CONFIG_RTE_ARCH_X86=y
>+CONFIG_RTE_ARCH_64=y
> 
> CONFIG_RTE_TOOLCHAIN="gcc"
> CONFIG_RTE_TOOLCHAIN_GCC=y
>-- 
>2.7.0
>
>


Regards,
Keith





^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 0/3] ABI change for RETA, cmdline
    @ 2016-03-03 15:16  4%   ` Adrien Mazarguil
  2016-03-03 19:39  4%     ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Adrien Mazarguil @ 2016-03-03 15:16 UTC (permalink / raw)
  To: Nelio Laranjeiro; +Cc: dev

On Tue, Jan 12, 2016 at 11:49:06AM +0100, Nelio Laranjeiro wrote:
> Previous version of commit
> "cmdline: increase command line buffer", had side effects and was breaking
> some commands.
> 
> In this version, I only applied John McNamara's solution which consists in
> increasing only RDLINE_BUF_SIZE define from 256 to 512 bytes [1].
> 
> [1] http://dpdk.org/ml/archives/dev/2015-November/027643.html

Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-03 10:11  0%             ` Ferruh Yigit
@ 2016-03-03 16:59  0%               ` Stephen Hemminger
  2016-03-03 18:18  0%                 ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2016-03-03 16:59 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: DPDK, Avi Kivity

On Thu, 3 Mar 2016 10:11:57 +0000
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> On 3/2/2016 10:18 PM, Jay Rolette wrote:
> > 
> > On Tue, Mar 1, 2016 at 8:02 PM, Stephen Hemminger
> > <stephen@networkplumber.org <mailto:stephen@networkplumber.org>> wrote:
> > 
> >     On Mon, 29 Feb 2016 08:33:25 -0600
> >     Jay Rolette <rolette@infiniteio.com <mailto:rolette@infiniteio.com>>
> >     wrote:
> > 
> >     > On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon
> >     <thomas.monjalon@6wind.com <mailto:thomas.monjalon@6wind.com>>
> >     > wrote:
> >     >
> >     > > Hi,
> >     > > I totally agree with Avi's comments.
> >     > > This topic is really important for the future of DPDK.
> >     > > So I think we must give some time to continue the discussion
> >     > > and have netdev involved in the choices done.
> >     > > As a consequence, these series should not be merged in the
> >     release 16.04.
> >     > > Thanks for continuing the work.
> >     > >
> >     >
> >     > I know you guys are very interested in getting rid of the out-of-tree
> >     > drivers, but please do not block incremental improvements to DPDK
> >     in the
> >     > meantime. Ferruh's patch improves the usability of KNI. Don't
> >     throw out
> >     > good and useful enhancements just because it isn't where you want
> >     to be in
> >     > the end.
> >     >
> >     > 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.
> > 
> > 
> > That's fair. To be clear, it wasn't my intent for code that wasn't baked
> > yet to be merged. 
> > 
> > The main point of my comment was that I think it is important not to
> > halt incremental improvements to existing capabilities (KNI in this
> > case) just because there are philosophical or directional changes that
> > the community would like to make longer-term.
> > 
> > Bird in the hand vs. two in the bush...
> > 
> 
> There are two different statements, first, code being not ready, I agree
> a fair point (although there is no argument to that statement, it makes
> hard to discuss this, I will put aside this), this implies when code is
> ready it can go in to repo.
> 
> But not having kernel module, independent from their state against what
> they are trying to replace is something else. And this won't help on KNI
> related problems.
> 
> Thanks,
> ferruh
> 

Why not re-submit patches but put in lib/librte_eal/staging or similar path
and make sure that it does not get build by normal build process.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module
  2016-03-03 16:59  0%               ` Stephen Hemminger
@ 2016-03-03 18:18  0%                 ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2016-03-03 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: DPDK, Avi Kivity

On 3/3/2016 4:59 PM, Stephen Hemminger wrote:
> On Thu, 3 Mar 2016 10:11:57 +0000
> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> On 3/2/2016 10:18 PM, Jay Rolette wrote:
>>>
>>> On Tue, Mar 1, 2016 at 8:02 PM, Stephen Hemminger
>>> <stephen@networkplumber.org <mailto:stephen@networkplumber.org>> wrote:
>>>
>>>     On Mon, 29 Feb 2016 08:33:25 -0600
>>>     Jay Rolette <rolette@infiniteio.com <mailto:rolette@infiniteio.com>>
>>>     wrote:
>>>
>>>     > On Mon, Feb 29, 2016 at 5:06 AM, Thomas Monjalon
>>>     <thomas.monjalon@6wind.com <mailto:thomas.monjalon@6wind.com>>
>>>     > wrote:
>>>     >
>>>     > > Hi,
>>>     > > I totally agree with Avi's comments.
>>>     > > This topic is really important for the future of DPDK.
>>>     > > So I think we must give some time to continue the discussion
>>>     > > and have netdev involved in the choices done.
>>>     > > As a consequence, these series should not be merged in the
>>>     release 16.04.
>>>     > > Thanks for continuing the work.
>>>     > >
>>>     >
>>>     > I know you guys are very interested in getting rid of the out-of-tree
>>>     > drivers, but please do not block incremental improvements to DPDK
>>>     in the
>>>     > meantime. Ferruh's patch improves the usability of KNI. Don't
>>>     throw out
>>>     > good and useful enhancements just because it isn't where you want
>>>     to be in
>>>     > the end.
>>>     >
>>>     > 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.
>>>
>>>
>>> That's fair. To be clear, it wasn't my intent for code that wasn't baked
>>> yet to be merged. 
>>>
>>> The main point of my comment was that I think it is important not to
>>> halt incremental improvements to existing capabilities (KNI in this
>>> case) just because there are philosophical or directional changes that
>>> the community would like to make longer-term.
>>>
>>> Bird in the hand vs. two in the bush...
>>>
>>
>> There are two different statements, first, code being not ready, I agree
>> a fair point (although there is no argument to that statement, it makes
>> hard to discuss this, I will put aside this), this implies when code is
>> ready it can go in to repo.
>>
>> But not having kernel module, independent from their state against what
>> they are trying to replace is something else. And this won't help on KNI
>> related problems.
>>
>> Thanks,
>> ferruh
>>
> 
> Why not re-submit patches but put in lib/librte_eal/staging or similar path
> and make sure that it does not get build by normal build process.
> 
I will do when staging is ready/defined.

Also will start working on upstreaming modules.

Thanks,
ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 0/3] ABI change for RETA, cmdline
  2016-03-03 15:16  4%   ` [dpdk-dev] [PATCH v2 0/3] ABI change for RETA, cmdline Adrien Mazarguil
@ 2016-03-03 19:39  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2016-03-03 19:39 UTC (permalink / raw)
  To: Nelio Laranjeiro; +Cc: dev

2016-03-03 16:16, Adrien Mazarguil:
> On Tue, Jan 12, 2016 at 11:49:06AM +0100, Nelio Laranjeiro wrote:
> > Previous version of commit
> > "cmdline: increase command line buffer", had side effects and was breaking
> > some commands.
> > 
> > In this version, I only applied John McNamara's solution which consists in
> > increasing only RDLINE_BUF_SIZE define from 256 to 512 bytes [1].
> > 
> > [1] http://dpdk.org/ml/archives/dev/2015-November/027643.html
> 
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

Applied, thanks

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v7 1/5] lib/librte_ether: change function name of tunnel port config
  @ 2016-03-04  2:35  4%   ` Wenzhuo Lu
  2016-03-08 23:35  0%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Wenzhuo Lu @ 2016-03-04  2: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>
---
 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          | 18 ++++++++++++++
 lib/librte_ether/rte_ether_version.map |  2 ++
 5 files changed, 70 insertions(+), 3 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..f1f96c1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -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;
 };
 
 /**
@@ -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);
+int
+rte_eth_dev_udp_tunnel_port_add(uint8_t port_id,
+				struct rte_eth_udp_tunnel *tunnel_udp);
 
  /**
  * 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);
 
 /**
  * Check whether the filter type is supported on an Ethernet device.
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..5122217 100644
--- 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: *;
 };
-- 
1.9.3

^ permalink raw reply	[relevance 4%]

* [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%]

* [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 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
                     ` (2 more replies)
  0 siblings, 3 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 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
  2016-03-07  9:28  0%   ` [dpdk-dev] [PATCH v2 0/3] i40e setting ether type of VLANs Thomas Monjalon
  2 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 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
  2 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%]

* 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
  2 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%]

* 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 1/5] mem: add --single-file to create single mem-backed file
  2016-02-05 11:20  2%   ` [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  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/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-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/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-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-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/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%]

* [dpdk-dev] [PATCH v5 1/2] librte_pipeline: add support for packet redirection at action handlers
  2016-03-03 11:01  3%     ` [dpdk-dev] [PATCH v4] " Jasvinder Singh
@ 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 3/3] igb_uio: deprecate sys files
  2016-02-22  3:59  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
@ 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 v3 0/3] enable extended tag for i40e
  2016-02-22  3:59  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
  2016-02-22  3:59  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
  2016-02-22  5:52  0%   ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Wu, Jingjing
@ 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
  2 siblings, 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%]

* [dpdk-dev] [PATCH v3 2/3] pci: remove config of extended tag
  2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 " 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%]

* Re: [dpdk-dev] [PATCH v7 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure
  2016-03-01  8:41 17%         ` [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
  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%]

* 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, 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 v7 1/5] lib/librte_ether: change function name of tunnel port config
  2016-03-04  2:35  4%   ` [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
  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/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-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-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%]

* [dpdk-dev] [PATCH v8 0/5] Support VxLAN & NVGRE checksum off-load on X550
                     ` (4 preceding siblings ...)
  @ 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
  6 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%]

* [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 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 v3 00/12] extend flow director fields in i40e driver
  2016-03-02 11:29  4% ` [dpdk-dev] [PATCH v2 " Jingjing Wu
  2016-03-02 11:30 18%   ` [dpdk-dev] [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
@ 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)
  1 sibling, 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 v3 07/12] librte_ether: extend flow director struct
  2016-03-09  5:42  4%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver 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%]

* 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 fields in i40e driver 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 0/4] external mempool manager
  2016-02-16 14:48  3% ` [dpdk-dev] [PATCH 0/6] external mempool manager David Hunt
  2016-02-16 14:48  4%   ` [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages David Hunt
@ 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
  1 sibling, 1 reply; 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%]

* [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] external mempool manager David Hunt
@ 2016-03-09  9:50  4%     ` David Hunt
  2016-03-09 10:46  7%       ` Panu Matilainen
  0 siblings, 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%]

* 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%]

* 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%]

* [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%]

* [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%]

* 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 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%]

* [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%]

* 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%]

* 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 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 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 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] 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%]

* [dpdk-dev] [RFC 00/35] mempool: rework memory allocation
@ 2016-03-09 16:19  2% Olivier Matz
  0 siblings, 0 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 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%]

* 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 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 0/3] ethdev: add helper functions to get eth_dev and dev private data
  2016-02-17 14:20  3% [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data Ferruh Yigit
  2016-02-17 14:20  3% ` [dpdk-dev] [PATCH 1/3] " Ferruh Yigit
@ 2016-03-10  0:00  0% ` Thomas Monjalon
  1 sibling, 0 replies; 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 1/3] kcp: add kernel control path kernel module
  2016-03-02 22:35  0%                 ` Thomas Monjalon
  2016-03-03  8:31  0%                   ` Panu Matilainen
@ 2016-03-10  0:04  0%                   ` Thomas Monjalon
  2016-03-10  6:31  0%                     ` Vincent JARDIN
  1 sibling, 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 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%]

* [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%]

* [dpdk-dev] [PATCH v9 0/5] Support VxLAN & NVGRE checksum off-load on X550
                     ` (5 preceding siblings ...)
  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
  6 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 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-10  2:42  7%   ` [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
  1 sibling, 0 replies; 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 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 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 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 fields in i40e driver 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
  2 siblings, 1 reply; 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 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
  0 siblings, 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%]

* 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 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 18% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen
  0 siblings, 1 reply; 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%]

* [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 18% ` Panu Matilainen
  0 siblings, 0 replies; 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 18%]

Results 1601-1800 of ~18000   |  | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2015-08-29  0:16     [dpdk-dev] [PATCH v4 0/2] ethdev: add port speed capability bitmap Marc Sune
2015-10-04 21:12     ` [dpdk-dev] [PATCH v5 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
2015-10-04 21:12       ` [dpdk-dev] [PATCH v5 3/4] ethdev: redesign link speed config API Marc Sune
2016-01-28 17:33         ` Harish Patil
2016-02-02  2:20           ` Stephen Hemminger
2016-02-02 22:30             ` Marc
2016-02-11 15:27  3%           ` Nélio Laranjeiro
2016-02-11 23:23  0%             ` Marc
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  2%   ` [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-11-24 14:31     [dpdk-dev] [PATCH] mk: fix the combined library problems by replacing it with a linker script Panu Matilainen
2016-02-23 22:20  4% ` [dpdk-dev] [PATCH v2] mk: replace the combined library " Thomas Monjalon
2015-12-13 23:35     [dpdk-dev] [PATCH 0/2] provide rte_pktmbuf_alloc_bulk API and call it in vhost dequeue Huawei Xie
2016-01-26 17:03     ` [dpdk-dev] [PATCH v6 " Huawei Xie
2016-01-26 17:03       ` [dpdk-dev] [PATCH v6 1/2] mbuf: provide rte_pktmbuf_alloc_bulk API Huawei Xie
2016-01-27 13:56         ` Panu Matilainen
2016-02-03 17:23  0%       ` Olivier MATZ
2016-02-22 14:49  0%         ` Xie, Huawei
2016-02-23  5:35  0%           ` Xie, Huawei
2016-02-24 12:11  0%             ` Panu Matilainen
2016-02-24 13:23  3%               ` Ananyev, Konstantin
2016-02-26  7:39  0%                 ` Xie, Huawei
2016-02-26  8:45  0%                   ` Olivier MATZ
2016-02-29 10:51  4%                 ` Panu Matilainen
2016-02-29 16:14  0%                   ` Thomas Monjalon
2015-12-21  2:38     [dpdk-dev] [PATCH 0/3] i40e: enable extended tag Helin Zhang
2016-02-22  6:31  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
2016-02-22  6:31  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
2015-12-21  2:38     [dpdk-dev] [PATCH 2/3] eal: remove pci config of extended tag Helin Zhang
2016-02-22  3:59  3% ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Helin Zhang
2016-02-22  3:59  6%   ` [dpdk-dev] [PATCH v2 3/3] igb_uio: deprecate sys files Helin Zhang
2016-03-08 18:02  0%     ` Thomas Monjalon
2016-02-22  5:52  0%   ` [dpdk-dev] [PATCH v2 0/3] enable extended tag for i40e Wu, Jingjing
2016-03-08 18:38  3%   ` [dpdk-dev] [PATCH v3 " Thomas Monjalon
2016-03-08 18:38  4%     ` [dpdk-dev] [PATCH v3 2/3] pci: remove config of extended tag Thomas Monjalon
2015-12-21 13:26     [dpdk-dev] [PATCH 0/3] switch to using YY.MM version numbers Bruce Richardson
2016-02-10 17:02     ` [dpdk-dev] [PATCH v3 1/2] version: switch to year/month " John McNamara
2016-02-10 17:02  9%   ` [dpdk-dev] [PATCH v3 2/2] doc: rename release notes 2.3 to 16.04 John McNamara
2015-12-21 13:26     [dpdk-dev] [PATCH 1/3] version: switch to year/month version numbers Bruce Richardson
2016-02-10 14:33     ` [dpdk-dev] [PATCH v2 1/2] " John McNamara
2016-02-10 14:33  9%   ` [dpdk-dev] [PATCH v2 2/2] doc: rename release notes 2.3 to 16.04 John McNamara
2015-12-31  6:53     [dpdk-dev] [PATCH 00/12] Add API to get packet type info Jianfeng Tan
2016-02-26  7:34     ` [dpdk-dev] [PATCH v5 00/11] " Jianfeng Tan
2016-02-26  7:34       ` [dpdk-dev] [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-29 11:34  3%     ` Panu Matilainen
2016-02-29 16:41  0%       ` Tan, Jianfeng
2016-03-09 19:31     ` [dpdk-dev] [PATCH v7 00/11] Add API to get packet type info 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-06 14:32     [dpdk-dev] [PATCH 0/3] ABI changes (RETA, cmdline) Nelio Laranjeiro
2016-01-12 10:49     ` [dpdk-dev] [PATCH v2 0/3] ABI change for RETA, cmdline Nelio Laranjeiro
2016-01-12 10:49       ` [dpdk-dev] [PATCH v2 1/3] cmdline: increase command line buffer Nelio Laranjeiro
2016-01-12 12:46         ` Panu Matilainen
2016-01-15  8:44           ` Nélio Laranjeiro
2016-01-15  9:00             ` Panu Matilainen
2016-01-18 14:38               ` Olivier MATZ
2016-02-26 15:16  0%             ` Nélio Laranjeiro
2016-03-03 15:16  4%   ` [dpdk-dev] [PATCH v2 0/3] ABI change for RETA, cmdline Adrien Mazarguil
2016-03-03 19:39  4%     ` Thomas Monjalon
2016-01-11  7:07     [dpdk-dev] [PATCH 0/4] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-02-18  3:17     ` [dpdk-dev] [PATCH v3 0/5] " Wenzhuo Lu
2016-02-18  3:17  4%   ` [dpdk-dev] [PATCH v3 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-02-26  8:35     ` [dpdk-dev] [PATCH v4 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-02-26  8:35  4%   ` [dpdk-dev] [PATCH v4 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-02  6:45     ` [dpdk-dev] [PATCH v5 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-02  6:45  4%   ` [dpdk-dev] [PATCH v5 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-02  8:56  0%     ` Panu Matilainen
2016-03-03  1:22     ` [dpdk-dev] [PATCH v6 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-03  1:22  4%   ` [dpdk-dev] [PATCH v6 1/5] lib/librte_ether: change function name of tunnel port config Wenzhuo Lu
2016-03-03  9:51  0%     ` Panu Matilainen
2016-03-04  2:35     ` [dpdk-dev] [PATCH v7 0/5] Support VxLAN & NVGRE checksum off-load on X550 Wenzhuo Lu
2016-03-04  2:35  4%   ` [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-10  2:42  7%   ` [dpdk-dev] [PATCH v9 5/5] ixgbe: support VxLAN & NVGRE TX checksum off-load Wenzhuo Lu
2016-01-15  2:40     [dpdk-dev] [PATCH 00/29] i40e base driver update Helin Zhang
2016-02-18  6:29     ` [dpdk-dev] [PATCH v2 00/30] " Helin Zhang
2016-02-18  6:30  4%   ` [dpdk-dev] [PATCH v2 28/30] i40e: add/remove new device IDs Helin Zhang
2016-01-15 14:43     [dpdk-dev] [PATCH 0/2] add support for buffered tx to ethdev Tomasz Kulasek
2016-01-15 14:43     ` [dpdk-dev] [PATCH 1/2] ethdev: add buffered tx api Tomasz Kulasek
2016-01-15 18:44       ` Ananyev, Konstantin
2016-02-02 10:00         ` Kulasek, TomaszX
2016-02-02 13:49           ` Ananyev, Konstantin
2016-02-09 17:02             ` Kulasek, TomaszX
2016-02-09 23:56               ` Ananyev, Konstantin
2016-02-12 11:44  3%             ` Ananyev, Konstantin
2016-02-12 16:40  0%               ` Ivan Boule
2016-02-12 17:33  0%                 ` Bruce Richardson
2016-02-24 17:08  4% ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Tomasz Kulasek
2016-02-24 17:08  2%   ` [dpdk-dev] [PATCH v2 1/2] ethdev: add buffered tx api Tomasz Kulasek
2016-02-25 16:17  0%   ` [dpdk-dev] [PATCH v2 0/2] add support for buffered tx to ethdev Ananyev, Konstantin
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-01-25  2:36     [dpdk-dev] [PATCH] PCI: ABI change request for adding new field in rte_pci_id structure Ziye Yang
2016-02-16  4:15 15% ` [dpdk-dev] [PATCH v2] " Ziye Yang
2016-02-16 10:11  7%   ` Bruce Richardson
2016-02-16 10:34  7%     ` Thomas Monjalon
2016-02-17  1:54 11%   ` [dpdk-dev] [PATCH v3] " Ziye Yang
2016-02-17 10:14  4%     ` Bruce Richardson
2016-02-18  1:57  4%     ` Zhang, Helin
2016-02-18  2:46  4%     ` Liang, Cunming
2016-01-25 14:11     [dpdk-dev] [PATCH 1/2] librte_pipeline: add support for packet redirection at action handlers Jasvinder Singh
2016-02-29 14:50  4% ` [dpdk-dev] [PATCH v2 " Jasvinder Singh
2016-03-02 20:41  4%   ` [dpdk-dev] [PATCH v3 " Jasvinder Singh
2016-03-03 11:01  3%     ` [dpdk-dev] [PATCH v4] " Jasvinder Singh
2016-03-08 18:07  2%       ` [dpdk-dev] [PATCH v5 1/2] " Jasvinder Singh
2016-01-26  6:26     [dpdk-dev] [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
2016-03-02 11:29  4% ` [dpdk-dev] [PATCH v2 " Jingjing Wu
2016-03-02 11:30 18%   ` [dpdk-dev] [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
2016-03-09  5:42  4%   ` [dpdk-dev] [PATCH v3 00/12] extend flow director fields in i40e driver 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-01-26 17:25     [dpdk-dev] [PATCH 0/5] add external mempool manager David Hunt
2016-01-26 17:25     ` [dpdk-dev] [PATCH 1/5] mempool: add external mempool manager support David Hunt
2016-02-04 14:52       ` Olivier MATZ
2016-02-04 16:47         ` Hunt, David
2016-02-08 11:02  4%       ` Olivier MATZ
2016-02-16 14:48  3% ` [dpdk-dev] [PATCH 0/6] external mempool manager David Hunt
2016-02-16 14:48  4%   ` [dpdk-dev] [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages David Hunt
2016-02-19 13:33  7%     ` Olivier MATZ
2016-03-09  9:50  3%   ` [dpdk-dev] [PATCH v3 0/4] external mempool manager 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-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-01-28  8:40     [dpdk-dev] [PATCH 0/3] support setting i40e VF MAC address from DPDK host side Helin Zhang
2016-02-26  8:14  4% ` Pei, Yulong
2016-01-29  0:42     [dpdk-dev] [PATCH v7 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
2016-02-14 22:17     ` [dpdk-dev] [PATCH v8 0/4] " Marc Sune
2016-02-14 22:17  8%   ` [dpdk-dev] [PATCH v8 4/4] doc: update with link changes Marc Sune
2016-02-18 18:14  0%     ` Mcnamara, John
2016-02-28 22:17  0%       ` Marc
2016-03-01  0:45       ` [dpdk-dev] [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
2016-03-01  0:45  9%     ` [dpdk-dev] [PATCH v9 4/4] doc: update with link changes Marc Sune
2016-02-02 22:59     [dpdk-dev] [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
2016-02-06 22:17  3% ` [dpdk-dev] [PATCH v2 " Thomas Monjalon
2016-02-06 22:17  1%   ` [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
2016-02-08  8:59  0%     ` Jerin Jacob
2016-02-16  7:30  0%   ` [dpdk-dev] [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon
2016-02-02 23:02     [dpdk-dev] [PATCH] mempool: Reduce rte_mempool structure size Keith Wiles
2016-02-08 11:02  4% ` Olivier MATZ
2016-02-08 15:57  0%   ` Wiles, Keith
2016-02-09 17:30  2% ` [dpdk-dev] [PATCH v2] mempool: reduce " Keith Wiles
2016-02-10 21:18  7%   ` [dpdk-dev] [PATCH v3] " Keith Wiles
2016-02-12 11:23  0%     ` Panu Matilainen
2016-02-12 14:19       ` Panu Matilainen
2016-02-12 15:07         ` Wiles, Keith
2016-02-12 15:38  4%       ` Thomas Monjalon
2016-02-12 15:50  0%         ` Olivier MATZ
2016-02-12 15:58  0%           ` Wiles, Keith
2016-02-15  9:58               ` Hunt, David
2016-02-15 10:15  4%             ` Olivier MATZ
2016-02-15 10:21  0%               ` Hunt, David
2016-02-15 12:31  0%                 ` Olivier MATZ
2016-02-12 15:54  0%         ` Wiles, Keith
2016-02-12 18:36  3%   ` [dpdk-dev] [PATCH v4] " Keith Wiles
2016-02-15  9:20  0%     ` Olivier MATZ
2016-02-03  8:32     [dpdk-dev] [PATCH 00/10] cxgbe: Add flow director support Rahul Lakkireddy
2016-02-03  8:32     ` [dpdk-dev] [PATCH 01/10] ethdev: add a generic flow and new behavior switch to fdir Rahul Lakkireddy
2016-02-25  3:26  0%   ` Wu, Jingjing
2016-02-25  9:11  0%     ` Rahul Lakkireddy
2016-02-10 18:01  3% [dpdk-dev] [PATCH v2] mempool: reduce rte_mempool structure size Wiles, Keith
2016-02-10 18:02  3% ` Thomas Monjalon
2016-02-12 11:52  3%   ` Panu Matilainen
2016-02-11 16:37  3% [dpdk-dev] [PATCH v3] af_packet: make the device detachable Wojciech Zmuda
2016-02-24 14:08  3% ` Iremonger, Bernard
2016-02-29 18:22  0%   ` Wojciech Żmuda
2016-03-01  9:43  3%     ` Panu Matilainen
2016-03-02 11:47  0%       ` Wojciech Żmuda
     [not found]     <1453911849-16562-1-git-send-email-ferruh.yigit@intel.com>
2016-02-12 13:45     ` [dpdk-dev] [PATCH v2 0/3] Use common Linux tools to control DPDK ports Ferruh Yigit
2016-02-12 13:45  1%   ` [dpdk-dev] [PATCH v2 2/3] rte_ctrl_if: add control interface library Ferruh Yigit
2016-02-17 19:58  0%     ` Ananyev, Konstantin
2016-02-18 10:43  0%       ` Yigit, Ferruh
2016-02-26 14:10       ` [dpdk-dev] [PATCH v3 0/4] Use common Linux tools to control DPDK ports Ferruh Yigit
2016-02-26 14:10  1%     ` [dpdk-dev] [PATCH v3 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder Ferruh Yigit
2016-03-01 15:41         ` [dpdk-dev] [PATCH v4 0/4] Use common Linux tools to control DPDK ports Ferruh Yigit
2016-03-01 15:41  1%       ` [dpdk-dev] [PATCH v4 1/4] lib/librte_ethtool: move librte_ethtool form examples to lib folder Ferruh Yigit
2016-03-09 11:41           ` [dpdk-dev] [PATCH v5 0/4] Use common Linux tools to control DPDK ports 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-02-29 10:43     ` [dpdk-dev] [PATCH 1/3] kcp: add kernel control path kernel module Ferruh Yigit
2016-02-29 10:58       ` Avi Kivity
2016-02-29 11:06         ` Thomas Monjalon
2016-02-29 14:33           ` Jay Rolette
2016-03-02  2:02  3%         ` Stephen Hemminger
2016-03-02  8:27  0%           ` Panu Matilainen
2016-03-02 10:47  0%             ` Vincent JARDIN
2016-03-02 10:51  0%               ` Jim Thompson
2016-03-02 11:21  3%               ` Thomas Monjalon
2016-03-02 22:35  0%                 ` Thomas Monjalon
2016-03-03  8:31  0%                   ` Panu Matilainen
2016-03-03 10:05  0%                     ` Ferruh Yigit
2016-03-03 10:11  0%                       ` Thomas Monjalon
2016-03-03 10:51  0%                       ` Panu Matilainen
2016-03-10  0:04  0%                   ` Thomas Monjalon
2016-03-10  6:31  0%                     ` Vincent JARDIN
2016-03-02 22:18  0%           ` Jay Rolette
2016-03-03 10:11  0%             ` Ferruh Yigit
2016-03-03 16:59  0%               ` Stephen Hemminger
2016-03-03 18:18  0%                 ` Ferruh Yigit
2016-02-12 18:38  5% [dpdk-dev] [PATCH] doc: deprecation notice in 16.04 for rte_mempool changes Keith Wiles
2016-02-16  3:16 15% [dpdk-dev] [PATCH v2] PCI: ABI change request for adding new field in rte_pci_id structure Ziye Yang
2016-02-16  7:38  9% ` Panu Matilainen
2016-02-16  7:43  9%   ` Yang, Ziye
2016-02-16  7:55  7%     ` Panu Matilainen
     [not found]     <1453689419-237252>
2016-02-16  4:08 15% ` Ziye Yang
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  3% [dpdk-dev] [PATCH 0/3] ethdev: add helper functions to get eth_dev and dev private data Ferruh Yigit
2016-02-17 14:20  3% ` [dpdk-dev] [PATCH 1/3] " Ferruh Yigit
2016-03-10  0:00  0% ` [dpdk-dev] [PATCH 0/3] " Thomas Monjalon
     [not found]     <1453976778-27807-1-git-send-email-xutao.sun@intel.com>
2016-02-18  9:58     ` [dpdk-dev] [PATCH v4 0/4] Add tunnel filter support for IP in GRE on i40e Xutao Sun
2016-02-18  9:58 17%   ` [dpdk-dev] [PATCH v4 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure Xutao Sun
2016-02-19  7:31       ` [dpdk-dev] [PATCH v5 0/4] Add tunnel filter support for IP in GRE on i40e Xutao Sun
2016-02-19  7:31 15%     ` [dpdk-dev] [PATCH v5 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure Xutao Sun
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  3:47 17%       ` [dpdk-dev] [PATCH v6 1/4] lib/ether: optimize the'rte_eth_tunnel_filter_conf' structure Xutao Sun
2016-03-01  8:53  3%         ` Panu Matilainen
2016-03-02  3:10  3%           ` Sun, Xutao
2016-03-02  7:12  0%             ` Panu Matilainen
2016-03-01  8:41           ` [dpdk-dev] [PATCH v7 0/4] Add tunnel filter support for IP in GRE on i40e Xutao Sun
2016-03-01  8:41 17%         ` [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-02-18 10:26     [dpdk-dev] [PATCH 6/8] bond: handle slaves with fewer queues than bonding device Iremonger, Bernard
2016-02-19 19:17     ` [dpdk-dev] [PATCH v2 0/6] bonding: fixes and enhancements Eric Kinzie
2016-02-19 19:17       ` [dpdk-dev] [PATCH v2 4/6] bond mode 4: allow external state machine Eric Kinzie
2016-02-22 13:03  4%     ` Panu Matilainen
2016-02-25 15:22  0%       ` Iremonger, Bernard
2016-03-01 17:40  0%         ` Eric Kinzie
2016-03-02  9:49  0%           ` Iremonger, Bernard
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  3%   ` Yuanhan Liu
2016-02-19  7:30  0%     ` Ilya Maximets
2016-02-19  8:10  3%       ` Xie, Huawei
2016-02-19 10:56     [dpdk-dev] [PATCH RFC v2 0/3] Thread safe rte_vhost_enqueue_burst() Ilya Maximets
2016-02-19 10:56  4% ` [dpdk-dev] [PATCH RFC v2 2/3] vhost: make buf vector for scatter RX local Ilya Maximets
2016-02-22 13:53  6% [dpdk-dev] [PATCH] config: remove duplicate configuration information Keith Wiles
2016-02-22 15:09  0% ` Trahe, Fiona
2016-02-22 16:02  0%   ` Wiles, Keith
2016-02-24 13:58  0% ` Wiles, Keith
2016-03-03 14:43  0% ` Wiles, Keith
2016-02-24 11:47     [dpdk-dev] [PATCH RFC v3 0/3] Thread safe rte_vhost_enqueue_burst() Ilya Maximets
2016-02-24 11:47  4% ` [dpdk-dev] [PATCH RFC v3 2/3] vhost: make buf vector for scatter RX local Ilya Maximets
2016-03-02 11:55  3% [dpdk-dev] [PATCH v4] af_packet: make the device detachable Wojciech Zmuda
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-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 18% ` [dpdk-dev] [PATCH 2/3] scripts: avoid editing defconfig_* files in validate-abi.sh Panu Matilainen

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).