[dpdk-dev] [PATCH 1/1] fix the number of operations in libcrypto test

2016-10-10 Thread Marcin Kerlin
This patch reduce the number of total operations from 1M to 10K, because
test is taking too long time now.

Fixes: ffbe3be0d4b5 ("app/test: add libcrypto")

Signed-off-by: Marcin Kerlin 
---
 app/test/test_cryptodev_perf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c
index 4aee9af..43a7166 100644
--- a/app/test/test_cryptodev_perf.c
+++ b/app/test/test_cryptodev_perf.c
@@ -3420,7 +3420,7 @@ test_perf_snow3G_vary_pkt_size(void)
 static int
 test_perf_libcrypto_vary_pkt_size(void)
 {
-   unsigned int total_operations = 100;
+   unsigned int total_operations = 1;
unsigned int burst_size = { 64 };
unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536,
1792, 2048 };
-- 
1.9.1



[dpdk-dev] [PATCH 2/2] app/testpmd: improve handling of multiprocess

2016-09-02 Thread Marcin Kerlin
Added lookup for pool name because secondary process should attach to
mempool created by primary process rather than create new one.

Added function free_shared_dev_data() used at the exit of the testpmd.
This causes detach devices data from array rte_eth_dev_data[] shared
between all processes. This allows to have a up-to-date list of devices
data and run again secondary application with the same name.

Signed-off-by: Marcin Kerlin 
---
 app/test-pmd/testpmd.c | 36 ++--
 app/test-pmd/testpmd.h |  1 +
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 1428974..b02f4eb 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -453,8 +453,10 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
} else {
/* wrapper to rte_mempool_create() */
-   rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
-   mb_mempool_cache, 0, mbuf_seg_size, socket_id);
+   rte_mp = rte_mempool_lookup(pool_name);
+   if (rte_mp == NULL)
+   rte_mp = rte_pktmbuf_pool_create(pool_name, 
nb_mbuf,
+   mb_mempool_cache, 0, 
mbuf_seg_size, socket_id);
}
}

@@ -1610,6 +1612,35 @@ detach_port(uint8_t port_id)
return;
 }

+void free_shared_dev_data(portid_t pid)
+{
+   portid_t pi;
+
+   if (port_id_is_invalid(pid, ENABLED_WARN))
+   return;
+
+   /* free data only if the secondary process exits */
+   if (rte_eal_process_type() != RTE_PROC_SECONDARY)
+   return;
+
+   printf("Cleaning device data...\n");
+
+   FOREACH_PORT(pi, ports)
+   {
+   if (pid != pi && pid != (portid_t) RTE_PORT_ALL)
+   continue;
+
+   if (!port_is_closed(pi)) {
+   printf("Port %d is not closed now\n", pi);
+   continue;
+   }
+
+   if (rte_eth_dev_release_dev_data(pi) < 0)
+   return;
+   }
+   printf("Done\n");
+}
+
 void
 pmd_test_exit(void)
 {
@@ -1625,6 +1656,7 @@ pmd_test_exit(void)
fflush(stdout);
stop_port(pt_id);
close_port(pt_id);
+   free_shared_dev_data(pt_id);
}
}
printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 2b281cc..3915a06 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -553,6 +553,7 @@ void attach_port(char *identifier);
 void detach_port(uint8_t port_id);
 int all_ports_stopped(void);
 int port_is_started(portid_t port_id);
+void free_shared_dev_data(portid_t pid);
 void pmd_test_exit(void);
 void fdir_get_infos(portid_t port_id);
 void fdir_set_flex_mask(portid_t port_id,
-- 
1.9.1



[dpdk-dev] [PATCH 1/2] librte_ether: ensure not overwrite device data in mp app

2016-09-02 Thread Marcin Kerlin
Added prevention not overwrite device data in array rte_eth_dev_data[].
Secondary process appends in the first free place rather than at the
beginning. This behavior prevents overwriting devices of primary process
by secondary process.

Signed-off-by: Marcin Kerlin 
---
 lib/librte_ether/rte_ethdev.c  | 90 +++---
 lib/librte_ether/rte_ethdev.h  | 24 +
 lib/librte_ether/rte_ether_version.map |  7 +++
 3 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f62a9ec..78e42bf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -177,6 +177,19 @@ rte_eth_dev_allocated(const char *name)
return NULL;
 }

+struct rte_eth_dev_data *
+rte_eth_dev_data_allocated(const char *name)
+{
+   unsigned int i;
+
+   for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+   if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+   return _eth_dev_data[i];
+   }
+
+   return NULL;
+}
+
 static uint8_t
 rte_eth_dev_find_free_port(void)
 {
@@ -189,10 +202,43 @@ rte_eth_dev_find_free_port(void)
return RTE_MAX_ETHPORTS;
 }

+static uint8_t
+rte_eth_dev_find_free_dev_data_id(void)
+{
+   unsigned int i;
+
+   for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+   if (!strlen(rte_eth_dev_data[i].name))
+   return i;
+   }
+   return RTE_MAX_ETHPORTS;
+}
+
+int
+rte_eth_dev_release_dev_data(uint8_t port_id)
+{
+   char device[RTE_ETH_NAME_MAX_LEN];
+   struct rte_eth_dev_data *eth_dev_data = NULL;
+
+   /* get device name by port id */
+   if (rte_eth_dev_get_name_by_port(port_id, device))
+   return -EINVAL;
+
+   /* look for an entry in the device data */
+   eth_dev_data = rte_eth_dev_data_allocated(device);
+   if (eth_dev_data == NULL)
+   return -EINVAL;
+
+   /* clear an entry in the device data */
+   memset(eth_dev_data, 0, sizeof(struct rte_eth_dev_data));
+
+   return 0;
+}
+
 struct rte_eth_dev *
 rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
 {
-   uint8_t port_id;
+   uint8_t port_id, dev_data_id;
struct rte_eth_dev *eth_dev;

port_id = rte_eth_dev_find_free_port();
@@ -204,17 +250,35 @@ rte_eth_dev_allocate(const char *name, enum 
rte_eth_dev_type type)
if (rte_eth_dev_data == NULL)
rte_eth_dev_data_alloc();

+   do {
+   dev_data_id = rte_eth_dev_find_free_dev_data_id();
+   } while (!rte_spinlock_trylock(_eth_dev_data[dev_data_id].lock)
+   && dev_data_id < RTE_MAX_ETHPORTS);
+
+   if (dev_data_id == RTE_MAX_ETHPORTS) {
+   RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports 
by all "
+   "the processes\n");
+   return NULL;
+   }
+
if (rte_eth_dev_allocated(name) != NULL) {
RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already 
allocated!\n",
name);
return NULL;
}

+   if (rte_eth_dev_data_allocated(name) != NULL) {
+   RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already 
allocated by "
+   "another process!\n", name);
+   return NULL;
+   }
+
eth_dev = _eth_devices[port_id];
-   eth_dev->data = _eth_dev_data[port_id];
+   eth_dev->data = _eth_dev_data[dev_data_id];
snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
eth_dev->data->port_id = port_id;
eth_dev->attached = DEV_ATTACHED;
+   rte_spinlock_unlock(_dev->data->lock);
eth_dev->dev_type = type;
nb_ports++;
return eth_dev;
@@ -418,9 +482,7 @@ rte_eth_dev_get_name_by_port(uint8_t port_id, char *name)
return -EINVAL;
}

-   /* shouldn't check 'rte_eth_devices[i].data',
-* because it might be overwritten by VDEV PMD */
-   tmp = rte_eth_dev_data[port_id].name;
+   tmp = rte_eth_devices[port_id].data->name;
strcpy(name, tmp);
return 0;
 }
@@ -439,9 +501,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t 
*port_id)

for (i = 0; i < RTE_MAX_ETHPORTS; i++) {

-   if (!strncmp(name,
-   rte_eth_dev_data[i].name, strlen(name))) {
-
+   if (!strncmp(name, rte_eth_devices[i].data->name, 
strlen(name))) {
*port_id = i;

return 0;
@@ -632,6 +692,8 @@ int
 rte_eth_dev_detach(uint8_t port_id, char *name)
 {
struct rte_pci_addr addr;
+   struct rte_eth_dev_data *eth_dev_data = NULL;
+   char device[RTE_ETH_NAME_MAX_LEN];
int ret = -1;

if (name == 

[dpdk-dev] [PATCH 0/2] app/testpmd: improve multiprocess support

2016-09-02 Thread Marcin Kerlin
This patch ensure not overwrite device data in the multiprocess application.

1)Changes in the library introduces continuity in array rte_eth_dev_data[]
shared between all processes. Secondary process adds new entries in free
space instead of overwriting existing entries.

2)Changes in application testpmd allow secondary process to attach the mempool
created by primary process rather than create new and in the case of quit or
force quit to free devices data from shared array rte_eth_dev_data[].

Breaking ABI:
Changes in the library librte_ether causes extending existing structure 
rte_eth_dev_data with a new field lock. The reason is that this structure is
sharing between all the processes so it should be protected against attempting
to write from two different processes.

Tomasz Kulasek sent announce ABI change in librte_ether on 21 July 2016. I would
like to join to this breaking ABI, if it is possible.

Marcin Kerlin (2):
  librte_ether: ensure not overwrite device data in mp app
  app/testpmd: improve handling of multiprocess

 app/test-pmd/testpmd.c | 36 +-
 app/test-pmd/testpmd.h |  1 +
 lib/librte_ether/rte_ethdev.c  | 90 +++---
 lib/librte_ether/rte_ethdev.h  | 24 +
 lib/librte_ether/rte_ether_version.map |  7 +++
 5 files changed, 148 insertions(+), 10 deletions(-)

-- 
1.9.1



[dpdk-dev] [PATCH 2/2] app/testpmd: fix handling of multiprocess

2016-07-29 Thread Marcin Kerlin
Added lookup for pool name because secondary process should attach to
mempool created by primary process rather than create new.

Added function free_mp_shared_dev_data() which causes that if secondary
process quit or force quit then detach own devices from common array
rte_eth_dev_data[] for all processes. This allows to have a up-to-date
list of devices and run again secondary application with the same name.

Signed-off-by: Marcin Kerlin 
---
 app/test-pmd/testpmd.c | 30 --
 app/test-pmd/testpmd.h |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 1428974..2fa33d0 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -453,8 +453,10 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
} else {
/* wrapper to rte_mempool_create() */
-   rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
-   mb_mempool_cache, 0, mbuf_seg_size, socket_id);
+   rte_mp = rte_mempool_lookup(pool_name);
+   if (rte_mp == NULL)
+   rte_mp = rte_pktmbuf_pool_create(pool_name, 
nb_mbuf,
+   mb_mempool_cache, 0, 
mbuf_seg_size, socket_id);
}
}

@@ -1610,6 +1612,29 @@ detach_port(uint8_t port_id)
return;
 }

+void free_mp_shared_dev_data(portid_t pid)
+{
+   portid_t pi;
+
+   if (port_id_is_invalid(pid, ENABLED_WARN))
+   return;
+
+   /* free data only if the secondary process exits */
+   if (rte_eal_process_type() != RTE_PROC_SECONDARY)
+   return;
+
+   FOREACH_PORT(pi, ports) {
+   if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
+   continue;
+
+   if (!port_is_closed(pi))
+   return;
+
+   if (rte_eth_dev_release_dev_data(pi) < 0)
+   return;
+   }
+}
+
 void
 pmd_test_exit(void)
 {
@@ -1625,6 +1650,7 @@ pmd_test_exit(void)
fflush(stdout);
stop_port(pt_id);
close_port(pt_id);
+   free_mp_shared_dev_data(pt_id);
}
}
printf("\nBye...\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 2b281cc..63f82f7 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -553,6 +553,7 @@ void attach_port(char *identifier);
 void detach_port(uint8_t port_id);
 int all_ports_stopped(void);
 int port_is_started(portid_t port_id);
+void free_mp_shared_dev_data(portid_t pid);
 void pmd_test_exit(void);
 void fdir_get_infos(portid_t port_id);
 void fdir_set_flex_mask(portid_t port_id,
-- 
1.9.1



[dpdk-dev] [PATCH 1/2] lib/librte_ether: ensure not overwrite device data

2016-07-29 Thread Marcin Kerlin
Added ensure consistent device data in the multiprocess application. Primary
process creates array rte_eth_dev_data[] and secondary process appends in the
first free place rather than at the beginning. This behavior prevents 
overwriting devices of primary process by secondary process. Two arrays 
rte_eth_dev_data[] and rte_eth_devices[] are shifted relative to each other 
and it required the addition new functions to search separately data.

Signed-off-by: Marcin Kerlin 
---
 lib/librte_ether/rte_ethdev.c  | 87 ++
 lib/librte_ether/rte_ethdev.h  | 23 +
 lib/librte_ether/rte_ether_version.map |  8 
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f62a9ec..a8f89c9 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -177,6 +177,19 @@ rte_eth_dev_allocated(const char *name)
return NULL;
 }

+struct rte_eth_dev_data *
+rte_eth_dev_data_shared_allocated(const char *name)
+{
+   unsigned i;
+
+   for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+   if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+   return _eth_dev_data[i];
+   }
+
+   return NULL;
+}
+
 static uint8_t
 rte_eth_dev_find_free_port(void)
 {
@@ -189,10 +202,43 @@ rte_eth_dev_find_free_port(void)
return RTE_MAX_ETHPORTS;
 }

+static uint8_t
+rte_eth_dev_find_free_dev_data_id(void)
+{
+   unsigned i;
+
+   for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+   if (!strlen(rte_eth_dev_data[i].name))
+   return i;
+   }
+   return RTE_MAX_ETHPORTS;
+}
+
+int
+rte_eth_dev_release_dev_data(uint8_t port_id)
+{
+   char device[RTE_ETH_NAME_MAX_LEN];
+   struct rte_eth_dev_data *eth_dev_data = NULL;
+
+   /* get device name by port id */
+   if (rte_eth_dev_get_name_by_port(port_id, device))
+   return -EINVAL;
+
+   /* look for an entry in the shared device data */
+   eth_dev_data = rte_eth_dev_data_shared_allocated(device);
+   if (eth_dev_data == NULL)
+   return -EINVAL;
+
+   /* clear an entry in the shared device data */
+   memset(eth_dev_data, 0, sizeof(struct rte_eth_dev_data));
+
+   return 0;
+}
+
 struct rte_eth_dev *
 rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
 {
-   uint8_t port_id;
+   uint8_t port_id, dev_data_id;
struct rte_eth_dev *eth_dev;

port_id = rte_eth_dev_find_free_port();
@@ -204,14 +250,28 @@ rte_eth_dev_allocate(const char *name, enum 
rte_eth_dev_type type)
if (rte_eth_dev_data == NULL)
rte_eth_dev_data_alloc();

+   dev_data_id = rte_eth_dev_find_free_dev_data_id();
+
+   if (dev_data_id == RTE_MAX_ETHPORTS) {
+   RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports 
by all "
+   "the processes\n");
+   return NULL;
+   }
+
if (rte_eth_dev_allocated(name) != NULL) {
RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already 
allocated!\n",
name);
return NULL;
}

+   if (rte_eth_dev_data_shared_allocated(name) != NULL) {
+   RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already 
allocated by "
+   "another process!\n", name);
+   return NULL;
+   }
+
eth_dev = _eth_devices[port_id];
-   eth_dev->data = _eth_dev_data[port_id];
+   eth_dev->data = _eth_dev_data[dev_data_id];
snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
eth_dev->data->port_id = port_id;
eth_dev->attached = DEV_ATTACHED;
@@ -237,6 +297,7 @@ rte_eth_dev_create_unique_device_name(char *name, size_t 
size,
 int
 rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 {
+
if (eth_dev == NULL)
return -EINVAL;

@@ -418,9 +479,7 @@ rte_eth_dev_get_name_by_port(uint8_t port_id, char *name)
return -EINVAL;
}

-   /* shouldn't check 'rte_eth_devices[i].data',
-* because it might be overwritten by VDEV PMD */
-   tmp = rte_eth_dev_data[port_id].name;
+   tmp = rte_eth_devices[port_id].data->name;
strcpy(name, tmp);
return 0;
 }
@@ -439,9 +498,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t 
*port_id)

for (i = 0; i < RTE_MAX_ETHPORTS; i++) {

-   if (!strncmp(name,
-   rte_eth_dev_data[i].name, strlen(name))) {
-
+   if (!strncmp(name, rte_eth_devices[i].data->name, 
strlen(name))) {
*port_id = i;

return 0;
@@ -632,6 +689,8 @@ int
 rte_eth_dev_detach(uint8_t port_id, char *name)
 {
 

[dpdk-dev] [PATCH 0/2] add ensure consistent device data in multiprocess mode

2016-07-29 Thread Marcin Kerlin
This patch ensure not overwrite device data in the multiprocess application.

1)Changes in the library introduces continuity in device data rte_eth_dev_data[]
common for to all processes. Functionality detach cleans data of detachable 
device and leaves space for other devices or for the next run app.

2)Changes in application testpmd allow secondary process to attach the mempool
created by primary process rather than create new and in the case of quit or
force quit to free devices of this process from shared array rte_eth_dev_data[].

Marcin Kerlin (2):
  lib/librte_ether: ensure not overwrite device data in multiprocess app
  app/testpmd: fix handling of multiprocess

 app/test-pmd/testpmd.c | 30 +++-
 app/test-pmd/testpmd.h |  1 +
 lib/librte_ether/rte_ethdev.c  | 87 ++
 lib/librte_ether/rte_ethdev.h  | 23 +
 lib/librte_ether/rte_ether_version.map |  8 
 5 files changed, 139 insertions(+), 10 deletions(-)

-- 
1.9.1



[dpdk-dev] [PATCH v5 1/1] eal: fix resource leak of mapped memory

2016-06-16 Thread Marcin Kerlin
Patch fixes resource leak in rte_eal_hugepage_attach() where mapped files
were not freed back to the OS in case of failure. Patch uses the behavior
of Linux munmap: "It is not an error if the indicated range does not
contain any mapped pages".

Coverity issue: 13295, 13296, 13303
Fixes: af75078fece3 ("first public release")

Signed-off-by: Marcin Kerlin 
Acked-by: Sergio Gonzalez Monroy 
---
v5:
 -shift the history of changes
v4:
 -removed keyword const from pointer and dependent on that casting (void *)
v3:
 -removed redundant casting
 -removed update error message
v2:
 -unmapping also previous addresses

 lib/librte_eal/linuxapp/eal/eal_memory.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c 
b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 79d1d2d..c935765 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1399,7 +1399,7 @@ int
 rte_eal_hugepage_attach(void)
 {
const struct rte_mem_config *mcfg = 
rte_eal_get_configuration()->mem_config;
-   const struct hugepage_file *hp = NULL;
+   struct hugepage_file *hp = NULL;
unsigned num_hp = 0;
unsigned i, s = 0; /* s used to track the segment number */
off_t size;
@@ -1481,7 +1481,7 @@ rte_eal_hugepage_attach(void)

size = getFileSize(fd_hugepage);
hp = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd_hugepage, 0);
-   if (hp == NULL) {
+   if (hp == MAP_FAILED) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n", 
eal_hugepage_info_path());
goto error;
}
@@ -1545,12 +1545,19 @@ rte_eal_hugepage_attach(void)
s++;
}
/* unmap the hugepage config file, since we are done using it */
-   munmap((void *)(uintptr_t)hp, size);
+   munmap(hp, size);
close(fd_zero);
close(fd_hugepage);
return 0;

 error:
+   s = 0;
+   while (s < RTE_MAX_MEMSEG && mcfg->memseg[s].len > 0) {
+   munmap(mcfg->memseg[s].addr, mcfg->memseg[s].len);
+   s++;
+   }
+   if (hp != NULL && hp != MAP_FAILED)
+   munmap(hp, size);
if (fd_zero >= 0)
close(fd_zero);
if (fd_hugepage >= 0)
-- 
1.9.1



[dpdk-dev] [PATCH v4 1/1] eal: fix resource leak of mapped memory

2016-06-15 Thread Marcin Kerlin
Patch fixes resource leak in rte_eal_hugepage_attach() where mapped files
were not freed back to the OS in case of failure. Patch uses the behavior
of Linux munmap: "It is not an error if the indicated range does not
contain any mapped pages".

v4:
1)removed keyword const from pointer and dependent on that casting (void *) 
v3:
1)removed redundant casting
2)removed update error message
v2:
1)unmapping also previous addresses

Coverity issue: 13295, 13296, 13303
Fixes: af75078fece3 ("first public release")

Signed-off-by: Marcin Kerlin 
---
 lib/librte_eal/linuxapp/eal/eal_memory.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c 
b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 79d1d2d..c935765 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1399,7 +1399,7 @@ int
 rte_eal_hugepage_attach(void)
 {
const struct rte_mem_config *mcfg = 
rte_eal_get_configuration()->mem_config;
-   const struct hugepage_file *hp = NULL;
+   struct hugepage_file *hp = NULL;
unsigned num_hp = 0;
unsigned i, s = 0; /* s used to track the segment number */
off_t size;
@@ -1481,7 +1481,7 @@ rte_eal_hugepage_attach(void)

size = getFileSize(fd_hugepage);
hp = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd_hugepage, 0);
-   if (hp == NULL) {
+   if (hp == MAP_FAILED) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n", 
eal_hugepage_info_path());
goto error;
}
@@ -1545,12 +1545,19 @@ rte_eal_hugepage_attach(void)
s++;
}
/* unmap the hugepage config file, since we are done using it */
-   munmap((void *)(uintptr_t)hp, size);
+   munmap(hp, size);
close(fd_zero);
close(fd_hugepage);
return 0;

 error:
+   s = 0;
+   while (s < RTE_MAX_MEMSEG && mcfg->memseg[s].len > 0) {
+   munmap(mcfg->memseg[s].addr, mcfg->memseg[s].len);
+   s++;
+   }
+   if (hp != NULL && hp != MAP_FAILED)
+   munmap(hp, size);
if (fd_zero >= 0)
close(fd_zero);
if (fd_hugepage >= 0)
-- 
1.9.1



[dpdk-dev] [PATCH 1/1] eal: fix typo in error message

2016-06-15 Thread Marcin Kerlin
Minor typo fix to error message

Fixes: 148f963fb532 ("xen: core library changes")

Signed-off-by: Marcin Kerlin 
---
 lib/librte_eal/linuxapp/eal/eal_memory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c 
b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 79d1d2d..2d6eef6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1417,7 +1417,7 @@ rte_eal_hugepage_attach(void)
if (internal_config.xen_dom0_support) {
 #ifdef RTE_LIBRTE_XEN_DOM0
if (rte_xen_dom0_memory_attach() < 0) {
-   RTE_LOG(ERR, EAL,"Failed to attach memory setments of 
primay "
+   RTE_LOG(ERR, EAL, "Failed to attach memory segments of 
primary "
"process\n");
return -1;
}
-- 
1.9.1



[dpdk-dev] [PATCH v3 1/1] eal: fix resource leak of mapped memory

2016-06-15 Thread Marcin Kerlin
Patch fixes resource leak in rte_eal_hugepage_attach() where mapped files
were not freed back to the OS in case of failure. Patch uses the behavior
of Linux munmap: "It is not an error if the indicated range does not 
contain any mapped pages".

V3:
1)removed redundant casting
2)removed update error message
V2:
1)unmapping also previous addresses 

Coverity issue: 13295, 13296, 13303
Fixes: af75078fece3 ("first public release")

Signed-off-by: Marcin Kerlin 
---
 lib/librte_eal/linuxapp/eal/eal_memory.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c 
b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 79d1d2d..44ff8e1 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1481,7 +1481,7 @@ rte_eal_hugepage_attach(void)

size = getFileSize(fd_hugepage);
hp = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd_hugepage, 0);
-   if (hp == NULL) {
+   if (hp == MAP_FAILED) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n", 
eal_hugepage_info_path());
goto error;
}
@@ -1545,12 +1545,19 @@ rte_eal_hugepage_attach(void)
s++;
}
/* unmap the hugepage config file, since we are done using it */
-   munmap((void *)(uintptr_t)hp, size);
+   munmap((void *)hp, size);
close(fd_zero);
close(fd_hugepage);
return 0;

 error:
+   s = 0;
+   while (s < RTE_MAX_MEMSEG && mcfg->memseg[s].len > 0) {
+   munmap(mcfg->memseg[s].addr, mcfg->memseg[s].len);
+   s++;
+   }
+   if (hp != NULL && hp != MAP_FAILED)
+   munmap((void *)hp, size);
if (fd_zero >= 0)
close(fd_zero);
if (fd_hugepage >= 0)
-- 
1.9.1



[dpdk-dev] [PATCH 1/1] vhost: fix null pointer dereference

2016-06-15 Thread Marcin Kerlin
Return value of function get_device() is not checking before
dereference. Fix this problem by adding checking condition.

Coverity issue: 119262
Fixes: 77d20126b4c2 ("vhost-user: handle message to enable vring")

Signed-off-by: Marcin Kerlin 
---
 lib/librte_vhost/vhost_user/virtio-net-user.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.c 
b/lib/librte_vhost/vhost_user/virtio-net-user.c
index f5248bc..94959f2 100644
--- a/lib/librte_vhost/vhost_user/virtio-net-user.c
+++ b/lib/librte_vhost/vhost_user/virtio-net-user.c
@@ -332,9 +332,13 @@ int
 user_set_vring_enable(struct vhost_device_ctx ctx,
  struct vhost_vring_state *state)
 {
-   struct virtio_net *dev = get_device(ctx);
+   struct virtio_net *dev;
int enable = (int)state->num;

+   dev = get_device(ctx);
+   if (dev == NULL)
+   return -1;
+
RTE_LOG(INFO, VHOST_CONFIG,
"set queue enable: %d to qp idx: %d\n",
enable, state->index);
-- 
1.9.1



[dpdk-dev] [PATCH 1/1] ip_pipeline: fix null pointer dereference

2016-06-13 Thread Marcin Kerlin
Return value of function app_pipeline_type_find is not checking before
dereference. Fix this problem by adding checking condition.

Coverity issue: 127196
Fixes: b4aee0fb9c6d ("examples/ip_pipeline: reconfigure thread binding 
dynamically")

Signed-off-by: Marcin Kerlin 
---
 examples/ip_pipeline/thread_fe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
index d1b72b4..6c547ca 100644
--- a/examples/ip_pipeline/thread_fe.c
+++ b/examples/ip_pipeline/thread_fe.c
@@ -81,6 +81,9 @@ app_pipeline_enable(struct app_params *app,
p_params = >pipeline_params[pipeline_id];
p_type = app_pipeline_type_find(app, p_params->type);

+   if (p_type == NULL)
+   return -1;
+
if (p->enabled == 1)
return -1;

-- 
1.9.1



[dpdk-dev] [PATCH 1/1] lib/librte_cmdline: fix added checking return value

2016-05-16 Thread Marcin Kerlin
Unchecked return value: value returned from a function rdline_init is 
not checked, fix added checking return value and in the case of failure
frees memory and return null pointer.

Fixes: af75078fece3 ("first public release")
Coverity ID 13204

Signed-off-by: Marcin Kerlin 
---
 lib/librte_cmdline/cmdline.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/librte_cmdline/cmdline.c b/lib/librte_cmdline/cmdline.c
index c405878..a9c47be 100644
--- a/lib/librte_cmdline/cmdline.c
+++ b/lib/librte_cmdline/cmdline.c
@@ -130,6 +130,7 @@ struct cmdline *
 cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
 {
struct cmdline *cl;
+   int ret;

if (!ctx || !prompt)
return NULL;
@@ -142,8 +143,13 @@ cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, 
int s_in, int s_out)
cl->s_out = s_out;
cl->ctx = ctx;

-   rdline_init(>rdl, cmdline_write_char,
-   cmdline_valid_buffer, cmdline_complete_buffer);
+   ret = rdline_init(>rdl, cmdline_write_char, cmdline_valid_buffer,
+   cmdline_complete_buffer);
+   if (ret != 0) {
+   free(cl);
+   return NULL;
+   }
+
cl->rdl.opaque = cl;
cmdline_set_prompt(cl, prompt);
rdline_newline(>rdl, cl->prompt);
-- 
1.9.1



[dpdk-dev] [PATCH 1/1] lib/librte_eal: fix resource leak

2016-04-19 Thread Marcin Kerlin
Fix issue reported by Coverity.

Coverity ID 13295, 13296, 13303:
Resource leak: The system resource will not be reclaimed
and reused, reducing the future availability of the resource.
In rte_eal_hugepage_attach: Leak of memory or pointers to system
resources.

Fixes: af75078fece3 ("first public release")

Signed-off-by: Marcin Kerlin 
---
 lib/librte_eal/linuxapp/eal/eal_memory.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c 
b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5b9132c..6320aa0 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1475,13 +1475,17 @@ rte_eal_hugepage_attach(void)
"and retry running both primary "
"and secondary processes\n");
}
+
+   if (base_addr != MAP_FAILED)
+   munmap((void *)(uintptr_t)base_addr, 
mcfg->memseg[s].len);
+
goto error;
}
}

size = getFileSize(fd_hugepage);
hp = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd_hugepage, 0);
-   if (hp == NULL) {
+   if (hp == MAP_FAILED) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n", 
eal_hugepage_info_path());
goto error;
}
@@ -1535,6 +1539,10 @@ rte_eal_hugepage_attach(void)
addr != RTE_PTR_ADD(base_addr, 
offset)) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n",
hp[i].filepath);
+
+   if (addr != MAP_FAILED)
+   munmap((void *)(uintptr_t)addr, 
mapping_size);
+
goto error;
}
offset+=mapping_size;
@@ -1551,6 +1559,8 @@ rte_eal_hugepage_attach(void)
return 0;

 error:
+   if (hp != NULL && hp != MAP_FAILED)
+   munmap((void *) (uintptr_t) hp, size);
if (fd_zero >= 0)
close(fd_zero);
if (fd_hugepage >= 0)
-- 
1.9.1



[dpdk-dev] [PATCH 1/1] examples/distributor: fix unchecked return value

2016-04-19 Thread Marcin Kerlin
Fix issue reported by Coverity.

Coverity ID 13207:
Value returned from a function is not checked for errors before being
used.

Fixes: 07db4a975094 ("examples/distributor: new sample app")

Signed-off-by: Marcin Kerlin 
---
 examples/distributor/main.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index c0201a9..8238520 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -178,19 +178,25 @@ struct lcore_params {
struct rte_mempool *mem_pool;
 };

-static void
+static int
 quit_workers(struct rte_distributor *d, struct rte_mempool *p)
 {
const unsigned num_workers = rte_lcore_count() - 2;
unsigned i;
struct rte_mbuf *bufs[num_workers];
-   rte_mempool_get_bulk(p, (void *)bufs, num_workers);
+
+   if (rte_mempool_get_bulk(p, (void *)bufs, num_workers) != 0) {
+   printf("line %d: Error getting mbufs from pool\n", __LINE__);
+   return -1;
+   }

for (i = 0; i < num_workers; i++)
bufs[i]->hash.rss = i << 1;

rte_distributor_process(d, bufs, num_workers);
rte_mempool_put_bulk(p, (void *)bufs, num_workers);
+
+   return 0;
 }

 static int
@@ -258,7 +264,8 @@ lcore_rx(struct lcore_params *p)
 * get packets till quit_signal is actually been
 * received and they gracefully shutdown
 */
-   quit_workers(d, mem_pool);
+   if (quit_workers(d, mem_pool) != 0)
+   return -1;
/* rx thread should quit at last */
return 0;
 }
@@ -588,7 +595,9 @@ main(int argc, char *argv[])
}
/* call lcore_main on master core only */
struct lcore_params p = { 0, d, output_ring, mbuf_pool};
-   lcore_rx();
+
+   if (lcore_rx() != 0)
+   return -1;

RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
-- 
1.9.1



[dpdk-dev] [PATCH] examples/ip_pipeline: fix out-of-bounds write

2016-04-14 Thread Marcin Kerlin
CID 124567:
In the function app_init_eal(struct app params * app) number of 
entries into array exceeds the size of the array if the conditions 
are fulfilled.

Fixes: 7f64b9c004aa ("examples/ip_pipeline: rework config file syntax")

Signed-off-by: Marcin Kerlin 
---
 examples/ip_pipeline/app.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 55a9841..e775024 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -415,7 +415,7 @@ struct app_eal_params {
 #endif

 #ifndef APP_EAL_ARGC
-#define APP_EAL_ARGC 32
+#define APP_EAL_ARGC 64
 #endif

 #ifndef APP_MAX_PIPELINE_TYPES
-- 
1.9.1



[dpdk-dev] [PATCH v2 1/1] examples/ip_pipeline: fix wrong size of argument

2016-04-08 Thread Marcin Kerlin
v2:
added fixline

CID 120150:
Wrong size of the allocated memory. Passing argument as size of pointer
(8UL) instead of size of structure app_pipeline_firewall_rule.

Fixes: 67ebdbef0c31 ("examples/ip_pipeline: add bulk update of firewall rules")

Signed-off-by: Marcin Kerlin 
---
 examples/ip_pipeline/pipeline/pipeline_firewall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c 
b/examples/ip_pipeline/pipeline/pipeline_firewall.c
index 320b25d..fd897d5 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
@@ -834,7 +834,7 @@ app_pipeline_firewall_add_bulk(struct app_params *app,
rules[i] = app_pipeline_firewall_rule_find(p, [i]);
new_rules[i] = (rules[i] == NULL);
if (rules[i] == NULL) {
-   rules[i] = rte_malloc(NULL, sizeof(rules[i]),
+   rules[i] = rte_malloc(NULL, sizeof(*rules[i]),
RTE_CACHE_LINE_SIZE);

if (rules[i] == NULL) {
-- 
1.9.1



[dpdk-dev] [examples/ip_pipeline: fix wrong size of argument 1/1]

2016-04-08 Thread Marcin Kerlin
CID 120150:
Wrong size of the allocated memory. Passing argument as size of pointer
(8UL) instead of size of structure app_pipeline_firewall_rule.


Signed-off-by: Marcin Kerlin 
---
 examples/ip_pipeline/pipeline/pipeline_firewall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c 
b/examples/ip_pipeline/pipeline/pipeline_firewall.c
index 320b25d..fd897d5 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
@@ -834,7 +834,7 @@ app_pipeline_firewall_add_bulk(struct app_params *app,
rules[i] = app_pipeline_firewall_rule_find(p, [i]);
new_rules[i] = (rules[i] == NULL);
if (rules[i] == NULL) {
-   rules[i] = rte_malloc(NULL, sizeof(rules[i]),
+   rules[i] = rte_malloc(NULL, sizeof(*rules[i]),
RTE_CACHE_LINE_SIZE);

if (rules[i] == NULL) {
-- 
1.9.1



[dpdk-dev] [PATCH v3 1/1] jobstats: added function abort for job

2016-02-12 Thread Marcin Kerlin
This patch adds new function rte_jobstats_abort. It marks *job* as finished and
time of this work will be add to management time instead of execution time. This
function should be used instead of rte_jobstats_finish if condition occurs,
condition is defined by the application for example when receiving n>0 packets.
Example of usage is added to the example l2fwd-jobstats. At maximum load 
do-while
loop inside Idle job will be execute once because one or more jobs waiting to be
executed, so this time should not be include as the execution time by calling 
rte_jobstats_abort().

v2:
* removed redundant field
v3:
* added an example of using

Signed-off-by: Marcin Kerlin 
---
 examples/l2fwd-jobstats/main.c   |  9 -
 lib/librte_jobstats/rte_jobstats.c   | 20 
 lib/librte_jobstats/rte_jobstats.h   | 14 ++
 lib/librte_jobstats/rte_jobstats_version.map |  7 +++
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index 7b59f4e..bd64e74 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -577,10 +577,13 @@ l2fwd_main_loop(void)
 */
rte_jobstats_start(>jobs_context, 
>idle_job);

+   uint64_t repeats = 0;
+
do {
uint8_t i;
uint64_t now = rte_get_timer_cycles();

+   repeats++;
need_manage = qconf->flush_timer.expire < now;
/* Check if we was esked to give a stats. */
stats_read_pending =
@@ -591,7 +594,11 @@ l2fwd_main_loop(void)
need_manage = 
qconf->rx_timers[i].expire < now;

} while (!need_manage);
-   rte_jobstats_finish(>idle_job, 
qconf->idle_job.target);
+
+   if (likely(repeats != 1))
+   rte_jobstats_finish(>idle_job, 
qconf->idle_job.target);
+   else
+   rte_jobstats_abort(>idle_job);

rte_timer_manage();
rte_jobstats_context_finish(>jobs_context);
diff --git a/lib/librte_jobstats/rte_jobstats.c 
b/lib/librte_jobstats/rte_jobstats.c
index 2eaac0c..2b42050 100644
--- a/lib/librte_jobstats/rte_jobstats.c
+++ b/lib/librte_jobstats/rte_jobstats.c
@@ -170,6 +170,26 @@ rte_jobstats_start(struct rte_jobstats_context *ctx, 
struct rte_jobstats *job)
 }

 int
+rte_jobstats_abort(struct rte_jobstats *job)
+{
+   struct rte_jobstats_context *ctx;
+   uint64_t now, exec_time;
+
+   /* Some sanity check. */
+   if (unlikely(job == NULL || job->context == NULL))
+   return -EINVAL;
+
+   ctx = job->context;
+   now = get_time();
+   exec_time = now - ctx->state_time;
+   ADD_TIME_MIN_MAX(ctx, management, exec_time);
+   ctx->state_time = now;
+   job->context = NULL;
+
+   return 0;
+}
+
+int
 rte_jobstats_finish(struct rte_jobstats *job, int64_t job_value)
 {
struct rte_jobstats_context *ctx;
diff --git a/lib/librte_jobstats/rte_jobstats.h 
b/lib/librte_jobstats/rte_jobstats.h
index de6a89a..c2b285f 100644
--- a/lib/librte_jobstats/rte_jobstats.h
+++ b/lib/librte_jobstats/rte_jobstats.h
@@ -237,6 +237,20 @@ int
 rte_jobstats_start(struct rte_jobstats_context *ctx, struct rte_jobstats *job);

 /**
+ * Mark that *job* finished its execution, but time of this work will be 
skipped
+ * and added to management time.
+ *
+ * @param job
+ *  Job object.
+ *
+ * @return
+ *  0 on success
+ *  -EINVAL if job is NULL or job was not started (it have no context).
+ */
+int
+rte_jobstats_abort(struct rte_jobstats *job);
+
+/**
  * Mark that *job* finished its execution. Context in which it was executing
  * will receive stat update. After this function call *job* object is ready to
  * be executed in other context.
diff --git a/lib/librte_jobstats/rte_jobstats_version.map 
b/lib/librte_jobstats/rte_jobstats_version.map
index cb01bfd..e3b21ca 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -17,3 +17,10 @@ DPDK_2.0 {

local: *;
 };
+
+DPDK_2.3 {
+   global:
+
+   rte_jobstats_abort;
+
+} DPDK_2.0;
-- 
1.9.1



[dpdk-dev] [PATCH v2 1/1] jobstats: added function abort for job

2016-01-29 Thread Marcin Kerlin
This patch adds new function rte_jobstats_abort. It marks *job* as finished
and time of this work will be add to management time instead of execution time.
This function should be used instead of rte_jobstats_finish if condition occurs,
condition is defined by the application for example when receiving n>0 packets.

v2:
* removed redundant field

Signed-off-by: Marcin Kerlin 
---
 lib/librte_jobstats/rte_jobstats.c   | 20 
 lib/librte_jobstats/rte_jobstats.h   | 14 ++
 lib/librte_jobstats/rte_jobstats_version.map |  7 +++
 3 files changed, 41 insertions(+)

diff --git a/lib/librte_jobstats/rte_jobstats.c 
b/lib/librte_jobstats/rte_jobstats.c
index 2eaac0c..2b42050 100644
--- a/lib/librte_jobstats/rte_jobstats.c
+++ b/lib/librte_jobstats/rte_jobstats.c
@@ -170,6 +170,26 @@ rte_jobstats_start(struct rte_jobstats_context *ctx, 
struct rte_jobstats *job)
 }

 int
+rte_jobstats_abort(struct rte_jobstats *job)
+{
+   struct rte_jobstats_context *ctx;
+   uint64_t now, exec_time;
+
+   /* Some sanity check. */
+   if (unlikely(job == NULL || job->context == NULL))
+   return -EINVAL;
+
+   ctx = job->context;
+   now = get_time();
+   exec_time = now - ctx->state_time;
+   ADD_TIME_MIN_MAX(ctx, management, exec_time);
+   ctx->state_time = now;
+   job->context = NULL;
+
+   return 0;
+}
+
+int
 rte_jobstats_finish(struct rte_jobstats *job, int64_t job_value)
 {
struct rte_jobstats_context *ctx;
diff --git a/lib/librte_jobstats/rte_jobstats.h 
b/lib/librte_jobstats/rte_jobstats.h
index de6a89a..c2b285f 100644
--- a/lib/librte_jobstats/rte_jobstats.h
+++ b/lib/librte_jobstats/rte_jobstats.h
@@ -237,6 +237,20 @@ int
 rte_jobstats_start(struct rte_jobstats_context *ctx, struct rte_jobstats *job);

 /**
+ * Mark that *job* finished its execution, but time of this work will be 
skipped
+ * and added to management time.
+ *
+ * @param job
+ *  Job object.
+ *
+ * @return
+ *  0 on success
+ *  -EINVAL if job is NULL or job was not started (it have no context).
+ */
+int
+rte_jobstats_abort(struct rte_jobstats *job);
+
+/**
  * Mark that *job* finished its execution. Context in which it was executing
  * will receive stat update. After this function call *job* object is ready to
  * be executed in other context.
diff --git a/lib/librte_jobstats/rte_jobstats_version.map 
b/lib/librte_jobstats/rte_jobstats_version.map
index cb01bfd..e3b21ca 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -17,3 +17,10 @@ DPDK_2.0 {

local: *;
 };
+
+DPDK_2.3 {
+   global:
+
+   rte_jobstats_abort;
+
+} DPDK_2.0;
-- 
1.9.1



[dpdk-dev] [PATCH V1 1/1] jobstats: added function abort for job

2016-01-26 Thread Marcin Kerlin
This patch adds new function rte_jobstats_abort. It marks *job* as finished
and time of this work will be add to management time instead of execution time. 
This function should be used instead of rte_jobstats_finish if condition occure,
condition is defined by the application for example when receiving n>0 packets.

Signed-off-by: Marcin Kerlin 
---
 lib/librte_jobstats/rte_jobstats.c   | 22 ++
 lib/librte_jobstats/rte_jobstats.h   | 17 +
 lib/librte_jobstats/rte_jobstats_version.map |  7 +++
 3 files changed, 46 insertions(+)

diff --git a/lib/librte_jobstats/rte_jobstats.c 
b/lib/librte_jobstats/rte_jobstats.c
index 2eaac0c..b603125 100644
--- a/lib/librte_jobstats/rte_jobstats.c
+++ b/lib/librte_jobstats/rte_jobstats.c
@@ -170,6 +170,26 @@ rte_jobstats_start(struct rte_jobstats_context *ctx, 
struct rte_jobstats *job)
 }

 int
+rte_jobstats_abort(struct rte_jobstats *job)
+{
+   struct rte_jobstats_context *ctx;
+   uint64_t now, exec_time;
+
+   /* Some sanity check. */
+   if (unlikely(job == NULL || job->context == NULL))
+   return -EINVAL;
+
+   ctx = job->context;
+   now = get_time();
+   exec_time = now - ctx->state_time;
+   ADD_TIME_MIN_MAX(ctx, management, exec_time);
+   ctx->state_time = now;
+   job->context = NULL;
+
+   return 0;
+}
+
+int
 rte_jobstats_finish(struct rte_jobstats *job, int64_t job_value)
 {
struct rte_jobstats_context *ctx;
@@ -191,6 +211,7 @@ rte_jobstats_finish(struct rte_jobstats *job, int64_t 
job_value)
 * executed. */
now = get_time();
exec_time = now - ctx->state_time;
+   job->last_job_time = exec_time;
ADD_TIME_MIN_MAX(job, exec, exec_time);
ADD_TIME_MIN_MAX(ctx, exec, exec_time);

@@ -269,5 +290,6 @@ void
 rte_jobstats_reset(struct rte_jobstats *job)
 {
RESET_TIME_MIN_MAX(job, exec);
+   job->last_job_time = 0;
job->exec_cnt = 0;
 }
diff --git a/lib/librte_jobstats/rte_jobstats.h 
b/lib/librte_jobstats/rte_jobstats.h
index de6a89a..9995319 100644
--- a/lib/librte_jobstats/rte_jobstats.h
+++ b/lib/librte_jobstats/rte_jobstats.h
@@ -90,6 +90,9 @@ struct rte_jobstats {
uint64_t exec_cnt;
/**< Execute count. */

+   uint64_t last_job_time;
+   /**< Last job time */
+
char name[RTE_JOBSTATS_NAMESIZE];
/**< Name of this job */

@@ -237,6 +240,20 @@ int
 rte_jobstats_start(struct rte_jobstats_context *ctx, struct rte_jobstats *job);

 /**
+ * Mark that *job* finished its execution, but time of this work will be 
skipped
+ * and added to management time.
+ *
+ * @param job
+ *  Job object.
+ *
+ * @return
+ *  0 on success
+ *  -EINVAL if job is NULL or job was not started (it have no context).
+ */
+int
+rte_jobstats_abort(struct rte_jobstats *job);
+
+/**
  * Mark that *job* finished its execution. Context in which it was executing
  * will receive stat update. After this function call *job* object is ready to
  * be executed in other context.
diff --git a/lib/librte_jobstats/rte_jobstats_version.map 
b/lib/librte_jobstats/rte_jobstats_version.map
index cb01bfd..0ec0650 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -17,3 +17,10 @@ DPDK_2.0 {

local: *;
 };
+
+DPDK_2.3 {
+   global:
+
+   rte_jobstats_abort;
+
+} DPDK_2.0;
\ No newline at end of file
-- 1
1.9.1



[dpdk-dev] [PATCH v3 5/5] doc: modify release notes and deprecation notice for table and pipeline

2015-10-13 Thread Marcin Kerlin
The LIBABIVER number is incremented for table and pipeline libraries.
The release notes is updated and the deprecation announce is removed.

Signed-off-by: Maciej Gajdzica 
Acked-by: Cristian Dumitrescu 
---
 doc/guides/rel_notes/deprecation.rst | 3 ---
 doc/guides/rel_notes/release_2_2.rst | 6 --
 lib/librte_pipeline/Makefile | 2 +-
 lib/librte_pipeline/rte_pipeline_version.map | 8 
 lib/librte_table/Makefile| 2 +-
 5 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index fa55117..2bf2df4 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -53,9 +53,6 @@ Deprecation Notices
 * librte_table LPM: A new parameter to hold the table name will be added to
   the LPM table parameter structure.

-* librte_table: New functions for table entry bulk add/delete will be added
-  to the table operations structure.
-
 * librte_table hash: Key mask parameter will be added to the hash table
   parameter structure for 8-byte key and 16-byte key extendible bucket and
   LRU tables.
diff --git a/doc/guides/rel_notes/release_2_2.rst 
b/doc/guides/rel_notes/release_2_2.rst
index 5687676..b46d2ae 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -98,6 +98,8 @@ ABI Changes

 * The LPM structure is changed. The deprecated field mem_location is removed.

+* Added functions add/delete bulk to table and pipeline libraries.
+

 Shared Library Versions
 ---
@@ -122,7 +124,7 @@ The libraries prepended with a plus sign were incremented 
in this version.
+ librte_mbuf.so.2
  librte_mempool.so.1
  librte_meter.so.1
- librte_pipeline.so.1
+   + librte_pipeline.so.2
  librte_pmd_bond.so.1
+ librte_pmd_ring.so.2
  librte_port.so.1
@@ -130,6 +132,6 @@ The libraries prepended with a plus sign were incremented 
in this version.
  librte_reorder.so.1
  librte_ring.so.1
  librte_sched.so.1
- librte_table.so.1
+   + librte_table.so.2
  librte_timer.so.1
  librte_vhost.so.1
diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index 15e406b..1166d3c 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)

 EXPORT_MAP := rte_pipeline_version.map

-LIBABIVER := 1
+LIBABIVER := 2

 #
 # all source are stored in SRCS-y
diff --git a/lib/librte_pipeline/rte_pipeline_version.map 
b/lib/librte_pipeline/rte_pipeline_version.map
index 8f25d0f..4cc86f6 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -29,3 +29,11 @@ DPDK_2.1 {
rte_pipeline_table_stats_read;

 } DPDK_2.0;
+
+DPDK_2.2 {
+   global:
+
+   rte_pipeline_table_entry_add_bulk;
+   rte_pipeline_table_entry_delete_bulk;
+
+} DPDK_2.1;
diff --git a/lib/librte_table/Makefile b/lib/librte_table/Makefile
index c5b3eaf..7f02af3 100644
--- a/lib/librte_table/Makefile
+++ b/lib/librte_table/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)

 EXPORT_MAP := rte_table_version.map

-LIBABIVER := 1
+LIBABIVER := 2

 #
 # all source are stored in SRCS-y
-- 
1.9.1

--
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

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




[dpdk-dev] [PATCH v3 4/5] ip_pipline: added cli commands for bulk add/delete to firewall pipeline

2015-10-13 Thread Marcin Kerlin
Added two new cli commands to firewall pipeline. Commands bulk add and
bulk delete takes as argument a file with rules to add/delete. The file
is parsed, and then rules are passed to backend functions which
add/delete records from pipeline tables.

Signed-off-by: Maciej Gajdzica 
Acked-by: Cristian Dumitrescu 
---
 examples/ip_pipeline/pipeline/pipeline_firewall.c  | 858 +
 examples/ip_pipeline/pipeline/pipeline_firewall.h  |  14 +
 .../ip_pipeline/pipeline/pipeline_firewall_be.c| 157 
 .../ip_pipeline/pipeline/pipeline_firewall_be.h|  38 +
 4 files changed, 1067 insertions(+)

diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c 
b/examples/ip_pipeline/pipeline/pipeline_firewall.c
index f6924ab..4137923 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
@@ -51,6 +51,8 @@
 #include "pipeline_common_fe.h"
 #include "pipeline_firewall.h"

+#define BUF_SIZE   1024
+
 struct app_pipeline_firewall_rule {
struct pipeline_firewall_key key;
int32_t priority;
@@ -73,6 +75,18 @@ struct app_pipeline_firewall {
void *default_rule_entry_ptr;
 };

+struct app_pipeline_add_bulk_params {
+   struct pipeline_firewall_key *keys;
+   uint32_t n_keys;
+   uint32_t *priorities;
+   uint32_t *port_ids;
+};
+
+struct app_pipeline_del_bulk_params {
+   struct pipeline_firewall_key *keys;
+   uint32_t n_keys;
+};
+
 static void
 print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
 {
@@ -256,6 +270,358 @@ app_pipeline_firewall_key_check_and_normalize(struct 
pipeline_firewall_key *key)
}
 }

+static int
+app_pipeline_add_bulk_parse_file(char *filename,
+   struct app_pipeline_add_bulk_params *params)
+{
+   FILE *f;
+   char file_buf[BUF_SIZE];
+   uint32_t i;
+   int status = 0;
+
+   f = fopen(filename, "r");
+   if (f == NULL)
+   return -1;
+
+   params->n_keys = 0;
+   while (fgets(file_buf, BUF_SIZE, f) != NULL)
+   params->n_keys++;
+   rewind(f);
+
+   if (params->n_keys == 0) {
+   status = -1;
+   goto end;
+   }
+
+   params->keys = rte_malloc(NULL,
+   params->n_keys * sizeof(struct pipeline_firewall_key),
+   RTE_CACHE_LINE_SIZE);
+   if (params->keys == NULL) {
+   status = -1;
+   goto end;
+   }
+
+   params->priorities = rte_malloc(NULL,
+   params->n_keys * sizeof(uint32_t),
+   RTE_CACHE_LINE_SIZE);
+   if (params->priorities == NULL) {
+   status = -1;
+   goto end;
+   }
+
+   params->port_ids = rte_malloc(NULL,
+   params->n_keys * sizeof(uint32_t),
+   RTE_CACHE_LINE_SIZE);
+   if (params->port_ids == NULL) {
+   status = -1;
+   goto end;
+   }
+
+   i = 0;
+   while (fgets(file_buf, BUF_SIZE, f) != NULL) {
+   char *str;
+
+   str = strtok(file_buf, " ");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->priorities[i] = atoi(str);
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
+
+   str = strtok(NULL, " ");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
+
+   str = strtok(NULL, " .");
+   if (str == NULL) {
+   status = -1;
+   goto end;
+   }
+   params->keys[i].key.ipv4_5tuple.dst_ip |= 

[dpdk-dev] [PATCH v3 3/5] test_table: added check for bulk add/delete to acl table unit test

2015-10-13 Thread Marcin Kerlin
Added to acl table unit test check for bulk add and bulk delete.

Signed-off-by: Maciej Gajdzica 
Acked-by: Cristian Dumitrescu 
---
 app/test/test_table_acl.c | 166 ++
 1 file changed, 166 insertions(+)

diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
index e4e9b9c..fe8e545 100644
--- a/app/test/test_table_acl.c
+++ b/app/test/test_table_acl.c
@@ -253,6 +253,94 @@ parse_cb_ipv4_rule(char *str, struct 
rte_table_acl_rule_add_params *v)
return 0;
 }

+static int
+parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
+{
+   int i, rc;
+   char *s, *sp, *in[CB_FLD_NUM];
+   static const char *dlm = " \t\n";
+
+   /*
+   ** Skip leading '@'
+   */
+   if (strchr(str, '@') != str)
+   return -EINVAL;
+
+   s = str + 1;
+
+   /*
+   * Populate the 'in' array with the location of each
+   * field in the string we're parsing
+   */
+   for (i = 0; i != DIM(in); i++) {
+   in[i] = strtok_r(s, dlm, );
+   if (in[i] == NULL)
+   return -EINVAL;
+   s = NULL;
+   }
+
+   /* Parse x.x.x.x/x */
+   rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
+   >field_value[SRC_FIELD_IPV4].value.u32,
+   >field_value[SRC_FIELD_IPV4].mask_range.u32);
+   if (rc != 0) {
+   RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n",
+   in[CB_FLD_SRC_ADDR]);
+   return rc;
+   }
+
+   printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
+   v->field_value[SRC_FIELD_IPV4].mask_range.u32);
+
+   /* Parse x.x.x.x/x */
+   rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
+   >field_value[DST_FIELD_IPV4].value.u32,
+   >field_value[DST_FIELD_IPV4].mask_range.u32);
+   if (rc != 0) {
+   RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n",
+   in[CB_FLD_DST_ADDR]);
+   return rc;
+   }
+
+   printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
+   v->field_value[DST_FIELD_IPV4].mask_range.u32);
+   /* Parse n:n */
+   rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
+   >field_value[SRCP_FIELD_IPV4].value.u16,
+   >field_value[SRCP_FIELD_IPV4].mask_range.u16);
+   if (rc != 0) {
+   RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n",
+   in[CB_FLD_SRC_PORT_RANGE]);
+   return rc;
+   }
+
+   printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
+   v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
+   /* Parse n:n */
+   rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
+   >field_value[DSTP_FIELD_IPV4].value.u16,
+   >field_value[DSTP_FIELD_IPV4].mask_range.u16);
+   if (rc != 0) {
+   RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n",
+   in[CB_FLD_DST_PORT_RANGE]);
+   return rc;
+   }
+
+   printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
+   v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
+   /* parse 0/0xnn */
+   GET_CB_FIELD(in[CB_FLD_PROTO],
+   v->field_value[PROTO_FIELD_IPV4].value.u8,
+   0, UINT8_MAX, '/');
+   GET_CB_FIELD(in[CB_FLD_PROTO],
+   v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
+   0, UINT8_MAX, 0);
+
+   printf("V=%u, mask=%u\n",
+   (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
+   v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
+   return 0;
+}

 /*
  * The format for these rules DO NOT need the port ranges to be
@@ -393,6 +481,84 @@ setup_acl_pipeline(void)
}
}

+   /* Add bulk entries to tables */
+   for (i = 0; i < N_PORTS; i++) {
+   struct rte_table_acl_rule_add_params keys[5];
+   struct rte_pipeline_table_entry entries[5];
+   struct rte_table_acl_rule_add_params *key_array[5];
+   struct rte_pipeline_table_entry *table_entries[5];
+   int key_found[5];
+   struct rte_pipeline_table_entry *table_entries_ptr[5];
+   struct rte_pipeline_table_entry entries_ptr[5];
+
+   parser = parse_cb_ipv4_rule;
+   for (n = 0; n < 5; n++) {
+   memset([n], 0, sizeof(struct 
rte_table_acl_rule_add_params));
+   key_array[n] = [n];
+
+   snprintf(line, sizeof(line), "%s", lines[n]);
+   printf("PARSING [%s]\n", line);
+
+   ret = parser(line, [n]);
+   if (ret != 0) {
+   RTE_LOG(ERR, PIPELINE,
+   "line %u: 

[dpdk-dev] [PATCH v3 2/5] pipeline: added bulk add/delete functions for table

2015-10-13 Thread Marcin Kerlin
Added functions for adding/deleting multiple records to table owned by
pipeline.

Signed-off-by: Maciej Gajdzica 
Signed-off-by: Marcin Kerlin 
Acked-by: Cristian Dumitrescu 
---
 lib/librte_pipeline/rte_pipeline.c | 106 +
 lib/librte_pipeline/rte_pipeline.h |  64 ++
 2 files changed, 170 insertions(+)

diff --git a/lib/librte_pipeline/rte_pipeline.c 
b/lib/librte_pipeline/rte_pipeline.c
index bd700d2..56022f4 100644
--- a/lib/librte_pipeline/rte_pipeline.c
+++ b/lib/librte_pipeline/rte_pipeline.c
@@ -587,6 +587,112 @@ rte_pipeline_table_entry_delete(struct rte_pipeline *p,
return (table->ops.f_delete)(table->h_table, key, key_found, entry);
 }

+int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
+   uint32_t table_id,
+   void **keys,
+   struct rte_pipeline_table_entry **entries,
+   uint32_t n_keys,
+   int *key_found,
+   struct rte_pipeline_table_entry **entries_ptr)
+{
+   struct rte_table *table;
+   uint32_t i;
+
+   /* Check input arguments */
+   if (p == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: pipeline parameter is NULL\n",
+   __func__);
+   return -EINVAL;
+   }
+
+   if (keys == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: keys parameter is NULL\n", 
__func__);
+   return -EINVAL;
+   }
+
+   if (entries == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: entries parameter is NULL\n",
+   __func__);
+   return -EINVAL;
+   }
+
+   if (table_id >= p->num_tables) {
+   RTE_LOG(ERR, PIPELINE,
+   "%s: table_id %d out of range\n", __func__, table_id);
+   return -EINVAL;
+   }
+
+   table = >tables[table_id];
+
+   if (table->ops.f_add_bulk == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: f_add_bulk function pointer NULL\n",
+   __func__);
+   return -EINVAL;
+   }
+
+   for (i = 0; i < n_keys; i++) {
+   if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
+   table->table_next_id_valid &&
+   (entries[i]->table_id != table->table_next_id)) {
+   RTE_LOG(ERR, PIPELINE,
+   "%s: Tree-like topologies not allowed\n", 
__func__);
+   return -EINVAL;
+   }
+   }
+
+   /* Add entry */
+   for (i = 0; i < n_keys; i++) {
+   if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
+   (table->table_next_id_valid == 0)) {
+   table->table_next_id = entries[i]->table_id;
+   table->table_next_id_valid = 1;
+   }
+   }
+
+   return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
+   n_keys, key_found, (void **) entries_ptr);
+}
+
+int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
+   uint32_t table_id,
+   void **keys,
+   uint32_t n_keys,
+   int *key_found,
+   struct rte_pipeline_table_entry **entries)
+{
+   struct rte_table *table;
+
+   /* Check input arguments */
+   if (p == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: pipeline parameter NULL\n",
+   __func__);
+   return -EINVAL;
+   }
+
+   if (keys == NULL) {
+   RTE_LOG(ERR, PIPELINE, "%s: key parameter is NULL\n",
+   __func__);
+   return -EINVAL;
+   }
+
+   if (table_id >= p->num_tables) {
+   RTE_LOG(ERR, PIPELINE,
+   "%s: table_id %d out of range\n", __func__, table_id);
+   return -EINVAL;
+   }
+
+   table = >tables[table_id];
+
+   if (table->ops.f_delete_bulk == NULL) {
+   RTE_LOG(ERR, PIPELINE,
+   "%s: f_delete function pointer NULL\n", __func__);
+   return -EINVAL;
+   }
+
+   return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, 
key_found,
+   (void **) entries);
+}
+
 /*
  * Port
  *
diff --git a/lib/librte_pipeline/rte_pipeline.h 
b/lib/librte_pipeline/rte_pipeline.h
index 59e0710..5459324 100644
--- a/lib/librte_pipeline/rte_pipeline.h
+++ b/lib/librte_pipeline/rte_pipeline.h
@@ -466,6 +466,70 @@ int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
struct rte_pipeline_table_entry *entry);

 /**
+ * Pipeline table entry add bulk
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param table_id
+ *   Table ID (returned by previous invocation of pipeline table create)
+ * @param keys
+ *   Array containing table entry keys
+ * 

[dpdk-dev] [PATCH v3 1/5] table: added bulk add/delete functions for table

2015-10-13 Thread Marcin Kerlin
New functions prototypes for bulk add/delete added to table API. New
functions allows adding/deleting multiple records with single function
call. For now those functions are implemented only for ACL table. For
other tables these function pointers are set to NULL.

Signed-off-by: Maciej Gajdzica 
Acked-by: Cristian Dumitrescu 
---
 lib/librte_table/rte_table.h|  85 -
 lib/librte_table/rte_table_acl.c| 309 
 lib/librte_table/rte_table_array.c  |   2 +
 lib/librte_table/rte_table_hash_ext.c   |   4 +
 lib/librte_table/rte_table_hash_key16.c |   4 +
 lib/librte_table/rte_table_hash_key32.c |   4 +
 lib/librte_table/rte_table_hash_key8.c  |   8 +
 lib/librte_table/rte_table_hash_lru.c   |   4 +
 lib/librte_table/rte_table_lpm.c|   2 +
 lib/librte_table/rte_table_lpm_ipv6.c   |   2 +
 lib/librte_table/rte_table_stub.c   |   2 +
 11 files changed, 420 insertions(+), 6 deletions(-)

diff --git a/lib/librte_table/rte_table.h b/lib/librte_table/rte_table.h
index c13d40d..720514e 100644
--- a/lib/librte_table/rte_table.h
+++ b/lib/librte_table/rte_table.h
@@ -154,6 +154,77 @@ typedef int (*rte_table_op_entry_delete)(
void *entry);

 /**
+ * Lookup table entry add bulk
+ *
+ * @param table
+ *   Handle to lookup table instance
+ * @param key
+ *   Array containing lookup keys
+ * @param entries
+ *   Array containing data to be associated with each key. Every item in the
+ *   array has to point to a valid memory buffer where the first entry_size
+ *   bytes (table create parameter) are populated with the data.
+ * @param n_keys
+ *   Number of keys to add
+ * @param key_found
+ *   After successful invocation, key_found for every item in the array is set
+ *   to a value different than 0 if the current key is already present in the
+ *   table and to 0 if not. This pointer has to be set to a valid memory
+ *   location before the table entry add function is called.
+ * @param entries_ptr
+ *   After successful invocation, array *entries_ptr stores the handle to the
+ *   table entry containing the data associated with every key. This handle can
+ *   be used to perform further read-write accesses to this entry. This handle
+ *   is valid until the key is deleted from the table or the same key is
+ *   re-added to the table, typically to associate it with different data. This
+ *   pointer has to be set to a valid memory location before the function is
+ *   called.
+ * @return
+ *   0 on success, error code otherwise
+ */
+typedef int (*rte_table_op_entry_add_bulk)(
+   void *table,
+   void **keys,
+   void **entries,
+   uint32_t n_keys,
+   int *key_found,
+   void **entries_ptr);
+
+/**
+ * Lookup table entry delete bulk
+ *
+ * @param table
+ *   Handle to lookup table instance
+ * @param key
+ *   Array containing lookup keys
+ * @param n_keys
+ *   Number of keys to delete
+ * @param key_found
+ *   After successful invocation, key_found for every item in the array is set
+ *   to a value different than 0if the current key was present in the table
+ *   before the delete operation was performed and to 0 if not. This pointer
+ *   has to be set to a valid memory location before the table entry delete
+ *   function is called.
+ * @param entries
+ *   If entries pointer is NULL, this pointer is ignored for every entry found.
+ *   Else, after successful invocation, if specific key is found in the table
+ *   (key_found is different than 0 for this item after function call is
+ *   completed) and item of entry array points to a valid buffer (entry is set
+ *   to a value different than NULL before the function is called), then the
+ *   first entry_size bytes (table create parameter) in *entry store a copy of
+ *   table entry that contained the data associated with the current key before
+ *   the key was deleted.
+ * @return
+ *   0 on success, error code otherwise
+ */
+typedef int (*rte_table_op_entry_delete_bulk)(
+   void *table,
+   void **keys,
+   uint32_t n_keys,
+   int *key_found,
+   void **entries);
+
+/**
  * Lookup table lookup
  *
  * @param table
@@ -213,12 +284,14 @@ typedef int (*rte_table_op_stats_read)(

 /** Lookup table interface defining the lookup table operation */
 struct rte_table_ops {
-   rte_table_op_create f_create;   /**< Create */
-   rte_table_op_free f_free;   /**< Free */
-   rte_table_op_entry_add f_add;   /**< Entry add */
-   rte_table_op_entry_delete f_delete; /**< Entry delete */
-   rte_table_op_lookup f_lookup;   /**< Lookup */
-   rte_table_op_stats_read f_stats;/**< Stats */
+   rte_table_op_create f_create; /**< Create */
+   rte_table_op_free f_free; /**< Free */
+   rte_table_op_entry_add f_add; /**< Entry add */
+   rte_table_op_entry_delete f_delete;   /**< Entry delete */
+   rte_table_op_entry_add_bulk