Re: [dpdk-dev] [PATCH v6 1/2] eal: add uevent monitor for hot plug

2017-12-25 Thread Guo, Jia



On 11/2/2017 5:41 AM, Stephen Hemminger wrote:

On Thu,  2 Nov 2017 04:16:44 +0800
Jeff Guo  wrote:


+
+static int
+dev_uev_parse(const char *buf, struct rte_eal_uevent *event)
+{
+   char action[RTE_EAL_UEVENT_MSG_LEN];
+   char subsystem[RTE_EAL_UEVENT_MSG_LEN];
+   char dev_path[RTE_EAL_UEVENT_MSG_LEN];
+   char pci_slot_name[RTE_EAL_UEVENT_MSG_LEN];
+   int i = 0;
+
+   memset(action, 0, RTE_EAL_UEVENT_MSG_LEN);
+   memset(subsystem, 0, RTE_EAL_UEVENT_MSG_LEN);
+   memset(dev_path, 0, RTE_EAL_UEVENT_MSG_LEN);
+   memset(pci_slot_name, 0, RTE_EAL_UEVENT_MSG_LEN);
+
+   while (i < RTE_EAL_UEVENT_MSG_LEN) {

Might be simpler, safer, clearer to use rte_strsplit here.

And then have a table of fields rather than open coding the parsing.

i think your  point must be make sense , but it hardly use rte_strsplit 
here , because the tokens which need to parse is splited by '\0', even 
more multi adjacent '\0' in the buf witch come from the uevent massage.

f+  for (; i < RTE_EAL_UEVENT_MSG_LEN; i++) {
+   if (*buf)
+   break;
+   buf++;
+   }
+   if (!strncmp(buf, "libudev", 7)) {
+   buf += 7;
+   i += 7;
+   event->group = UEV_MONITOR_UDEV;
+   }
+   if (!strncmp(buf, "ACTION=", 7)) {
+   buf += 7;
+   i += 7;
+   snprintf(action, sizeof(action), "%s", buf);
+   } else if (!strncmp(buf, "DEVPATH=", 8)) {
+   buf += 8;
+   i += 8;
+   snprintf(dev_path, sizeof(dev_path), "%s", buf);
+   } else if (!strncmp(buf, "SUBSYSTEM=", 10)) {
+   buf += 10;
+   i += 10;
+   snprintf(subsystem, sizeof(subsystem), "%s", buf);
+   } else if (!strncmp(buf, "PCI_SLOT_NAME=", 14)) {
+   buf += 14;
+   i += 14;
+   snprintf(pci_slot_name, sizeof(subsystem), "%s", buf);
+   }
+   for (; i < RTE_EAL_UEVENT_MSG_LEN; i++) {
+   if (*buf == '\0')
+   break;
+   buf++;
+   }
+   }
+
+   if (!strncmp(subsystem, "pci", 3))
+   event->subsystem = UEV_SUBSYSTEM_PCI;
+   if (!strncmp(action, "add", 3))
+   event->type = RTE_EAL_DEV_EVENT_ADD;
+   if (!strncmp(action, "remove", 6))
+   event->type = RTE_EAL_DEV_EVENT_REMOVE;
+   event->devname = pci_slot_name;
+
+   return 0;

Function always returns 0, why is it not void?




[dpdk-dev] [PATCH] lib/librte_vhost: remove redundant logic judgement

2017-12-25 Thread Zhiyong Yang
At the beginning of vring_translate, the code
if(!(dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) already judges
if IOMMU_PLATFORM is supported. The function vhost_iova_to_vva always
repeats the logic, __vhost_iova_to_vva can be used directly to avoid it
here.

Signed-off-by: Zhiyong Yang 
---
 lib/librte_vhost/vhost.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 4f8b73a09..bb615fd2a 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -157,7 +157,7 @@ vring_translate(struct virtio_net *dev, struct 
vhost_virtqueue *vq)
goto out;
 
size = sizeof(struct vring_desc) * vq->size;
-   vq->desc = (struct vring_desc *)(uintptr_t)vhost_iova_to_vva(dev, vq,
+   vq->desc = (struct vring_desc *)(uintptr_t)__vhost_iova_to_vva(dev, vq,
vq->ring_addrs.desc_user_addr,
size, VHOST_ACCESS_RW);
if (!vq->desc)
@@ -165,7 +165,8 @@ vring_translate(struct virtio_net *dev, struct 
vhost_virtqueue *vq)
 
size = sizeof(struct vring_avail);
size += sizeof(uint16_t) * vq->size;
-   vq->avail = (struct vring_avail *)(uintptr_t)vhost_iova_to_vva(dev, vq,
+   vq->avail = (struct vring_avail *)(uintptr_t)__vhost_iova_to_vva(dev,
+   vq,
vq->ring_addrs.avail_user_addr,
size, VHOST_ACCESS_RW);
if (!vq->avail)
@@ -173,7 +174,7 @@ vring_translate(struct virtio_net *dev, struct 
vhost_virtqueue *vq)
 
size = sizeof(struct vring_used);
size += sizeof(struct vring_used_elem) * vq->size;
-   vq->used = (struct vring_used *)(uintptr_t)vhost_iova_to_vva(dev, vq,
+   vq->used = (struct vring_used *)(uintptr_t)__vhost_iova_to_vva(dev, vq,
vq->ring_addrs.used_user_addr,
size, VHOST_ACCESS_RW);
if (!vq->used)
-- 
2.13.3



[dpdk-dev] [PATCH v8] net/i40e: determine number of queues per VF during run time

2017-12-25 Thread Wei Dai
Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e PF is
:bb.cc, with the EAL parameter -w :bb.cc,queue-num-per-vf=8 ,
the number of queues per VF created from this PF is 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai 
Acked-by: Konstantin Ananyev 
---
v8:
As v7 patch has been accepted into dpdk-next-net-intel, this patch
is based on v7 patch.
add description in i40e document
fix the last member of valid_keys[] for rte_kvargs_parse( )
add RTE_PMD_REGISTER_PARAM_STRING for this feature
v7:
use the macro instead of natural number
correct git log message as the EAL parameter is only valid for PF
v6:
fix a small bug when detecting end character of strtoul
v5:
fix git log message and WARNING of coding stype
v4:
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
v3:
fix WARNING of coding style issues from checkpa...@dpdk.org
v2:
fix WARNING of coding style issues from checkpa...@dpdk.org
---
 doc/guides/nics/i40e.rst   | 12 
 drivers/net/i40e/i40e_ethdev.c |  4 +++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 2507d5f..68ae8eb 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -117,10 +117,6 @@ Please note that enabling debugging options may affect 
system performance.
 
 - ``CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF`` (default ``4``)
 
-  Number of queues reserved for each SR-IOV VF.
-
-- ``CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM`` (default ``4``)
-
   Number of queues reserved for each VMDQ Pool.
 
 - ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` (default ``-1``)
@@ -374,6 +370,14 @@ configuration passed on the EAL command line.
 The floating VEB functionality requires a NIC firmware version of 5.0
 or greater.
 
+Number of Queues per VF
+~~~
+
+The number of queue per VF is determined by its host PF. If the PCI address of
+an i40e PF is :bb.cc, the number of queues per VF can be configured with
+EAL paramter like -w :bb.cc,queue-num-per-vf=n. The value n can be 1, 2, 4,
+8 or 16. If no such paramter is configured, the number of queues per VF is 4
+by default.
 
 Limitations or Known issues
 ---
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 9916f49..24dae37 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3973,6 +3973,8 @@ i40e_get_cap(struct i40e_hw *hw)
 
 #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF   4
 #define QUEUE_NUM_PER_VF_ARG   "queue-num-per-vf"
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,QUEUE_NUM_PER_VF_ARG 
"=1|2|4|8|16");
+
 static int i40e_pf_parse_vf_queue_number_handler(const char *key,
const char *value,
void *opaque)
@@ -4005,7 +4007,7 @@ static int i40e_pf_parse_vf_queue_number_handler(const 
char *key,
 
 static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
 {
-   static const char * const valid_keys[] = {QUEUE_NUM_PER_VF_ARG, ""};
+   static const char * const valid_keys[] = {QUEUE_NUM_PER_VF_ARG, NULL};
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct rte_kvargs *kvlist;
 
-- 
2.7.5



Re: [dpdk-dev] [PATCH v6 1/2] eal: add uevent monitor for hot plug

2017-12-25 Thread Stephen Hemminger
On Thu,  2 Nov 2017 04:16:44 +0800
Jeff Guo  wrote:

> +int
> +rte_dev_bind_driver(const char *dev_name, const char *drv_type) {

Bracket left after declaration.


> + snprintf(drv_override_path, sizeof(drv_override_path),
> + "/sys/bus/pci/devices/%s/driver_override", dev_name);
> +
> + /* specify the driver for a device by writing to driver_override */
> + drv_override_fd = open(drv_override_path, O_WRONLY);
> + if (drv_override_fd < 0) {
> + RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
> + drv_override_path, strerror(errno));
> + goto err;
> + }


You should not have dev functions that assume PCI. Please split into common
and bus specific code.



> +static int
> +dev_uev_parse(const char *buf, struct rte_eal_uevent *event)
> +{
> + char action[RTE_EAL_UEVENT_MSG_LEN];
> + char subsystem[RTE_EAL_UEVENT_MSG_LEN];
> + char dev_path[RTE_EAL_UEVENT_MSG_LEN];
> + char pci_slot_name[RTE_EAL_UEVENT_MSG_LEN];
> + int i = 0;
> +
> + memset(action, 0, RTE_EAL_UEVENT_MSG_LEN);
> + memset(subsystem, 0, RTE_EAL_UEVENT_MSG_LEN);
> + memset(dev_path, 0, RTE_EAL_UEVENT_MSG_LEN);
> + memset(pci_slot_name, 0, RTE_EAL_UEVENT_MSG_LEN);
> +
> + while (i < RTE_EAL_UEVENT_MSG_LEN) {
> + for (; i < RTE_EAL_UEVENT_MSG_LEN; i++) {
> + if (*buf)
> + break;
> + buf++;
> + }
> + if (!strncmp(buf, "libudev", 7)) {
> + buf += 7;
> + i += 7;
> + event->group = UEV_MONITOR_UDEV;
> + }
> + if (!strncmp(buf, "ACTION=", 7)) {
> + buf += 7;
> + i += 7;
> + snprintf(action, sizeof(action), "%s", buf);

Why snprintf rather than strncpy?


> + } else if (!strncmp(buf, "DEVPATH=", 8)) {
> + buf += 8;
> + i += 8;
> + snprintf(dev_path, sizeof(dev_path), "%s", buf);
> + } else if (!strncmp(buf, "SUBSYSTEM=", 10)) {
> + buf += 10;
> + i += 10;
> + snprintf(subsystem, sizeof(subsystem), "%s", buf);
> + } else if (!strncmp(buf, "PCI_SLOT_NAME=", 14)) {
> + buf += 14;
> + i += 14;
> + snprintf(pci_slot_name, sizeof(subsystem), "%s", buf);
> + }
> + for (; i < RTE_EAL_UEVENT_MSG_LEN; i++) {
> + if (*buf == '\0')
> + break;
> + buf++;
> + }
> + }
> +
> + if (!strncmp(subsystem, "pci", 3))
> + event->subsystem = UEV_SUBSYSTEM_PCI;
> + if (!strncmp(action, "add", 3))
> + event->type = RTE_EAL_DEV_EVENT_ADD;
> + if (!strncmp(action, "remove", 6))
> + event->type = RTE_EAL_DEV_EVENT_REMOVE;
> + event->devname = pci_slot_name;

Why do you need to first capture the strings, then set state variables?
Instead why not update event->xxx directly?


[dpdk-dev] [PATCH v3 02/11] eventdev: add API to perform self test

2017-12-25 Thread Pavan Nikhilesh
Add API to perform self test on the underlying event device driver.

Signed-off-by: Pavan Nikhilesh 
Acked-by: Harry van Haaren 
---
 lib/librte_eventdev/rte_eventdev.c   | 10 ++
 lib/librte_eventdev/rte_eventdev.h   | 12 
 lib/librte_eventdev/rte_eventdev_pmd.h   | 11 +++
 lib/librte_eventdev/rte_eventdev_version.map |  6 ++
 4 files changed, 39 insertions(+)

diff --git a/lib/librte_eventdev/rte_eventdev.c 
b/lib/librte_eventdev/rte_eventdev.c
index 035bd0017..85496e575 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -1114,6 +1114,16 @@ int rte_event_dev_xstats_reset(uint8_t dev_id,
return -ENOTSUP;
 }
 
+int rte_event_dev_selftest(uint8_t dev_id)
+{
+   RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+   struct rte_eventdev *dev = &rte_eventdevs[dev_id];
+
+   if (dev->dev_ops->dev_selftest != NULL)
+   return (*dev->dev_ops->dev_selftest)();
+   return -ENOTSUP;
+}
+
 int
 rte_event_dev_start(uint8_t dev_id)
 {
diff --git a/lib/librte_eventdev/rte_eventdev.h 
b/lib/librte_eventdev/rte_eventdev.h
index 1bbea57db..9201a5af8 100644
--- a/lib/librte_eventdev/rte_eventdev.h
+++ b/lib/librte_eventdev/rte_eventdev.h
@@ -1787,6 +1787,18 @@ rte_event_dev_xstats_reset(uint8_t dev_id,
   const uint32_t ids[],
   uint32_t nb_ids);
 
+/**
+ * Trigger the eventdev self test.
+ *
+ * @param dev_id
+ *   The identifier of the device
+ * @return
+ *   - 0: Selftest successful
+ *   - -ENOTSUP if the device doesn't support selftest
+ *   - other values < 0 on failure.
+ */
+int rte_event_dev_selftest(uint8_t dev_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eventdev/rte_eventdev_pmd.h 
b/lib/librte_eventdev/rte_eventdev_pmd.h
index 6ed40cd38..8bf0462f6 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd.h
@@ -603,6 +603,14 @@ typedef int (*eventdev_eth_rx_adapter_stats_get)
 typedef int (*eventdev_eth_rx_adapter_stats_reset)
(const struct rte_eventdev *dev,
const struct rte_eth_dev *eth_dev);
+/**
+ * Start eventdev selftest.
+ *
+ * @return
+ *   Return 0 on success.
+ */
+typedef int (*eventdev_selftest)
+   (void);
 
 /** Event device operations function pointer table */
 struct rte_eventdev_ops {
@@ -658,6 +666,9 @@ struct rte_eventdev_ops {
/**< Get ethernet Rx stats */
eventdev_eth_rx_adapter_stats_reset eth_rx_adapter_stats_reset;
/**< Reset ethernet Rx stats */
+
+   eventdev_selftest dev_selftest;
+   /**< Start eventdev Selftest */
 };
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_version.map 
b/lib/librte_eventdev/rte_eventdev_version.map
index 108ae61fb..2aef470b5 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -68,3 +68,9 @@ DPDK_17.11 {
rte_event_eth_rx_adapter_stop;
 
 } DPDK_17.08;
+
+DPDK_18.02 {
+   global:
+
+   rte_event_dev_selftest;
+} DPDK_17.11;
-- 
2.14.1



[dpdk-dev] [PATCH v3 04/11] event/octeontx: modify octeontx eventdev test

2017-12-25 Thread Pavan Nikhilesh
Modify test_eventdev_octeontx to be standalone selftest independent of
test framework.

Signed-off-by: Pavan Nikhilesh 
---
 drivers/event/octeontx/octeontx_evdev_selftest.c | 427 +--
 1 file changed, 234 insertions(+), 193 deletions(-)

diff --git a/drivers/event/octeontx/octeontx_evdev_selftest.c 
b/drivers/event/octeontx/octeontx_evdev_selftest.c
index 8fddb4fd2..3877bca4a 100644
--- a/drivers/event/octeontx/octeontx_evdev_selftest.c
+++ b/drivers/event/octeontx/octeontx_evdev_selftest.c
@@ -46,12 +46,21 @@
 #include 
 #include 
 #include 
+#include 
 
-#include "test.h"
+#include "ssovf_evdev.h"
 
 #define NUM_PACKETS (1 << 18)
 #define MAX_EVENTS  (16 * 1024)
 
+#define OCTEONTX_TEST_RUN(setup, teardown, test) \
+   octeontx_test_run(setup, teardown, test, #test)
+
+static int total;
+static int passed;
+static int failed;
+static int unsupported;
+
 static int evdev;
 static struct rte_mempool *eventdev_test_mempool;
 
@@ -79,11 +88,11 @@ static inline int
 seqn_list_update(int val)
 {
if (seqn_list_index >= NUM_PACKETS)
-   return TEST_FAILED;
+   return -1;
 
seqn_list[seqn_list_index++] = val;
rte_smp_wmb();
-   return TEST_SUCCESS;
+   return 0;
 }
 
 static inline int
@@ -93,11 +102,11 @@ seqn_list_check(int limit)
 
for (i = 0; i < limit; i++) {
if (seqn_list[i] != i) {
-   printf("Seqn mismatch %d %d\n", seqn_list[i], i);
-   return TEST_FAILED;
+   ssovf_log_dbg("Seqn mismatch %d %d", seqn_list[i], i);
+   return -1;
}
}
-   return TEST_SUCCESS;
+   return 0;
 }
 
 struct test_core_param {
@@ -114,20 +123,21 @@ testsuite_setup(void)
 
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
-   printf("%d: Eventdev %s not found - creating.\n",
+   ssovf_log_dbg("%d: Eventdev %s not found - creating.",
__LINE__, eventdev_name);
if (rte_vdev_init(eventdev_name, NULL) < 0) {
-   printf("Error creating eventdev %s\n", eventdev_name);
-   return TEST_FAILED;
+   ssovf_log_dbg("Error creating eventdev %s",
+   eventdev_name);
+   return -1;
}
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
-   printf("Error finding newly created eventdev\n");
-   return TEST_FAILED;
+   ssovf_log_dbg("Error finding newly created eventdev");
+   return -1;
}
}
 
-   return TEST_SUCCESS;
+   return 0;
 }
 
 static void
@@ -177,31 +187,34 @@ _eventdev_setup(int mode)
512, /* Use very small mbufs */
rte_socket_id());
if (!eventdev_test_mempool) {
-   printf("ERROR creating mempool\n");
-   return TEST_FAILED;
+   ssovf_log_dbg("ERROR creating mempool");
+   return -1;
}
 
ret = rte_event_dev_info_get(evdev, &info);
-   TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
-   TEST_ASSERT(info.max_num_events >= (int32_t)MAX_EVENTS,
-   "max_num_events=%d < max_events=%d",
-   info.max_num_events, MAX_EVENTS);
+   RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
+   if (!(info.max_num_events >= (int32_t)MAX_EVENTS)) {
+   ssovf_log_dbg("ERROR max_num_events=%d < max_events=%d",
+   info.max_num_events, MAX_EVENTS);
+   return -1;
+   }
 
devconf_set_default_sane_values(&dev_conf, &info);
if (mode == TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT)
dev_conf.event_dev_cfg |= RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT;
 
ret = rte_event_dev_configure(evdev, &dev_conf);
-   TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev");
+   RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev");
 
uint32_t queue_count;
-   TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
+   RTE_TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(evdev,
RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
&queue_count), "Queue count get failed");
 
if (mode == TEST_EVENTDEV_SETUP_PRIORITY) {
if (queue_count > 8) {
-   printf("test expects the unique priority per queue\n");
+   ssovf_log_dbg(
+   "test expects the unique priority per queue");
return -ENOTSUP;
}
 
@@ -216,35 +229,39 @@ _eventdev_setup(int mode)
 
ret = rte_event_queue_default_conf

[dpdk-dev] [PATCH v3 01/11] eal: add common test assert macros

2017-12-25 Thread Pavan Nikhilesh
Adding common test assertion macros for unit testing.
Taken from test/test.h.

Signed-off-by: Pavan Nikhilesh 
---

 v3 Changes:
  - add eventdev driver specific selftest to test/test

 v2 Changes:
  - remove duplications of test macros.
  - add selftest to test/test.
  - remove selftest devargs from sw eventdev.

 lib/librte_eal/common/Makefile   |  2 +-
 lib/librte_eal/common/include/rte_test.h | 97 
 2 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/include/rte_test.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 9effd0d45..eba1059f2 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -43,7 +43,7 @@ INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
-INC += rte_bitmap.h rte_vfio.h
+INC += rte_bitmap.h rte_vfio.h rte_test.h

 GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
 GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
diff --git a/lib/librte_eal/common/include/rte_test.h 
b/lib/librte_eal/common/include/rte_test.h
new file mode 100644
index 0..256117f79
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_test.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Cavium, Inc. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *  * Neither the name of Cavium, Inc nor the names of its
+ *contributors may be used to endorse or promote products derived
+ *from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_TEST_H_
+#define _RTE_TEST_H_
+
+#include 
+
+#define RTE_TEST_ASSERT(cond, msg, ...) do {  \
+   if (!(cond)) {\
+   RTE_LOG(DEBUG, EAL, "Test assert %s line %d failed: " \
+   msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
+   return -1;\
+   } \
+} while (0)
+
+#define RTE_TEST_ASSERT_EQUAL(a, b, msg, ...) do {\
+   if (!(a == b)) {  \
+   RTE_LOG(DEBUG, EAL, "Test assert %s line %d failed: " \
+   msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
+   return -1;\
+   } \
+} while (0)
+
+#define RTE_TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do {\
+   if (!(a != b)) {  \
+   RTE_LOG(DEBUG, EAL, "Test assert %s line %d failed: " \
+   msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
+   return -1;\
+   } \
+} while (0)
+
+#define RTE_TEST_ASSERT_SUCCESS(val, msg, ...) do {   \
+   typeof(val) _val = (val); \
+   if (!(_val == 0)) {   \
+   RTE_LOG(DEBUG, EAL,   \
+ 

[dpdk-dev] [PATCH v3 03/11] event/octeontx: move eventdev octeontx test to driver

2017-12-25 Thread Pavan Nikhilesh
Move octeontx eventdev specific test (test_eventdev_octeontx.c) to
driver/event/octeontx.

Signed-off-by: Pavan Nikhilesh 
---
 .../event/octeontx/octeontx_evdev_selftest.c | 0
 test/test/Makefile   | 1 -
 2 files changed, 1 deletion(-)
 rename test/test/test_eventdev_octeontx.c => 
drivers/event/octeontx/octeontx_evdev_selftest.c (100%)

diff --git a/test/test/test_eventdev_octeontx.c 
b/drivers/event/octeontx/octeontx_evdev_selftest.c
similarity index 100%
rename from test/test/test_eventdev_octeontx.c
rename to drivers/event/octeontx/octeontx_evdev_selftest.c
diff --git a/test/test/Makefile b/test/test/Makefile
index bb54c9808..87e3169d2 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -211,7 +211,6 @@ SRCS-y += test_eventdev.c
 SRCS-y += test_event_ring.c
 SRCS-y += test_event_eth_rx_adapter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += test_eventdev_sw.c
-SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += test_eventdev_octeontx.c
 endif
 
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
-- 
2.14.1



[dpdk-dev] [PATCH v3 05/11] event/octeontx: update octeontx eventdev selftest ops

2017-12-25 Thread Pavan Nikhilesh
Update octeontx eventdev ops to invoke selftest when application
invokes `rte_event_dev_selftest`.

Signed-off-by: Pavan Nikhilesh 
---
 drivers/event/octeontx/Makefile  | 3 ++-
 drivers/event/octeontx/ssovf_evdev.c | 2 ++
 drivers/event/octeontx/ssovf_evdev.h | 4 
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index fdf1b7385..1ad638574 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -42,7 +42,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
-LDLIBS += -lrte_bus_pci
+LDLIBS += -lrte_bus_pci -lrte_mempool -lrte_mbuf
 LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_octeontx_ssovf_version.map
@@ -54,6 +54,7 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += ssovf_worker.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += ssovf_evdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += octeontx_evdev_selftest.c
 
 ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
 CFLAGS_ssovf_worker.o += -fno-prefetch-loop-arrays
diff --git a/drivers/event/octeontx/ssovf_evdev.c 
b/drivers/event/octeontx/ssovf_evdev.c
index b80a6c0ae..0a96fbd7f 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -613,6 +613,8 @@ static const struct rte_eventdev_ops ssovf_ops = {
.eth_rx_adapter_start = ssovf_eth_rx_adapter_start,
.eth_rx_adapter_stop = ssovf_eth_rx_adapter_stop,
 
+   .dev_selftest = test_eventdev_octeontx,
+
.dump = ssovf_dump,
.dev_start= ssovf_start,
.dev_stop = ssovf_stop,
diff --git a/drivers/event/octeontx/ssovf_evdev.h 
b/drivers/event/octeontx/ssovf_evdev.h
index b093a3e73..72a980447 100644
--- a/drivers/event/octeontx/ssovf_evdev.h
+++ b/drivers/event/octeontx/ssovf_evdev.h
@@ -57,6 +57,9 @@
 #define ssovf_log_err(fmt, args...) \
RTE_LOG(ERR, EVENTDEV, "[%s] %s() " fmt "\n", \
RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD), __func__, ## args)
+#define ssovf_log_selftest(fmt, args...) \
+   RTE_LOG(INFO, EVENTDEV, "[%s] %s() " fmt "\n", \
+   RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD), __func__, ## args)
 
 #define SSO_MAX_VHGRP (64)
 #define SSO_MAX_VHWS  (32)
@@ -196,5 +199,6 @@ uint16_t ssows_deq_timeout_burst(void *port, struct 
rte_event ev[],
uint16_t nb_events, uint64_t timeout_ticks);
 void ssows_flush_events(struct ssows *ws, uint8_t queue_id);
 void ssows_reset(struct ssows *ws);
+int test_eventdev_octeontx(void);
 
 #endif /* __SSOVF_EVDEV_H__ */
-- 
2.14.1



[dpdk-dev] [PATCH v3 06/11] event/octeontx: add selftest to device arguments

2017-12-25 Thread Pavan Nikhilesh
Add selftest as a device argument that can be enabled by suppling
'self_test=1' as a vdev parameter

--vdev="event_octeontx,self_test=1"

The selftest is run after vdev creation is successfully
complete.

Signed-off-by: Pavan Nikhilesh 
---
 drivers/event/octeontx/Makefile  |  2 +-
 drivers/event/octeontx/ssovf_evdev.c | 43 
 drivers/event/octeontx/ssovf_evdev.h |  2 ++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index 1ad638574..bf45133f7 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -42,7 +42,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
-LDLIBS += -lrte_bus_pci -lrte_mempool -lrte_mbuf
+LDLIBS += -lrte_bus_pci -lrte_mempool -lrte_mbuf -lrte_kvargs
 LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_octeontx_ssovf_version.map
diff --git a/drivers/event/octeontx/ssovf_evdev.c 
b/drivers/event/octeontx/ssovf_evdev.c
index 0a96fbd7f..8c78b323a 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -593,6 +594,15 @@ ssovf_close(struct rte_eventdev *dev)
return 0;
 }
 
+static int
+ssovf_selftest(const char *key __rte_unused, const char *value,
+   void *opaque)
+{
+   int *flag = opaque;
+   *flag = !!atoi(value);
+   return 0;
+}
+
 /* Initialize and register event driver with DPDK Application */
 static const struct rte_eventdev_ops ssovf_ops = {
.dev_infos_get= ssovf_info_get,
@@ -630,7 +640,14 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev)
struct rte_eventdev *eventdev;
static int ssovf_init_once;
const char *name;
+   const char *params;
int ret;
+   int selftest = 0;
+
+   static const char *const args[] = {
+   SSOVF_SELFTEST_ARG,
+   NULL
+   };
 
name = rte_vdev_device_name(vdev);
/* More than one instance is not supported */
@@ -639,6 +656,30 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev)
return -EINVAL;
}
 
+   params = rte_vdev_device_args(vdev);
+   if (params != NULL && params[0] != '\0') {
+   struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
+
+   if (!kvlist) {
+   ssovf_log_info(
+   "Ignoring unsupported paramss supplied '%s'",
+   name);
+   } else {
+   int ret = rte_kvargs_process(kvlist,
+   SSOVF_SELFTEST_ARG,
+   ssovf_selftest, &selftest);
+   if (ret != 0) {
+   ssovf_log_err(
+   "%s: Error in selftest",
+   name);
+   rte_kvargs_free(kvlist);
+   return ret;
+   }
+   }
+
+   rte_kvargs_free(kvlist);
+   }
+
eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev),
rte_socket_id());
if (eventdev == NULL) {
@@ -689,6 +730,8 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev)
edev->max_event_ports);
 
ssovf_init_once = 1;
+   if (selftest)
+   test_eventdev_octeontx();
return 0;
 
 error:
diff --git a/drivers/event/octeontx/ssovf_evdev.h 
b/drivers/event/octeontx/ssovf_evdev.h
index 72a980447..018fbdfa5 100644
--- a/drivers/event/octeontx/ssovf_evdev.h
+++ b/drivers/event/octeontx/ssovf_evdev.h
@@ -117,6 +117,8 @@
 #define SSO_GRP_GET_PRIORITY  0x7
 #define SSO_GRP_SET_PRIORITY  0x8
 
+#define SSOVF_SELFTEST_ARG   ("selftest")
+
 /*
  * In Cavium OcteonTX SoC, all accesses to the device registers are
  * implictly strongly ordered. So, The relaxed version of IO operation is
-- 
2.14.1



[dpdk-dev] [PATCH v3 07/11] event/sw: move eventdev software test to driver

2017-12-25 Thread Pavan Nikhilesh
Move software eventdev specific test (test_eventdev_sw) to
driver/event/sw/.

Signed-off-by: Pavan Nikhilesh 
Acked-by: Harry van Haaren 
---
 test/test/test_eventdev_sw.c => drivers/event/sw/sw_evdev_selftest.c | 0
 test/test/Makefile   | 1 -
 2 files changed, 1 deletion(-)
 rename test/test/test_eventdev_sw.c => drivers/event/sw/sw_evdev_selftest.c 
(100%)

diff --git a/test/test/test_eventdev_sw.c b/drivers/event/sw/sw_evdev_selftest.c
similarity index 100%
rename from test/test/test_eventdev_sw.c
rename to drivers/event/sw/sw_evdev_selftest.c
diff --git a/test/test/Makefile b/test/test/Makefile
index 87e3169d2..c551ad964 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -210,7 +210,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
 SRCS-y += test_eventdev.c
 SRCS-y += test_event_ring.c
 SRCS-y += test_event_eth_rx_adapter.c
-SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += test_eventdev_sw.c
 endif
 
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
-- 
2.14.1



[dpdk-dev] [PATCH v3 08/11] event/sw: modify eventdev software test

2017-12-25 Thread Pavan Nikhilesh
Modify test_eventdev_sw to be standalone selftest independent of test
framework.

Signed-off-by: Pavan Nikhilesh 
Acked-by: Harry van Haaren 
---
 drivers/event/sw/sw_evdev_selftest.c | 70 ++--
 1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/event/sw/sw_evdev_selftest.c 
b/drivers/event/sw/sw_evdev_selftest.c
index 4108b00bf..0e84b2003 100644
--- a/drivers/event/sw/sw_evdev_selftest.c
+++ b/drivers/event/sw/sw_evdev_selftest.c
@@ -52,7 +52,7 @@
 #include 
 #include 
 
-#include "test.h"
+#include "sw_evdev.h"
 
 #define MAX_PORTS 16
 #define MAX_QIDS 16
@@ -3042,7 +3042,7 @@ worker_loopback(struct test *t, uint8_t 
disable_implicit_release)
 
 static struct rte_mempool *eventdev_func_mempool;
 
-static int
+int
 test_sw_eventdev(void)
 {
struct test *t = malloc(sizeof(struct test));
@@ -3053,25 +3053,25 @@ test_sw_eventdev(void)
 */
release_ev.op = RTE_EVENT_OP_RELEASE;
 
-   const char *eventdev_name = "event_sw0";
+   const char *eventdev_name = "event_sw";
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
printf("%d: Eventdev %s not found - creating.\n",
__LINE__, eventdev_name);
if (rte_vdev_init(eventdev_name, NULL) < 0) {
printf("Error creating eventdev\n");
-   return -1;
+   goto test_fail;
}
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
printf("Error finding newly created eventdev\n");
-   return -1;
+   goto test_fail;
}
}
 
if (rte_event_dev_service_id_get(evdev, &t->service_id) < 0) {
printf("Failed to get service ID for software event dev\n");
-   return -1;
+   goto test_fail;
}
 
rte_service_runstate_set(t->service_id, 1);
@@ -3088,7 +3088,7 @@ test_sw_eventdev(void)
rte_socket_id());
if (!eventdev_func_mempool) {
printf("ERROR creating mempool\n");
-   return -1;
+   goto test_fail;
}
}
t->mbuf_pool = eventdev_func_mempool;
@@ -3096,146 +3096,146 @@ test_sw_eventdev(void)
ret = test_single_directed_packet(t);
if (ret != 0) {
printf("ERROR - Single Directed Packet test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Directed Forward Credit test...\n");
ret = test_directed_forward_credits(t);
if (ret != 0) {
printf("ERROR - Directed Forward Credit test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Single Load Balanced Packet test...\n");
ret = single_packet(t);
if (ret != 0) {
printf("ERROR - Single Packet test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Unordered Basic test...\n");
ret = unordered_basic(t);
if (ret != 0) {
printf("ERROR -  Unordered Basic test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Ordered Basic test...\n");
ret = ordered_basic(t);
if (ret != 0) {
printf("ERROR -  Ordered Basic test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Burst Packets test...\n");
ret = burst_packets(t);
if (ret != 0) {
printf("ERROR - Burst Packets test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Load Balancing test...\n");
ret = load_balancing(t);
if (ret != 0) {
printf("ERROR - Load Balancing test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Prioritized Directed test...\n");
ret = test_priority_directed(t);
if (ret != 0) {
printf("ERROR - Prioritized Directed test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Running Prioritized Atomic test...\n");
ret = test_priority_atomic(t);
if (ret != 0) {
printf("ERROR - Prioritized Atomic test FAILED.\n");
-   return ret;
+   goto test_fail;
}
 
printf("*** Running Prioritized Ordered test...\n");
ret = test_priority_ordered(t);
if (ret != 0) {
printf("ERROR - Prioritized Ordered test FAILED.\n");
-   return ret;
+   goto test_fail;
}
printf("*** Runnin

[dpdk-dev] [PATCH v3 09/11] event/sw: update software eventdev selftest ops

2017-12-25 Thread Pavan Nikhilesh
Update software eventdev ops to invoke selftest when application invokes
`rte_event_dev_selftest`.

Signed-off-by: Pavan Nikhilesh 
Acked-by: Harry van Haaren 
---
 drivers/event/sw/Makefile   | 2 ++
 drivers/event/sw/sw_evdev.c | 2 ++
 drivers/event/sw/sw_evdev.h | 1 +
 3 files changed, 5 insertions(+)

diff --git a/drivers/event/sw/Makefile b/drivers/event/sw/Makefile
index 2f2b67bac..149258748 100644
--- a/drivers/event/sw/Makefile
+++ b/drivers/event/sw/Makefile
@@ -44,6 +44,7 @@ CFLAGS += -Wno-missing-field-initializers
 endif
 endif
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_kvargs -lrte_ring
+LDLIBS += -lrte_mempool -lrte_mbuf
 LDLIBS += -lrte_bus_vdev
 
 # library version
@@ -57,6 +58,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_worker.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_scheduler.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_xstats.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_selftest.c
 
 # export include files
 SYMLINK-y-include +=
diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index 1ef634093..f40597aae 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -794,6 +794,8 @@ sw_probe(struct rte_vdev_device *vdev)
.xstats_get_names = sw_xstats_get_names,
.xstats_get_by_name = sw_xstats_get_by_name,
.xstats_reset = sw_xstats_reset,
+
+   .dev_selftest = test_sw_eventdev,
};
 
static const char *const args[] = {
diff --git a/drivers/event/sw/sw_evdev.h b/drivers/event/sw/sw_evdev.h
index d08f7d042..b1d2c371c 100644
--- a/drivers/event/sw/sw_evdev.h
+++ b/drivers/event/sw/sw_evdev.h
@@ -334,5 +334,6 @@ int sw_xstats_reset(struct rte_eventdev *dev,
const uint32_t ids[],
uint32_t nb_ids);
 
+int test_sw_eventdev(void);
 
 #endif /* _SW_EVDEV_H_ */
-- 
2.14.1



[dpdk-dev] [PATCH v3 11/11] doc: update eventdev documentation

2017-12-25 Thread Pavan Nikhilesh
Update octeontx eventdev documentation to include new selftest feature.

Signed-off-by: Pavan Nikhilesh 
Acked-by: Marko Kovacevic 
---
 doc/guides/eventdevs/octeontx.rst | 13 +
 1 file changed, 13 insertions(+)

diff --git a/doc/guides/eventdevs/octeontx.rst 
b/doc/guides/eventdevs/octeontx.rst
index cef004a20..bf2985be1 100644
--- a/doc/guides/eventdevs/octeontx.rst
+++ b/doc/guides/eventdevs/octeontx.rst
@@ -114,6 +114,19 @@ Example:
 
 ./your_eventdev_application --vdev="event_octeontx"
 
+
+Selftest
+
+
+The functionality of octeontx eventdev can be verified using this option,
+various unit and functional tests are run to verify the sanity.
+The tests are run once the vdev creation is successfully complete.
+
+.. code-block:: console
+
+--vdev="event_octeontx,self_test=1"
+
+
 Limitations
 ---
 
-- 
2.14.1



[dpdk-dev] [PATCH v3 10/11] test: register eventdev selftest

2017-12-25 Thread Pavan Nikhilesh
Signed-off-by: Pavan Nikhilesh 
---
 test/test/test_eventdev.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index f8ee1bef6..7465251dc 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -1018,4 +1018,26 @@ test_eventdev_common(void)
return unit_test_suite_runner(&eventdev_common_testsuite);
 }
 
+static int
+test_eventdev_selftest_impl(const char *pmd, const char *opts)
+{
+   rte_vdev_init(pmd, opts);
+   return rte_event_dev_selftest(rte_event_dev_get_dev_id(pmd));
+}
+
+static int
+test_eventdev_selftest_sw(void)
+{
+   return test_eventdev_selftest_impl("event_sw", "");
+}
+
+static int
+test_eventdev_selftest_octeontx(void)
+{
+   return test_eventdev_selftest_impl("event_octeontx", "");
+}
+
 REGISTER_TEST_COMMAND(eventdev_common_autotest, test_eventdev_common);
+REGISTER_TEST_COMMAND(eventdev_selftest_sw, test_eventdev_selftest_sw);
+REGISTER_TEST_COMMAND(eventdev_selftest_octeontx,
+   test_eventdev_selftest_octeontx);
-- 
2.14.1



Re: [dpdk-dev] [RFC v2 3/5] ether: Add flow timeout support

2017-12-25 Thread Zhang, Qi Z
Hi Alex:

> -Original Message-
> From: Alex Rosenbaum [mailto:rosenbauma...@gmail.com]
> Sent: Saturday, December 23, 2017 6:27 AM
> To: Zhang, Qi Z 
> Cc: adrien.mazarg...@6wind.com; DPDK ; Doherty, Declan
> 
> Subject: Re: [dpdk-dev] [RFC v2 3/5] ether: Add flow timeout support
> 
> On Fri, Dec 22, 2017 at 11:03 AM, Zhang, Qi Z  wrote:
> >> On Thu, Dec 21, 2017 at 4:35 AM, Qi Zhang  wrote:
> >> > Add new APIs to support flow timeout, application is able to 1.
> >> > Setup the time duration of a flow, the flow is expected to be
> >> > deleted automatically when timeout.
> >>
> >> Can you explain how the application (OVS) is expected to use this API?
> >> It will help to better understand the motivation here...
> >
> > I think the purpose of the APIs is to expose the hardware feature that
> > support flow auto delete with a timeout.
> > As I know, for OVS, every flow in flow table will have time duration A
> > flow be offloaded to hardware is still required to be deleted in
> > specific time, I think these APIs help OVS to take advantage HW
> > feature and simplify the flow aging management
> 
> Are you sure this will allow OVS to 'fire-and-forget' about the rule removal?
> or will OVS anyway do rule cleanup from application tables?

There is some framework design about offload flow management on OVS side. 
Since I'm not a OVS guy, I can't answer OVS specific question precisely right 
now,
but the feedback I got is, it will be nice if rte_flow could support flow 
timeout 
I may check with some OVS expert to give further explanation.
BTW, I think there is no harmful to add these APIs into rte_flow, since a flow 
timeout is quite 
generic feature to me. it may be useful even for non-OVS case in future.

> 
> Do you know if OVS flow timers are (or can be) re-armed in different use
> cases? e.g. extending the timeout duration if traffic is still flowing?

As I know, for OVS every flow just has a fixed time duration, so "hard_timeout"
is going for this requirement, but by following OpenFlow spec, idle_timeout is 
paired 
with hard_timeout so I just add it since its generic and maybe useful for 
future.
> 
> 
> >> Are you trying to move the aging timer from application code into the
> PMD?
> >> or can your HW remove/disable/inactivate a flow at certain time
> >> semantics without software context?
> >
> > Yes, it for hardware feature.
> 
> So if the hardware auto removes the hardware steering entry, what software
> part deletes the rte_flow handle?
> What software part triggers the application callback? from what context? will
> locks be required? 
> How do you prevent races between application thread and the context
> deleting/accessing the rte_flow handle?
> I mean in cases that application wants to delete the flow before the timeout
> expires, but actually it is same time hardware deletes it.

Usually the flow auto delete is running on a separate background thread
(an interrupt handler or a watchdog thread base on hardware capability)
The low level driver is responsible to take care of the race condition between 
background and foreground flow deleting.
For application, it should be aware that the callback function is running on a 
separate thread, so it is also required to 
take care of race condition if it will access some data that is shared by 
foreground thread.

> 
> Alex

Regards
Qi


[dpdk-dev] [PATCH v2] kernel folder for Linux and BSD modules

2017-12-25 Thread Hemant Agrawal
This patch moves the kernel modules code from EAL to a common place.
 - Separate the kernel module code from user space code.

Signed-off-by: Hemant Agrawal 
---
 GNUmakefile  | 2 +-
 MAINTAINERS  | 6 +++---
 kernel/Makefile  | 9 +
 kernel/freebsd/Makefile  | 8 
 {lib/librte_eal/bsdapp => kernel/freebsd}/nic_uio/BSDmakefile| 0
 {lib/librte_eal/bsdapp => kernel/freebsd}/nic_uio/Makefile   | 0
 {lib/librte_eal/bsdapp => kernel/freebsd}/nic_uio/nic_uio.c  | 0
 kernel/linux/Makefile| 9 +
 {lib/librte_eal/linuxapp => kernel/linux}/igb_uio/Makefile   | 0
 {lib/librte_eal/linuxapp => kernel/linux}/igb_uio/compat.h   | 0
 {lib/librte_eal/linuxapp => kernel/linux}/igb_uio/igb_uio.c  | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/Makefile   | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/compat.h   | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/ethtool/README | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_82575.c  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_82575.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_api.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_api.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_defines.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_hw.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_i210.c   | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_i210.h   | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_mac.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_mac.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_manage.c | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_manage.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_mbx.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_mbx.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_nvm.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_nvm.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_osdep.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_phy.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_phy.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/e1000_regs.h   | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/ethtool/igb/igb.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_ethtool.c  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_main.c | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_param.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_regtest.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_vmdq.c | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/igb_vmdq.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/igb/kcompat.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_82598.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_82598.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_82599.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_82599.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_api.c  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_api.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_common.c   | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_common.h   | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_dcb.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_ethtool.c  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_fcoe.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_main.c | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_mbx.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_osdep.h| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_phy.c  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_phy.h  | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_type.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_x540.c | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/ixgbe_x540.h | 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/kcompat.c| 0
 .../linuxapp => kernel/linux}/kni/ethtool/ixgbe/kcompat.h| 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/kni_dev.h  | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/kni_ethtool.c  | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/kni_fifo.h | 0
 {lib/librte_eal/linuxapp => kernel/linux}/kni/kni_misc.c | 0
 {lib/librte_eal/linuxapp => kernel/li

[dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific

2017-12-25 Thread Andrew Rybchenko
EFX_RXQ_LIMIT is libefx-specifics and it should not be used
for other Rx datapaths implementations (e.g. EF10 native).

EF10 native Rx datapath has its own understanding of the maximum
RxQ fill level imposed by EvQ clear strategy and space reserved
for Rx error and flush events.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_rx.h   | 17 +
 drivers/net/sfc/sfc_ef10_rx.c | 15 +++
 drivers/net/sfc/sfc_rx.c  | 40 +++-
 3 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3f6a604..3c29089 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -101,6 +101,22 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get size of receive and event queue rings by the number of Rx
+ * descriptors.
+ *
+ * @param nb_rx_desc   Number of Rx descriptors
+ * @param rxq_entries  Location for number of Rx ring entries
+ * @param evq_entries  Location for number of event ring entries
+ * @param rxq_max_fill_level   Location for maximum Rx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_rx_qsize_up_rings_t)(uint16_t nb_rx_desc,
+unsigned int *rxq_entries,
+unsigned int *evq_entries,
+unsigned int *rxq_max_fill_level);
+
+/**
  * Allocate and initialize datapath receive queue.
  *
  * @param port_id  The port identifier
@@ -166,6 +182,7 @@ struct sfc_dp_rx {
unsigned intfeatures;
 #define SFC_DP_RX_FEAT_SCATTER 0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS   0x2
+   sfc_dp_rx_qsize_up_rings_t  *qsize_up_rings;
sfc_dp_rx_qcreate_t *qcreate;
sfc_dp_rx_qdestroy_t*qdestroy;
sfc_dp_rx_qstart_t  *qstart;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 18d60c6..29524ce 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -553,6 +553,20 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq 
*dp_rxq,
 }
 
 
+static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
+static int
+sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
+  unsigned int *rxq_entries,
+  unsigned int *evq_entries,
+  unsigned int *rxq_max_fill_level)
+{
+   *rxq_entries = nb_rx_desc;
+   *evq_entries = nb_rx_desc;
+   *rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+   return 0;
+}
+
+
 static uint64_t
 sfc_ef10_mk_mbuf_rearm_data(uint16_t port_id, uint16_t prefix_size)
 {
@@ -708,6 +722,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF10,
},
.features   = SFC_DP_RX_FEAT_MULTI_PROCESS,
+   .qsize_up_rings = sfc_ef10_rx_qsize_up_rings,
.qcreate= sfc_ef10_rx_qcreate,
.qdestroy   = sfc_ef10_rx_qdestroy,
.qstart = sfc_ef10_rx_qstart,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 7816393..43d51c4 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -413,6 +413,19 @@ sfc_rxq_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq)
return rxq;
 }
 
+static sfc_dp_rx_qsize_up_rings_t sfc_efx_rx_qsize_up_rings;
+static int
+sfc_efx_rx_qsize_up_rings(uint16_t nb_rx_desc,
+ unsigned int *rxq_entries,
+ unsigned int *evq_entries,
+ unsigned int *rxq_max_fill_level)
+{
+   *rxq_entries = nb_rx_desc;
+   *evq_entries = nb_rx_desc;
+   *rxq_max_fill_level = EFX_RXQ_LIMIT(*rxq_entries);
+   return 0;
+}
+
 static sfc_dp_rx_qcreate_t sfc_efx_rx_qcreate;
 static int
 sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -535,6 +548,7 @@ struct sfc_dp_rx sfc_efx_rx = {
.hw_fw_caps = 0,
},
.features   = SFC_DP_RX_FEAT_SCATTER,
+   .qsize_up_rings = sfc_efx_rx_qsize_up_rings,
.qcreate= sfc_efx_rx_qcreate,
.qdestroy   = sfc_efx_rx_qdestroy,
.qstart = sfc_efx_rx_qstart,
@@ -771,10 +785,9 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 }
 
 static int
-sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
+sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
   const struct rte_eth_rxconf *rx_conf)
 {
-   const uint16_t rx_free_thresh_max = EFX_RXQ_LIMIT(nb_rx_desc);
int rc = 0;
 
if (rx_conf->rx_thresh.pthresh != 0 ||
@@ -784,10 +797,10 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t 
nb_rx_desc,

[dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs

2017-12-25 Thread Andrew Rybchenko
The minimum size of Rx/Tx descriptor rings supported by Solarflare HW is 512.
It adds inconvenience to run DPDK applications which typically use smaller
default values. Also smaller numbers of used descriptors is better for
performance.

The patch series adds possibility to use any number of Rx/Tx descriptors
in the range, for example, from 1 to 2048 for Tx and from 8 to 4096 for Rx.
Maximum value is defined by HW maximum.

The patch series is made independent from [1] submitted a bit earlier
to avoid automatic build failures and to be able to apply this one first.
When one is applied, the second should be rebased.

[1] http://dpdk.org/ml/archives/dev/2017-December/084843.html

Andrew Rybchenko (6):
  net/sfc: make refill threshold check Rx datapath specific
  net/sfc: make Tx free threshold check datapath specific
  net/sfc: use Rx queue max fill level calculated on init
  net/sfc: use Tx queue max fill level calculated on init
  net/sfc: support more options for a number of Rx descriptors
  net/sfc: support more options for a number of Tx descriptors

 drivers/net/sfc/sfc_dp_rx.h   | 27 
 drivers/net/sfc/sfc_dp_tx.h   | 27 
 drivers/net/sfc/sfc_ef10_rx.c | 44 ++--
 drivers/net/sfc/sfc_ef10_tx.c | 58 ++-
 drivers/net/sfc/sfc_ethdev.c  |  7 ++
 drivers/net/sfc/sfc_rx.c  | 49 
 drivers/net/sfc/sfc_rx.h  |  1 +
 drivers/net/sfc/sfc_tx.c  | 48 +++
 drivers/net/sfc/sfc_tx.h  |  1 +
 9 files changed, 227 insertions(+), 35 deletions(-)

-- 
2.7.4



[dpdk-dev] [PATCH 4/6] net/sfc: use Tx queue max fill level calculated on init

2017-12-25 Thread Andrew Rybchenko
Prepare to support more options for number of Tx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_tx.h   |  2 ++
 drivers/net/sfc/sfc_ef10_tx.c | 20 
 drivers/net/sfc/sfc_tx.c  |  6 --
 drivers/net/sfc/sfc_tx.h  |  1 +
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 32d7681..4485b2f 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -57,6 +57,8 @@ struct sfc_dp_txq {
  * readable.
  */
 struct sfc_dp_tx_qcreate_info {
+   /** Maximum number of pushed Tx descriptors */
+   unsigned intmax_fill_level;
/** Minimum number of unused Tx descriptors to do reap */
unsigned intfree_thresh;
/** Transmit queue configuration flags */
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index ab3334a..99fe87e 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -77,6 +77,7 @@ struct sfc_ef10_txq {
unsigned intptr_mask;
unsigned intadded;
unsigned intcompleted;
+   unsigned intmax_fill_level;
unsigned intfree_thresh;
unsigned intevq_read_ptr;
struct sfc_ef10_tx_sw_desc  *sw_ring;
@@ -288,7 +289,6 @@ static uint16_t
 sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
struct sfc_ef10_txq * const txq = sfc_ef10_txq_by_dp_txq(tx_queue);
-   unsigned int ptr_mask;
unsigned int added;
unsigned int dma_desc_space;
bool reap_done;
@@ -299,16 +299,13 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts, uint16_t nb_pkts)
 (SFC_EF10_TXQ_NOT_RUNNING | SFC_EF10_TXQ_EXCEPTION)))
return 0;
 
-   ptr_mask = txq->ptr_mask;
added = txq->added;
-   dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-(added - txq->completed);
+   dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
reap_done = (dma_desc_space < txq->free_thresh);
if (reap_done) {
sfc_ef10_tx_reap(txq);
-   dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-(added - txq->completed);
+   dma_desc_space = txq->max_fill_level - (added - txq->completed);
}
 
for (pktp = &tx_pkts[0], pktp_end = &tx_pkts[nb_pkts];
@@ -333,7 +330,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts, uint16_t nb_pkts)
 
sfc_ef10_tx_reap(txq);
reap_done = true;
-   dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
+   dma_desc_space = txq->max_fill_level -
(added - txq->completed);
if (sfc_ef10_tx_pkt_descs_max(m_seg) > dma_desc_space)
break;
@@ -343,7 +340,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts, uint16_t nb_pkts)
do {
rte_iova_t seg_addr = rte_mbuf_data_iova(m_seg);
unsigned int seg_len = rte_pktmbuf_data_len(m_seg);
-   unsigned int id = added & ptr_mask;
+   unsigned int id = added & txq->ptr_mask;
 
SFC_ASSERT(seg_len <= SFC_EF10_TX_DMA_DESC_LEN_MAX);
 
@@ -446,14 +443,12 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
ptr_mask = txq->ptr_mask;
added = txq->added;
-   dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-(added - txq->completed);
+   dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
reap_done = (dma_desc_space < RTE_MAX(txq->free_thresh, nb_pkts));
if (reap_done) {
sfc_ef10_simple_tx_reap(txq);
-   dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-(added - txq->completed);
+   dma_desc_space = txq->max_fill_level - (added - txq->completed);
}
 
pktp_end = &tx_pkts[MIN(nb_pkts, dma_desc_space)];
@@ -532,6 +527,7 @@ sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
 
txq->flags = SFC_EF10_TXQ_NOT_RUNNING;
txq->ptr_mask = info->txq_entries - 1;
+   txq->max_fill_level = info->max_fill_level;
txq->free_thresh = info->free_thresh;
txq->txq_hw_ring = info->txq_hw_ring;
txq->doorbell = (volatile uint8_t *)info->mem_bar +
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 3c9a6e9..f8ee976 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/dr

[dpdk-dev] [PATCH 6/6] net/sfc: support more options for a number of Tx descriptors

2017-12-25 Thread Andrew Rybchenko
The number of Tx descriptors is not used as HW Tx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_tx.h   |  8 
 drivers/net/sfc/sfc_ef10_tx.c | 29 ++---
 drivers/net/sfc/sfc_ethdev.c  |  3 +++
 drivers/net/sfc/sfc_tx.c  |  5 -
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 4485b2f..a384a53 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -80,6 +80,13 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get Tx datapath specific device info.
+ *
+ * @param dev_info Device info to be adjusted
+ */
+typedef void (sfc_dp_tx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of transmit and event queue rings by the number of Tx
  * descriptors.
  *
@@ -162,6 +169,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS   0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL  0x10
 #define SFC_DP_TX_FEAT_REFCNT  0x20
+   sfc_dp_tx_get_dev_info_t*get_dev_info;
sfc_dp_tx_qsize_up_rings_t  *qsize_up_rings;
sfc_dp_tx_qcreate_t *qcreate;
sfc_dp_tx_qdestroy_t*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 99fe87e..02df39c 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -481,6 +481,17 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
return pktp - &tx_pkts[0];
 }
 
+static sfc_dp_tx_get_dev_info_t sfc_ef10_get_dev_info;
+static void
+sfc_ef10_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+   /*
+* Number of descriptors just defines maximum number of pushed
+* descriptors (fill level).
+*/
+   dev_info->tx_desc_lim.nb_min = 1;
+   dev_info->tx_desc_lim.nb_align = 1;
+}
 
 static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
 static int
@@ -489,9 +500,19 @@ sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
   unsigned int *evq_entries,
   unsigned int *txq_max_fill_level)
 {
-   *txq_entries = nb_tx_desc;
-   *evq_entries = nb_tx_desc;
-   *txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+   /*
+* rte_ethdev API guarantees that the number meets min, max and
+* alignment requirements.
+*/
+   if (nb_tx_desc <= EFX_TXQ_MINNDESCS)
+   *txq_entries = EFX_TXQ_MINNDESCS;
+   else
+   *txq_entries = rte_align32pow2(nb_tx_desc);
+
+   *evq_entries = *txq_entries;
+
+   *txq_max_fill_level = RTE_MIN(nb_tx_desc,
+ SFC_EF10_TXQ_LIMIT(*evq_entries));
return 0;
 }
 
@@ -637,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
  SFC_DP_TX_FEAT_MULTI_POOL |
  SFC_DP_TX_FEAT_REFCNT |
  SFC_DP_TX_FEAT_MULTI_PROCESS,
+   .get_dev_info   = sfc_ef10_get_dev_info,
.qsize_up_rings = sfc_ef10_tx_qsize_up_rings,
.qcreate= sfc_ef10_tx_qcreate,
.qdestroy   = sfc_ef10_tx_qdestroy,
@@ -654,6 +676,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
.type   = SFC_DP_TX,
},
.features   = SFC_DP_TX_FEAT_MULTI_PROCESS,
+   .get_dev_info   = sfc_ef10_get_dev_info,
.qsize_up_rings = sfc_ef10_tx_qsize_up_rings,
.qcreate= sfc_ef10_tx_qcreate,
.qdestroy   = sfc_ef10_tx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6ff4595..7d75f55 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -171,6 +171,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
 */
dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
 
+   /* Initialize to hardware limits */
dev_info->tx_desc_lim.nb_max = sa->txq_max_entries;
dev_info->tx_desc_lim.nb_min = EFX_TXQ_MINNDESCS;
/*
@@ -181,6 +182,8 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
 
if (sa->dp_rx->get_dev_info != NULL)
sa->dp_rx->get_dev_info(dev_info);
+   if (sa->dp_tx->get_dev_info != NULL)
+   sa->dp_tx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index f8ee976..f3f447b 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -160,6 +160,10 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
   &txq_max_fill_level);
if (rc != 0)
goto fail_size_up_rings;
+   SFC_ASSERT(txq_entries >= EFX_TXQ_MINNDESCS);
+  

[dpdk-dev] [PATCH 2/6] net/sfc: make Tx free threshold check datapath specific

2017-12-25 Thread Andrew Rybchenko
EFX_TXQ_LIMIT is libefx-specifics and it should not be used
for other Tx datapaths implementations (e.g. EF10 native).

EF10 native Tx datapath has its own understanding of the maximum
TxQ fill level imposed by EvQ clear strategy and space reserved
for Tx error and flush events.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_tx.h   | 17 +
 drivers/net/sfc/sfc_ef10_tx.c | 15 +++
 drivers/net/sfc/sfc_tx.c  | 39 +++
 3 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 94d1b10..32d7681 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -78,6 +78,22 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get size of transmit and event queue rings by the number of Tx
+ * descriptors.
+ *
+ * @param nb_tx_desc   Number of Tx descriptors
+ * @param txq_entries  Location for number of Tx ring entries
+ * @param evq_entries  Location for number of event ring entries
+ * @param txq_max_fill_level   Location for maximum Tx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_tx_qsize_up_rings_t)(uint16_t nb_tx_desc,
+unsigned int *txq_entries,
+unsigned int *evq_entries,
+unsigned int *txq_max_fill_level);
+
+/**
  * Allocate and initialize datapath transmit queue.
  *
  * @param port_id  The port identifier
@@ -144,6 +160,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS   0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL  0x10
 #define SFC_DP_TX_FEAT_REFCNT  0x20
+   sfc_dp_tx_qsize_up_rings_t  *qsize_up_rings;
sfc_dp_tx_qcreate_t *qcreate;
sfc_dp_tx_qdestroy_t*qdestroy;
sfc_dp_tx_qstart_t  *qstart;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 0454e79..ab3334a 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -487,6 +487,19 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 }
 
 
+static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
+static int
+sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
+  unsigned int *txq_entries,
+  unsigned int *evq_entries,
+  unsigned int *txq_max_fill_level)
+{
+   *txq_entries = nb_tx_desc;
+   *evq_entries = nb_tx_desc;
+   *txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+   return 0;
+}
+
 static sfc_dp_tx_qcreate_t sfc_ef10_tx_qcreate;
 static int
 sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -628,6 +641,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
  SFC_DP_TX_FEAT_MULTI_POOL |
  SFC_DP_TX_FEAT_REFCNT |
  SFC_DP_TX_FEAT_MULTI_PROCESS,
+   .qsize_up_rings = sfc_ef10_tx_qsize_up_rings,
.qcreate= sfc_ef10_tx_qcreate,
.qdestroy   = sfc_ef10_tx_qdestroy,
.qstart = sfc_ef10_tx_qstart,
@@ -644,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
.type   = SFC_DP_TX,
},
.features   = SFC_DP_TX_FEAT_MULTI_PROCESS,
+   .qsize_up_rings = sfc_ef10_tx_qsize_up_rings,
.qcreate= sfc_ef10_tx_qcreate,
.qdestroy   = sfc_ef10_tx_qdestroy,
.qstart = sfc_ef10_tx_qstart,
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index d1320f4..3c9a6e9 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -57,7 +57,7 @@
 #define SFC_TX_QFLUSH_POLL_ATTEMPTS(2000)
 
 static int
-sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
+sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
   const struct rte_eth_txconf *tx_conf)
 {
unsigned int flags = tx_conf->txq_flags;
@@ -69,10 +69,10 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t 
nb_tx_desc,
rc = EINVAL;
}
 
-   if (tx_conf->tx_free_thresh > EFX_TXQ_LIMIT(nb_tx_desc)) {
+   if (tx_conf->tx_free_thresh > txq_max_fill_level) {
sfc_err(sa,
"TxQ free threshold too large: %u vs maximum %u",
-   tx_conf->tx_free_thresh, EFX_TXQ_LIMIT(nb_tx_desc));
+   tx_conf->tx_free_thresh, txq_max_fill_level);
rc = EINVAL;
}
 
@@ -145,6 +145,9 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 const struct rte_eth_txconf *tx_conf)
 {
const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+   unsigned int txq_entries;
+   unsigned int evq_entries;
+   un

[dpdk-dev] [PATCH 3/6] net/sfc: use Rx queue max fill level calculated on init

2017-12-25 Thread Andrew Rybchenko
Prepare to support more options for number of Rx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_rx.h   | 2 ++
 drivers/net/sfc/sfc_ef10_rx.c | 5 +++--
 drivers/net/sfc/sfc_rx.c  | 5 +++--
 drivers/net/sfc/sfc_rx.h  | 1 +
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3c29089..f62d79a 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -60,6 +60,8 @@ struct sfc_dp_rxq {
 struct sfc_dp_rx_qcreate_info {
/** Memory pool to allocate Rx buffer from */
struct rte_mempool  *refill_mb_pool;
+   /** Maximum number of pushed Rx descriptors in the queue */
+   unsigned intmax_fill_level;
/** Minimum number of unused Rx descriptors to do refill */
unsigned intrefill_threshold;
/**
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 29524ce..fc89078 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -93,6 +93,7 @@ struct sfc_ef10_rxq {
/* Used on refill */
uint16_tbuf_size;
unsigned intadded;
+   unsigned intmax_fill_level;
unsigned intrefill_threshold;
struct rte_mempool  *refill_mb_pool;
efx_qword_t *rxq_hw_ring;
@@ -141,8 +142,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
void *objs[SFC_RX_REFILL_BULK];
unsigned int added = rxq->added;
 
-   free_space = SFC_EF10_RXQ_LIMIT(ptr_mask + 1) -
-   (added - rxq->completed);
+   free_space = rxq->max_fill_level - (added - rxq->completed);
 
if (free_space < rxq->refill_threshold)
return;
@@ -620,6 +620,7 @@ sfc_ef10_rx_qcreate(uint16_t port_id, uint16_t queue_id,
rxq->flags |= SFC_EF10_RXQ_RSS_HASH;
rxq->ptr_mask = info->rxq_entries - 1;
rxq->evq_hw_ring = info->evq_hw_ring;
+   rxq->max_fill_level = info->max_fill_level;
rxq->refill_threshold = info->refill_threshold;
rxq->rearm_data =
sfc_ef10_mk_mbuf_rearm_data(port_id, info->prefix_size);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 43d51c4..ecf8e99 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -88,8 +88,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
struct rte_mbuf *m;
uint16_t port_id = rxq->dp.dpq.port_id;
 
-   free_space = EFX_RXQ_LIMIT(rxq->ptr_mask + 1) -
-   (added - rxq->completed);
+   free_space = rxq->max_fill_level - (added - rxq->completed);
 
if (free_space < rxq->refill_threshold)
return;
@@ -459,6 +458,7 @@ sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
rxq->ptr_mask = info->rxq_entries - 1;
rxq->batch_max = info->batch_max;
rxq->prefix_size = info->prefix_size;
+   rxq->max_fill_level = info->max_fill_level;
rxq->refill_threshold = info->refill_threshold;
rxq->buf_size = info->buf_size;
rxq->refill_mb_pool = info->refill_mb_pool;
@@ -993,6 +993,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
memset(&info, 0, sizeof(info));
info.refill_mb_pool = rxq->refill_mb_pool;
+   info.max_fill_level = rxq_max_fill_level;
info.refill_threshold = rxq->refill_threshold;
info.buf_size = buf_size;
info.batch_max = encp->enc_rx_batch_max;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 9e6282e..d2f4471 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -121,6 +121,7 @@ struct sfc_efx_rxq {
/* Used on refill */
unsigned intadded;
unsigned intpushed;
+   unsigned intmax_fill_level;
unsigned intrefill_threshold;
uint16_tbuf_size;
struct rte_mempool  *refill_mb_pool;
-- 
2.7.4



[dpdk-dev] [PATCH 5/6] net/sfc: support more options for a number of Rx descriptors

2017-12-25 Thread Andrew Rybchenko
The number of Rx descriptors is not used as HW Rx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko 
Reviewed-by: Andy Moreton 
---
 drivers/net/sfc/sfc_dp_rx.h   |  8 
 drivers/net/sfc/sfc_ef10_rx.c | 30 +++---
 drivers/net/sfc/sfc_ethdev.c  |  4 
 drivers/net/sfc/sfc_rx.c  |  4 
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index f62d79a..367477a 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -103,6 +103,13 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get Rx datapath specific device info.
+ *
+ * @param dev_info Device info to be adjusted
+ */
+typedef void (sfc_dp_rx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of receive and event queue rings by the number of Rx
  * descriptors.
  *
@@ -184,6 +191,7 @@ struct sfc_dp_rx {
unsigned intfeatures;
 #define SFC_DP_RX_FEAT_SCATTER 0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS   0x2
+   sfc_dp_rx_get_dev_info_t*get_dev_info;
sfc_dp_rx_qsize_up_rings_t  *qsize_up_rings;
sfc_dp_rx_qcreate_t *qcreate;
sfc_dp_rx_qdestroy_t*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index fc89078..8516e25 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -553,6 +553,19 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq 
*dp_rxq,
 }
 
 
+static sfc_dp_rx_get_dev_info_t sfc_ef10_rx_get_dev_info;
+static void
+sfc_ef10_rx_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+   /*
+* Number of descriptors just defines maximum number of pushed
+* descriptors (fill level).
+*/
+   dev_info->rx_desc_lim.nb_min = SFC_RX_REFILL_BULK;
+   dev_info->rx_desc_lim.nb_align = SFC_RX_REFILL_BULK;
+}
+
+
 static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
 static int
 sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
@@ -560,9 +573,19 @@ sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
   unsigned int *evq_entries,
   unsigned int *rxq_max_fill_level)
 {
-   *rxq_entries = nb_rx_desc;
-   *evq_entries = nb_rx_desc;
-   *rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+   /*
+* rte_ethdev API guarantees that the number meets min, max and
+* alignment requirements.
+*/
+   if (nb_rx_desc <= EFX_RXQ_MINNDESCS)
+   *rxq_entries = EFX_RXQ_MINNDESCS;
+   else
+   *rxq_entries = rte_align32pow2(nb_rx_desc);
+
+   *evq_entries = *rxq_entries;
+
+   *rxq_max_fill_level = RTE_MIN(nb_rx_desc,
+ SFC_EF10_RXQ_LIMIT(*evq_entries));
return 0;
 }
 
@@ -723,6 +746,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF10,
},
.features   = SFC_DP_RX_FEAT_MULTI_PROCESS,
+   .get_dev_info   = sfc_ef10_rx_get_dev_info,
.qsize_up_rings = sfc_ef10_rx_qsize_up_rings,
.qcreate= sfc_ef10_rx_qcreate,
.qdestroy   = sfc_ef10_rx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index fabcc32..6ff4595 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -163,6 +163,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
if (sa->tso)
dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 
+   /* Initialize to hardware limits */
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
@@ -177,6 +178,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
 * of 2, but tx_desc_lim cannot properly describe that constraint
 */
dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
+
+   if (sa->dp_rx->get_dev_info != NULL)
+   sa->dp_rx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index ecf8e99..6b31e56 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -933,6 +933,10 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
   &rxq_max_fill_level);
if (rc != 0)
goto fail_size_up_rings;
+   SFC_ASSERT(rxq_entries >= EFX_RXQ_MINNDESCS);
+   SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
+   SFC_ASSERT(rxq_entries >= nb_rx_desc);
+   SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf)

[dpdk-dev] [PATCH] net/mlx5: fix RSS key configuration

2017-12-25 Thread Shahaf Shuler
The trigger for PMD to use the application RSS configuration should be
based on the validity of rss_key and not the rss_key_len. Otherwise
segmentation fault can occur if application provide valid RSS key length
but without any RSS key.

Fixes: 29c1d8bb3e79 ("net/mlx5: handle a single RSS hash key for all protocols")
Cc: nelio.laranje...@6wind.com
Cc: sta...@dpdk.org

Signed-off-by: Shahaf Shuler 
Acked-by: Yongseok Koh 
---
 drivers/net/mlx5/mlx5_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index ca9ad0fef..282ef241e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -550,7 +550,7 @@ dev_configure(struct rte_eth_dev *dev)
unsigned int j;
unsigned int reta_idx_n;
const uint8_t use_app_rss_key =
-   !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len;
+   !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
 
if (use_app_rss_key &&
(dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
-- 
2.12.0



Re: [dpdk-dev] [RFC v2 3/5] ether: Add flow timeout support

2017-12-25 Thread Alex Rosenbaum
On Tue, Dec 26, 2017 at 5:28 AM, Zhang, Qi Z  wrote:
>> On Fri, Dec 22, 2017 at 11:03 AM, Zhang, Qi Z  wrote:
>> >> On Thu, Dec 21, 2017 at 4:35 AM, Qi Zhang  wrote:
>> >> > Add new APIs to support flow timeout, application is able to 1.
>> >> > Setup the time duration of a flow, the flow is expected to be
>> >> > deleted automatically when timeout.
>> >>
>> >> Can you explain how the application (OVS) is expected to use this API?
>> >> It will help to better understand the motivation here...
>> >
>> > I think the purpose of the APIs is to expose the hardware feature that
>> > support flow auto delete with a timeout.
>> > As I know, for OVS, every flow in flow table will have time duration A
>> > flow be offloaded to hardware is still required to be deleted in
>> > specific time, I think these APIs help OVS to take advantage HW
>> > feature and simplify the flow aging management
>>
>> Are you sure this will allow OVS to 'fire-and-forget' about the rule removal?
>> or will OVS anyway do rule cleanup from application tables?
>
> There is some framework design about offload flow management on OVS side.
> Since I'm not a OVS guy, I can't answer OVS specific question precisely right 
> now,
> but the feedback I got is, it will be nice if rte_flow could support flow 
> timeout
> I may check with some OVS expert to give further explanation.
> BTW, I think there is no harmful to add these APIs into rte_flow, since a 
> flow timeout is quite
> generic feature to me. it may be useful even for non-OVS case in future.

I'm not a core OVS guy ether :) but adding a feature to DPDK because
it "might be nice" and not a "real benefit" does not sound like a
right approach to me. Each new feature will add extra
work/support/bugs for something which might not really used. I think
it is critical that OVS guys provide you a clear evidence how this
will help.
And we need to try and make this generic so other then OVS application
can use this. e.g. adding a re-arm to the timeout.


>> Do you know if OVS flow timers are (or can be) re-armed in different use
>> cases? e.g. extending the timeout duration if traffic is still flowing?
>
> As I know, for OVS every flow just has a fixed time duration, so 
> "hard_timeout"
> is going for this requirement, but by following OpenFlow spec, idle_timeout 
> is paired
> with hard_timeout so I just add it since its generic and maybe useful for 
> future.

Yes, I also heard OF does issue a hard timeout value.
But I also understood from OVS guys that OVS will manage the timeout
internally. OVS will do traffic sampling for activity before deleting
the flow. so that the timeout value needs to be updated constantly
depending on connection state information (re you other patch exposing
the last_seen_timeout).
So the current suggestion, based on hard timeout, will not fit OVS. At
least as I understood from other OVS guys.
You can see that Kernel OVS guys did not add this to TC flower offload
support ether. I am sure they would have if it would have improved
performance.
That will be a fame if we miss the target of the feature.


>> >> Are you trying to move the aging timer from application code into the
>> PMD?
>> >> or can your HW remove/disable/inactivate a flow at certain time
>> >> semantics without software context?
>> >
>> > Yes, it for hardware feature.
>>
>> So if the hardware auto removes the hardware steering entry, what software
>> part deletes the rte_flow handle?
>> What software part triggers the application callback? from what context? will
>> locks be required?
>> How do you prevent races between application thread and the context
>> deleting/accessing the rte_flow handle?
>> I mean in cases that application wants to delete the flow before the timeout
>> expires, but actually it is same time hardware deletes it.
>
> Usually the flow auto delete is running on a separate background thread
> (an interrupt handler or a watchdog thread base on hardware capability)
> The low level driver is responsible to take care of the race condition 
> between background and foreground flow deleting.

Please explain in details how the race is solved. Maybe a patch will
make this clearer? This is one of the main objection for this feature.
e.g.: If the application holds a rte_flow handle, and the timeout
expired, is not handled yet. Now the application will try to use the
rte_flow which state changed underneath, or even got deleted.

Besides you now require each and every low level driver to add this
same timeout expiration logic, alarm registration and race protection.
This should be done once for all PMD's.
PS: Will this callback thread clear the HW rule as well?

> For application, it should be aware

Need to make this clear in API definitions

> that the callback function is running on a separate thread, so it is also 
> required to
> take care of race condition if it will access some data that is shared by 
> foreground thread.

This means locks in application? or some lock-less async model?
Isn't it