[dpdk-dev] [PATCH] app/crypto-perf: fix total_ops value validation

2017-02-07 Thread Kuba Kozak
Added total_ops value validation in parse_total_ops() function.

Coverity issue: 141070

Fixes: f8be1786b1b8 ("app/crypto-perf: introduce performance test application")

Signed-off-by: Kuba Kozak 
---
 app/test-crypto-perf/cperf_options_parsing.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/app/test-crypto-perf/cperf_options_parsing.c 
b/app/test-crypto-perf/cperf_options_parsing.c
index 3b7342d..3a8b898 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -128,7 +128,13 @@ struct name_id_map {
int ret = parse_uint32_t(&opts->total_ops, arg);
 
if (ret)
-   RTE_LOG(ERR, USER1, "failed to parse total operations count");
+   RTE_LOG(ERR, USER1, "failed to parse total operations count\n");
+
+   if (opts->total_ops == 0) {
+   RTE_LOG(ERR, USER1,
+   "invalid total operations count number 
specified\n");
+   return -1;
+   }
 
return ret;
 }
-- 
1.9.1



Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial 
Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | 
Kapital zakladowy 200.000 PLN.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i 
moze zawierac informacje poufne. W razie przypadkowego otrzymania tej 
wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; 
jakiekolwiek
przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). If you are not the intended recipient, please 
contact the sender and delete all copies; any review or distribution by
others is strictly prohibited.



[dpdk-dev] [PATCH v4 1/3] eal: add functions parsing EAL arguments

2017-07-10 Thread Kuba Kozak
added function rte_eal_configure which configure
Environment Abstraction Layer (EAL) using
configuration structure.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 lib/Makefile|   3 +
 lib/librte_eal/bsdapp/eal/Makefile  |   4 +
 lib/librte_eal/bsdapp/eal/eal.c | 165 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   1 +
 lib/librte_eal/common/eal_common_lcore.c|   7 +
 lib/librte_eal/common/eal_common_options.c  | 106 ++
 lib/librte_eal/common/eal_options.h |   3 +
 lib/librte_eal/common/include/rte_eal.h |  20 ++
 lib/librte_eal/linuxapp/eal/Makefile|   3 +
 lib/librte_eal/linuxapp/eal/eal.c   | 265 
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   1 +
 mk/rte.app.mk   |   2 +-
 12 files changed, 452 insertions(+), 128 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 1080a95..2c6c380 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,6 +34,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+DEPDIRS-librte_eal := librte_cfgfile
+endif
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile 
b/lib/librte_eal/bsdapp/eal/Makefile
index a0f9950..d70eefb 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -50,6 +50,10 @@ EXPORT_MAP := rte_eal_version.map
 
 LIBABIVER := 4
 
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
+
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 05f0c1f..4a0c221 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -73,6 +73,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -99,6 +100,8 @@ static struct flock wr_lock = {
.l_len = sizeof(early_mem_config.memseg),
 };
 
+static int run_once_reset_internal_config;
+
 /* Address of global and public configuration */
 static struct rte_config rte_config = {
.mem_config = &early_mem_config,
@@ -347,6 +350,58 @@ eal_log_level_parse(int argc, char **argv)
optarg = old_optarg;
 }
 
+/* Parse single argument */
+static int
+eal_parse_option(int opt, char *optarg, int option_index, char *prgname)
+{
+   int ret;
+
+   /* getopt is not happy, stop right now */
+   if (opt == '?') {
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+
+   ret = eal_parse_common_option(opt, optarg, &internal_config);
+   /* common parser is not happy */
+   if (ret < 0) {
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+   /* common parser handled this option */
+   if (ret == 0)
+   return 0;
+
+   switch (opt) {
+   case 'h':
+   eal_usage(prgname);
+   exit(EXIT_SUCCESS);
+   break;
+
+   default:
+   if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+   RTE_LOG(ERR, EAL, "Option %c is not supported "
+   "on FreeBSD\n", opt);
+   } else if (opt >= OPT_LONG_MIN_NUM &&
+  opt < OPT_LONG_MAX_NUM) {
+   RTE_LOG(ERR, EAL, "Option %s is not supported "
+   "on FreeBSD\n",
+   eal_long_options[option_index].name);
+   } else {
+   RTE_LOG(ERR, EAL, "Option %d is not supported "
+   "on FreeBSD\n", opt);
+   }
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+   return 0;
+out:
+   return ret;
+}
+
 /* Parse the argument given in the command line of the application */
 static int
 eal_parse_args(int argc, char **argv)
@@ -367,45 +422,9 @@ eal_parse_args(int argc, char **argv)
while ((opt = getopt_long(argc, argvopt, eal_short_options,
  eal_long_options, &option_index)) != EOF) {
 
-   /* getopt is not happy, stop right now */
-   if (opt == '?') {
-   eal_usage(prgname);
-   ret = -1;
-   goto out;
-   }
-
-   ret = eal_parse_common_option(opt

[dpdk-dev] [PATCH v4 0/3] EAL change for using a config file for DPDK

2017-07-10 Thread Kuba Kozak
This patchset introduce a mechanism for running dpdk application with 
parameters provided by configuration file.

A new API for EAL takes a config file data type - either loaded from
file, or built up programmatically in the application - and extracts
DPDK parameters from it to be used when eal init is called. 
This allows apps to have an alternative method to configure EAL,
other than via command-line parameters.

Reworked applications are used to demonstrate the new eal API.
If a --cfgfile-path  option is passed into command line non
EAL section, then the file is loaded and used by app. If a file
called config.ini is present in current working directory, and
no --cfgfile-path option is passed in, config.ini file will be
loaded and used by app.

Patch "app/testpmd: add parse options from JSON cfg file" 
demonstrates the usage of JSON instead of INI file format. 
JSON file can be called the same way as above, 
through --cfgfile-path  argument.
---
this patch depends on:
"Rework cfgfile API to enable apps config file support"

v4:
 Code optimalisation in parse_vdev_devices() function.
 Moved some functions from librte_eal/bsdapp and librte_eal/linuxapp
 to the librte_eal/common.
 Bug fixes.

v3: 
 split one patchset into two distinct patchsets:
 1. cfgfile library and TEST app changes
 2. EAL changes and examples (this patchset depends on cfgfile)

v2:
  lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments. 
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.

  lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add  set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function  simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function

Kuba Kozak (3):
  eal: add functions parsing EAL arguments
  app/testpmd: add parse options from cfg file
  app/testpmd: add parse options from JSON cfg file

 app/test-pmd/Makefile   |6 +
 app/test-pmd/config.ini |   24 +
 app/test-pmd/config.json|   33 +
 app/test-pmd/parameters.c   | 1181 +--
 app/test-pmd/testpmd.c  |  159 ++-
 app/test-pmd/testpmd.h  |3 +-
 config/common_base  |5 +
 lib/Makefile|3 +
 lib/librte_eal/bsdapp/eal/Makefile  |4 +
 lib/librte_eal/bsdapp/eal/eal.c |  165 +++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |1 +
 lib/librte_eal/common/eal_common_lcore.c|7 +
 lib/librte_eal/common/eal_common_options.c  |  106 ++
 lib/librte_eal/common/eal_options.h |3 +
 lib/librte_eal/common/include/rte_eal.h |   20 +
 lib/librte_eal/linuxapp/eal/Makefile|3 +
 lib/librte_eal/linuxapp/eal/eal.c   |  265 +++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |1 +
 mk/rte.app.mk   |2 +-
 19 files changed, 1349 insertions(+), 642 deletions(-)
 create mode 100644 app/test-pmd/config.ini
 create mode 100644 app/test-pmd/config.json

-- 
2.7.4



[dpdk-dev] [PATCH v4 2/3] app/testpmd: add parse options from cfg file

2017-07-10 Thread Kuba Kozak
This patch shows how to pass arguments to application
using config.ini file.

If a --cfgfile-path  option is passed into commandline
non EAL section, then the file is loaded and used by app.

If a config.ini file is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app as default configuration.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 app/test-pmd/config.ini   |   24 +
 app/test-pmd/parameters.c | 1181 +
 app/test-pmd/testpmd.c|   67 ++-
 app/test-pmd/testpmd.h|3 +-
 4 files changed, 761 insertions(+), 514 deletions(-)
 create mode 100644 app/test-pmd/config.ini

diff --git a/app/test-pmd/config.ini b/app/test-pmd/config.ini
new file mode 100644
index 000..54c83a2
--- /dev/null
+++ b/app/test-pmd/config.ini
@@ -0,0 +1,24 @@
+[DPDK]
+v =
+l = 0-4
+n = 4
+master-lcore = 0
+proc-type = primary
+
+[TEST-PMD]
+i =
+portmask = 0xff
+nb-cores = 4
+port-topology = paired
+
+[DPDK.vdev0]
+net_ring0 =
+
+[DPDK.vdev1]
+net_ring1 =
+
+[DPDK.vdev2]
+net_ring2 =
+
+[DPDK.vdev3]
+net_ring3 =
\ No newline at end of file
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 958b3d0..d32861a 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -77,9 +77,98 @@
 #include 
 #endif
 #include 
+#ifdef RTE_LIBRTE_CFGFILE
+#include 
+#endif
 
 #include "testpmd.h"
 
+enum { TX, RX };
+
+static struct option lgopts[] = {
+   { "cfgfile-path",   1, 0, 1 },
+   { "help",   0, 0, 0 },
+#ifdef RTE_LIBRTE_CMDLINE
+   { "interactive",0, 0, 0 },
+   { "cmdline-file",   1, 0, 0 },
+   { "auto-start", 0, 0, 0 },
+   { "eth-peers-configfile",   1, 0, 0 },
+   { "eth-peer",   1, 0, 0 },
+#endif
+   { "tx-first",   0, 0, 0 },
+   { "stats-period",   1, 0, 0 },
+   { "ports",  1, 0, 0 },
+   { "nb-cores",   1, 0, 0 },
+   { "nb-ports",   1, 0, 0 },
+   { "coremask",   1, 0, 0 },
+   { "portmask",   1, 0, 0 },
+   { "numa",   0, 0, 0 },
+   { "no-numa",0, 0, 0 },
+   { "mp-anon",0, 0, 0 },
+   { "port-numa-config",   1, 0, 0 },
+   { "ring-numa-config",   1, 0, 0 },
+   { "socket-num", 1, 0, 0 },
+   { "mbuf-size",  1, 0, 0 },
+   { "total-num-mbufs",1, 0, 0 },
+   { "max-pkt-len",1, 0, 0 },
+   { "pkt-filter-mode",1, 0, 0 },
+   { "pkt-filter-report-hash", 1, 0, 0 },
+   { "pkt-filter-size",1, 0, 0 },
+   { "pkt-filter-drop-queue",  1, 0, 0 },
+#ifdef RTE_LIBRTE_LATENCY_STATS
+   { "latencystats",   1, 0, 0 },
+#endif
+#ifdef RTE_LIBRTE_BITRATE
+   { "bitrate-stats",  1, 0, 0 },
+#endif
+   { "disable-crc-strip",  0, 0, 0 },
+   { "enable-lro", 0, 0, 0 },
+   { "enable-rx-cksum",0, 0, 0 },
+   { "enable-scatter", 0, 0, 0 },
+   { "disable-hw-vlan",0, 0, 0 },
+   { "disable-hw-vlan-filter", 0, 0, 0 },
+   { "disable-hw-vlan-strip",  0, 0, 0 },
+   { "disable-hw-vlan-extend", 0, 0, 0 },
+   { "enable-drop-en",0, 0, 0 },
+   { "disable-rss",0, 0, 0 },
+   { "port-topology",  1, 0, 0 },
+   { "forward-mode",   1, 0, 0 },
+   { "rss-ip", 0, 0, 0 },
+   { "rss-udp",0, 0, 0 },
+   { "rxq",1, 0, 0 },
+   { "txq",1, 0, 0 },
+   { "rxd",1, 0, 0 },
+   { "txd",1, 0, 0 },
+   { "burst",  1, 0, 0 },
+   { "mbcache",1, 0, 0 },
+   { "txpt",   1, 0, 0 },
+   { "txht",   1, 0, 0 },
+   { "txwt",   1, 0, 0 },
+   { "txfreet",1, 0, 0 },
+   { "txrst",  1, 0, 0 },
+   { "txqflags",   

[dpdk-dev] [PATCH v4 3/3] app/testpmd: add parse options from JSON cfg file

2017-07-10 Thread Kuba Kozak
This patch shows usage of Jansson library to parse
application arguments from JSON config file.

https://github.com/akheron/jansson

If a --cfgfile-path  option is passed into commandline
non EAL section, then the disired JSON file is loaded and used
by app. In case when JSON doesn't exist an INI file is loaded.
The INI file can be passed also from --cfgfile-path option.

If a file called config.ini is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 app/test-pmd/Makefile|  6 
 app/test-pmd/config.json | 33 +
 app/test-pmd/testpmd.c   | 94 +++-
 config/common_base   |  5 +++
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 app/test-pmd/config.json

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..a1c84cc 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -83,6 +83,12 @@ endif
 
 endif
 
+ifeq ($(CONFIG_RTE_JSON_SUPPORT),y)
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -ljansson
+endif
+endif
+
 CFLAGS_cmdline.o := -D_GNU_SOURCE
 
 include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-pmd/config.json b/app/test-pmd/config.json
new file mode 100644
index 000..4589dbc
--- /dev/null
+++ b/app/test-pmd/config.json
@@ -0,0 +1,33 @@
+{
+   "DPDK":
+   {
+   "v": "",
+   "l": "0-4",
+   "n": "4",
+   "master-lcore": "0",
+   "proc-type": "primary"
+   },
+   "TEST-PMD":
+   {
+   "i": "",
+   "portmask": "0xff",
+   "nb-cores": "4",
+   "port-topology": "paired"
+   },
+   "DPDK.vdev0":
+   {
+   "net_ring0": ""
+   },
+   "DPDK.vdev1":
+   {
+   "net_ring1": ""
+   },
+   "DPDK.vdev2":
+   {
+   "net_ring2": ""
+   },
+   "DPDK.vdev3":
+   {
+   "net_ring3": ""
+   }
+}
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7b82976..014bb46 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -46,6 +46,10 @@
 
 #include 
 #include 
+
+#ifdef RTE_JSON_SUPPORT
+#include 
+#endif
 #include 
 
 #include 
@@ -2290,6 +2294,87 @@ cfgfile_load_path(int argc, char **argv)
}
return NULL;
 }
+
+#ifdef RTE_JSON_SUPPORT
+/*
+ * Decoding JSON structure to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_json_to_cfg(json_t *json, int flags)
+{
+   if (!json) {
+   printf("Error: JSON structure is NULL, nothing to parse\n");
+   return NULL;
+   }
+   /* create an empty instance of cfgfile structure */
+   struct rte_cfgfile *cfgfile = rte_cfgfile_create(flags);
+
+   if (!cfgfile)
+   return NULL;
+
+   const char *section;
+   json_t *entry;
+
+   /* set pointer to first section */
+   void *iter_section = json_object_iter(json);
+
+   while (iter_section) {
+
+   section = json_object_iter_key(iter_section);
+   entry = json_object_iter_value(iter_section);
+
+   /* add parsed section name of current section to cfgfile */
+   rte_cfgfile_add_section(cfgfile, section);
+
+   /* set pointer to first entry */
+   void *iter_entry = json_object_iter(entry);
+
+   while (iter_entry) {
+
+   const char *key;
+   const char *value;
+
+   key = json_object_iter_key(iter_entry);
+   value = json_string_value(
+   json_object_iter_value(iter_entry));
+
+   /* add parsed key and value of current entry */
+   /* to cfgfile */
+   rte_cfgfile_add_entry(cfgfile, section, key, value);
+
+   /* pointer to next entry */
+   iter_entry = json_object_iter_next(entry, iter_entry);
+   }
+   /* pointer to next section */
+   iter_section = json_object_iter_next(json, iter_section);
+   }
+   return cfgfile;
+}
+
+/*
+ * Check presence and load JSON file to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_load_json_to_cfg(const char *path)
+{
+   struct rte_cfgfile *cfgfile = NULL;
+   /* check if config file e

[dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK

2017-07-13 Thread Kuba Kozak
This patchset introduce a mechanism for running dpdk application with 
parameters provided by configuration file.

A new API for EAL takes a config file data type - either loaded from
file, or built up programmatically in the application - and extracts
DPDK parameters from it to be used when eal init is called. 
This allows apps to have an alternative method to configure EAL,
other than via command-line parameters.

Reworked applications are used to demonstrate the new eal API.
If a --cfgfile-path  option is passed into command line non
EAL section, then the file is loaded and used by app. If a file
called config.ini is present in current working directory, and
no --cfgfile-path option is passed in, config.ini file will be
loaded and used by app.

Patch "app/testpmd: add parse options from JSON cfg file" 
demonstrates the usage of JSON instead of INI file format. 
JSON file can be called the same way as above, 
through --cfgfile-path  argument.
---
this patch depends on:
"Rework cfgfile API to enable apps config file support"

v5:
  changed define "RTE_DEVTYPE_VIRTUAL" to "RTE_DEVTYPE_UNDEFINED"
  due to compilation errors (changes on current master).

v4:
 Code optimalisation in parse_vdev_devices() function.
 Moved some functions from librte_eal/bsdapp and librte_eal/linuxapp
 to the librte_eal/common.
 Bug fixes.

v3: 
 split one patchset into two distinct patchsets:
 1. cfgfile library and TEST app changes
 2. EAL changes and examples (this patchset depends on cfgfile)

v2:
  lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments. 
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.

  lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add  set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function  simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function

Kuba Kozak (3):
  eal: add functions parsing EAL arguments
  app/testpmd: add parse options from cfg file
  app/testpmd: add parse options from JSON cfg file

 app/test-pmd/Makefile   |6 +
 app/test-pmd/config.ini |   24 +
 app/test-pmd/config.json|   33 +
 app/test-pmd/parameters.c   | 1181 +--
 app/test-pmd/testpmd.c  |  159 ++-
 app/test-pmd/testpmd.h  |3 +-
 config/common_base  |5 +
 lib/Makefile|3 +
 lib/librte_eal/bsdapp/eal/Makefile  |4 +
 lib/librte_eal/bsdapp/eal/eal.c |  165 +++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |1 +
 lib/librte_eal/common/eal_common_lcore.c|7 +
 lib/librte_eal/common/eal_common_options.c  |  106 ++
 lib/librte_eal/common/eal_options.h |3 +
 lib/librte_eal/common/include/rte_eal.h |   20 +
 lib/librte_eal/linuxapp/eal/Makefile|3 +
 lib/librte_eal/linuxapp/eal/eal.c   |  265 +++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |1 +
 mk/rte.app.mk   |2 +-
 19 files changed, 1349 insertions(+), 642 deletions(-)
 create mode 100644 app/test-pmd/config.ini
 create mode 100644 app/test-pmd/config.json

-- 
2.7.4



[dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK

2017-07-13 Thread Kuba Kozak
This patchset introduce a mechanism for running dpdk application with 
parameters provided by configuration file.

A new API for EAL takes a config file data type - either loaded from
file, or built up programmatically in the application - and extracts
DPDK parameters from it to be used when eal init is called. 
This allows apps to have an alternative method to configure EAL,
other than via command-line parameters.

Reworked applications are used to demonstrate the new eal API.
If a --cfgfile-path  option is passed into command line non
EAL section, then the file is loaded and used by app. If a file
called config.ini is present in current working directory, and
no --cfgfile-path option is passed in, config.ini file will be
loaded and used by app.

Patch "app/testpmd: add parse options from JSON cfg file" 
demonstrates the usage of JSON instead of INI file format. 
JSON file can be called the same way as above, 
through --cfgfile-path  argument.
---
this patch depends on:
"Rework cfgfile API to enable apps config file support"

v5:
  changed define "RTE_DEVTYPE_VIRTUAL" to "RTE_DEVTYPE_UNDEFINED"
  due to compilation errors (changes on current master).

v4:
 Code optimalisation in parse_vdev_devices() function.
 Moved some functions from librte_eal/bsdapp and librte_eal/linuxapp
 to the librte_eal/common.
 Bug fixes.

v3: 
 split one patchset into two distinct patchsets:
 1. cfgfile library and TEST app changes
 2. EAL changes and examples (this patchset depends on cfgfile)

v2:
  lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments. 
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.

  lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add  set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function  simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function

Kuba Kozak (3):
  eal: add functions parsing EAL arguments
  app/testpmd: add parse options from cfg file
  app/testpmd: add parse options from JSON cfg file

 app/test-pmd/Makefile   |6 +
 app/test-pmd/config.ini |   24 +
 app/test-pmd/config.json|   33 +
 app/test-pmd/parameters.c   | 1181 +--
 app/test-pmd/testpmd.c  |  159 ++-
 app/test-pmd/testpmd.h  |3 +-
 config/common_base  |5 +
 lib/Makefile|3 +
 lib/librte_eal/bsdapp/eal/Makefile  |4 +
 lib/librte_eal/bsdapp/eal/eal.c |  165 +++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |1 +
 lib/librte_eal/common/eal_common_lcore.c|7 +
 lib/librte_eal/common/eal_common_options.c  |  106 ++
 lib/librte_eal/common/eal_options.h |3 +
 lib/librte_eal/common/include/rte_eal.h |   20 +
 lib/librte_eal/linuxapp/eal/Makefile|3 +
 lib/librte_eal/linuxapp/eal/eal.c   |  265 +++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |1 +
 mk/rte.app.mk   |2 +-
 19 files changed, 1349 insertions(+), 642 deletions(-)
 create mode 100644 app/test-pmd/config.ini
 create mode 100644 app/test-pmd/config.json

-- 
2.7.4



[dpdk-dev] [PATCH v5 1/3] eal: add functions parsing EAL arguments

2017-07-13 Thread Kuba Kozak
added function rte_eal_configure which configure
Environment Abstraction Layer (EAL) using
configuration structure.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 lib/Makefile|   3 +
 lib/librte_eal/bsdapp/eal/Makefile  |   4 +
 lib/librte_eal/bsdapp/eal/eal.c | 165 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   1 +
 lib/librte_eal/common/eal_common_lcore.c|   7 +
 lib/librte_eal/common/eal_common_options.c  | 106 ++
 lib/librte_eal/common/eal_options.h |   3 +
 lib/librte_eal/common/include/rte_eal.h |  20 ++
 lib/librte_eal/linuxapp/eal/Makefile|   3 +
 lib/librte_eal/linuxapp/eal/eal.c   | 265 
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   1 +
 mk/rte.app.mk   |   2 +-
 12 files changed, 452 insertions(+), 128 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 1080a95..2c6c380 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,6 +34,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+DEPDIRS-librte_eal := librte_cfgfile
+endif
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile 
b/lib/librte_eal/bsdapp/eal/Makefile
index a0f9950..d70eefb 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -50,6 +50,10 @@ EXPORT_MAP := rte_eal_version.map
 
 LIBABIVER := 4
 
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
+
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 05f0c1f..4a0c221 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -73,6 +73,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -99,6 +100,8 @@ static struct flock wr_lock = {
.l_len = sizeof(early_mem_config.memseg),
 };
 
+static int run_once_reset_internal_config;
+
 /* Address of global and public configuration */
 static struct rte_config rte_config = {
.mem_config = &early_mem_config,
@@ -347,6 +350,58 @@ eal_log_level_parse(int argc, char **argv)
optarg = old_optarg;
 }
 
+/* Parse single argument */
+static int
+eal_parse_option(int opt, char *optarg, int option_index, char *prgname)
+{
+   int ret;
+
+   /* getopt is not happy, stop right now */
+   if (opt == '?') {
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+
+   ret = eal_parse_common_option(opt, optarg, &internal_config);
+   /* common parser is not happy */
+   if (ret < 0) {
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+   /* common parser handled this option */
+   if (ret == 0)
+   return 0;
+
+   switch (opt) {
+   case 'h':
+   eal_usage(prgname);
+   exit(EXIT_SUCCESS);
+   break;
+
+   default:
+   if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+   RTE_LOG(ERR, EAL, "Option %c is not supported "
+   "on FreeBSD\n", opt);
+   } else if (opt >= OPT_LONG_MIN_NUM &&
+  opt < OPT_LONG_MAX_NUM) {
+   RTE_LOG(ERR, EAL, "Option %s is not supported "
+   "on FreeBSD\n",
+   eal_long_options[option_index].name);
+   } else {
+   RTE_LOG(ERR, EAL, "Option %d is not supported "
+   "on FreeBSD\n", opt);
+   }
+   eal_usage(prgname);
+   ret = -1;
+   goto out;
+   }
+   return 0;
+out:
+   return ret;
+}
+
 /* Parse the argument given in the command line of the application */
 static int
 eal_parse_args(int argc, char **argv)
@@ -367,45 +422,9 @@ eal_parse_args(int argc, char **argv)
while ((opt = getopt_long(argc, argvopt, eal_short_options,
  eal_long_options, &option_index)) != EOF) {
 
-   /* getopt is not happy, stop right now */
-   if (opt == '?') {
-   eal_usage(prgname);
-   ret = -1;
-   goto out;
-   }
-
-   ret = eal_parse_common_option(opt

[dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file

2017-07-13 Thread Kuba Kozak
This patch shows usage of Jansson library to parse
application arguments from JSON config file.

https://github.com/akheron/jansson

If a --cfgfile-path  option is passed into commandline
non EAL section, then the disired JSON file is loaded and used
by app. In case when JSON doesn't exist an INI file is loaded.
The INI file can be passed also from --cfgfile-path option.

If a file called config.ini is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 app/test-pmd/Makefile|  6 
 app/test-pmd/config.json | 33 +
 app/test-pmd/testpmd.c   | 94 +++-
 config/common_base   |  5 +++
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 app/test-pmd/config.json

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..a1c84cc 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -83,6 +83,12 @@ endif
 
 endif
 
+ifeq ($(CONFIG_RTE_JSON_SUPPORT),y)
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -ljansson
+endif
+endif
+
 CFLAGS_cmdline.o := -D_GNU_SOURCE
 
 include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-pmd/config.json b/app/test-pmd/config.json
new file mode 100644
index 000..4589dbc
--- /dev/null
+++ b/app/test-pmd/config.json
@@ -0,0 +1,33 @@
+{
+   "DPDK":
+   {
+   "v": "",
+   "l": "0-4",
+   "n": "4",
+   "master-lcore": "0",
+   "proc-type": "primary"
+   },
+   "TEST-PMD":
+   {
+   "i": "",
+   "portmask": "0xff",
+   "nb-cores": "4",
+   "port-topology": "paired"
+   },
+   "DPDK.vdev0":
+   {
+   "net_ring0": ""
+   },
+   "DPDK.vdev1":
+   {
+   "net_ring1": ""
+   },
+   "DPDK.vdev2":
+   {
+   "net_ring2": ""
+   },
+   "DPDK.vdev3":
+   {
+   "net_ring3": ""
+   }
+}
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7b82976..014bb46 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -46,6 +46,10 @@
 
 #include 
 #include 
+
+#ifdef RTE_JSON_SUPPORT
+#include 
+#endif
 #include 
 
 #include 
@@ -2290,6 +2294,87 @@ cfgfile_load_path(int argc, char **argv)
}
return NULL;
 }
+
+#ifdef RTE_JSON_SUPPORT
+/*
+ * Decoding JSON structure to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_json_to_cfg(json_t *json, int flags)
+{
+   if (!json) {
+   printf("Error: JSON structure is NULL, nothing to parse\n");
+   return NULL;
+   }
+   /* create an empty instance of cfgfile structure */
+   struct rte_cfgfile *cfgfile = rte_cfgfile_create(flags);
+
+   if (!cfgfile)
+   return NULL;
+
+   const char *section;
+   json_t *entry;
+
+   /* set pointer to first section */
+   void *iter_section = json_object_iter(json);
+
+   while (iter_section) {
+
+   section = json_object_iter_key(iter_section);
+   entry = json_object_iter_value(iter_section);
+
+   /* add parsed section name of current section to cfgfile */
+   rte_cfgfile_add_section(cfgfile, section);
+
+   /* set pointer to first entry */
+   void *iter_entry = json_object_iter(entry);
+
+   while (iter_entry) {
+
+   const char *key;
+   const char *value;
+
+   key = json_object_iter_key(iter_entry);
+   value = json_string_value(
+   json_object_iter_value(iter_entry));
+
+   /* add parsed key and value of current entry */
+   /* to cfgfile */
+   rte_cfgfile_add_entry(cfgfile, section, key, value);
+
+   /* pointer to next entry */
+   iter_entry = json_object_iter_next(entry, iter_entry);
+   }
+   /* pointer to next section */
+   iter_section = json_object_iter_next(json, iter_section);
+   }
+   return cfgfile;
+}
+
+/*
+ * Check presence and load JSON file to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_load_json_to_cfg(const char *path)
+{
+   struct rte_cfgfile *cfgfile = NULL;
+   /* check if config file e

[dpdk-dev] [PATCH v5 2/3] app/testpmd: add parse options from cfg file

2017-07-13 Thread Kuba Kozak
This patch shows how to pass arguments to application
using config.ini file.

If a --cfgfile-path  option is passed into commandline
non EAL section, then the file is loaded and used by app.

If a config.ini file is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app as default configuration.

Signed-off-by: Kuba Kozak 
Suggested-by: Bruce Richardson 
---
 app/test-pmd/config.ini   |   24 +
 app/test-pmd/parameters.c | 1181 +
 app/test-pmd/testpmd.c|   67 ++-
 app/test-pmd/testpmd.h|3 +-
 4 files changed, 761 insertions(+), 514 deletions(-)
 create mode 100644 app/test-pmd/config.ini

diff --git a/app/test-pmd/config.ini b/app/test-pmd/config.ini
new file mode 100644
index 000..54c83a2
--- /dev/null
+++ b/app/test-pmd/config.ini
@@ -0,0 +1,24 @@
+[DPDK]
+v =
+l = 0-4
+n = 4
+master-lcore = 0
+proc-type = primary
+
+[TEST-PMD]
+i =
+portmask = 0xff
+nb-cores = 4
+port-topology = paired
+
+[DPDK.vdev0]
+net_ring0 =
+
+[DPDK.vdev1]
+net_ring1 =
+
+[DPDK.vdev2]
+net_ring2 =
+
+[DPDK.vdev3]
+net_ring3 =
\ No newline at end of file
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 958b3d0..d32861a 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -77,9 +77,98 @@
 #include 
 #endif
 #include 
+#ifdef RTE_LIBRTE_CFGFILE
+#include 
+#endif
 
 #include "testpmd.h"
 
+enum { TX, RX };
+
+static struct option lgopts[] = {
+   { "cfgfile-path",   1, 0, 1 },
+   { "help",   0, 0, 0 },
+#ifdef RTE_LIBRTE_CMDLINE
+   { "interactive",0, 0, 0 },
+   { "cmdline-file",   1, 0, 0 },
+   { "auto-start", 0, 0, 0 },
+   { "eth-peers-configfile",   1, 0, 0 },
+   { "eth-peer",   1, 0, 0 },
+#endif
+   { "tx-first",   0, 0, 0 },
+   { "stats-period",   1, 0, 0 },
+   { "ports",  1, 0, 0 },
+   { "nb-cores",   1, 0, 0 },
+   { "nb-ports",   1, 0, 0 },
+   { "coremask",   1, 0, 0 },
+   { "portmask",   1, 0, 0 },
+   { "numa",   0, 0, 0 },
+   { "no-numa",0, 0, 0 },
+   { "mp-anon",0, 0, 0 },
+   { "port-numa-config",   1, 0, 0 },
+   { "ring-numa-config",   1, 0, 0 },
+   { "socket-num", 1, 0, 0 },
+   { "mbuf-size",  1, 0, 0 },
+   { "total-num-mbufs",1, 0, 0 },
+   { "max-pkt-len",1, 0, 0 },
+   { "pkt-filter-mode",1, 0, 0 },
+   { "pkt-filter-report-hash", 1, 0, 0 },
+   { "pkt-filter-size",1, 0, 0 },
+   { "pkt-filter-drop-queue",  1, 0, 0 },
+#ifdef RTE_LIBRTE_LATENCY_STATS
+   { "latencystats",   1, 0, 0 },
+#endif
+#ifdef RTE_LIBRTE_BITRATE
+   { "bitrate-stats",  1, 0, 0 },
+#endif
+   { "disable-crc-strip",  0, 0, 0 },
+   { "enable-lro", 0, 0, 0 },
+   { "enable-rx-cksum",0, 0, 0 },
+   { "enable-scatter", 0, 0, 0 },
+   { "disable-hw-vlan",0, 0, 0 },
+   { "disable-hw-vlan-filter", 0, 0, 0 },
+   { "disable-hw-vlan-strip",  0, 0, 0 },
+   { "disable-hw-vlan-extend", 0, 0, 0 },
+   { "enable-drop-en",0, 0, 0 },
+   { "disable-rss",0, 0, 0 },
+   { "port-topology",  1, 0, 0 },
+   { "forward-mode",   1, 0, 0 },
+   { "rss-ip", 0, 0, 0 },
+   { "rss-udp",0, 0, 0 },
+   { "rxq",1, 0, 0 },
+   { "txq",1, 0, 0 },
+   { "rxd",1, 0, 0 },
+   { "txd",1, 0, 0 },
+   { "burst",  1, 0, 0 },
+   { "mbcache",1, 0, 0 },
+   { "txpt",   1, 0, 0 },
+   { "txht",   1, 0, 0 },
+   { "txwt",   1, 0, 0 },
+   { "txfreet",1, 0, 0 },
+   { "txrst",  1, 0, 0 },
+   { "txqflags",   

[dpdk-dev] [PATCH] examples/l2fwd-crypto: add option --[no-]mac-updating

2017-07-19 Thread Kuba Kozak
This patch adds a new option to enable/disable the
MAC addresses updating done at forwarding time: --[no-]mac-updating

By default, MAC address updating remains enabled, to keep consistency
with previous usage.

Signed-off-by: Kuba Kozak 
---
 doc/guides/sample_app_ug/l2_forward_crypto.rst |  7 ++--
 examples/l2fwd-crypto/main.c   | 50 ++
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/doc/guides/sample_app_ug/l2_forward_crypto.rst 
b/doc/guides/sample_app_ug/l2_forward_crypto.rst
index 2a61af7..91ce278 100644
--- a/doc/guides/sample_app_ug/l2_forward_crypto.rst
+++ b/doc/guides/sample_app_ug/l2_forward_crypto.rst
@@ -46,7 +46,7 @@ for each packet that is received on a RX_PORT and performs L2 
forwarding.
 The destination port is the adjacent port from the enabled portmask, that is,
 if the first four ports are enabled (portmask 0xf),
 ports 0 and 1 forward into each other, and ports 2 and 3 forward into each 
other.
-Also, the MAC addresses are affected as follows:
+Also, if MAC addresses updating is enabled, the MAC addresses are affected as 
follows:
 
 *   The source MAC address is replaced by the TX_PORT MAC address
 
@@ -90,7 +90,8 @@ The application requires a number of command line options:
 [--auth_algo ALGO] [--auth_op GENERATE/VERIFY] [--auth_key KEY] /
 [--auth_key_random_size SIZE] [--auth_iv IV] [--auth_iv_random_size SIZE] /
 [--aad AAD] [--aad_random_size SIZE] /
-[--digest size SIZE] [--sessionless] [--cryptodev_mask MASK]
+[--digest size SIZE] [--sessionless] [--cryptodev_mask MASK] /
+[--mac-updating] [--no-mac-updating]
 
 where,
 
@@ -191,6 +192,8 @@ where,
 
 (default is all cryptodevs).
 
+*   [no-]mac-updating: Enable or disable MAC addresses updating (enabled by 
default).
+
 
 The application requires that crypto devices capable of performing
 the specified crypto operation are available on application initialization.
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 71cb133..a347ad6 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -193,6 +193,8 @@ struct l2fwd_crypto_options {
char string_type[MAX_STR_LEN];
 
uint64_t cryptodev_mask;
+
+   unsigned int mac_updating;
 };
 
 /** l2fwd crypto lcore params */
@@ -608,21 +610,31 @@ l2fwd_send_packet(struct rte_mbuf *m, uint8_t port)
 }
 
 static void
-l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid)
+l2fwd_mac_updating(struct rte_mbuf *m, unsigned int dest_portid)
 {
struct ether_hdr *eth;
void *tmp;
-   unsigned dst_port;
 
-   dst_port = l2fwd_dst_ports[portid];
eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
 
/* 02:00:00:00:00:xx */
tmp = ð->d_addr.addr_bytes[0];
-   *((uint64_t *)tmp) = 0x0002 + ((uint64_t)dst_port << 40);
+   *((uint64_t *)tmp) = 0x0002 + ((uint64_t)dest_portid << 40);
 
/* src addr */
-   ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], ð->s_addr);
+   ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], ð->s_addr);
+}
+
+static void
+l2fwd_simple_forward(struct rte_mbuf *m, unsigned int portid,
+   struct l2fwd_crypto_options *options)
+{
+   unsigned int dst_port;
+
+   dst_port = l2fwd_dst_ports[portid];
+
+   if (options->mac_updating)
+   l2fwd_mac_updating(m, dst_port);
 
l2fwd_send_packet(m, (uint8_t) dst_port);
 }
@@ -920,7 +932,8 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
m = ops_burst[j]->sym->m_src;
 
rte_crypto_op_free(ops_burst[j]);
-   l2fwd_simple_forward(m, portid);
+   l2fwd_simple_forward(m, portid,
+   options);
}
} while (nb_rx == MAX_PKT_BURST);
}
@@ -975,7 +988,12 @@ l2fwd_crypto_usage(const char *prgname)
"  --digest_size SIZE: size of digest to be 
generated/verified\n"
 
"  --sessionless\n"
-   "  --cryptodev_mask MASK: hexadecimal bitmask of crypto devices 
to configure\n",
+   "  --cryptodev_mask MASK: hexadecimal bitmask of crypto devices 
to configure\n"
+
+   "  --[no-]mac-updating: Enable or disable MAC addresses 
updating (enabled by default)\n"
+   "  When enabled:\n"
+   "   - The source MAC address is replaced by the TX port MAC 
address\n"
+   "   - The destination MAC address is replaced by 
02:00:00:00:00:TX_PORT_ID\n",
   prgname);
 }
 
@@ -1322,6 +1340,16 @@ l2fwd_crypto_parse_args_long_options(struct 
l2fwd_crypto_options *options,

[dpdk-dev] [PATCH] net/e1000: fix out of bounds access

2017-07-25 Thread Kuba Kozak
Fix wrong structure type used as argument
in memset() call.

Coverity issue: 147223
Coverity issue: 147227
Fixes: a8600af43738 ("net/igb: parse flow API ethertype filter")
Fixes: 22bb13410cb2 ("net/igb: create consistent filter")
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
---
 drivers/net/e1000/igb_flow.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index db73b18..ed2ecc4 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -694,7 +694,8 @@ igb_parse_ethertype_filter(struct rte_eth_dev *dev,
 
if (hw->mac.type == e1000_82576) {
if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
-   memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+   memset(filter, 0, sizeof(
+   struct rte_eth_ethertype_filter));
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM,
NULL, "queue number not supported "
@@ -703,7 +704,8 @@ igb_parse_ethertype_filter(struct rte_eth_dev *dev,
}
} else {
if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
-   memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+   memset(filter, 0, sizeof(
+   struct rte_eth_ethertype_filter));
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM,
NULL, "queue number not supported "
-- 
2.7.4



[dpdk-dev] [PATCH] net/i40e: fix dereferencing null pointer

2017-07-27 Thread Kuba Kozak
Add check if o_vlan_mask and i_vlan_mask are
not a NULL pointer.

Coverity issue: 143448
Coverity issue: 143449
Fixes: d37705068ee8 ("net/i40e: parse QinQ pattern")
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
---
 drivers/net/i40e/i40e_flow.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index 95af701..b92719a 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -3719,8 +3719,10 @@ i40e_flow_parse_qinq_pattern(__rte_unused struct 
rte_eth_dev *dev,
}
 
/* Get filter specification */
-   if ((o_vlan_mask->tci == rte_cpu_to_be_16(I40E_TCI_MASK)) &&
-   (i_vlan_mask->tci == rte_cpu_to_be_16(I40E_TCI_MASK))) {
+   if ((o_vlan_mask != NULL) && (o_vlan_mask->tci ==
+   rte_cpu_to_be_16(I40E_TCI_MASK)) &&
+   (i_vlan_mask != NULL) &&
+   (i_vlan_mask->tci == rte_cpu_to_be_16(I40E_TCI_MASK))) {
filter->outer_vlan = rte_be_to_cpu_16(o_vlan_spec->tci)
& I40E_TCI_MASK;
filter->inner_vlan = rte_be_to_cpu_16(i_vlan_spec->tci)
-- 
2.7.4



[dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name

2017-03-02 Thread Kuba Kozak
Added three new functions to API: rte_eth_xstats_get_by_name(),
rte_eth_xstats_get_by_group(), rte_eth_xstats_get_names_by_group().

Extension of the 'rte_igb_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is now
specified group (e.g. TX_GROUP), one xstatistic can be in several groups.
To implement new functionality of retriving xstats by group
on e1000 driver level, there are two functions added:
eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group(),
on ixgbe driver level, there are new functions added:
ixgbe_dev_xstats_get_by_group() and ixgbe_dev_xstats_get_names_by_group()

Extended functionality of proc_info application:
--xstats-name NAME: to display single xstat value by NAME
--xstats-group GROUPNAME: to display group of xstats by GROUPNAME

Jacek Piasecki (4):
  ethdev: add retrieving xstats by group and xstats by name
  net/e1000: add grouping of xstats for e1000 driver
  net/ixgbe: add grouping of xstats for ixgbe driver
  app/proc_info: add support for xstats-name and xstats-group

 app/proc_info/main.c | 112 +++-
 drivers/net/e1000/igb_ethdev.c   | 268 +-
 drivers/net/ixgbe/ixgbe_ethdev.c | 586 +++
 lib/librte_ether/rte_ethdev.c| 310 -
 lib/librte_ether/rte_ethdev.h| 105 ++-
 5 files changed, 1193 insertions(+), 188 deletions(-)

-- 
1.9.1



[dpdk-dev] [PATCH 1/4] ethdev: add retrieving xstats by group and xstats by name

2017-03-02 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends library for retriving xstats by specified groups and
single xstat by given name.

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 lib/librte_ether/rte_ethdev.c | 310 --
 lib/librte_ether/rte_ethdev.h | 105 +-
 2 files changed, 401 insertions(+), 14 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index eb0a94a..e18ca1d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -87,33 +87,37 @@
 struct rte_eth_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
-   {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
-   {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
-   {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
-   {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
-   {"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-   {"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+   {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets), RX_GROUP},
+   {"tx_good_packets", offsetof(struct rte_eth_stats, opackets), TX_GROUP},
+   {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes), RX_GROUP},
+   {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes), TX_GROUP},
+   {"rx_errors", offsetof(struct rte_eth_stats, ierrors),
+   RX_GROUP | ERR_GROUP},
+   {"tx_errors", offsetof(struct rte_eth_stats, oerrors),
+   TX_GROUP | ERR_GROUP},
{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
-   rx_nombuf)},
+   rx_nombuf), RX_GROUP | ERR_GROUP},
 };
 
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
-   {"packets", offsetof(struct rte_eth_stats, q_ipackets)},
-   {"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
-   {"errors", offsetof(struct rte_eth_stats, q_errors)},
+   {"packets", offsetof(struct rte_eth_stats, q_ipackets), RXQ_GROUP},
+   {"bytes", offsetof(struct rte_eth_stats, q_ibytes), RXQ_GROUP},
+   {"errors", offsetof(struct rte_eth_stats, q_errors),
+   RXQ_GROUP | ERR_GROUP},
 };
 
 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /  \
sizeof(rte_rxq_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
-   {"packets", offsetof(struct rte_eth_stats, q_opackets)},
-   {"bytes", offsetof(struct rte_eth_stats, q_obytes)},
+   {"packets", offsetof(struct rte_eth_stats, q_opackets), TXQ_GROUP},
+   {"bytes", offsetof(struct rte_eth_stats, q_obytes), TXQ_GROUP},
 };
 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /  \
sizeof(rte_txq_stats_strings[0]))
@@ -1448,6 +1452,110 @@ struct rte_eth_dev *
return count;
 }
 
+static int
+get_xstats_count_by_group(uint8_t port_id, uint64_t group_mask)
+{
+   struct rte_eth_dev *dev;
+   int count = 0;
+   int dcount = 0;
+   unsigned i;
+
+   RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+   dev = &rte_eth_devices[port_id];
+   if (dev->dev_ops->xstats_get_names_by_group != NULL) {
+   dcount = (*dev->dev_ops->xstats_get_names_by_group)
+   (dev, NULL, 0, group_mask);
+   if (dcount < 0)
+   return dcount;
+   }
+
+
+
+
+   for (i = 0; i < RTE_NB_STATS; i++) {
+   if (rte_stats_strings[i].group_mask & group_mask)
+   count++;
+   }
+   for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+   if (rte_rxq_stats_strings[i].group_mask & group_mask)
+   count += RTE_MIN(dev->data->nb_rx_queues,
+   RTE_ETHDEV_QUEUE_STAT_CNTRS);
+   }
+   for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+   if (rte_txq_stats_strings[i].group_mask & group_mask)
+   count += RTE_MIN(dev->data->nb_tx_queues,
+   RTE_ETHDEV_QUEUE_STAT_CNTRS);
+   }
+   return count+dcount;
+}
+
+int
+rte_eth_xstats_get_by_name(uint8_t port_id, struct rte_eth_xstat *xstat,
+   const char *name)
+{
+   struct rte_eth_xstat *xstats;
+   int cnt_xstats, idx_xstat;
+   struct rte_eth_xstat_name *xstats_names;
+
+
+
+   /* Get count */
+   cnt_xstats = rte_eth_xs

[dpdk-dev] [PATCH 3/4] net/ixgbe: add grouping of xstats for ixgbe driver

2017-03-02 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends the 'rte_ixgbe_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is
now specified group (e.g. MAC_GROUP), one xstatistic can be in
several groups. To implement new functionality of retriving
xstats by group on driver level, there are two functions added:
ixgbe_dev_xstats_get_by_group() and ixgbe_dev_xstats_get_names_by_group()

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 586 +++
 1 file changed, 475 insertions(+), 111 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7169007..31aa4e2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -124,7 +124,8 @@
 
 #define IXGBEVF_PMD_NAME "rte_ixgbevf_pmd" /* PMD name */
 
-#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / 
sizeof(hw_stats->qprc[0]))
+#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) \
+   / sizeof(hw_stats->qprc[0]))
 
 #define IXGBE_HKEY_MAX_INDEX 10
 
@@ -187,12 +188,25 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *xstats, unsigned n);
+static int ixgbe_dev_xstats_get_by_group(struct rte_eth_dev *dev,
+   struct rte_eth_xstat *xstats,
+   unsigned n, uint64_t group_mask);
 static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
+static int ixgbe_xstats_get_by_name(struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   struct rte_eth_xstat *xstat,
+   const char *name);
 static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
+static
+int ixgbe_dev_xstats_get_names_by_group(__rte_unused
+   struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   unsigned limit,
+   uint64_t group_mask);
 static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -532,10 +546,13 @@ static int ixgbe_dev_udp_tunnel_port_del(struct 
rte_eth_dev *dev,
.link_update  = ixgbe_dev_link_update,
.stats_get= ixgbe_dev_stats_get,
.xstats_get   = ixgbe_dev_xstats_get,
+   .xstats_get_by_name   = ixgbe_xstats_get_by_name,
+   .xstats_get_by_group  = ixgbe_dev_xstats_get_by_group,
.stats_reset  = ixgbe_dev_stats_reset,
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
+   .xstats_get_names_by_group = ixgbe_dev_xstats_get_names_by_group,
.fw_version_get   = ixgbe_fw_version_get,
.dev_infos_get= ixgbe_dev_info_get,
.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -653,87 +670,125 @@ static int ixgbe_dev_udp_tunnel_port_del(struct 
rte_eth_dev *dev,
 struct rte_ixgbe_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-   {"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-   {"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
-   {"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
-   {"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
-   {"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
-   {"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
-   {"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
-   {"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-   {"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-   {"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
-   {"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
-   {"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
-   {"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
-   {"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, prc511)},

[dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver

2017-03-02 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends the 'rte_igb_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is now
specified group (e.g. TX_GROUP), one xstatistic can be in several groups.
To implement new functionality of retriving xstats by group
on driver level, there are two functions added:
eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group()

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/e1000/igb_ethdev.c | 268 +++--
 1 file changed, 206 insertions(+), 62 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a112b38..8057b6f 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -115,9 +115,18 @@ static void eth_igb_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *rte_stats);
 static int eth_igb_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
+static
+int eth_igb_xstats_get_by_group(struct rte_eth_dev *dev,
+   struct rte_eth_xstat *xstats,
+   unsigned n, uint64_t group_mask);
 static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
+static int
+eth_igb_xstats_get_names_by_group(__rte_unused struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   __rte_unused unsigned limit,
+   uint64_t group_mask);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static int eth_igb_fw_version_get(struct rte_eth_dev *dev,
@@ -390,7 +399,9 @@ static void eth_igbvf_interrupt_handler(struct 
rte_intr_handle *handle,
.link_update  = eth_igb_link_update,
.stats_get= eth_igb_stats_get,
.xstats_get   = eth_igb_xstats_get,
+   .xstats_get_by_group  = eth_igb_xstats_get_by_group,
.xstats_get_names = eth_igb_xstats_get_names,
+   .xstats_get_names_by_group = eth_igb_xstats_get_names_by_group,
.stats_reset  = eth_igb_stats_reset,
.xstats_reset = eth_igb_xstats_reset,
.fw_version_get   = eth_igb_fw_version_get,
@@ -473,78 +484,128 @@ static void eth_igbvf_interrupt_handler(struct 
rte_intr_handle *handle,
 struct rte_igb_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
-   {"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
-   {"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
-   {"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
-   {"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
-   {"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
-   {"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+   {"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs),
+   RX_GROUP | ERR_GROUP},
+   {"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc),
+   RX_GROUP | ERR_GROUP},
+   {"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs),
+   RX_GROUP | ERR_GROUP},
+   {"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc),
+   RX_GROUP},
+   {"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc),
+   TX_GROUP},
+   {"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc),
+   TX_GROUP},
{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
-   ecol)},
-   {"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
-   {"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
-   {"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
-   {"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
-   {"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
-   {"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
-   {"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
-   {"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
-   {"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
-   {"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+   ecol), TX_GROUP},
+   {"tx_late_collisions", offsetof(struct e1000_hw

[dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name

2017-03-03 Thread Kuba Kozak
Added three new functions to API: rte_eth_xstats_get_by_name(),
rte_eth_xstats_get_by_group(), rte_eth_xstats_get_names_by_group().

Extension of the 'rte_igb_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is now
specified group (e.g. TX_GROUP), one xstatistic can be in several groups.
To implement new functionality of retriving xstats by group
on e1000 driver level, there are two functions added:
eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group(),
on ixgbe driver level, there are new functions added:
ixgbe_dev_xstats_get_by_group() and ixgbe_dev_xstats_get_names_by_group()

Extended functionality of proc_info application:
--xstats-name NAME: to display single xstat value by NAME
--xstats-group GROUPNAME: to display group of xstats by GROUPNAME

Jacek Piasecki (4):
  ethdev: add retrieving xstats by group and xstats by name
  net/e1000: add grouping of xstats for e1000 driver
  net/ixgbe: add grouping of xstats for ixgbe driver
  app/proc_info: add support for xstats-name and xstats-group

 app/proc_info/main.c | 112 -
 drivers/net/e1000/igb_ethdev.c   | 261 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c | 496 +++
 lib/librte_ether/rte_ethdev.c| 310 +++-
 lib/librte_ether/rte_ethdev.h| 105 -
 5 files changed, 1114 insertions(+), 170 deletions(-)

-- 
1.9.1



[dpdk-dev] [PATCH 1/4] ethdev: add retrieving xstats by group and xstats by name

2017-03-03 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends library for retriving xstats by specified groups and
single xstat by given name.

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 lib/librte_ether/rte_ethdev.c | 310 --
 lib/librte_ether/rte_ethdev.h | 105 +-
 2 files changed, 401 insertions(+), 14 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index eb0a94a..aad8913 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -87,33 +87,37 @@
 struct rte_eth_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
-   {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
-   {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
-   {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
-   {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
-   {"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-   {"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+   {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets), RX_GROUP},
+   {"tx_good_packets", offsetof(struct rte_eth_stats, opackets), TX_GROUP},
+   {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes), RX_GROUP},
+   {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes), TX_GROUP},
+   {"rx_errors", offsetof(struct rte_eth_stats, ierrors),
+   RX_GROUP | ERR_GROUP},
+   {"tx_errors", offsetof(struct rte_eth_stats, oerrors),
+   TX_GROUP | ERR_GROUP},
{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
-   rx_nombuf)},
+   rx_nombuf), RX_GROUP | ERR_GROUP},
 };
 
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
-   {"packets", offsetof(struct rte_eth_stats, q_ipackets)},
-   {"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
-   {"errors", offsetof(struct rte_eth_stats, q_errors)},
+   {"packets", offsetof(struct rte_eth_stats, q_ipackets), RXQ_GROUP},
+   {"bytes", offsetof(struct rte_eth_stats, q_ibytes), RXQ_GROUP},
+   {"errors", offsetof(struct rte_eth_stats, q_errors),
+   RXQ_GROUP | ERR_GROUP},
 };
 
 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /  \
sizeof(rte_rxq_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
-   {"packets", offsetof(struct rte_eth_stats, q_opackets)},
-   {"bytes", offsetof(struct rte_eth_stats, q_obytes)},
+   {"packets", offsetof(struct rte_eth_stats, q_opackets), TXQ_GROUP},
+   {"bytes", offsetof(struct rte_eth_stats, q_obytes), TXQ_GROUP},
 };
 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /  \
sizeof(rte_txq_stats_strings[0]))
@@ -1448,6 +1452,110 @@ struct rte_eth_dev *
return count;
 }
 
+static int
+get_xstats_count_by_group(uint8_t port_id, uint64_t group_mask)
+{
+   struct rte_eth_dev *dev;
+   int count = 0;
+   int dcount = 0;
+   unsigned int i;
+
+   RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+   dev = &rte_eth_devices[port_id];
+   if (dev->dev_ops->xstats_get_names_by_group != NULL) {
+   dcount = (*dev->dev_ops->xstats_get_names_by_group)
+   (dev, NULL, 0, group_mask);
+   if (dcount < 0)
+   return dcount;
+   }
+
+
+
+
+   for (i = 0; i < RTE_NB_STATS; i++) {
+   if (rte_stats_strings[i].group_mask & group_mask)
+   count++;
+   }
+   for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+   if (rte_rxq_stats_strings[i].group_mask & group_mask)
+   count += RTE_MIN(dev->data->nb_rx_queues,
+   RTE_ETHDEV_QUEUE_STAT_CNTRS);
+   }
+   for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+   if (rte_txq_stats_strings[i].group_mask & group_mask)
+   count += RTE_MIN(dev->data->nb_tx_queues,
+   RTE_ETHDEV_QUEUE_STAT_CNTRS);
+   }
+   return count+dcount;
+}
+
+int
+rte_eth_xstats_get_by_name(uint8_t port_id, struct rte_eth_xstat *xstat,
+   const char *name)
+{
+   struct rte_eth_xstat *xstats;
+   int cnt_xstats, idx_xstat;
+   struct rte_eth_xstat_name *xstats_names;
+
+
+
+   /* Get count */
+   cnt_xstat

[dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver

2017-03-03 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends the 'rte_igb_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is now
specified group (e.g. TX_GROUP), one xstatistic can be in several groups.
To implement new functionality of retriving xstats by group
on driver level, there are two functions added:
eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group()

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/e1000/igb_ethdev.c | 261 +++--
 1 file changed, 199 insertions(+), 62 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a112b38..28eced6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -115,9 +115,18 @@ static void eth_igb_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *rte_stats);
 static int eth_igb_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
+static
+int eth_igb_xstats_get_by_group(struct rte_eth_dev *dev,
+   struct rte_eth_xstat *xstats,
+   unsigned int n, uint64_t group_mask);
 static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
+static int
+eth_igb_xstats_get_names_by_group(__rte_unused struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   __rte_unused unsigned int limit,
+   uint64_t group_mask);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static int eth_igb_fw_version_get(struct rte_eth_dev *dev,
@@ -390,7 +399,9 @@ static void eth_igbvf_interrupt_handler(struct 
rte_intr_handle *handle,
.link_update  = eth_igb_link_update,
.stats_get= eth_igb_stats_get,
.xstats_get   = eth_igb_xstats_get,
+   .xstats_get_by_group  = eth_igb_xstats_get_by_group,
.xstats_get_names = eth_igb_xstats_get_names,
+   .xstats_get_names_by_group = eth_igb_xstats_get_names_by_group,
.stats_reset  = eth_igb_stats_reset,
.xstats_reset = eth_igb_xstats_reset,
.fw_version_get   = eth_igb_fw_version_get,
@@ -473,78 +484,128 @@ static void eth_igbvf_interrupt_handler(struct 
rte_intr_handle *handle,
 struct rte_igb_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
-   {"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
-   {"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
-   {"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
-   {"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
-   {"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
-   {"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+   {"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs),
+   RX_GROUP | ERR_GROUP},
+   {"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc),
+   RX_GROUP | ERR_GROUP},
+   {"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs),
+   RX_GROUP | ERR_GROUP},
+   {"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc),
+   RX_GROUP},
+   {"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc),
+   TX_GROUP},
+   {"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc),
+   TX_GROUP},
{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
-   ecol)},
-   {"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
-   {"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
-   {"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
-   {"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
-   {"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
-   {"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
-   {"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
-   {"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
-   {"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
-   {"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+   ecol), TX_GROUP},
+   {"tx_late_collisions", offsetof(struct e1000_hw

[dpdk-dev] [PATCH 3/4] net/ixgbe: add grouping of xstats for ixgbe driver

2017-03-03 Thread Kuba Kozak
From: Jacek Piasecki 

This patch extends the 'rte_ixgbe_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is
now specified group (e.g. MAC_GROUP), one xstatistic can be in
several groups. To implement new functionality of retriving
xstats by group on driver level, there are two functions added:
ixgbe_dev_xstats_get_by_group() and ixgbe_dev_xstats_get_names_by_group()

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 496 +++
 1 file changed, 403 insertions(+), 93 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7169007..69731ce 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -124,7 +124,8 @@
 
 #define IXGBEVF_PMD_NAME "rte_ixgbevf_pmd" /* PMD name */
 
-#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / 
sizeof(hw_stats->qprc[0]))
+#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) \
+   / sizeof(hw_stats->qprc[0]))
 
 #define IXGBE_HKEY_MAX_INDEX 10
 
@@ -187,12 +188,25 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *xstats, unsigned n);
+static int ixgbe_dev_xstats_get_by_group(struct rte_eth_dev *dev,
+   struct rte_eth_xstat *xstats,
+   unsigned int n, uint64_t group_mask);
 static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
+static int ixgbe_xstats_get_by_name(struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   struct rte_eth_xstat *xstat,
+   const char *name);
 static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
+static
+int ixgbe_dev_xstats_get_names_by_group(__rte_unused
+   struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   unsigned int limit,
+   uint64_t group_mask);
 static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -532,10 +546,13 @@ static int ixgbe_dev_udp_tunnel_port_del(struct 
rte_eth_dev *dev,
.link_update  = ixgbe_dev_link_update,
.stats_get= ixgbe_dev_stats_get,
.xstats_get   = ixgbe_dev_xstats_get,
+   .xstats_get_by_name   = ixgbe_xstats_get_by_name,
+   .xstats_get_by_group  = ixgbe_dev_xstats_get_by_group,
.stats_reset  = ixgbe_dev_stats_reset,
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
+   .xstats_get_names_by_group = ixgbe_dev_xstats_get_names_by_group,
.fw_version_get   = ixgbe_fw_version_get,
.dev_infos_get= ixgbe_dev_info_get,
.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -653,87 +670,118 @@ static int ixgbe_dev_udp_tunnel_port_del(struct 
rte_eth_dev *dev,
 struct rte_ixgbe_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+   uint64_t group_mask;
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-   {"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-   {"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
-   {"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
-   {"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
-   {"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
-   {"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
-   {"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
-   {"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-   {"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-   {"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
-   {"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
-   {"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
-   {"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
-   {"rx_size_256_to_511_packets", offseto

[dpdk-dev] [PATCH 4/4] app/proc_info: add support for xstats-name and xstats-group

2017-03-03 Thread Kuba Kozak
From: Jacek Piasecki 

This patch provides support for proc_info application
to allow printing single xstat value specified by its
name and printing xstats values specified by its group name.
New proc_info arguments:
--xstats-name NAME: to display single xstat value by NAME
--xstats-group GROUPNAME: to display group of xstats by GROUPNAME

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 app/proc_info/main.c | 112 ++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/app/proc_info/main.c b/app/proc_info/main.c
index 2c56d10..8826090 100644
--- a/app/proc_info/main.c
+++ b/app/proc_info/main.c
@@ -74,6 +74,11 @@
 static uint32_t reset_xstats;
 /**< Enable memory info. */
 static uint32_t mem_info;
+/**< Enable displaying xstat name. */
+static uint32_t enable_xstats_name;
+static char *xstats_name;
+/**< Enable displaying xstat group name. */
+static uint64_t enable_xstats_group;
 
 /**< display usage */
 static void
@@ -85,6 +90,8 @@
"  --stats: to display port statistics, enabled by default\n"
"  --xstats: to display extended port statistics, disabled by "
"default\n"
+   "  --xstats-name NAME: to display single xstat value by NAME\n"
+   "  --xstats-group GROUPNAME: to display group of xstats by 
GROUPNAME\n"
"  --stats-reset: to reset port statistics\n"
"  --xstats-reset: to reset port extended statistics\n",
prgname);
@@ -128,6 +135,8 @@
{"stats-reset", 0, NULL, 0},
{"xstats", 0, NULL, 0},
{"xstats-reset", 0, NULL, 0},
+   {"xstats-name", required_argument, NULL, 1},
+   {"xstats-group", required_argument, NULL, 1},
{NULL, 0, 0, 0}
};
 
@@ -168,7 +177,27 @@
MAX_LONG_OPT_SZ))
reset_xstats = 1;
break;
-
+   case 1:
+   /* Print xstat single value given by name*/
+   if (!strncmp(long_option[option_index].name,
+   "xstats-name",
+   MAX_LONG_OPT_SZ))   {
+   enable_xstats_name = 1;
+   xstats_name = optarg;
+   printf("name:%s:%s\n",
+   long_option[option_index].name,
+   optarg);
+   }
+   /* Print xstat group values given by group name*/
+   else if (!strncmp(long_option[option_index].name,
+   "xstats-group",
+   MAX_LONG_OPT_SZ))   {
+   enable_xstats_group = atoi(optarg);
+   printf("name:%s:%s\n",
+   long_option[option_index].name,
+   optarg);
+   }
+   break;
default:
proc_info_usage(prgname);
return -1;
@@ -241,6 +270,82 @@
 }
 
 static void
+nic_xstats_by_name_display(__rte_unused uint8_t port_id,
+   __rte_unused char *name)
+{
+   struct rte_eth_xstat xstat;
+
+   printf("## NIC statistics for port %-2d, statistic name '%s':\n",
+  port_id, name);
+
+   if (rte_eth_xstats_get_by_name(port_id, &xstat, name) == 0)
+   printf("%s: %"PRIu64"\n", name, xstat.value);
+   else
+   printf("Statistic not found...\n");
+
+}
+
+static void
+nic_xstats_by_group_display(__rte_unused uint8_t port_id,
+   __rte_unused uint64_t group_mask)
+{
+   struct rte_eth_xstat *xstats;
+   int cnt_xstats, idx_xstat;
+   struct rte_eth_xstat_name *xstats_names;
+
+   printf("## NIC extended statistics for port %-2d,"
+   " group %-2lu #\n",
+  port_id, group_mask);
+
+   /* Get count */
+   cnt_xstats = rte_eth_xstats_get_names_by_group(port_id, NULL, 0,
+   group_mask);
+   if (cnt_xstats  < 0) {
+   printf("Error: Cannot get count of xstats\n");
+   return;
+   }
+
+   /* Get id-name lookup table */
+   xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
+   if (xstats_names == NULL) {
+   printf("Cannot allocate memory for xstats 

[dpdk-dev] [PATCH v6 0/5] Extended xstats API in ethdev library to allow grouping of stats

2017-04-13 Thread Kuba Kozak
Extended xstats API in ethdev library to allow grouping of stats logically
so they can be retrieved per logical grouping  managed by the application.
Changed existing functions rte_eth_xstats_get_names and rte_eth_xstats_get
to use a new list of arguments: array of ids and array of values.
ABI versioning mechanism was used to support backward compatibility.
Introduced two new functions rte_eth_xstats_get_all and
rte_eth_xstats_get_names_all which keeps functionality of the previous
ones (respectively rte_eth_xstats_get and rte_eth_xstats_get_names)
but use new API inside. Both functions marked as deprecated. 
Introduced new function: rte_eth_xstats_get_id_by_name to retrieve
xstats ids by its names.
Extended functionality of proc_info application:
--xstats-name NAME: to display single xstat value by NAME
Updated test-pmd application to use new API.

v6 changes:
* patches arrangement in patchset
* fixes spelling bugs
* release notes

v5 changes:
* fix clang shared build compilation
* remove wrong versioning macros
* Makefile LIBABIVER 6 change 

v4 changes:
* documentation change after API modification
* fix xstats display for PMD without _by_ids() functions
* fix ABI validator errors

v3 changes:
* checkpatch fixes
* removed malloc bug in ethdev
* add new command to proc_info and IDs parsing
* merged testpmd and proc_info patch with library patch

Jacek Piasecki (3):
  ethdev: new xstats API add retrieving by ID
  net/e1000: new xstats API add ID support for e1000
  net/ixgbe: new xstats API add ID support for ixgbe

Kuba Kozak (2):
  ethdev: added new function for xstats ID
  proc-info: add support for new xstats API

 app/proc_info/main.c| 148 ++-
 app/test-pmd/config.c   |  19 +-
 doc/guides/prog_guide/poll_mode_drv.rst | 173 +++--
 doc/guides/rel_notes/release_17_05.rst  |   8 +
 drivers/net/e1000/igb_ethdev.c  |  92 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c| 179 +
 lib/librte_ether/rte_ethdev.c   | 430 
 lib/librte_ether/rte_ethdev.h   | 167 -
 lib/librte_ether/rte_ether_version.map  |   5 +
 9 files changed, 1070 insertions(+), 151 deletions(-)

-- 
1.9.1



[dpdk-dev] [PATCH v6 1/5] ethdev: new xstats API add retrieving by ID

2017-04-13 Thread Kuba Kozak
From: Jacek Piasecki 

Extended xstats API in ethdev library to allow grouping of stats
logically so they can be retrieved per logical grouping  managed
by the application.
Changed existing functions rte_eth_xstats_get_names and
rte_eth_xstats_get to use a new list of arguments: array of ids
and array of values. ABI versioning mechanism was used to
support backward compatibility.
Introduced two new functions rte_eth_xstats_get_all and
rte_eth_xstats_get_names_all which keeps functionality of the
previous ones (respectively rte_eth_xstats_get and
rte_eth_xstats_get_names) but use new API inside.

test-pmd: add support for new xstats API retrieving by id in
testpmd application: xstats_get() and
xstats_get_names() call with modified parameters.

doc: add description for modified xstats API
Documentation change for modified extended statistics API functions.
The old API only allows retrieval of *all* of the NIC statistics
at once. Given this requires a MMIO read PCI transaction per statistic
it is an inefficient way of retrieving just a few key statistics.
Often a monitoring agent only has an interest in a few key statistics,
and the old API forces wasting CPU time and PCIe bandwidth in retrieving
*all* statistics; even those that the application didn't explicitly
show an interest in.
The new, more flexible API allow retrieval of statistics per ID.
If a PMD wishes, it can be implemented to read just the required
NIC registers. As a result, the monitoring application no longer wastes
PCIe bandwidth and CPU time.

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
Signed-off-by: Tomasz Kulasek 
---
 app/proc_info/main.c|   6 +-
 app/test-pmd/config.c   |  19 +-
 doc/guides/prog_guide/poll_mode_drv.rst | 173 --
 doc/guides/rel_notes/release_17_05.rst  |   6 +
 lib/librte_ether/rte_ethdev.c   | 386 +++-
 lib/librte_ether/rte_ethdev.h   | 144 +++-
 lib/librte_ether/rte_ether_version.map  |   4 +
 7 files changed, 596 insertions(+), 142 deletions(-)

diff --git a/app/proc_info/main.c b/app/proc_info/main.c
index d576b42..9f5e219 100644
--- a/app/proc_info/main.c
+++ b/app/proc_info/main.c
@@ -358,7 +358,7 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
int len, ret, i;
static const char *nic_stats_border = "";
 
-   len = rte_eth_xstats_get_names(port_id, NULL, 0);
+   len = rte_eth_xstats_get_names_all(port_id, NULL, 0);
if (len < 0) {
printf("Cannot get xstats count\n");
return;
@@ -375,7 +375,7 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
free(xstats);
return;
}
-   if (len != rte_eth_xstats_get_names(
+   if (len != rte_eth_xstats_get_names_all(
port_id, xstats_names, len)) {
printf("Cannot get xstat names\n");
goto err;
@@ -385,7 +385,7 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
   port_id);
printf("%s\n",
   nic_stats_border);
-   ret = rte_eth_xstats_get(port_id, xstats, len);
+   ret = rte_eth_xstats_get_all(port_id, xstats, len);
if (ret < 0 || ret > len) {
printf("Cannot get xstats\n");
goto err;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4d873cd..ef07925 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -264,9 +264,9 @@ struct rss_type_info {
 void
 nic_xstats_display(portid_t port_id)
 {
-   struct rte_eth_xstat *xstats;
int cnt_xstats, idx_xstat;
struct rte_eth_xstat_name *xstats_names;
+   uint64_t *values;
 
printf("## NIC extended statistics for port %-2d\n", port_id);
if (!rte_eth_dev_is_valid_port(port_id)) {
@@ -275,7 +275,7 @@ struct rss_type_info {
}
 
/* Get count */
-   cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0);
+   cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0, NULL);
if (cnt_xstats  < 0) {
printf("Error: Cannot get count of xstats\n");
return;
@@ -288,23 +288,24 @@ struct rss_type_info {
return;
}
if (cnt_xstats != rte_eth_xstats_get_names(
-   port_id, xstats_names, cnt_xstats)) {
+   port_id, xstats_names, cnt_xstats, NULL)) {
printf("Error: Cannot get xstats lookup\n");
free(xstats_names);
return;
}
 
/* Get stats themselves */
-   xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
-   if (xstats == NULL) {
+   values = malloc(sizeof(values) * cnt_x

[dpdk-dev] [PATCH v6 2/5] ethdev: added new function for xstats ID

2017-04-13 Thread Kuba Kozak
Introduced new function: rte_eth_xstats_get_id_by_name
to retrieve xstats ids by its names.

doc: added release note

Signed-off-by: Kuba Kozak 
---
 doc/guides/rel_notes/release_17_05.rst |  2 ++
 lib/librte_ether/rte_ethdev.c  | 44 ++
 lib/librte_ether/rte_ethdev.h  | 21 
 lib/librte_ether/rte_ether_version.map |  1 +
 4 files changed, 68 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_05.rst 
b/doc/guides/rel_notes/release_17_05.rst
index 5b77226..dae4261 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -423,6 +423,8 @@ API Changes
   * Added new functions ``rte_eth_xstats_get_all`` and 
``rte_eth_xstats_get_names_all to provide backward compatibility for
 ``rte_eth_xstats_get`` and ``rte_eth_xstats_get_names``
 
+  * Added new function ``rte_eth_xstats_get_id_by_name``
+
 ABI Changes
 ---
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0adc1d0..ef30883 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1476,6 +1476,50 @@ struct rte_eth_dev *
 }
 
 int
+rte_eth_xstats_get_id_by_name(uint8_t port_id, const char *xstat_name,
+   uint64_t *id)
+{
+   int cnt_xstats, idx_xstat;
+
+   RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+   if (!id) {
+   RTE_PMD_DEBUG_TRACE("Error: id pointer is NULL\n");
+   return -1;
+   }
+
+   if (!xstat_name) {
+   RTE_PMD_DEBUG_TRACE("Error: xstat_name pointer is NULL\n");
+   return -1;
+   }
+
+   /* Get count */
+   cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0, NULL);
+   if (cnt_xstats  < 0) {
+   RTE_PMD_DEBUG_TRACE("Error: Cannot get count of xstats\n");
+   return -1;
+   }
+
+   /* Get id-name lookup table */
+   struct rte_eth_xstat_name xstats_names[cnt_xstats];
+
+   if (cnt_xstats != rte_eth_xstats_get_names(
+   port_id, xstats_names, cnt_xstats, NULL)) {
+   RTE_PMD_DEBUG_TRACE("Error: Cannot get xstats lookup\n");
+   return -1;
+   }
+
+   for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
+   if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
+   *id = idx_xstat;
+   return 0;
+   };
+   }
+
+   return -EINVAL;
+}
+
+int
 rte_eth_xstats_get_names_v1607(uint8_t port_id,
struct rte_eth_xstat_name *xstats_names,
unsigned int size)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8c94b88..058c435 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2346,6 +2346,27 @@ int rte_eth_tx_queue_setup(uint8_t port_id, uint16_t 
tx_queue_id,
  */
 void rte_eth_stats_reset(uint8_t port_id);
 
+
+/**
+ * Gets the ID of a statistic from its name.
+ *
+ * This function searches for the statistics using string compares, and
+ * as such should not be used on the fast-path. For fast-path retrieval of
+ * specific statistics, store the ID as provided in *id* from this function,
+ * and pass the ID to rte_eth_xstats_get()
+ *
+ * @param port_id The port to look up statistics from
+ * @param xstat_name The name of the statistic to return
+ * @param[out] id A pointer to an app-supplied uint64_t which should be
+ *set to the ID of the stat if the stat exists.
+ * @return
+ *0 on success
+ *-ENODEV for invalid port_id,
+ *-EINVAL if the xstat_name doesn't exist in port_id
+ */
+int rte_eth_xstats_get_id_by_name(uint8_t port_id, const char *xstat_name,
+   uint64_t *id);
+
 /**
  * Retrieve all extended statistics of an Ethernet device.
  *
diff --git a/lib/librte_ether/rte_ether_version.map 
b/lib/librte_ether/rte_ether_version.map
index a404434..7c41617 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -161,6 +161,7 @@ DPDK_17.05 {
rte_eth_find_next;
rte_eth_xstats_get;
rte_eth_xstats_get_all;
+   rte_eth_xstats_get_id_by_name;
rte_eth_xstats_get_names;
rte_eth_xstats_get_names_all;
 
-- 
1.9.1



[dpdk-dev] [PATCH v6 3/5] proc-info: add support for new xstats API

2017-04-13 Thread Kuba Kozak
There is a new argument --xstats-ids and --xstats-name
in proc_info command line to retrieve statistics given by ids
and by name.
E.g. --xstats-ids="1,3,5,7,8"
E.g. --xstats-name rx_errors

ethdev: mark functions as deprecated

Functions rte_eth_xstats_get_all and rte_eth_xstats_get_names_all
are marked as deprecated

Signed-off-by: Kuba Kozak 
---
 app/proc_info/main.c  | 150 ++
 lib/librte_ether/rte_ethdev.c |   4 +-
 lib/librte_ether/rte_ethdev.h |   2 +
 3 files changed, 143 insertions(+), 13 deletions(-)

diff --git a/app/proc_info/main.c b/app/proc_info/main.c
index 9f5e219..9c9b2b5 100644
--- a/app/proc_info/main.c
+++ b/app/proc_info/main.c
@@ -86,6 +86,14 @@
 static uint32_t reset_xstats;
 /**< Enable memory info. */
 static uint32_t mem_info;
+/**< Enable displaying xstat name. */
+static uint32_t enable_xstats_name;
+static char *xstats_name;
+
+/**< Enable xstats by ids. */
+#define MAX_NB_XSTATS_IDS 1024
+static uint32_t nb_xstats_ids;
+static uint64_t xstats_ids[MAX_NB_XSTATS_IDS];
 
 /**< display usage */
 static void
@@ -99,6 +107,9 @@
"default\n"
"  --metrics: to display derived metrics of the ports, disabled 
by "
"default\n"
+   "  --xstats-name NAME: to display single xstat value by NAME\n"
+   "  --xstats-ids IDLIST: to display xstat values by id. "
+   "The argument is comma-separated list of xstat ids to 
print out.\n"
"  --stats-reset: to reset port statistics\n"
"  --xstats-reset: to reset port extended statistics\n"
"  --collectd-format: to print statistics to STDOUT in expected 
by collectd format\n"
@@ -132,6 +143,33 @@
 
 }
 
+/*
+ * Parse ids value list into array
+ */
+static int
+parse_xstats_ids(char *list, uint64_t *ids, int limit) {
+   int length;
+   char *token;
+   char *ctx = NULL;
+   char *endptr;
+
+   length = 0;
+   token = strtok_r(list, ",", &ctx);
+   while (token != NULL) {
+   ids[length] = strtoull(token, &endptr, 10);
+   if (*endptr != '\0')
+   return -EINVAL;
+
+   length++;
+   if (length >= limit)
+   return -E2BIG;
+
+   token = strtok_r(NULL, ",", &ctx);
+   }
+
+   return length;
+}
+
 static int
 proc_info_preparse_args(int argc, char **argv)
 {
@@ -178,7 +216,9 @@
{"xstats", 0, NULL, 0},
{"metrics", 0, NULL, 0},
{"xstats-reset", 0, NULL, 0},
+   {"xstats-name", required_argument, NULL, 1},
{"collectd-format", 0, NULL, 0},
+   {"xstats-ids", 1, NULL, 1},
{"host-id", 0, NULL, 0},
{NULL, 0, 0, 0}
};
@@ -224,7 +264,28 @@
MAX_LONG_OPT_SZ))
reset_xstats = 1;
break;
+   case 1:
+   /* Print xstat single value given by name*/
+   if (!strncmp(long_option[option_index].name,
+   "xstats-name", MAX_LONG_OPT_SZ)) {
+   enable_xstats_name = 1;
+   xstats_name = optarg;
+   printf("name:%s:%s\n",
+   long_option[option_index].name,
+   optarg);
+   } else if (!strncmp(long_option[option_index].name,
+   "xstats-ids",
+   MAX_LONG_OPT_SZ))   {
+   nb_xstats_ids = parse_xstats_ids(optarg,
+   xstats_ids, MAX_NB_XSTATS_IDS);
+
+   if (nb_xstats_ids <= 0) {
+   printf("xstats-id list parse error.\n");
+   return -1;
+   }
 
+   }
+   break;
default:
proc_info_usage(prgname);
return -1;
@@ -351,20 +412,82 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
 }
 
 static void
+nic_xstats_by_name_display(uint8_t port_id, char *name)
+{
+   uint64_t id;
+
+   printf("## NIC statistics for port %-2d, statistic name '%s':\n",
+  port_id, name);
+
+   if (rte_eth_xstats_get_id_by_name(port_id, name, &id) == 0)
+

[dpdk-dev] [PATCH v6 4/5] net/e1000: new xstats API add ID support for e1000

2017-04-13 Thread Kuba Kozak
From: Jacek Piasecki 

To achieve functionality of retrieving only specific statistics
given by application there are two new functions added:
eth_igb_xstats_get_by_ids() which retrieve
values of statistics specified by ids array
and eth_igb_xstats_get_names_by_ids() which retrieve
names of statistics specified by ids array.

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/e1000/igb_ethdev.c | 92 +-
 1 file changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index cc2c244..8fed210 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -115,9 +115,13 @@ static void eth_igb_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *rte_stats);
 static int eth_igb_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
+static int eth_igb_xstats_get_by_ids(struct rte_eth_dev *dev, uint64_t *ids,
+   uint64_t *values, unsigned int n);
 static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
-   struct rte_eth_xstat_name *xstats_names,
-   unsigned limit);
+   struct rte_eth_xstat_name *xstats_names, unsigned int limit);
+static int eth_igb_xstats_get_names_by_ids(struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names, uint64_t *ids,
+   unsigned int limit);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static int eth_igb_fw_version_get(struct rte_eth_dev *dev,
@@ -388,6 +392,8 @@ static void eth_igb_write_ivar(struct e1000_hw *hw, uint8_t 
msix_vector,
.link_update  = eth_igb_link_update,
.stats_get= eth_igb_stats_get,
.xstats_get   = eth_igb_xstats_get,
+   .xstats_get_by_ids= eth_igb_xstats_get_by_ids,
+   .xstats_get_names_by_ids = eth_igb_xstats_get_names_by_ids,
.xstats_get_names = eth_igb_xstats_get_names,
.stats_reset  = eth_igb_stats_reset,
.xstats_reset = eth_igb_xstats_reset,
@@ -1846,6 +1852,41 @@ static int eth_igb_xstats_get_names(__rte_unused struct 
rte_eth_dev *dev,
return IGB_NB_XSTATS;
 }
 
+static int eth_igb_xstats_get_names_by_ids(struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names, uint64_t *ids,
+   unsigned int limit)
+{
+   unsigned int i;
+
+   if (!ids) {
+   if (xstats_names == NULL)
+   return IGB_NB_XSTATS;
+
+   for (i = 0; i < IGB_NB_XSTATS; i++)
+   snprintf(xstats_names[i].name,
+   sizeof(xstats_names[i].name),
+   "%s", rte_igb_stats_strings[i].name);
+
+   return IGB_NB_XSTATS;
+
+   } else {
+   struct rte_eth_xstat_name xstats_names_copy[IGB_NB_XSTATS];
+
+   eth_igb_xstats_get_names_by_ids(dev, xstats_names_copy, NULL,
+   IGB_NB_XSTATS);
+
+   for (i = 0; i < limit; i++) {
+   if (ids[i] >= IGB_NB_XSTATS) {
+   PMD_INIT_LOG(ERR, "id value isn't valid");
+   return -1;
+   }
+   strcpy(xstats_names[i].name,
+   xstats_names_copy[ids[i]].name);
+   }
+   return limit;
+   }
+}
+
 static int
 eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
   unsigned n)
@@ -1876,6 +1917,53 @@ static int eth_igb_xstats_get_names(__rte_unused struct 
rte_eth_dev *dev,
return IGB_NB_XSTATS;
 }
 
+static int
+eth_igb_xstats_get_by_ids(struct rte_eth_dev *dev, uint64_t *ids,
+   uint64_t *values, unsigned int n)
+{
+   unsigned int i;
+
+   if (!ids) {
+   struct e1000_hw *hw =
+   E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   struct e1000_hw_stats *hw_stats =
+   E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+   if (n < IGB_NB_XSTATS)
+   return IGB_NB_XSTATS;
+
+   igb_read_stats_registers(hw, hw_stats);
+
+   /* If this is a reset xstats is NULL, and we have cleared the
+* registers by reading them.
+*/
+   if (!values)
+   return 0;
+
+   /* Extended stats */
+   for (i = 0; i < IGB_NB_XSTATS; i++)
+   values[i] = *(uint64_t *)(((char *)hw_stats) +
+   rte_igb_stats_strings[i].offset);
+
+ 

[dpdk-dev] [PATCH v6 5/5] net/ixgbe: new xstats API add ID support for ixgbe

2017-04-13 Thread Kuba Kozak
From: Jacek Piasecki 

To achieve functionality of retrieving only specific statistics
given by application there are two new functions added:
ixgbe_dev_xstats_get_by_ids() which retrieve
values of statistics specified by ids array
and ixgbe_dev_xstats_get_names_by_ids() which retrieve
names of statistics specified by ids array.

Signed-off-by: Jacek Piasecki 
Signed-off-by: Kuba Kozak 
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++
 1 file changed, 179 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 1462324..76a5499 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -183,12 +183,20 @@ static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *xstats, unsigned n);
 static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
  struct rte_eth_xstat *xstats, unsigned n);
+static int
+ixgbe_dev_xstats_get_by_ids(struct rte_eth_dev *dev, uint64_t *ids,
+   uint64_t *values, unsigned int n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
 static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
+static int ixgbe_dev_xstats_get_names_by_ids(
+   __rte_unused struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   uint64_t *ids,
+   unsigned int limit);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 uint16_t queue_id,
 uint8_t stat_idx,
@@ -524,9 +532,11 @@ static int ixgbe_dev_udp_tunnel_port_del(struct 
rte_eth_dev *dev,
.link_update  = ixgbe_dev_link_update,
.stats_get= ixgbe_dev_stats_get,
.xstats_get   = ixgbe_dev_xstats_get,
+   .xstats_get_by_ids= ixgbe_dev_xstats_get_by_ids,
.stats_reset  = ixgbe_dev_stats_reset,
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
+   .xstats_get_names_by_ids = ixgbe_dev_xstats_get_names_by_ids,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
.fw_version_get   = ixgbe_fw_version_get,
.dev_infos_get= ixgbe_dev_info_get,
@@ -3095,6 +3105,84 @@ static int ixgbe_dev_xstats_get_names(__rte_unused 
struct rte_eth_dev *dev,
return cnt_stats;
 }
 
+static int ixgbe_dev_xstats_get_names_by_ids(
+   __rte_unused struct rte_eth_dev *dev,
+   struct rte_eth_xstat_name *xstats_names,
+   uint64_t *ids,
+   unsigned int limit)
+{
+   if (!ids) {
+   const unsigned int cnt_stats = ixgbe_xstats_calc_num();
+   unsigned int stat, i, count;
+
+   if (xstats_names != NULL) {
+   count = 0;
+
+   /* Note: limit >= cnt_stats checked upstream
+* in rte_eth_xstats_names()
+*/
+
+   /* Extended stats from ixgbe_hw_stats */
+   for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+   snprintf(xstats_names[count].name,
+   sizeof(xstats_names[count].name),
+   "%s",
+   rte_ixgbe_stats_strings[i].name);
+   count++;
+   }
+
+   /* MACsec Stats */
+   for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+   snprintf(xstats_names[count].name,
+   sizeof(xstats_names[count].name),
+   "%s",
+   rte_ixgbe_macsec_strings[i].name);
+   count++;
+   }
+
+   /* RX Priority Stats */
+   for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
+   for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
+   snprintf(xstats_names[count].name,
+   sizeof(xstats_names[count].name),
+   "rx_priority%u_%s", i,
+   rte_ixgbe_rxq_strings[stat].name);
+   count++;
+   }
+   }
+
+   /* TX Priority Stats *

[dpdk-dev] [PATCH] ethdev: fix wrong sizeof argument in malloc function

2017-05-08 Thread Kuba Kozak
From: Michal Jastrzebski 

Coverity reported that an argument for sizeof was used improperly. 
We should allocate memory for value size that pointer points to,
instead of pointer size itself. 

Coverity issue: 144522
Fixes: 79c913a42f0e ("ethdev: retrieve xstats by ID")

Signed-off-by: Michal Jastrzebski 
---
 lib/librte_ether/rte_ethdev.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 8cf8b65..83898a8 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1714,7 +1714,7 @@ struct rte_eth_dev *
 
size = rte_eth_xstats_get_by_id(port_id, NULL, NULL, 0);
 
-   values_copy = malloc(sizeof(values_copy) * size);
+   values_copy = malloc(sizeof(*values_copy) * size);
if (!values_copy) {
RTE_PMD_DEBUG_TRACE(
"ERROR: can't allocate memory for values_copy\n");
-- 
1.7.9.5



[dpdk-dev] [PATCH] proc-info: wrong sizeof argument in malloc function

2017-05-08 Thread Kuba Kozak
From: Michal Jastrzebski 

Coverity reported that an argument for sizeof was used improperly. 
We should allocate memory for value size that pointer points to,
instead of pointer size itself. 

Coverity issue: 144523, 144521
Fixes: 7ac16a3660c0 ("app/proc-info: support xstats by ID and by name")

Signed-off-by: Michal Jastrzebski 
---
 app/proc_info/main.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/proc_info/main.c b/app/proc_info/main.c
index 17a1c87..d4f6a82 100644
--- a/app/proc_info/main.c
+++ b/app/proc_info/main.c
@@ -434,7 +434,7 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
int ret, i;
static const char *nic_stats_border = "";
 
-   values = malloc(sizeof(values) * len);
+   values = malloc(sizeof(*values) * len);
if (values == NULL) {
printf("Cannot allocate memory for xstats\n");
return;
@@ -486,7 +486,7 @@ static void collectd_resolve_cnt_type(char *cnt_type, 
size_t cnt_type_len,
printf("Cannot get xstats count\n");
return;
}
-   values = malloc(sizeof(values) * len);
+   values = malloc(sizeof(*values) * len);
if (values == NULL) {
printf("Cannot allocate memory for xstats\n");
return;
-- 
1.7.9.5



[dpdk-dev] [PATCH v5 0/5] Rework cfgfile API to enable apps config file support

2017-09-19 Thread Kuba Kozak
New API for cfgfile library allows to create a cfgfile at runtime, add new
section, add entry in a section, update existing entry and save cfgfile
structure to INI file - opens up the possibility to have applications
dynamically build up a proper DPDK configuration, rather than
having to have a pre-existing one. Due the new API functions, simplification
of load() function was made. One new unit test to TEST app was added. It
contains an example of a large INI file whose parsing requires multiple
reallocation of memory.

---
v5:
Some commit message reword
test_cfgfile.c - remove *.ini file created during realloc test
Add #ifdef RTE_NEXT_ABI for return value change in
- rte_cfgfile_section_num_entries(),
- rte_cfgfile_section_entries(),
- rte_cfgfile_section_entries_by_index()
v4: 
Change members of structure cfgfile:
- struct *sections[] to *sections
- struct *entries[] to *entries
- remove free_sections and free_entries
Rework of existing cfgfile API functions to work with modified
rte_cfgfile struct.
Rework of malloc/realloc implementation due rte_cfgfile struct change,
reducing mulitiple mallocs.
Change return error codes for all library functions (errno.h)
Checkpatch fixes
v3: 
split one patchset into two distinct patchsets:
1. cfgfile library and TEST app changes
2. EAL changes and examples (this patchset depends on cfgfile)
v2:
  lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments. 
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.

  lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add  set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function  simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function

Jacek Piasecki (5):
  cfgfile: remove EAL dependency
  cfgfile: change existing API functions
  cfgfile: add APIs for cfgfile modification
  cfgfile: rework of load function
  test/cfgfile: add new unit test

 doc/guides/rel_notes/deprecation.rst |   5 +
 lib/Makefile |   3 +-
 lib/librte_cfgfile/Makefile  |   1 +
 lib/librte_cfgfile/rte_cfgfile.c | 431 ++-
 lib/librte_cfgfile/rte_cfgfile.h |  82 -
 lib/librte_cfgfile/rte_cfgfile_version.map   |  11 +
 test/test/test_cfgfile.c |  41 +++
 test/test/test_cfgfiles/etc/realloc_sections.ini | 128 +++
 8 files changed, 532 insertions(+), 170 deletions(-)
 create mode 100644 test/test/test_cfgfiles/etc/realloc_sections.ini

-- 
2.7.4



[dpdk-dev] [PATCH v5 1/5] cfgfile: remove EAL dependency

2017-09-19 Thread Kuba Kozak
From: Jacek Piasecki 

This patch removes the dependency to EAL in cfgfile library.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/Makefile |  3 +--
 lib/librte_cfgfile/Makefile  |  1 +
 lib/librte_cfgfile/rte_cfgfile.c | 29 +
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..1080a95 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
+DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
@@ -41,8 +42,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf
 DEPDIRS-librte_mbuf := librte_eal librte_mempool
 DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
-DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
-DEPDIRS-librte_cfgfile := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
 DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
diff --git a/lib/librte_cfgfile/Makefile b/lib/librte_cfgfile/Makefile
index 755ef11..0bee43e 100644
--- a/lib/librte_cfgfile/Makefile
+++ b/lib/librte_cfgfile/Makefile
@@ -38,6 +38,7 @@ LIB = librte_cfgfile.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -I$(SRCDIR)/../librte_eal/common/include
 
 EXPORT_MAP := rte_cfgfile_version.map
 
diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 2588093..9dc25cc 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -36,7 +36,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "rte_cfgfile.h"
 
@@ -258,19 +257,25 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
 
struct rte_cfgfile_section *sect =
cfg->sections[curr_section];
-   int n;
+
char *split[2] = {NULL};
-   n = rte_strsplit(buffer, sizeof(buffer), split, 2, '=');
-   if (flags & CFG_FLAG_EMPTY_VALUES) {
-   if ((n < 1) || (n > 2)) {
-   printf("Error at line %d - cannot split 
string, n=%d\n",
-  lineno, n);
-   goto error1;
-   }
+   split[0] = buffer;
+   split[1] = memchr(buffer, '=', len);
+
+   /* when delimeter not found */
+   if (split[1] == NULL) {
+   printf("Error at line %d - cannot "
+   "split string\n", lineno);
+   goto error1;
} else {
-   if (n != 2) {
-   printf("Error at line %d - cannot split 
string, n=%d\n",
-  lineno, n);
+   /* when delimeter found */
+   *split[1] = '\0';
+   split[1]++;
+
+   if (!(flags & CFG_FLAG_EMPTY_VALUES) &&
+   (*split[1] == '\0')) {
+   printf("Error at line %d - cannot "
+   "split string\n", lineno);
goto error1;
}
}
-- 
2.7.4



[dpdk-dev] [PATCH v5 3/5] cfgfile: add APIs for cfgfile modification

2017-09-19 Thread Kuba Kozak
From: Jacek Piasecki 

Extend existing cfgfile library with providing new API functions:

rte_cfgfile_create() - create new cfgfile object
rte_cfgfile_add_section() - add new section to existing cfgfile
object
rte_cfgfile_add_entry() - add new entry to existing cfgfile
object in specified section
rte_cfgfile_set_entry() - update existing entry in cfgfile object
rte_cfgfile_save() - save existing cfgfile object to INI file

This modification allows to create a cfgfile on
runtime and opens up the possibility to have applications
dynamically build up a proper DPDK configuration, rather than having
to have a pre-existing one.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/librte_cfgfile/rte_cfgfile.c   | 186 +
 lib/librte_cfgfile/rte_cfgfile.h   |  76 
 lib/librte_cfgfile/rte_cfgfile_version.map |  11 ++
 3 files changed, 273 insertions(+)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index d7b3ff6..dd51268 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -121,6 +121,36 @@ _get_section(struct rte_cfgfile *cfg, const char 
*sectionname)
 }
 
 static int
+_add_entry(struct rte_cfgfile_section *section, const char *entryname,
+   const char *entryvalue)
+{
+   /* resize entry structure if we don't have room for more entries */
+   if (section->num_entries == section->allocated_entries) {
+   struct rte_cfgfile_entry *n_entries = realloc(
+   section->entries,
+   sizeof(struct rte_cfgfile_entry) *
+   ((section->allocated_entries) +
+   CFG_ALLOC_ENTRY_BATCH));
+
+   if (n_entries == NULL)
+   return -ENOMEM;
+
+   section->entries = n_entries;
+   section->allocated_entries += CFG_ALLOC_ENTRY_BATCH;
+   }
+   /* fill up entry fields with key name and value */
+   struct rte_cfgfile_entry *curr_entry =
+   §ion->entries[section->num_entries];
+
+   snprintf(curr_entry->name, sizeof(curr_entry->name), "%s", entryname);
+   snprintf(curr_entry->value,
+   sizeof(curr_entry->value), "%s", entryvalue);
+   section->num_entries++;
+
+   return 0;
+}
+
+static int
 rte_cfgfile_check_params(const struct rte_cfgfile_parameters *params)
 {
unsigned int valid_comment;
@@ -346,6 +376,162 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
return NULL;
 }
 
+struct rte_cfgfile *
+rte_cfgfile_create(int flags)
+{
+   int i;
+   struct rte_cfgfile *cfg = NULL;
+
+   cfg = malloc(sizeof(*cfg));
+
+   if (cfg == NULL)
+   return NULL;
+
+   cfg->flags = flags;
+   cfg->num_sections = 0;
+
+   /* allocate first batch of sections and entries */
+   cfg->sections = malloc(sizeof(struct rte_cfgfile_section) *
+   CFG_ALLOC_SECTION_BATCH);
+
+   if (cfg->sections == NULL)
+   return NULL;
+
+   cfg->allocated_sections = CFG_ALLOC_SECTION_BATCH;
+
+   for (i = 0; i < CFG_ALLOC_SECTION_BATCH; i++) {
+   cfg->sections[i].entries = malloc(sizeof(
+   struct rte_cfgfile_entry) * CFG_ALLOC_ENTRY_BATCH);
+
+   if (cfg->sections[i].entries == NULL)
+   return NULL;
+
+   cfg->sections[i].num_entries = 0;
+   cfg->sections[i].allocated_entries = CFG_ALLOC_ENTRY_BATCH;
+   }
+
+   if (flags & CFG_FLAG_GLOBAL_SECTION)
+   rte_cfgfile_add_section(cfg, "GLOBAL");
+   return cfg;
+}
+
+int
+rte_cfgfile_add_section(struct rte_cfgfile *cfg, const char *sectionname)
+{
+   int i;
+
+   if (cfg == NULL)
+   return -EINVAL;
+
+   if (sectionname == NULL)
+   return -EINVAL;
+
+   /* resize overall struct if we don't have room for more sections */
+   if (cfg->num_sections == cfg->allocated_sections) {
+
+   struct rte_cfgfile_section *n_sections =
+   realloc(cfg->sections,
+   sizeof(struct rte_cfgfile_section) *
+   ((cfg->allocated_sections) +
+   CFG_ALLOC_SECTION_BATCH));
+
+   if (n_sections == NULL)
+   return -ENOMEM;
+
+   for (i = 0; i < CFG_ALLOC_SECTION_BATCH; i++) {
+   n_sections[i + cfg->allocated_sections].num_entries = 0;
+   n_sections[i +
+cfg->allocated_sections].allocated_entries = 0;
+   n_sections[i + cfg->allocated_sections].entries = NULL;
+   }
+   cfg->sections = n_sections;
+   cfg->allocated_sections += CFG_ALLOC

[dpdk-dev] [PATCH v5 5/5] test/cfgfile: add new unit test

2017-09-19 Thread Kuba Kozak
From: Jacek Piasecki 

Load huge realloc_sections.ini file to check malloc/realloc
ability of cfgfile library.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 test/test/test_cfgfile.c |  41 
 test/test/test_cfgfiles/etc/realloc_sections.ini | 128 +++
 2 files changed, 169 insertions(+)
 create mode 100644 test/test/test_cfgfiles/etc/realloc_sections.ini

diff --git a/test/test/test_cfgfile.c b/test/test/test_cfgfile.c
index 4cc9b14..25e8539 100644
--- a/test/test/test_cfgfile.c
+++ b/test/test/test_cfgfile.c
@@ -111,6 +111,7 @@ _test_cfgfile_sample(struct rte_cfgfile *cfgfile)
return 0;
 }
 
+
 static int
 test_cfgfile_sample1(void)
 {
@@ -154,6 +155,43 @@ test_cfgfile_sample2(void)
 }
 
 static int
+test_cfgfile_realloc_sections(void)
+{
+   struct rte_cfgfile *cfgfile;
+   int ret;
+   const char *value;
+
+   cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/realloc_sections.ini", 0);
+   TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
+
+   ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
+   TEST_ASSERT(ret == 9, "Unexpected number of sections: %d", ret);
+
+   ret = rte_cfgfile_has_section(cfgfile, "section9");
+   TEST_ASSERT(ret, "section9 missing");
+
+   ret = rte_cfgfile_section_num_entries(cfgfile, "section3");
+   TEST_ASSERT(ret == 21,
+   "section3 unexpected number of entries: %d", ret);
+
+   ret = rte_cfgfile_section_num_entries(cfgfile, "section9");
+   TEST_ASSERT(ret == 8, "section9 unexpected number of entries: %d", ret);
+
+   value = rte_cfgfile_get_entry(cfgfile, "section9", "key8");
+   TEST_ASSERT(strcmp("value8_section9", value) == 0,
+   "key unexpected value: %s", value);
+
+   ret = rte_cfgfile_save(cfgfile, "/tmp/cfgfile_save.ini");
+   TEST_ASSERT_SUCCESS(ret, "Failed to save *.ini file");
+   remove("/tmp/cfgfile_save.ini");
+
+   ret = rte_cfgfile_close(cfgfile);
+   TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
+
+   return 0;
+}
+
+static int
 test_cfgfile_invalid_section_header(void)
 {
struct rte_cfgfile *cfgfile;
@@ -292,6 +330,9 @@ test_cfgfile(void)
if (test_cfgfile_sample2())
return -1;
 
+   if (test_cfgfile_realloc_sections())
+   return -1;
+
if (test_cfgfile_invalid_section_header())
return -1;
 
diff --git a/test/test/test_cfgfiles/etc/realloc_sections.ini 
b/test/test/test_cfgfiles/etc/realloc_sections.ini
new file mode 100644
index 000..e653e40
--- /dev/null
+++ b/test/test/test_cfgfiles/etc/realloc_sections.ini
@@ -0,0 +1,128 @@
+[section1]
+key1=value1_section1
+key2=value2_section1
+key3=value3_section1
+key4=value4_section1
+key5=value5_section1
+key6=value6_section1
+key7=value7_section1
+key8=value8_section1
+key9=value9_section1
+key10=value10_section1
+key11=value11_section1
+key12=value12_section1
+key13=value13_section1
+key14=value14_section1
+key15=value15_section1
+key16=value16_section1
+key17=value17_section1
+key18=value18_section1
+key19=value19_section1
+key20=value20_section1
+key21=value21_section1
+
+[section2]
+key1=value1_section2
+key2=value2_section2
+key3=value3_section2
+key4=value4_section2
+key5=value5_section2
+key6=value6_section2
+key7=value7_section2
+key8=value8_section2
+key9=value9_section2
+key10=value10_section2
+key11=value11_section2
+key12=value12_section2
+key13=value13_section2
+key14=value14_section2
+key15=value15_section2
+key16=value16_section2
+key17=value17_section2
+key18=value18_section2
+key19=value19_section2
+key20=value20_section2
+key21=value21_section2
+
+[section3]
+key1=value1_section3
+key2=value2_section3
+key3=value3_section3
+key4=value4_section3
+key5=value5_section3
+key6=value6_section3
+key7=value7_section3
+key8=value8_section3
+key9=value9_section3
+key10=value10_section3
+key11=value11_section3
+key12=value12_section3
+key13=value13_section3
+key14=value14_section3
+key15=value15_section3
+key16=value16_section3
+key17=value17_section3
+key18=value18_section3
+key19=value19_section3
+key20=value20_section3
+key21=value21_section3
+
+[section4]
+key1=value1_section4
+key2=value2_section4
+key3=value3_section4
+key4=value4_section4
+key5=value5_section4
+key6=value6_section4
+key7=value7_section4
+key8=value8_section4
+
+[section5]
+key1=value1_section5
+key2=value2_section5
+key3=value3_section5
+key4=value4_section5
+key5=value5_section5
+key6=value6_section5
+key7=value7_section5
+key8=value8_section5
+
+[section6]
+key1=value1_section6
+key2=value2_section6
+key3=value3_section6
+key4=value4_section6
+key5=value5_section6
+key6=value6_section6
+key7=value7_section6
+key8=value8_section6
+
+[section7]
+key1=value1_section7
+key2=value2_section7
+key3=value3_section7
+key4=value4_section7
+key5=value5_section7
+key6=value6_section7
+key7=value7_section7
+key8=value8_section7
+
+[section8]
+key1=value1_secti

[dpdk-dev] [PATCH v5 4/5] cfgfile: rework of load function

2017-09-19 Thread Kuba Kozak
From: Jacek Piasecki 

New functions added to cfgfile library make it possible
to significantly simplify the code of rte_cfgfile_load_with_params()

This patch shows the new body of this function.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/librte_cfgfile/rte_cfgfile.c | 157 ---
 1 file changed, 30 insertions(+), 127 deletions(-)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index dd51268..40954c5 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -189,10 +189,6 @@ struct rte_cfgfile *
 rte_cfgfile_load_with_params(const char *filename, int flags,
 const struct rte_cfgfile_parameters *params)
 {
-   int allocated_sections = CFG_ALLOC_SECTION_BATCH;
-   int allocated_entries = 0;
-   int curr_section = -1;
-   int curr_entry = -1;
char buffer[CFG_NAME_LEN + CFG_VALUE_LEN + 4] = {0};
int lineno = 0;
struct rte_cfgfile *cfg = NULL;
@@ -204,28 +200,7 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
if (f == NULL)
return NULL;
 
-   cfg = malloc(sizeof(*cfg) + sizeof(cfg->sections[0]) *
-   allocated_sections);
-   if (cfg == NULL)
-   goto error2;
-
-   memset(cfg->sections, 0, sizeof(cfg->sections[0]) * allocated_sections);
-
-   if (flags & CFG_FLAG_GLOBAL_SECTION) {
-   curr_section = 0;
-   allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   cfg->sections = malloc(
-   sizeof(cfg->sections[0]) +
-   sizeof(cfg->sections[0].entries) *
-   allocated_entries);
-   if (cfg->sections == NULL) {
-   printf("Error - no memory for global section\n");
-   goto error1;
-   }
-
-   snprintf(cfg->sections[curr_section].name,
-sizeof(cfg->sections[0].name), "GLOBAL");
-   }
+   cfg = rte_cfgfile_create(flags);
 
while (fgets(buffer, sizeof(buffer), f) != NULL) {
char *pos = NULL;
@@ -236,13 +211,15 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
"Check if line too long\n", lineno);
goto error1;
}
+   /* skip parsing if comment character found */
pos = memchr(buffer, params->comment_character, len);
-   if (pos != NULL) {
+   if (pos != NULL && (*(pos-1) != '\\')) {
*pos = '\0';
len = pos -  buffer;
}
 
len = _strip(buffer, len);
+   /* skip lines without useful content */
if (buffer[0] != '[' && memchr(buffer, '=', len) == NULL)
continue;
 
@@ -250,128 +227,54 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
/* section heading line */
char *end = memchr(buffer, ']', len);
if (end == NULL) {
-   printf("Error line %d - no terminating '['"
+   printf("Error line %d - no terminating ']'"
"character found\n", lineno);
goto error1;
}
*end = '\0';
_strip(&buffer[1], end - &buffer[1]);
 
-   /* close off old section and add start new one */
-   if (curr_section >= 0)
-   cfg->sections[curr_section].num_entries =
-   curr_entry + 1;
-   curr_section++;
-
-   /* resize overall struct if we don't have room for more
-   sections */
-   if (curr_section == allocated_sections) {
-   allocated_sections += CFG_ALLOC_SECTION_BATCH;
-   struct rte_cfgfile *n_cfg = realloc(cfg,
-   sizeof(*cfg) + sizeof(cfg->sections[0])
-   * allocated_sections);
-   if (n_cfg == NULL) {
-   curr_section--;
-   printf("Error - no more memory\n");
-   goto error1;
-   }
-   cfg = n_cfg;
-   }
-
-   /* allocate space for new section */
-   allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   curr_entry = -1;
-   cfg->sections = malloc(
-   sizeof(cfg->sections[0]) +
- 

[dpdk-dev] [PATCH v5 2/5] cfgfile: change existing API functions

2017-09-19 Thread Kuba Kozak
From: Jacek Piasecki 

Change to flat arrays in cfgfile struct force slightly
diffrent data access for most of cfgfile functions.
This patch provides necessary changes in existing API.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 doc/guides/rel_notes/deprecation.rst |   5 ++
 lib/librte_cfgfile/rte_cfgfile.c | 133 ++-
 lib/librte_cfgfile/rte_cfgfile.h |   6 +-
 3 files changed, 78 insertions(+), 66 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 3362f33..4f67646 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -120,3 +120,8 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* cfgfile: Return value in ``rte_cfgfile_section_num_entries``,
+  ``rte_cfgfile_section_entries`` and ``rte_cfgfile_section_entries_by_index``
+  will change from ``-1`` to ``-EINVAL`` to get a consistent error
+  handling in whole cfgfile library.
diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 9dc25cc..d7b3ff6 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "rte_cfgfile.h"
@@ -42,13 +43,15 @@
 struct rte_cfgfile_section {
char name[CFG_NAME_LEN];
int num_entries;
-   struct rte_cfgfile_entry *entries[0];
+   int allocated_entries;
+   struct rte_cfgfile_entry *entries;
 };
 
 struct rte_cfgfile {
int flags;
int num_sections;
-   struct rte_cfgfile_section *sections[0];
+   int allocated_sections;
+   struct rte_cfgfile_section *sections;
 };
 
 /** when we resize a file structure, how many extra entries
@@ -104,6 +107,19 @@ _strip(char *str, unsigned len)
return newlen;
 }
 
+static struct rte_cfgfile_section *
+_get_section(struct rte_cfgfile *cfg, const char *sectionname)
+{
+   int i;
+
+   for (i = 0; i < cfg->num_sections; i++) {
+   if (strncmp(cfg->sections[i].name, sectionname,
+   sizeof(cfg->sections[0].name)) == 0)
+   return &cfg->sections[i];
+   }
+   return NULL;
+}
+
 static int
 rte_cfgfile_check_params(const struct rte_cfgfile_parameters *params)
 {
@@ -168,17 +184,17 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
if (flags & CFG_FLAG_GLOBAL_SECTION) {
curr_section = 0;
allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   cfg->sections[curr_section] = malloc(
-   sizeof(*cfg->sections[0]) +
-   sizeof(cfg->sections[0]->entries[0]) *
+   cfg->sections = malloc(
+   sizeof(cfg->sections[0]) +
+   sizeof(cfg->sections[0].entries) *
allocated_entries);
-   if (cfg->sections[curr_section] == NULL) {
+   if (cfg->sections == NULL) {
printf("Error - no memory for global section\n");
goto error1;
}
 
-   snprintf(cfg->sections[curr_section]->name,
-sizeof(cfg->sections[0]->name), "GLOBAL");
+   snprintf(cfg->sections[curr_section].name,
+sizeof(cfg->sections[0].name), "GLOBAL");
}
 
while (fgets(buffer, sizeof(buffer), f) != NULL) {
@@ -213,7 +229,7 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
 
/* close off old section and add start new one */
if (curr_section >= 0)
-   cfg->sections[curr_section]->num_entries =
+   cfg->sections[curr_section].num_entries =
curr_entry + 1;
curr_section++;
 
@@ -235,17 +251,17 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
/* allocate space for new section */
allocated_entries = CFG_ALLOC_ENTRY_BATCH;
curr_entry = -1;
-   cfg->sections[curr_section] = malloc(
-   sizeof(*cfg->sections[0]) +
-   sizeof(cfg->sections[0]->entries[0]) *
+   cfg->sections = malloc(
+   sizeof(cfg->sections[0]) +
+   sizeof(cfg->sections[0].entries) *
allocated_entries);
-   if (cfg->sections[curr_section] == NULL) {
+   if (cfg->sections == NULL) {
printf("Error - no more memory\n");
goto err

[dpdk-dev] [PATCH] vfio: fix close unchecked file descriptor

2017-09-20 Thread Kuba Kozak
Add file descriptor value check before calling close() function.

Coverity issue: 141297
Fixes: 811b6b25060f ("vfio: fix file descriptor leak in multi-process")
Cc: patr...@patrickmacarthur.net
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
---
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c 
b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 7e8095c..c04f548 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -301,7 +301,8 @@ vfio_mp_sync_thread(void __rte_unused * arg)
vfio_mp_sync_send_request(conn_sock, 
SOCKET_ERR);
else
vfio_mp_sync_send_fd(conn_sock, fd);
-   close(fd);
+   if (fd != -1)
+   close(fd);
break;
case SOCKET_REQ_GROUP:
/* wait for group number */
-- 
2.7.4



[dpdk-dev] [PATCH] acl: fix unchecked return value

2017-09-20 Thread Kuba Kozak
Add return value check and error handling for fseek call.

Coverity issue: 143435
Fixes: 361b2e9559fc ("acl: new sample l3fwd-acl")
Cc: konstantin.anan...@intel.com
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
---
 examples/l3fwd-acl/main.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 8eff4de..708e9eb 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1026,6 +1026,7 @@ add_rules(const char *rule_path,
char buff[LINE_MAX];
FILE *fh = fopen(rule_path, "rb");
unsigned int i = 0;
+   int val;
 
if (fh == NULL)
rte_exit(EXIT_FAILURE, "%s: Open %s failed\n", __func__,
@@ -1042,7 +1043,11 @@ add_rules(const char *rule_path,
rte_exit(EXIT_FAILURE, "Not find any route entries in %s!\n",
rule_path);
 
-   fseek(fh, 0, SEEK_SET);
+   val = fseek(fh, 0, SEEK_SET);
+   if (val < 0) {
+   rte_exit(EXIT_FAILURE, "%s: File seek operation failed\n",
+   __func__);
+   }
 
acl_rules = calloc(acl_num, rule_size);
 
-- 
2.7.4



[dpdk-dev] [PATCH v6 0/5] Rework cfgfile API to enable apps config file support

2017-09-22 Thread Kuba Kozak
New API for cfgfile library allows to create a cfgfile at runtime, add new
section, add entry in a section, update existing entry and save cfgfile
structure to INI file - opens up the possibility to have applications
dynamically build up a proper DPDK configuration, rather than
having to have a pre-existing one. Due the new API functions, simplification
of load() function was made. One new unit test to TEST app was added. It
contains an example of a large INI file whose parsing requires multiple
reallocation of memory.

---
v6:
  Drop changes from v5 for return value in
- rte_cfgfile_section_num_entries(),
- rte_cfgfile_section_entries(),
- rte_cfgfile_section_entries_by_index()
v5:
Some commit message reword
test_cfgfile.c - remove *.ini file created during realloc test
Add #ifdef RTE_NEXT_ABI for return value change in
- rte_cfgfile_section_num_entries(),
- rte_cfgfile_section_entries(),
- rte_cfgfile_section_entries_by_index()
v4: 
Change members of structure cfgfile:
- struct *sections[] to *sections
- struct *entries[] to *entries
- remove free_sections and free_entries
Rework of existing cfgfile API functions to work with modified
rte_cfgfile struct.
Rework of malloc/realloc implementation due rte_cfgfile struct change,
reducing mulitiple mallocs.
Change return error codes for all library functions (errno.h)
Checkpatch fixes
v3: 
split one patchset into two distinct patchsets:
1. cfgfile library and TEST app changes
2. EAL changes and examples (this patchset depends on cfgfile)
v2:
  lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments. 
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.

  lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add  set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function  simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function

Jacek Piasecki (5):
  cfgfile: remove EAL dependency
  cfgfile: change existing API functions
  cfgfile: add APIs for cfgfile modification
  cfgfile: rework of load function
  test/cfgfile: add new unit test

 lib/Makefile |   3 +-
 lib/librte_cfgfile/Makefile  |   1 +
 lib/librte_cfgfile/rte_cfgfile.c | 419 ++-
 lib/librte_cfgfile/rte_cfgfile.h |  76 
 lib/librte_cfgfile/rte_cfgfile_version.map   |  11 +
 test/test/test_cfgfile.c |  41 +++
 test/test/test_cfgfiles/etc/realloc_sections.ini | 128 +++
 7 files changed, 512 insertions(+), 167 deletions(-)
 create mode 100644 test/test/test_cfgfiles/etc/realloc_sections.ini

-- 
2.7.4



[dpdk-dev] [PATCH v6 1/5] cfgfile: remove EAL dependency

2017-09-22 Thread Kuba Kozak
From: Jacek Piasecki 

This patch removes the dependency to EAL in cfgfile library.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/Makefile |  3 +--
 lib/librte_cfgfile/Makefile  |  1 +
 lib/librte_cfgfile/rte_cfgfile.c | 29 +
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..1080a95 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
+DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
@@ -41,8 +42,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf
 DEPDIRS-librte_mbuf := librte_eal librte_mempool
 DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
-DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
-DEPDIRS-librte_cfgfile := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
 DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
diff --git a/lib/librte_cfgfile/Makefile b/lib/librte_cfgfile/Makefile
index 755ef11..0bee43e 100644
--- a/lib/librte_cfgfile/Makefile
+++ b/lib/librte_cfgfile/Makefile
@@ -38,6 +38,7 @@ LIB = librte_cfgfile.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -I$(SRCDIR)/../librte_eal/common/include
 
 EXPORT_MAP := rte_cfgfile_version.map
 
diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 2588093..9dc25cc 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -36,7 +36,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "rte_cfgfile.h"
 
@@ -258,19 +257,25 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
 
struct rte_cfgfile_section *sect =
cfg->sections[curr_section];
-   int n;
+
char *split[2] = {NULL};
-   n = rte_strsplit(buffer, sizeof(buffer), split, 2, '=');
-   if (flags & CFG_FLAG_EMPTY_VALUES) {
-   if ((n < 1) || (n > 2)) {
-   printf("Error at line %d - cannot split 
string, n=%d\n",
-  lineno, n);
-   goto error1;
-   }
+   split[0] = buffer;
+   split[1] = memchr(buffer, '=', len);
+
+   /* when delimeter not found */
+   if (split[1] == NULL) {
+   printf("Error at line %d - cannot "
+   "split string\n", lineno);
+   goto error1;
} else {
-   if (n != 2) {
-   printf("Error at line %d - cannot split 
string, n=%d\n",
-  lineno, n);
+   /* when delimeter found */
+   *split[1] = '\0';
+   split[1]++;
+
+   if (!(flags & CFG_FLAG_EMPTY_VALUES) &&
+   (*split[1] == '\0')) {
+   printf("Error at line %d - cannot "
+   "split string\n", lineno);
goto error1;
}
}
-- 
2.7.4



[dpdk-dev] [PATCH v6 3/5] cfgfile: add APIs for cfgfile modification

2017-09-22 Thread Kuba Kozak
From: Jacek Piasecki 

Extend existing cfgfile library with providing new API functions:

rte_cfgfile_create() - create new cfgfile object
rte_cfgfile_add_section() - add new section to existing cfgfile
object
rte_cfgfile_add_entry() - add new entry to existing cfgfile
object in specified section
rte_cfgfile_set_entry() - update existing entry in cfgfile object
rte_cfgfile_save() - save existing cfgfile object to INI file

This modification allows to create a cfgfile on
runtime and opens up the possibility to have applications
dynamically build up a proper DPDK configuration, rather than having
to have a pre-existing one.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/librte_cfgfile/rte_cfgfile.c   | 186 +
 lib/librte_cfgfile/rte_cfgfile.h   |  76 
 lib/librte_cfgfile/rte_cfgfile_version.map |  11 ++
 3 files changed, 273 insertions(+)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 39f61e5..ad9bb2e 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -121,6 +121,36 @@ _get_section(struct rte_cfgfile *cfg, const char 
*sectionname)
 }
 
 static int
+_add_entry(struct rte_cfgfile_section *section, const char *entryname,
+   const char *entryvalue)
+{
+   /* resize entry structure if we don't have room for more entries */
+   if (section->num_entries == section->allocated_entries) {
+   struct rte_cfgfile_entry *n_entries = realloc(
+   section->entries,
+   sizeof(struct rte_cfgfile_entry) *
+   ((section->allocated_entries) +
+   CFG_ALLOC_ENTRY_BATCH));
+
+   if (n_entries == NULL)
+   return -ENOMEM;
+
+   section->entries = n_entries;
+   section->allocated_entries += CFG_ALLOC_ENTRY_BATCH;
+   }
+   /* fill up entry fields with key name and value */
+   struct rte_cfgfile_entry *curr_entry =
+   §ion->entries[section->num_entries];
+
+   snprintf(curr_entry->name, sizeof(curr_entry->name), "%s", entryname);
+   snprintf(curr_entry->value,
+   sizeof(curr_entry->value), "%s", entryvalue);
+   section->num_entries++;
+
+   return 0;
+}
+
+static int
 rte_cfgfile_check_params(const struct rte_cfgfile_parameters *params)
 {
unsigned int valid_comment;
@@ -346,6 +376,162 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
return NULL;
 }
 
+struct rte_cfgfile *
+rte_cfgfile_create(int flags)
+{
+   int i;
+   struct rte_cfgfile *cfg = NULL;
+
+   cfg = malloc(sizeof(*cfg));
+
+   if (cfg == NULL)
+   return NULL;
+
+   cfg->flags = flags;
+   cfg->num_sections = 0;
+
+   /* allocate first batch of sections and entries */
+   cfg->sections = malloc(sizeof(struct rte_cfgfile_section) *
+   CFG_ALLOC_SECTION_BATCH);
+
+   if (cfg->sections == NULL)
+   return NULL;
+
+   cfg->allocated_sections = CFG_ALLOC_SECTION_BATCH;
+
+   for (i = 0; i < CFG_ALLOC_SECTION_BATCH; i++) {
+   cfg->sections[i].entries = malloc(sizeof(
+   struct rte_cfgfile_entry) * CFG_ALLOC_ENTRY_BATCH);
+
+   if (cfg->sections[i].entries == NULL)
+   return NULL;
+
+   cfg->sections[i].num_entries = 0;
+   cfg->sections[i].allocated_entries = CFG_ALLOC_ENTRY_BATCH;
+   }
+
+   if (flags & CFG_FLAG_GLOBAL_SECTION)
+   rte_cfgfile_add_section(cfg, "GLOBAL");
+   return cfg;
+}
+
+int
+rte_cfgfile_add_section(struct rte_cfgfile *cfg, const char *sectionname)
+{
+   int i;
+
+   if (cfg == NULL)
+   return -EINVAL;
+
+   if (sectionname == NULL)
+   return -EINVAL;
+
+   /* resize overall struct if we don't have room for more sections */
+   if (cfg->num_sections == cfg->allocated_sections) {
+
+   struct rte_cfgfile_section *n_sections =
+   realloc(cfg->sections,
+   sizeof(struct rte_cfgfile_section) *
+   ((cfg->allocated_sections) +
+   CFG_ALLOC_SECTION_BATCH));
+
+   if (n_sections == NULL)
+   return -ENOMEM;
+
+   for (i = 0; i < CFG_ALLOC_SECTION_BATCH; i++) {
+   n_sections[i + cfg->allocated_sections].num_entries = 0;
+   n_sections[i +
+cfg->allocated_sections].allocated_entries = 0;
+   n_sections[i + cfg->allocated_sections].entries = NULL;
+   }
+   cfg->sections = n_sections;
+   cfg->allocated_sections += CFG_ALLOC

[dpdk-dev] [PATCH v6 2/5] cfgfile: change existing API functions

2017-09-22 Thread Kuba Kozak
From: Jacek Piasecki 

Change to flat arrays in cfgfile struct force slightly
diffrent data access for most of cfgfile functions.
This patch provides necessary changes in existing API.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/librte_cfgfile/rte_cfgfile.c | 121 +++
 1 file changed, 58 insertions(+), 63 deletions(-)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 9dc25cc..39f61e5 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "rte_cfgfile.h"
@@ -42,13 +43,15 @@
 struct rte_cfgfile_section {
char name[CFG_NAME_LEN];
int num_entries;
-   struct rte_cfgfile_entry *entries[0];
+   int allocated_entries;
+   struct rte_cfgfile_entry *entries;
 };
 
 struct rte_cfgfile {
int flags;
int num_sections;
-   struct rte_cfgfile_section *sections[0];
+   int allocated_sections;
+   struct rte_cfgfile_section *sections;
 };
 
 /** when we resize a file structure, how many extra entries
@@ -104,6 +107,19 @@ _strip(char *str, unsigned len)
return newlen;
 }
 
+static struct rte_cfgfile_section *
+_get_section(struct rte_cfgfile *cfg, const char *sectionname)
+{
+   int i;
+
+   for (i = 0; i < cfg->num_sections; i++) {
+   if (strncmp(cfg->sections[i].name, sectionname,
+   sizeof(cfg->sections[0].name)) == 0)
+   return &cfg->sections[i];
+   }
+   return NULL;
+}
+
 static int
 rte_cfgfile_check_params(const struct rte_cfgfile_parameters *params)
 {
@@ -168,17 +184,17 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
if (flags & CFG_FLAG_GLOBAL_SECTION) {
curr_section = 0;
allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   cfg->sections[curr_section] = malloc(
-   sizeof(*cfg->sections[0]) +
-   sizeof(cfg->sections[0]->entries[0]) *
+   cfg->sections = malloc(
+   sizeof(cfg->sections[0]) +
+   sizeof(cfg->sections[0].entries) *
allocated_entries);
-   if (cfg->sections[curr_section] == NULL) {
+   if (cfg->sections == NULL) {
printf("Error - no memory for global section\n");
goto error1;
}
 
-   snprintf(cfg->sections[curr_section]->name,
-sizeof(cfg->sections[0]->name), "GLOBAL");
+   snprintf(cfg->sections[curr_section].name,
+sizeof(cfg->sections[0].name), "GLOBAL");
}
 
while (fgets(buffer, sizeof(buffer), f) != NULL) {
@@ -213,7 +229,7 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
 
/* close off old section and add start new one */
if (curr_section >= 0)
-   cfg->sections[curr_section]->num_entries =
+   cfg->sections[curr_section].num_entries =
curr_entry + 1;
curr_section++;
 
@@ -235,17 +251,17 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
/* allocate space for new section */
allocated_entries = CFG_ALLOC_ENTRY_BATCH;
curr_entry = -1;
-   cfg->sections[curr_section] = malloc(
-   sizeof(*cfg->sections[0]) +
-   sizeof(cfg->sections[0]->entries[0]) *
+   cfg->sections = malloc(
+   sizeof(cfg->sections[0]) +
+   sizeof(cfg->sections[0].entries) *
allocated_entries);
-   if (cfg->sections[curr_section] == NULL) {
+   if (cfg->sections == NULL) {
printf("Error - no more memory\n");
goto error1;
}
 
-   snprintf(cfg->sections[curr_section]->name,
-   sizeof(cfg->sections[0]->name),
+   snprintf(cfg->sections[curr_section].name,
+   sizeof(cfg->sections[0].name),
"%s", &buffer[1]);
} else {
/* value line */
@@ -255,8 +271,7 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
goto error1;
}
 
-   struct rte_cfgfile_section *sect =
-   cfg->sections[curr_section];
+   struct rte_cfgfile_sec

[dpdk-dev] [PATCH v6 4/5] cfgfile: rework of load function

2017-09-22 Thread Kuba Kozak
From: Jacek Piasecki 

New functions added to cfgfile library make it possible
to significantly simplify the code of rte_cfgfile_load_with_params()

This patch shows the new body of this function.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 lib/librte_cfgfile/rte_cfgfile.c | 157 ---
 1 file changed, 30 insertions(+), 127 deletions(-)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index ad9bb2e..124aef5 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -189,10 +189,6 @@ struct rte_cfgfile *
 rte_cfgfile_load_with_params(const char *filename, int flags,
 const struct rte_cfgfile_parameters *params)
 {
-   int allocated_sections = CFG_ALLOC_SECTION_BATCH;
-   int allocated_entries = 0;
-   int curr_section = -1;
-   int curr_entry = -1;
char buffer[CFG_NAME_LEN + CFG_VALUE_LEN + 4] = {0};
int lineno = 0;
struct rte_cfgfile *cfg = NULL;
@@ -204,28 +200,7 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
if (f == NULL)
return NULL;
 
-   cfg = malloc(sizeof(*cfg) + sizeof(cfg->sections[0]) *
-   allocated_sections);
-   if (cfg == NULL)
-   goto error2;
-
-   memset(cfg->sections, 0, sizeof(cfg->sections[0]) * allocated_sections);
-
-   if (flags & CFG_FLAG_GLOBAL_SECTION) {
-   curr_section = 0;
-   allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   cfg->sections = malloc(
-   sizeof(cfg->sections[0]) +
-   sizeof(cfg->sections[0].entries) *
-   allocated_entries);
-   if (cfg->sections == NULL) {
-   printf("Error - no memory for global section\n");
-   goto error1;
-   }
-
-   snprintf(cfg->sections[curr_section].name,
-sizeof(cfg->sections[0].name), "GLOBAL");
-   }
+   cfg = rte_cfgfile_create(flags);
 
while (fgets(buffer, sizeof(buffer), f) != NULL) {
char *pos = NULL;
@@ -236,13 +211,15 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
"Check if line too long\n", lineno);
goto error1;
}
+   /* skip parsing if comment character found */
pos = memchr(buffer, params->comment_character, len);
-   if (pos != NULL) {
+   if (pos != NULL && (*(pos-1) != '\\')) {
*pos = '\0';
len = pos -  buffer;
}
 
len = _strip(buffer, len);
+   /* skip lines without useful content */
if (buffer[0] != '[' && memchr(buffer, '=', len) == NULL)
continue;
 
@@ -250,128 +227,54 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
/* section heading line */
char *end = memchr(buffer, ']', len);
if (end == NULL) {
-   printf("Error line %d - no terminating '['"
+   printf("Error line %d - no terminating ']'"
"character found\n", lineno);
goto error1;
}
*end = '\0';
_strip(&buffer[1], end - &buffer[1]);
 
-   /* close off old section and add start new one */
-   if (curr_section >= 0)
-   cfg->sections[curr_section].num_entries =
-   curr_entry + 1;
-   curr_section++;
-
-   /* resize overall struct if we don't have room for more
-   sections */
-   if (curr_section == allocated_sections) {
-   allocated_sections += CFG_ALLOC_SECTION_BATCH;
-   struct rte_cfgfile *n_cfg = realloc(cfg,
-   sizeof(*cfg) + sizeof(cfg->sections[0])
-   * allocated_sections);
-   if (n_cfg == NULL) {
-   curr_section--;
-   printf("Error - no more memory\n");
-   goto error1;
-   }
-   cfg = n_cfg;
-   }
-
-   /* allocate space for new section */
-   allocated_entries = CFG_ALLOC_ENTRY_BATCH;
-   curr_entry = -1;
-   cfg->sections = malloc(
-   sizeof(cfg->sections[0]) +
- 

[dpdk-dev] [PATCH v6 5/5] test/cfgfile: add new unit test

2017-09-22 Thread Kuba Kozak
From: Jacek Piasecki 

Load huge realloc_sections.ini file to check malloc/realloc
ability of cfgfile library.

Signed-off-by: Jacek Piasecki 
Acked-by: Bruce Richardson 
---
 test/test/test_cfgfile.c |  41 
 test/test/test_cfgfiles/etc/realloc_sections.ini | 128 +++
 2 files changed, 169 insertions(+)
 create mode 100644 test/test/test_cfgfiles/etc/realloc_sections.ini

diff --git a/test/test/test_cfgfile.c b/test/test/test_cfgfile.c
index 4cc9b14..25e8539 100644
--- a/test/test/test_cfgfile.c
+++ b/test/test/test_cfgfile.c
@@ -111,6 +111,7 @@ _test_cfgfile_sample(struct rte_cfgfile *cfgfile)
return 0;
 }
 
+
 static int
 test_cfgfile_sample1(void)
 {
@@ -154,6 +155,43 @@ test_cfgfile_sample2(void)
 }
 
 static int
+test_cfgfile_realloc_sections(void)
+{
+   struct rte_cfgfile *cfgfile;
+   int ret;
+   const char *value;
+
+   cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/realloc_sections.ini", 0);
+   TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
+
+   ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
+   TEST_ASSERT(ret == 9, "Unexpected number of sections: %d", ret);
+
+   ret = rte_cfgfile_has_section(cfgfile, "section9");
+   TEST_ASSERT(ret, "section9 missing");
+
+   ret = rte_cfgfile_section_num_entries(cfgfile, "section3");
+   TEST_ASSERT(ret == 21,
+   "section3 unexpected number of entries: %d", ret);
+
+   ret = rte_cfgfile_section_num_entries(cfgfile, "section9");
+   TEST_ASSERT(ret == 8, "section9 unexpected number of entries: %d", ret);
+
+   value = rte_cfgfile_get_entry(cfgfile, "section9", "key8");
+   TEST_ASSERT(strcmp("value8_section9", value) == 0,
+   "key unexpected value: %s", value);
+
+   ret = rte_cfgfile_save(cfgfile, "/tmp/cfgfile_save.ini");
+   TEST_ASSERT_SUCCESS(ret, "Failed to save *.ini file");
+   remove("/tmp/cfgfile_save.ini");
+
+   ret = rte_cfgfile_close(cfgfile);
+   TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
+
+   return 0;
+}
+
+static int
 test_cfgfile_invalid_section_header(void)
 {
struct rte_cfgfile *cfgfile;
@@ -292,6 +330,9 @@ test_cfgfile(void)
if (test_cfgfile_sample2())
return -1;
 
+   if (test_cfgfile_realloc_sections())
+   return -1;
+
if (test_cfgfile_invalid_section_header())
return -1;
 
diff --git a/test/test/test_cfgfiles/etc/realloc_sections.ini 
b/test/test/test_cfgfiles/etc/realloc_sections.ini
new file mode 100644
index 000..e653e40
--- /dev/null
+++ b/test/test/test_cfgfiles/etc/realloc_sections.ini
@@ -0,0 +1,128 @@
+[section1]
+key1=value1_section1
+key2=value2_section1
+key3=value3_section1
+key4=value4_section1
+key5=value5_section1
+key6=value6_section1
+key7=value7_section1
+key8=value8_section1
+key9=value9_section1
+key10=value10_section1
+key11=value11_section1
+key12=value12_section1
+key13=value13_section1
+key14=value14_section1
+key15=value15_section1
+key16=value16_section1
+key17=value17_section1
+key18=value18_section1
+key19=value19_section1
+key20=value20_section1
+key21=value21_section1
+
+[section2]
+key1=value1_section2
+key2=value2_section2
+key3=value3_section2
+key4=value4_section2
+key5=value5_section2
+key6=value6_section2
+key7=value7_section2
+key8=value8_section2
+key9=value9_section2
+key10=value10_section2
+key11=value11_section2
+key12=value12_section2
+key13=value13_section2
+key14=value14_section2
+key15=value15_section2
+key16=value16_section2
+key17=value17_section2
+key18=value18_section2
+key19=value19_section2
+key20=value20_section2
+key21=value21_section2
+
+[section3]
+key1=value1_section3
+key2=value2_section3
+key3=value3_section3
+key4=value4_section3
+key5=value5_section3
+key6=value6_section3
+key7=value7_section3
+key8=value8_section3
+key9=value9_section3
+key10=value10_section3
+key11=value11_section3
+key12=value12_section3
+key13=value13_section3
+key14=value14_section3
+key15=value15_section3
+key16=value16_section3
+key17=value17_section3
+key18=value18_section3
+key19=value19_section3
+key20=value20_section3
+key21=value21_section3
+
+[section4]
+key1=value1_section4
+key2=value2_section4
+key3=value3_section4
+key4=value4_section4
+key5=value5_section4
+key6=value6_section4
+key7=value7_section4
+key8=value8_section4
+
+[section5]
+key1=value1_section5
+key2=value2_section5
+key3=value3_section5
+key4=value4_section5
+key5=value5_section5
+key6=value6_section5
+key7=value7_section5
+key8=value8_section5
+
+[section6]
+key1=value1_section6
+key2=value2_section6
+key3=value3_section6
+key4=value4_section6
+key5=value5_section6
+key6=value6_section6
+key7=value7_section6
+key8=value8_section6
+
+[section7]
+key1=value1_section7
+key2=value2_section7
+key3=value3_section7
+key4=value4_section7
+key5=value5_section7
+key6=value6_section7
+key7=value7_section7
+key8=value8_section7
+
+[section8]
+key1=value1_secti

[dpdk-dev] [PATCH] vhost: fix unchecked return value

2017-09-22 Thread Kuba Kozak
Add return value check for poll() call.

Coverity issue: 140740
Fixes: 59317cef249c ("vhost: allow many vhost-user ports")
Cc: jan.wick...@ericsson.com
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
---
 lib/librte_vhost/fd_man.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/librte_vhost/fd_man.c b/lib/librte_vhost/fd_man.c
index 2ceacc9..4c6fed4 100644
--- a/lib/librte_vhost/fd_man.c
+++ b/lib/librte_vhost/fd_man.c
@@ -222,6 +222,7 @@ fdset_event_dispatch(void *arg)
int remove1, remove2;
int need_shrink;
struct fdset *pfdset = arg;
+   int val;
 
if (pfdset == NULL)
return NULL;
@@ -239,7 +240,9 @@ fdset_event_dispatch(void *arg)
numfds = pfdset->num;
pthread_mutex_unlock(&pfdset->fd_mutex);
 
-   poll(pfdset->rwfds, numfds, 1000 /* millisecs */);
+   val = poll(pfdset->rwfds, numfds, 1000 /* millisecs */);
+   if (val < 0)
+   continue;
 
need_shrink = 0;
for (i = 0; i < numfds; i++) {
-- 
2.7.4



[dpdk-dev] [PATCH] l3fwd-acl: fix unchecked return value

2017-10-03 Thread Kuba Kozak
Add return value check and error handling for fseek call.

Coverity issue: 143435
Fixes: 361b2e9559fc ("acl: new sample l3fwd-acl")
Cc: konstantin.anan...@intel.com
Cc: sta...@dpdk.org

Signed-off-by: Kuba Kozak 
Acked-by: Konstantin Ananyev 
---
 examples/l3fwd-acl/main.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 8eff4de..708e9eb 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1026,6 +1026,7 @@ add_rules(const char *rule_path,
char buff[LINE_MAX];
FILE *fh = fopen(rule_path, "rb");
unsigned int i = 0;
+   int val;
 
if (fh == NULL)
rte_exit(EXIT_FAILURE, "%s: Open %s failed\n", __func__,
@@ -1042,7 +1043,11 @@ add_rules(const char *rule_path,
rte_exit(EXIT_FAILURE, "Not find any route entries in %s!\n",
rule_path);
 
-   fseek(fh, 0, SEEK_SET);
+   val = fseek(fh, 0, SEEK_SET);
+   if (val < 0) {
+   rte_exit(EXIT_FAILURE, "%s: File seek operation failed\n",
+   __func__);
+   }
 
acl_rules = calloc(acl_num, rule_size);
 
-- 
2.7.4