Re: [lng-odp] [API-NEXT PATCH] api: clib: added standard c library api

2015-10-22 Thread Savolainen, Petri (Nokia - FI/Espoo)
Ping. I think we agreed to merge this and potentially add some more common C 
lib calls in the future.


Here's some cycle count measurements from x86 with DPDK. Compiled with -O2 
-mavx2, so that GCC knows about AVX2 and memcpy could use the same vector 
instructions that DPDK uses (== best case results for memcpy). Code warms up 
caches before measuring and repeats each data len 6 times. Generally rte_memcpy 
is at least 20% faster.

-Petri


len   memcpy  rte_memcpy
 256  232   15688888888   14872687272   
 68 
 512  208   104   104   104   104   104   136   112808080   
 80 
 768  156   120   120   116   120   120   192   116929288   
 88 
1024  224   136   132   136   136   136   136   100   100   10096   
100 
1280  184   168   152   152   152   152   136   112   104   104   108   
104 
1536  200   168   164   164   168   168   156   152   136   140   140   
140 
1792  208   212   184   184   180   180   160   132   124   124   120   
120 
2048  220   212   204   204   200   200   148   144   128   128   132   
128 
2304  252   228   220   216   216   212   152   144   136   140   136   
136 
2560  272   240   232   232   228   232   164   144   148   144   144   
148 
2816  280   256   248   248   248   248   164   164   152   152   152   
156 
3072  296   272   264   264   268   264   188   172   160   160   164   
164 
3328  312   288   284   280   284   280   180   176   168   168   172   
168 
3584  324   304   300   300   296   296   180   184   176   176   176   
176 
3840  340   320   320   316   316   316   208   188   184   188   184   
188 
4096  348   348   332   332   332   332   204   204   192   196   196   
192


> -Original Message-
> From: EXT Jerin Jacob [mailto:jerin.ja...@caviumnetworks.com]
> Sent: Monday, October 19, 2015 1:35 PM
> To: Savolainen, Petri (Nokia - FI/Espoo)
> Cc: lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [API-NEXT PATCH] api: clib: added standard c library
> api
> 
> On Fri, Oct 16, 2015 at 03:13:48PM +0300, Petri Savolainen wrote:
> > Some C library calls are often used in data plane code. This
> > API enables possibility to HW optimized implementation of those.
> > Added first memcpy and memset.
> >
> > Signed-off-by: Petri Savolainen 
> 
> Reviewed-by: Jerin Jacob 
> 
> > ---
> >  include/odp.h |  1 +
> >  include/odp/api/std_clib.h| 64
> +++
> >  platform/linux-generic/Makefile.am|  2 +
> >  platform/linux-generic/include/odp/std_clib.h | 30 +
> >  4 files changed, 97 insertions(+)
> >  create mode 100644 include/odp/api/std_clib.h
> >  create mode 100644 platform/linux-generic/include/odp/std_clib.h
> >
> > diff --git a/include/odp.h b/include/odp.h
> > index 825c7e1..f2cd2d3 100644
> > --- a/include/odp.h
> > +++ b/include/odp.h
> > @@ -56,6 +56,7 @@ extern "C" {
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #ifdef __cplusplus
> >  }
> > diff --git a/include/odp/api/std_clib.h b/include/odp/api/std_clib.h
> > new file mode 100644
> > index 000..2119ec4
> > --- /dev/null
> > +++ b/include/odp/api/std_clib.h
> > @@ -0,0 +1,64 @@
> > +/* Copyright (c) 2015, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier: BSD-3-Clause
> > + */
> > +
> > +/**
> > + * @file
> > + *
> > + * ODP version of often used C library calls
> > + */
> > +
> > +#ifndef ODP_API_STD_CLIB_H_
> > +#define ODP_API_STD_CLIB_H_
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +/**
> > + * @defgroup odp_std_clib ODP STD CLIB
> > + * @details
> > + * ODP version of often used C library calls
> > + * @{
> > + */
> > +
> > +/**
> > + * Memcpy
> > + *
> > + * ODP version of C library memcpy function. It copies 'num' bytes from
> source
> > + * to destination address. Source and destination memory blocks must not
> > + * overlap.
> > + *
> > + * @param dstPointer to destination memory block
> > + * @param srcPointer to source memory block
> > + * @param numNumber of bytes to copy
> > + *
> > + * @return 'dst' address
> > + */
> > +void *odp_memcpy(void *dst, const void *src, size_t num);
> > +
> > +/**
> > + * Memset
> > + *
> > + * ODP version of C library memset function. It sets 'value' to first
> 'num'
> > + * bytes of memory block pointed by 'ptr'.
> > + *
> > + * @param ptrPointer to the memory block
> > + * @param value  Value to be set
> > + * @param numNumber of bytes to set
> > + *
> > + * @return 'ptr' address
> > + */
> > +void *odp_memset(void *ptr, int value, size_t num);
> > +
> > +/**
> > + * @}
> > + */
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif
> > diff --git 

[lng-odp] [PATCH 1/3] doc: images: add svg for user-guide

2015-10-22 Thread Mike Holmes
Signed-off-by: Mike Holmes 
---
 DEPENDENCIES  |   9 +-
 configure.ac  |  11 +
 doc/Makefile.am   |   4 +-
 doc/images/.gitignore |   2 +
 doc/images/Makefile.am|  33 +++
 doc/images/atomic_queue.svg   | 302 +++
 doc/images/ordered_queue.svg  | 658 ++
 doc/images/parallel_queue.svg | 470 ++
 8 files changed, 1486 insertions(+), 3 deletions(-)
 create mode 100644 doc/images/.gitignore
 create mode 100644 doc/images/Makefile.am
 create mode 100644 doc/images/atomic_queue.svg
 create mode 100644 doc/images/ordered_queue.svg
 create mode 100644 doc/images/parallel_queue.svg

diff --git a/DEPENDENCIES b/DEPENDENCIES
index 51951d7..7d22bde 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -187,7 +187,12 @@ Prerequisites for building the OpenDataPlane (ODP) API
./configure  --enable-cunit  #if cunit is in the PATH
./configure  --with-cunit-path=DIR #only if you need a path to Cunit libs 
and headers
 
-5.0 Documentation & Doxygen
+5.0 Documentation Images & Doxygen
+
+  Images are stored as svg files and the png or eps versions generated when 
the docs are built
+  Image magics convert application is used
+  # Debian/Ubuntu
+  # apt-get install imagemagick
 
 5.1 API Guide
 See http://www.stack.nl/~dimitri/doxygen/manual/install.html
@@ -206,7 +211,7 @@ The tested version of doxygen is 1.8.8
 
 5.2.1 HTML
# Ubuntu
-   $ apt-get install asciidoc
+   $ apt-get install asciidoc source-highlight
 
# Debian
$ apt-get install asciidoc source-highlight
diff --git a/configure.ac b/configure.ac
index 5d84f92..0d08e58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -248,6 +248,16 @@ AC_ARG_ENABLE([user-guides],
 AM_CONDITIONAL([user_guide], [test "x${user_guides}" = "xyes" ])
 
 ##
+# Check for imagemagic availability
+##
+   AC_CHECK_PROGS([IMAGEMAGIC], [convert])
+   if test -z "$IMAGEMAGIC";
+  then AC_MSG_WARN([Imagemagic (convert) not found - continuing 
without image support])
+   fi
+
+AM_CONDITIONAL([HAVE_IMAGEMAGIC], [test "x${IMAGEMAGIC}" = "xconvert"])
+
+##
 # Save and set temporary compilation flags
 ##
 OLD_LDFLAGS=$LDFLAGS
@@ -296,6 +306,7 @@ AM_CXXFLAGS="-std=c++11"
 AC_CONFIG_FILES([Makefile
 doc/Makefile
 doc/implementers-guide/Makefile
+doc/images/Makefile
 example/Makefile
 example/classifier/Makefile
 example/generator/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 73bd8e2..3aa29a3 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,8 +1,10 @@
+SUBDIRS = images
+
 if HAVE_DOXYGEN
 clean-local:
rm -rf output
 endif
 
 if user_guide
-SUBDIRS = implementers-guide
+SUBDIRS += implementers-guide
 endif
diff --git a/doc/images/.gitignore b/doc/images/.gitignore
new file mode 100644
index 000..148f2f2
--- /dev/null
+++ b/doc/images/.gitignore
@@ -0,0 +1,2 @@
+*.png
+*.eps
diff --git a/doc/images/Makefile.am b/doc/images/Makefile.am
new file mode 100644
index 000..df8f9d4
--- /dev/null
+++ b/doc/images/Makefile.am
@@ -0,0 +1,33 @@
+SVG_SRCS =  atomic_queue.svg \
+   ordered_queue.svg \
+   parallel_queue.svg
+SVG_TARGETS = $(SVG_SRCS:svg=png)
+SVG_TARGETS += $(SVG_SRCS:svg=eps)
+
+EXTRA_DIST = $(SVG_SRCS)
+
+TARGETS=
+
+if HAVE_IMAGEMAGIC
+TARGETS += $(SVG_TARGETS)
+endif
+
+all-local: $(TARGETS)
+
+clean-local:
+   rm -f $(TARGETS)
+
+atomic_queue.png: atomic_queue.svg
+   convert $< $@
+atomic_queue.eps: atomic_queue.svg
+   convert $< $@
+
+ordered_queue.png: ordered_queue.svg
+   convert $< $@
+parallel_queue.eps: parallel_queue.svg
+   convert $< $@
+
+parallel_queue.png: parallel_queue.svg
+   convert $< $@
+ordered_queue.eps: ordered_queue.svg
+   convert $< $@
diff --git a/doc/images/atomic_queue.svg b/doc/images/atomic_queue.svg
new file mode 100644
index 000..bd4958f
--- /dev/null
+++ b/doc/images/atomic_queue.svg
@@ -0,0 +1,302 @@
+
+http://purl.org/dc/elements/1.1/;
+   xmlns:cc="http://creativecommons.org/ns#;
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#;
+   xmlns:svg="http://www.w3.org/2000/svg;
+   xmlns="http://www.w3.org/2000/svg;
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd;
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape;
+   version="1.1"
+   viewBox="0 0 528.09972 227.74805"
+   stroke-miterlimit="10"
+   id="svg4406"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="atomic_queue.svg"
+   width="528.09973"
+   height="227.74805"
+   

[lng-odp] [PATCH 3/3] doc: users-guide convert to asciidoc

2015-10-22 Thread Mike Holmes
Signed-off-by: Mike Holmes 
---
 configure.ac |  1 +
 doc/Makefile.am  |  2 +-
 doc/users-guide/Makefile.am  | 10 +
 doc/users-guide/guide.dox| 14 --
 doc/users-guide/users-guide.adoc | 92 
 5 files changed, 104 insertions(+), 15 deletions(-)
 create mode 100644 doc/users-guide/Makefile.am
 delete mode 100644 doc/users-guide/guide.dox
 create mode 100644 doc/users-guide/users-guide.adoc

diff --git a/configure.ac b/configure.ac
index fde7d94..3a42e22 100644
--- a/configure.ac
+++ b/configure.ac
@@ -316,6 +316,7 @@ AM_CXXFLAGS="-std=c++11"
 AC_CONFIG_FILES([Makefile
 doc/Makefile
 doc/implementers-guide/Makefile
+doc/users-guide/Makefile
 doc/images/Makefile
 example/Makefile
 example/classifier/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 3aa29a3..16d2160 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -6,5 +6,5 @@ clean-local:
 endif
 
 if user_guide
-SUBDIRS += implementers-guide
+SUBDIRS += implementers-guide users-guide
 endif
diff --git a/doc/users-guide/Makefile.am b/doc/users-guide/Makefile.am
new file mode 100644
index 000..312358d
--- /dev/null
+++ b/doc/users-guide/Makefile.am
@@ -0,0 +1,10 @@
+TARGET = $(top_srcdir)/doc/output/users-guide.html
+
+all-local: $(TARGET)
+
+$(TARGET): users-guide.adoc
+   @mkdir -p $(top_srcdir)/doc/output
+   asciidoc --out-file=$@ $<
+
+clean-local:
+   rm -f $(TARGET)
diff --git a/doc/users-guide/guide.dox b/doc/users-guide/guide.dox
deleted file mode 100644
index f9289b8..000
--- a/doc/users-guide/guide.dox
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
- * All rights reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/**
- *
- * @page users_guide Users Guide
- *
- * @section sec_gene Linux Generic
- * @verbinclude linux-generic/README
- *
- */
diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc
new file mode 100644
index 000..1f71e35
--- /dev/null
+++ b/doc/users-guide/users-guide.adoc
@@ -0,0 +1,92 @@
+OpenDataPlane (ODP)  Users-Guide
+
+:toc:
+
+
+:numbered!:
+[abstract]
+Abstract
+
+This document is intended to guide a new ODP application developer.
+Further details about ODP may be found at then http://opendataplane.org[ODP] 
home page.
+
+.Overview of a system running ODP applications
+image::../images/overview.png[align="center"]
+
+ODP is an API specification that allows many implementations to provide 
platform independence, automatic hardware acceleration and CPU scaling to high 
performance networking  applications.
+This document describes how to write an application that can successfully take 
advantage of the API.
+
+Glossary
+
+[glossary]
+odp_worker::
+An opd_worker is a flow of execution a flow of execution that in a Linux 
environment could be a process or thread.
+event::
+An event is a notification that can be placed in a queue.
+
+:numbered:
+The include structure
+-
+Applications only include the 'include/odp.h file which includes the 
'platform//include/plat' files to provide a complete 
definition of the API on that platform.
+The doxygen documentation defining the behavior of the ODP API is all 
contained in the public API files, and the actual definitions for an 
implementation will be found in the per platform directories.
+Per-platform data that might normally be a #define can be recovered via the 
appropriate access function if the #define is not directly visible to the 
application.
+
+.Users include structure
+
+./
+├── include/
+│   ├── odp/
+│   │   └── api/
+│   │   └── The Public API and the documentation.
+│   │
+│   └── odp.h   This file should be the only file included by the application.
+
+
+Initialization
+--
+IMPORTANT: ODP depends on the application to perform a graceful shutdown, 
calling the terminate functions should only be done when the application is 
sure it has closed the ingress and subsequently drained all queues etc.
+
+Startup
+
+The first API that must be called is 'odp_init_global()'.
+This takes two pointers, odp_init_t contains ODP initialization data that is 
platform independent and portable.
+The second odp_platform_init_t is passed un parsed to the  implementation and 
can be used for platform specific data that is not yet, or may never be 
suitable for the ODP API.
+
+The second API that must be called is 'odp_init_local()', this must be called 
once per ODP worker, regardless of worker type.
+
+Shutdown
+~
+Shutdown is the logical reverse of the initialization procedure, with 
'odp_thread_term()' called for each worker before 'odp_term_global()' is called.
+
+image::../images/resource_management.png[align="center"]
+
+Queues
+--
+There are three queue 

[lng-odp] [Bug 1862] New: pktio/netmap.c:168:31: error: cast from 'u_char *

2015-10-22 Thread bugzilla-daemon
https://bugs.linaro.org/show_bug.cgi?id=1862

Bug ID: 1862
   Summary: pktio/netmap.c:168:31: error: cast from 'u_char *
   Product: OpenDataPlane - linux- generic reference
   Version: 1.3
  Hardware: Other
OS: Linux
Status: UNCONFIRMED
  Severity: enhancement
  Priority: ---
 Component: Packet IO
  Assignee: maxim.uva...@linaro.org
  Reporter: mike.hol...@linaro.org
CC: lng-odp@lists.linaro.org

19:24:03 pktio/netmap.c:168:31: error: cast from 'u_char *' (aka 'unsigned char
*') to 'struct dispatch_args *' increases required alignment from 1 to 8
[-Werror,-Wcast-align]
19:24:03 struct dispatch_args *args = (struct dispatch_args *)arg;
19:24:03  ^~~
19:24:03 1 error generated.

https://ci.linaro.org/job/odp-publish/GIT_BRANCH=master,build_type=clang,label=docker-utopic,platform_type=netmap/256/console

-- 
You are receiving this mail because:
You are on the CC list for the bug.___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH 2/3] doc: images: add resource_management.msc for users-guide

2015-10-22 Thread Mike Holmes
Signed-off-by: Mike Holmes 
---
 DEPENDENCIES   |  5 +
 configure.ac   | 10 +
 doc/images/Makefile.am | 13 +--
 doc/images/resource_management.msc | 45 ++
 4 files changed, 71 insertions(+), 2 deletions(-)
 create mode 100644 doc/images/resource_management.msc

diff --git a/DEPENDENCIES b/DEPENDENCIES
index 7d22bde..d551a58 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -194,6 +194,11 @@ Prerequisites for building the OpenDataPlane (ODP) API
   # Debian/Ubuntu
   # apt-get install imagemagick
 
+  Message squence diagrams are stored as msc files and the png or eps versions 
generated when the docs are built
+  mscgen is used
+  #Debian/Ubuntu
+  # apt-get install mscgen
+
 5.1 API Guide
 See http://www.stack.nl/~dimitri/doxygen/manual/install.html
 
diff --git a/configure.ac b/configure.ac
index 0d08e58..fde7d94 100644
--- a/configure.ac
+++ b/configure.ac
@@ -258,6 +258,16 @@ AM_CONDITIONAL([user_guide], [test "x${user_guides}" = 
"xyes" ])
 AM_CONDITIONAL([HAVE_IMAGEMAGIC], [test "x${IMAGEMAGIC}" = "xconvert"])
 
 ##
+# Check for mscgen availability
+##
+   AC_CHECK_PROGS([MSCGEN], [mscgen])
+   if test -z "$MSCGEN";
+  then AC_MSG_WARN([mscgen not found - continuing without sequence 
message support])
+   fi
+
+AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"])
+
+##
 # Save and set temporary compilation flags
 ##
 OLD_LDFLAGS=$LDFLAGS
diff --git a/doc/images/Makefile.am b/doc/images/Makefile.am
index df8f9d4..0f9a8a8 100644
--- a/doc/images/Makefile.am
+++ b/doc/images/Makefile.am
@@ -3,8 +3,10 @@ SVG_SRCS =  atomic_queue.svg \
parallel_queue.svg
 SVG_TARGETS = $(SVG_SRCS:svg=png)
 SVG_TARGETS += $(SVG_SRCS:svg=eps)
+MSG_SRCS = resource_management.msc
+MSG_TARGETS = $(MSG_SRCS:msc=png)
 
-EXTRA_DIST = $(SVG_SRCS)
+EXTRA_DIST = $(SVG_SRCS) $(MSG_SRCS)
 
 TARGETS=
 
@@ -12,10 +14,14 @@ if HAVE_IMAGEMAGIC
 TARGETS += $(SVG_TARGETS)
 endif
 
+if HAVE_MSCGEN
+TARGETS += $(MSG_TARGETS)
+endif
+
 all-local: $(TARGETS)
 
 clean-local:
-   rm -f $(TARGETS)
+   rm -f $(SVG_TARGETS) $(MSG_TARGETS)
 
 atomic_queue.png: atomic_queue.svg
convert $< $@
@@ -31,3 +37,6 @@ parallel_queue.png: parallel_queue.svg
convert $< $@
 ordered_queue.eps: ordered_queue.svg
convert $< $@
+
+resource_management.png: resource_management.msc
+   mscgen -T png -i $< -o $@
diff --git a/doc/images/resource_management.msc 
b/doc/images/resource_management.msc
new file mode 100644
index 000..fa54c4c
--- /dev/null
+++ b/doc/images/resource_management.msc
@@ -0,0 +1,45 @@
+# ODP resource management
+msc {
+
+  a,b,c;
+
+  a->a [ label = "odp_init_global()"];
+  a->b [ label = "odp_thread_start()"];
+  a->c [ label = "odp_thread_start()"];
+  a->a [ label = "odp_init_local()"],
+  b->b [ label = "odp_init_local()"],
+  c->c [ label = "odp_init_local()"];
+  ---;
+  b->b [ label = "pool = odp_pool_create()", textcolour="#7f7fff"];
+
+  a->a [ label = "barrier()"],
+  b->b [ label = "barrier()"],
+  c->c [ label = "barrier()"];
+
+  a->a [ label = " buf = alloc(pool)", textcolour="#ffb000"],
+  b->b [ label = " buf = alloc(pool)", textcolour="#ffb000"],
+  c->c [ label = " buf = alloc(pool)", textcolour="#ffb000"];
+
+  a->a [ label = " free(buf)", textcolour="#ffb000"],
+  b->b [ label = " free(buf)", textcolour="#ffb000"],
+  c->c [ label = " free(buf)", textcolour="#ffb000"];
+
+  a->a [ label = "barrier()"],
+  b->b [ label = "barrier()"],
+  c->c [ label = "barrier()"];
+
+  a->a [ label = "pool = odp_pool_destroy(pool)", textcolour="#7f7fff"];
+  ---;
+  a->a [ label = "barrier()"],
+  b->b [ label = "barrier()"],
+  c->c [ label = "barrier()"];
+
+  ---  [ label = "do work", ID="*" ];
+
+  a->a [ label = "odp_term_local()"],
+  b->b [ label = "odp_term_local()"],
+  c->c [ label = "odp_term_local()"];
+  b->a [ label = "odp_thread_term()"];
+  c->a [ label = "odp_thread_term()"];
+  a->a [ label = "odp_term_global()"];
+}
-- 
2.5.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [RFC API-NEXT PATCH 0/6] Multiple queue packet IO API

2015-10-22 Thread Stuart Haslam
On Thu, Oct 22, 2015 at 06:06:58PM +0300, Nikita Kalyazin wrote:
> Hi,
> 
> > [Alex] ODP queues are neither software nor hardware by definition, each
> > implementation is free to implement them as they see fit. Also PacketI/O
> > abstraction is not an abstraction for a NIC device. The ODP way to use 
> > multiple
> > queues for ingress is through the classifier. There was a former proposal of
> > enabling RSS at pktio level but it was not accepted. I also noticed that 
> > this
> > patch tries to introduce multiple default queues which is kind of confusing 
> > -
> > default traffic is all traffic which does not satisfy classifier criteria. 
> > For
> > output, multiple queues are used by the means of TM api. 
> As I understand, ODP implies three options of ingress processing:
>  - "recv" (poll pktio with raw recv() method);

I think we should be deprecating this method, and users of it move over
to using polled (or scheduled) queues. There should be no performance
penalty and the presence of recv mode just causes confusion.

>  - "poll" (poll poll pktio via default input queue associated with the pktio);

It's also possible to poll an input queue which is associated with a
class of service. Although, looking at the validation test and example
just now I see that they don't do this and they work exclusively with
scheduled queues, this should be changed.

>  - "sched" (call schedule() which makes use of classifier and queue 
> priorities).
> Looks like each ODP implementation should support all the three options.
> 
> For "sched" option, classification may be implemented in hardware, and ODP
> queues, in their turn, can also be implemented in hardware.  The hardware 
> would
> distribute packets to its hardware queues according to PMRs or L2/L3 QoS.

There's no way to do hash based distribution with the classification API
currently, it would need to be extended. The initial design included
some APIs for this but they weren't fully formed and didn't make it into
the release. There has been some debate since then about whether support
should be added as part of the pktio or classification API, but consensus
seems to be that the classification API is the right place.

The rough idea would be to use the classification API to assign a CoS
and then packets matching that CoS are distributed to a number of queues
based on a hash of a set of preconfigured fields. At the minute packets
can only be delivered to a single queue (assigned using odp_cos_set_queue())
so this would need to be extended. If the hardware is only capable of
RSS type distribution then you'd have no PMR or L2/L3 based CoS and
everything would be distributed within the default CoS.

> For "recv" option, the only way possible to access NIC's hardware queues
> (if any), is to call recv() on a specified queue explicitly.  So there should 
> be
> an API for it.  In my patch I proposed such APIs (odp_pktio_recv_queue()).
> I admit, this might be not the best API name possible.  However I don't see 
> any
> other way to access NIC's hardware queues at "recv" level.

The right way to do this is to expose the hardware queues as ODP queues
(odp_queue_t).

ODP queues should map directly to hardware queues wherever possible, so
calling odp_queue_deq[_multi]() on a packet input queue reads packets
directly from the hardware queue.

> We can add
> hw_queue_id parameter to existing odp_pktio_recv() alternatively (same way as
> DPDK does with rte_eth_rx_burst()).  

No, the queue_id passed to rte_eth_rx_burst() should be seen as being
equivalent to an ODP queue. So these APIs are logically equivalent;

uint16_t rte_eth_rx_burst(uint8_t port_id, uint16_t queue_id, struct rte_mbuf 
**rx_pkts, const uint16_t nb_pkts);

int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num);

> In case of using such an explicit hardware
> queue polling, RSS should be configured somehow to distribute packets across 
> them.
>
> For "poll" option, it's not completely clear to me how it should relate to 
> NIC's
> hardware queues.  It looks like classification is not involved here, and this
> option isn't really different from "recv".  If this is correct, presence of
> multiple default input queues is reasonable, since they're directly mapped to
> NIC's hardware queues, and odp_queue_deq() simply extracts a packet from the
> appropriate HW queue.
> 
> -- 
> 
> Best regards,
> 
> Nikita Kalyazin,
> n.kalya...@samsung.com
> 
> Software Engineer
> Virtualization Group
> Samsung R Institute Russia
> Tel: +7 (495) 797-25-00 #3816
> Tel: +7 (495) 797-25-03
> Office #1501, 12-1, Dvintsev str.,
> Moscow, 127018, Russia
> 
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [API-NEXT PATCH] api: pktio: add odp_pktio_print() API

2015-10-22 Thread Savolainen, Petri (Nokia - FI/Espoo)
Reviewed-by: Petri Savolainen 


> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> Matias Elo
> Sent: Wednesday, October 21, 2015 1:29 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [API-NEXT PATCH] api: pktio: add odp_pktio_print() API
> 
> Add API function for printing implementation specific pktio
> debug information.
> 
> Signed-off-by: Matias Elo 
> ---
>  include/odp/api/packet_io.h|  9 
>  platform/linux-generic/odp_packet_io.c | 40
> ++
>  2 files changed, 49 insertions(+)
> 
> diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
> index 3479af1..e8126b2 100644
> --- a/include/odp/api/packet_io.h
> +++ b/include/odp/api/packet_io.h
> @@ -358,6 +358,15 @@ uint64_t odp_pktio_to_u64(odp_pktio_t pktio);
>  void odp_pktio_param_init(odp_pktio_param_t *param);
> 
>  /**
> + * Print pktio info to the console
> + *
> + * Print implementation-defined pktio debug information to the console.
> + *
> + * @param pktio  Packet IO handle
> + */
> +void odp_pktio_print(odp_pktio_t pktio);
> +
> +/**
>   * @}
>   */
> 
> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-
> generic/odp_packet_io.c
> index b3ca4c8..de08628 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -820,3 +820,43 @@ void odp_pktio_param_init(odp_pktio_param_t *params)
>  {
>   memset(params, 0, sizeof(odp_pktio_param_t));
>  }
> +
> +void odp_pktio_print(odp_pktio_t id)
> +{
> + pktio_entry_t *entry;
> + uint8_t addr[ETH_ALEN];
> + int max_len = 512;
> + char str[max_len];
> + int len = 0;
> + int n = max_len - 1;
> +
> + entry = get_pktio_entry(id);
> + if (entry == NULL) {
> + ODP_DBG("pktio entry %d does not exist\n", id);
> + return;
> + }
> +
> + len += snprintf([len], n - len,
> + "pktio\n");
> + len += snprintf([len], n - len,
> + "  handle   %" PRIu64 "\n", odp_pktio_to_u64(id));
> + len += snprintf([len], n - len,
> + "  name %s\n", entry->s.name);
> + len += snprintf([len], n - len,
> + "  state%s\n",
> + entry->s.state ==  STATE_START ? "start" :
> +(entry->s.state ==  STATE_STOP ? "stop" : "unknown"));
> + memset(addr, 0, sizeof(addr));
> + odp_pktio_mac_addr(id, addr, ETH_ALEN);
> + len += snprintf([len], n - len,
> + "  mac  %02x:%02x:%02x:%02x:%02x:%02x\n",
> + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
> + len += snprintf([len], n - len,
> + "  mtu  %d\n", odp_pktio_mtu(id));
> + len += snprintf([len], n - len,
> + "  promisc  %s\n",
> + odp_pktio_promisc_mode(id) ? "yes" : "no");
> + str[len] = '\0';
> +
> + ODP_PRINT("\n%s\n", str);
> +}
> --
> 1.9.1
> 
> ___
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [PATCH v4 0/6] l2fwd test improvements

2015-10-22 Thread Savolainen, Petri (Nokia - FI/Espoo)
Reviewed-by: Petri Savolainen 

> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> Matias Elo
> Sent: Wednesday, October 21, 2015 2:13 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [PATCH v4 0/6] l2fwd test improvements
> 
> Added various improvements to the l2fwd test application:
> - Supports using odd number of ports
> - Scheduler queue type can be selected
> - Added options for enabling/disabling eth address filling
> 
> New options:
> -d, --dst_change <0/1>: Enable/disable changing packets' dst eth addresses
> -s, --src_change <0/1>: Enable/disable changing packets' src eth addresses
> -m, --mode <0>: Send packets directly from NIC (default)
><1>: Send packets through scheduler sync none queues
><2>: Send packets through scheduler sync atomic queues
><3>: Send packets through scheduler sync ordered queues
> 
> v2:
> - Rebased to master
> - Word copy ethernet addresses
> 
> v3:
> - Rebased to master
> 
> v4:
> - Rebased to master
> - Load words before usage in fill_eth_addrs() (Ola Liljedahl)
> 
> Matias Elo (6):
>   test: l2fwd: add option to change destination eth addresses
>   test: l2fwd: add option to select scheduler queue type
>   test: l2fwd: fix crash when accuracy is set to 0
>   test: l2fwd: add support for using odd number of ports
>   test: l2fwd: add option to disable filling eth addresses
>   test: l2fwd: word copy ethernet addresses
> 
>  test/performance/odp_l2fwd.c | 279 +--
> 
>  1 file changed, 190 insertions(+), 89 deletions(-)
> 
> --
> 1.9.1
> 
> ___
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv5 1/2] api: define pktio statistics api

2015-10-22 Thread Maxim Uvarov
Signed-off-by: Maxim Uvarov 
---
 include/odp/api/packet_io_stats.h  | 133 +
 platform/linux-generic/include/odp/packet_io.h |   1 +
 2 files changed, 134 insertions(+)
 create mode 100644 include/odp/api/packet_io_stats.h

diff --git a/include/odp/api/packet_io_stats.h 
b/include/odp/api/packet_io_stats.h
new file mode 100644
index 000..1bff9ca
--- /dev/null
+++ b/include/odp/api/packet_io_stats.h
@@ -0,0 +1,133 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP Packet IO
+ */
+
+#ifndef ODP_API_PACKET_IO_STATS_H_
+#define ODP_API_PACKET_IO_STATS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup odp_packet_io ODP PACKET IO
+ *  @{
+ */
+
+/**
+ * Packet IO statistics
+ *
+ * Packet IO statictics counters follow RFCs for Management Information Base
+ * (MIB)for use with network management protocols in the Internet community:
+ * https://tools.ietf.org/html/rfc3635
+ * https://tools.ietf.org/html/rfc2863
+ * https://tools.ietf.org/html/rfc2819
+ */
+typedef struct odp_pktio_stats_t {
+   /**
+* The number of octets in valid MAC frames received on this interface,
+* including the MAC header and FCS. See ifHCInOctets counter
+* description in RFC 3635 for details.
+*/
+   uint64_t in_octets;
+   /**
+* The number of packets, delivered by this sub-layer to a higher
+* (sub-)layer, which were not addressed to a multicast or broadcast
+* address at this sub-layer. See InUcastPkts in RFC 2863.
+*/
+   uint64_t in_ucast_pkts;
+   /**
+* The number of inbound packets which were chosen to be discarded
+* even though no errors had been detected to preven their being
+* deliverable to a higher-layer protocol.  One possible reason for
+* discarding such a packet could be to free up buffer space.
+* See InDiscards in RFC 2863.
+*/
+   uint64_t in_discards;
+   /**
+* The sum for this interface of AlignmentErrors, FCSErrors, 
FrameTooLongs,
+* InternalMacReceiveErrors. See InErrors in RFC 3635.
+*/
+   uint64_t in_errors;
+   /**
+* For packet-oriented interfaces, the number of packets received via
+* the interface which were discarded because of an unknown or
+* unsupported protocol.  For character-oriented or fixed-length
+* interfaces that support protocol multiplexing the number of
+* transmission units received via the interface which were discarded
+* because of an unknown or unsupported protocol.  For any interface
+* that does not support protocol multiplexing, this counter will always
+* be 0. See InUnknownProtos in RFC 2863.
+*/
+   uint64_t in_unknown_protos;
+   /**
+* The number of octets transmitted in valid MAC frames on this
+* interface, including the MAC header and FCS.  This does include
+* the number of octets in valid MAC Control frames transmitted on
+* this interface. See OutOctets in RFC 3635.
+*/
+   uint64_t out_octets;
+   /**
+* The total number of packets that higher-level protocols requested
+* be transmitted, and which were not addressed to a multicast or
+* broadcast address at this sub-layer, including those that were
+* discarded or not sent. does not include MAC Control frames.
+* See OutUcastPkts in RFC 2863, 3635.
+*/
+   uint64_t out_ucast_pkts;
+   /**
+* The number of outbound packets which were chosen to be discarded
+* even though no errors had been detected to prevent their being
+* transmitted.  One possible reason for discarding such a packet could
+* be to free up buffer space.  See  OutDiscards in  RFC 2863.
+*/
+   uint64_t out_discards;
+   /**
+* The sum for this interface of SQETestErrors, LateCollisions,
+* ExcessiveCollisions, InternalMacTransmitErrors and
+* CarrierSenseErrors. See OutErrors in RFC 3635.
+*/
+   uint64_t out_errors;
+} odp_pktio_stats_t;
+
+/**
+ * Get statistics for pktio handle
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] *stats   Output buffer for counters
+ * @retval  0 on success
+ * @retval <0 on failure
+ *
+ * @note: If counter is not supported by platform it has
+ *   to be set to 0.
+ */
+int odp_pktio_stats(odp_pktio_t pktio,
+   odp_pktio_stats_t *stats);
+
+/**
+ * Reset statistics for pktio handle
+ *
+ * Reset all pktio counters to 0.
+ * @param  pktioPacket IO handle
+ * @retval  0 on success
+ * @retval <0 on failure
+ *
+ */
+int odp_pktio_stats_reset(odp_pktio_t pktio);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git 

[lng-odp] [PATCH v2 2/2] linux-generic: netmap: use separate rx and tx descriptors

2015-10-22 Thread Matias Elo
Using separate file descriptors enables using rx and tx
functions simultaneously from different threads.

Previously netmap tx queues were flushed only after no free
slots were left which caused long delays on slow packet
rates. Now queues are flushed after each packet
burst.

Signed-off-by: Matias Elo 
---

v2:
  - Rebased to master

 platform/linux-generic/include/odp_packet_netmap.h |  3 ++-
 platform/linux-generic/pktio/netmap.c  | 29 ++
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_netmap.h 
b/platform/linux-generic/include/odp_packet_netmap.h
index 23aea5b..0577dfe 100644
--- a/platform/linux-generic/include/odp_packet_netmap.h
+++ b/platform/linux-generic/include/odp_packet_netmap.h
@@ -15,7 +15,8 @@
 typedef struct {
odp_pool_t pool;/**< pool to alloc packets from */
size_t max_frame_len;   /**< buf_size - sizeof(pkt_hdr) */
-   struct nm_desc *desc;   /**< netmap meta-data for the device */
+   struct nm_desc *rx_desc;/**< netmap meta-data for the device */
+   struct nm_desc *tx_desc;/**< netmap meta-data for the device */
uint32_t if_flags;  /**< interface flags */
int sockfd; /**< control socket */
unsigned char if_mac[ETH_ALEN]; /**< eth mac address */
diff --git a/platform/linux-generic/pktio/netmap.c 
b/platform/linux-generic/pktio/netmap.c
index 0dfe511..b3a2ca2 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -89,10 +89,13 @@ static int netmap_close(pktio_entry_t *pktio_entry)
 {
pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
 
-   if (pkt_nm->desc != NULL) {
-   nm_close(pkt_nm->desc);
+   if (pkt_nm->rx_desc != NULL) {
+   nm_close(pkt_nm->rx_desc);
mmap_desc.mem = NULL;
}
+   if (pkt_nm->tx_desc != NULL)
+   nm_close(pkt_nm->tx_desc);
+
if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
__odp_errno = errno;
ODP_ERR("close(sockfd): %s\n", strerror(errno));
@@ -131,18 +134,21 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
pktio_entry_t *pktio_entry,
snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
 
if (mmap_desc.mem == NULL)
-   pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL, NULL);
+   pkt_nm->rx_desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL,
+ NULL);
else
-   pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL |
-  NM_OPEN_NO_MMAP, _desc);
-   if (pkt_nm->desc == NULL) {
+   pkt_nm->rx_desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL |
+ NM_OPEN_NO_MMAP, _desc);
+   pkt_nm->tx_desc = nm_open(ifname, NULL, NM_OPEN_NO_MMAP, _desc);
+
+   if (pkt_nm->rx_desc == NULL || pkt_nm->tx_desc == NULL) {
ODP_ERR("nm_open(%s) failed\n", ifname);
goto error;
}
 
if (mmap_desc.mem == NULL) {
-   mmap_desc.mem = pkt_nm->desc->mem;
-   mmap_desc.memsize = pkt_nm->desc->memsize;
+   mmap_desc.mem = pkt_nm->rx_desc->mem;
+   mmap_desc.memsize = pkt_nm->rx_desc->memsize;
}
 
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -215,7 +221,7 @@ static int netmap_recv(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_table[],
   unsigned num)
 {
struct dispatch_args args;
-   struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.desc;
+   struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.rx_desc;
struct pollfd polld;
 
polld.fd = nm_desc->fd;
@@ -236,8 +242,8 @@ static int netmap_recv(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_table[],
 static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
   unsigned num)
 {
-   struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.desc;
struct pollfd polld;
+   struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.tx_desc;
unsigned i, nb_tx;
uint8_t *frame;
uint32_t frame_len;
@@ -259,6 +265,9 @@ static int netmap_send(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_table[],
break;
}
}
+   /* Send pending packets */
+   poll(, 1, 0);
+
for (i = 0; i < nb_tx; i++)
odp_packet_free(pkt_table[i]);
 
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2 1/2] linux-generic: netmap: wait for the interface to become active

2015-10-22 Thread Matias Elo
Netmap interface takes a few seconds to become active after
setup. This caused several test applications to fail.
Check link status at the end of netmap_open() to fix this.

Signed-off-by: Matias Elo 
---

v2:
  - Rebased to master
  - The other end of a directly attached loopback cable may come up after a
small delay. Sleep once after link is detected to enable running validation
tests with directly attached loopback cable. (Stuart Haslam)

 platform/linux-generic/pktio/netmap.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/platform/linux-generic/pktio/netmap.c 
b/platform/linux-generic/pktio/netmap.c
index ab4667e..0dfe511 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -28,6 +28,7 @@ static struct nm_desc mmap_desc;  /** Used to store the 
mmap address;
  filled in first time, used for
  subsequent calls to nm_open */
 
+#define NM_OPEN_RETRIES 5
 #define NM_INJECT_RETRIES 10
 
 struct dispatch_args {
@@ -70,6 +71,10 @@ static int netmap_do_ioctl(pktio_entry_t *pktio_entry, 
unsigned long cmd,
pkt_nm->if_flags = (ifr.ifr_flags << 16) |
(0x & ifr.ifr_flags);
break;
+   case SIOCETHTOOL:
+   if (subcmd == ETHTOOL_GLINK)
+   return !eval.data;
+   break;
default:
break;
}
@@ -84,9 +89,10 @@ static int netmap_close(pktio_entry_t *pktio_entry)
 {
pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
 
-   if (pkt_nm->desc != NULL)
+   if (pkt_nm->desc != NULL) {
nm_close(pkt_nm->desc);
-
+   mmap_desc.mem = NULL;
+   }
if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
__odp_errno = errno;
ODP_ERR("close(sockfd): %s\n", strerror(errno));
@@ -101,6 +107,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
pktio_entry_t *pktio_entry,
char ifname[IFNAMSIZ + 7]; /* netmap: */
int err;
int sockfd;
+   int i;
pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
 
if (getenv("ODP_PKTIO_DISABLE_NETMAP"))
@@ -155,7 +162,14 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
pktio_entry_t *pktio_entry,
if (err)
goto error;
 
-   return 0;
+   /* Wait for the link to come up */
+   for (i = 0; i < NM_OPEN_RETRIES; i++) {
+   err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL, ETHTOOL_GLINK);
+   sleep(1);
+   if (err == 0)
+   return 0;
+   }
+   ODP_ERR("%s didn't come up\n", pktio_entry->s.name);
 
 error:
netmap_close(pktio_entry);
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v5 1/5] performance: odp_pktio_perf: fix potential overflow in wait loop

2015-10-22 Thread Ivan Khoronzhuk
There cannot be used direct comparison of timestamps of counter
that can overflow, better to compare ranges.

Signed-off-by: Ivan Khoronzhuk 
---
 test/performance/odp_pktio_perf.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/test/performance/odp_pktio_perf.c 
b/test/performance/odp_pktio_perf.c
index efd26dc..ae5b4c0 100644
--- a/test/performance/odp_pktio_perf.c
+++ b/test/performance/odp_pktio_perf.c
@@ -591,9 +591,13 @@ static int setup_txrx_masks(odp_cpumask_t *thd_mask_tx,
  */
 static void busy_loop_ns(uint64_t wait_ns)
 {
-   uint64_t end = odp_time_cycles() + odp_time_ns_to_cycles(wait_ns);
-   while (odp_time_cycles() < end)
-   ;
+   uint64_t diff;
+   uint64_t start_time = odp_time_cycles();
+   uint64_t wait = odp_time_ns_to_cycles(wait_ns);
+
+   do {
+   diff = odp_time_diff_cycles(start_time, odp_time_cycles());
+   } while (diff < wait);
 }
 
 /*
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v5 4/5] linux-generic: align implementation with new time API

2015-10-22 Thread Ivan Khoronzhuk
The time API names were changed from odp_time_cycle* to odp_time*.
Also new time API operates with new opaque type - odp_time_t, as
result several new API calls were added. For odp_schdule.c avoid
"cycle" word usage as it was left from old time API names.

This patch is intended to align linux-generic implementation with
new time API.

Signed-off-by: Ivan Khoronzhuk 
---
 platform/linux-generic/Makefile.am |  1 +
 .../linux-generic/include/odp/plat/time_types.h| 36 +
 platform/linux-generic/include/odp/time.h  |  1 +
 platform/linux-generic/odp_schedule.c  | 16 +++---
 platform/linux-generic/odp_time.c  | 62 ++
 5 files changed, 97 insertions(+), 19 deletions(-)
 create mode 100644 platform/linux-generic/include/odp/plat/time_types.h

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 85c976d..b0842c5 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -74,6 +74,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/strong_types.h \
  $(srcdir)/include/odp/plat/thrmask_types.h \
  $(srcdir)/include/odp/plat/ticketlock_types.h \
+ $(srcdir)/include/odp/plat/time_types.h \
  $(srcdir)/include/odp/plat/timer_types.h \
  $(srcdir)/include/odp/plat/version_types.h
 
diff --git a/platform/linux-generic/include/odp/plat/time_types.h 
b/platform/linux-generic/include/odp/plat/time_types.h
new file mode 100644
index 000..9ba1508
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/time_types.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP time service
+ */
+
+#ifndef ODP_TIME_TYPES_H_
+#define ODP_TIME_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_time
+ *  @{
+ **/
+
+typedef uint64_t odp_time_t;
+
+#define ODP_TIME_NULL ((odp_time_t)0)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/time.h 
b/platform/linux-generic/include/odp/time.h
index 3a3960b..44e0d0d 100644
--- a/platform/linux-generic/include/odp/time.h
+++ b/platform/linux-generic/include/odp/time.h
@@ -21,6 +21,7 @@ extern "C" {
 
 
 
+#include 
 #include 
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/odp_schedule.c 
b/platform/linux-generic/odp_schedule.c
index 6df8073..e88f3f2 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -585,10 +585,10 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t 
wait,
 odp_event_t out_ev[],
 unsigned int max_num, unsigned int max_deq)
 {
-   uint64_t start_cycle, cycle, diff;
+   odp_time_t start_time, time, diff;
int ret;
 
-   start_cycle = 0;
+   start_time = ODP_TIME_NULL;
 
while (1) {
ret = schedule(out_queue, out_ev, max_num, max_deq);
@@ -602,15 +602,15 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t 
wait,
if (wait == ODP_SCHED_NO_WAIT)
break;
 
-   if (start_cycle == 0) {
-   start_cycle = odp_time_cycles();
+   if (!odp_time_cmp(start_time, ODP_TIME_NULL)) {
+   start_time = odp_time();
continue;
}
 
-   cycle = odp_time_cycles();
-   diff  = odp_time_diff_cycles(start_cycle, cycle);
+   time = odp_time();
+   diff  = odp_time_diff(start_time, time);
 
-   if (wait < diff)
+   if (odp_time_cmp(diff, wait) > 0)
break;
}
 
@@ -651,7 +651,7 @@ void odp_schedule_resume(void)
 
 uint64_t odp_schedule_wait_time(uint64_t ns)
 {
-   return odp_time_ns_to_cycles(ns);
+   return odp_time_to_u64(odp_time_from_ns(ns));
 }
 
 
diff --git a/platform/linux-generic/odp_time.c 
b/platform/linux-generic/odp_time.c
index abafd12..e0aceb1 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -14,33 +14,73 @@
 
 #define GIGA 10
 
-uint64_t odp_time_cycles(void)
+static inline
+uint64_t time_to_tick(odp_time_t time)
 {
-   return odp_cpu_cycles();
+   return (uint64_t)time;
 }
 
-uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2)
+static inline
+odp_time_t tick_to_time(uint64_t tick)
 {
-   return _odp_cpu_cycles_diff(t1, t2);
+   return (odp_time_t)tick;
 }
 
-uint64_t odp_time_cycles_to_ns(uint64_t cycles)
+odp_time_t odp_time(void)
+{
+   return tick_to_time(odp_cpu_cycles());
+}
+
+odp_time_t odp_time_diff(odp_time_t t1, odp_time_t t2)
+{
+   return tick_to_time(_odp_cpu_cycles_diff(t1, t2));
+}
+
+uint64_t 

[lng-odp] [API-NEXT PATCH v5 5/5] test/example: avoid "cycle" word usage

2015-10-22 Thread Ivan Khoronzhuk
The word "cycle" is left from old API time names. The "cycle" is
ambiguous word, especially when it can be used for other purposes.
So better to use "tick" or "time" word or just "t" symbol.

Signed-off-by: Ivan Khoronzhuk 
---
 test/performance/odp_pktio_perf.c | 35 ++---
 test/validation/scheduler/scheduler.c |  5 ++---
 test/validation/time/time.c   | 42 +--
 test/validation/time/time.h   |  6 ++---
 4 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/test/performance/odp_pktio_perf.c 
b/test/performance/odp_pktio_perf.c
index cf29802..5e52ae2 100644
--- a/test/performance/odp_pktio_perf.c
+++ b/test/performance/odp_pktio_perf.c
@@ -106,7 +106,7 @@ struct tx_stats_s {
uint64_t tx_cnt;/* Packets transmitted */
uint64_t alloc_failures;/* Packet allocation failures */
uint64_t enq_failures;  /* Enqueue failures */
-   odp_time_t idle_cycles; /* Idle cycle count in TX loop */
+   odp_time_t idle_ticks;  /* Idle ticks count in TX loop */
 };
 
 typedef union tx_stats_u {
@@ -305,8 +305,8 @@ static void *run_thread_tx(void *arg)
int thr_id;
odp_queue_t outq;
pkt_tx_stats_t *stats;
-   odp_time_t start_cycles, cur_cycles, send_duration;
-   odp_time_t burst_start_cycles, burst_gap_cycles;
+   odp_time_t start_time, cur_time, send_duration;
+   odp_time_t burst_start_time, burst_gap;
uint32_t batch_len;
int unsent_pkts = 0;
odp_event_t  tx_event[BATCH_LEN_MAX];
@@ -328,36 +328,35 @@ static void *run_thread_tx(void *arg)
if (outq == ODP_QUEUE_INVALID)
LOG_ABORT("Failed to get output queue for thread %d\n", thr_id);
 
-   burst_gap_cycles = odp_time_from_ns(
+   burst_gap = odp_time_from_ns(
ODP_TIME_SEC / (targs->pps / targs->batch_len));
send_duration = odp_time_from_ns(targs->duration * ODP_TIME_SEC);
 
odp_barrier_wait(>tx_barrier);
 
-   cur_cycles = odp_time();
-   start_cycles   = cur_cycles;
-   burst_start_cycles = odp_time_diff(burst_gap_cycles, cur_cycles);
-   while (odp_time_diff(start_cycles, cur_cycles) < send_duration) {
+   cur_time = odp_time();
+   start_time   = cur_time;
+   burst_start_time = odp_time_diff(burst_gap, cur_time);
+   while (odp_time_diff(start_time, cur_time) < send_duration) {
unsigned alloc_cnt = 0, tx_cnt;
 
-   if (odp_time_diff(burst_start_cycles, cur_cycles)
-   < burst_gap_cycles) {
-   cur_cycles = odp_time();
+   if (odp_time_diff(burst_start_time, cur_time) < burst_gap) {
+   cur_time = odp_time();
if (!odp_time_cmp(ODP_TIME_NULL, idle_start))
-   idle_start = cur_cycles;
+   idle_start = cur_time;
continue;
}
 
if (odp_time_cmp(ODP_TIME_NULL, idle_start)) {
-   odp_time_t diff = odp_time_diff(idle_start, cur_cycles);
+   odp_time_t diff = odp_time_diff(idle_start, cur_time);
 
-   stats->s.idle_cycles =
-   odp_time_sum(diff, stats->s.idle_cycles);
+   stats->s.idle_ticks =
+   odp_time_sum(diff, stats->s.idle_ticks);
 
idle_start = ODP_TIME_NULL;
}
 
-   burst_start_cycles += burst_gap_cycles;
+   burst_start_time += burst_gap;
 
alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts);
if (alloc_cnt != batch_len)
@@ -368,14 +367,14 @@ static void *run_thread_tx(void *arg)
stats->s.enq_failures += unsent_pkts;
stats->s.tx_cnt += tx_cnt;
 
-   cur_cycles = odp_time();
+   cur_time = odp_time();
}
 
VPRINT(" %02d: TxPkts %-8"PRIu64" EnqFail %-6"PRIu64
   " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
   thr_id, stats->s.tx_cnt,
   stats->s.enq_failures, stats->s.alloc_failures,
-  odp_time_to_ns(stats->s.idle_cycles) / (uint64_t)ODP_TIME_MSEC);
+  odp_time_to_ns(stats->s.idle_ticks) / (uint64_t)ODP_TIME_MSEC);
 
return NULL;
 }
diff --git a/test/validation/scheduler/scheduler.c 
b/test/validation/scheduler/scheduler.c
index 96e0781..8d8a0a5 100644
--- a/test/validation/scheduler/scheduler.c
+++ b/test/validation/scheduler/scheduler.c
@@ -465,11 +465,10 @@ static void *schedule_common_(void *arg)
CU_ASSERT(from != ODP_QUEUE_INVALID);
if (locked) {
int cnt;
-   odp_time_t cycles = ODP_TIME_NULL;
+  

[lng-odp] [PATCHv1] example:generator : Fix statistics print

2015-10-22 Thread ion.grigore
From: Grigore Ion 

The statistics are displayed at a fixed time interval. If the configured
number of packets is processed before this interval expires, no statistic
is shown. If many packets are processed it is very possible the last
statistic is not displayed.

Signed-off-by: Grigore Ion 
---
 example/generator/odp_generator.c |   61 +++--
 1 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/example/generator/odp_generator.c 
b/example/generator/odp_generator.c
index 34fb226..ab592bd 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -103,6 +103,7 @@ static void usage(char *progname);
 static int scan_ip(char *buf, unsigned int *paddr);
 static int scan_mac(char *in, odph_ethaddr_t *des);
 static void tv_sub(struct timeval *recvtime, struct timeval *sendtime);
+static void print_on_time_expire_stats(int verbose_interval);
 static void print_global_stats(int num_workers);
 
 /**
@@ -581,13 +582,45 @@ static void *gen_recv_thread(void *arg)
 }
 
 /**
+ * printing on time interval expiration statistics
+ *
+ */
+static void print_on_time_expire_stats(int verbose_interval)
+{
+   uint64_tpkts, pps;
+   static uint64_t pkts_prev, maximum_pps;
+
+   if (args->appl.mode == APPL_MODE_RCV) {
+   pkts = odp_atomic_load_u64();
+   printf(" total receive(UDP: %" PRIu64 ")\n", pkts);
+   return;
+   }
+
+   if (args->appl.mode == APPL_MODE_PING) {
+   pkts = odp_atomic_load_u64();
+   printf(" total receive(ICMP: %" PRIu64 ")\n", pkts);
+   }
+
+   pkts = odp_atomic_load_u64();
+   printf(" total sent: %" PRIu64 "\n", pkts);
+
+   if (args->appl.mode == APPL_MODE_UDP) {
+   pps = (pkts - pkts_prev) / verbose_interval;
+   if (pps > maximum_pps)
+   maximum_pps = pps;
+   printf(" %" PRIu64 " pps, %" PRIu64 " max pps\n",
+  pps, maximum_pps);
+   pkts_prev = pkts;
+   }
+}
+
+/**
  * printing verbose statistics
  *
  */
 static void print_global_stats(int num_workers)
 {
uint64_t start, now, diff;
-   uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0;
int verbose_interval = 20;
odp_thrmask_t thrd_mask;
 
@@ -612,29 +645,11 @@ static void print_global_stats(int num_workers)
 
start = odp_time_cycles();
 
-   if (args->appl.mode == APPL_MODE_RCV) {
-   pkts = odp_atomic_load_u64();
-   printf(" total receive(UDP: %" PRIu64 ")\n", pkts);
-   continue;
-   }
-
-   if (args->appl.mode == APPL_MODE_PING) {
-   pkts = odp_atomic_load_u64();
-   printf(" total receive(ICMP: %" PRIu64 ")\n", pkts);
-   }
-
-   pkts = odp_atomic_load_u64();
-   printf(" total sent: %" PRIu64 "\n", pkts);
-
-   if (args->appl.mode == APPL_MODE_UDP) {
-   pps = (pkts - pkts_prev) / verbose_interval;
-   if (pps > maximum_pps)
-   maximum_pps = pps;
-   printf(" %" PRIu64 " pps, %" PRIu64 " max pps\n",
-  pps, maximum_pps);
-   pkts_prev = pkts;
-   }
+   print_on_time_expire_stats(verbose_interval);
}
+   /* Print remaining statistics */
+   if (odp_time_cycles_to_ns(diff) < verbose_interval * ODP_TIME_SEC)
+   print_on_time_expire_stats(verbose_interval);
 }
 
 /**
-- 
1.7.3.4

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v5 3/5] api: time: unbind CPU cycles from time API

2015-10-22 Thread Ivan Khoronzhuk
Current time API supposes that frequency of counter is equal
to CPU frequency. But that's not always true, for instance,
in case if no access to CPU cycle counter, another hi-resolution
timer can be used, and it`s rate can be different from CPU
rate. There is no big difference in which cycles to measure
time, the better hi-resolution timer the better measurements.
So, unbind CPU cycle counter from time API by eliminating word
"cycle" as it's believed to be used with CPU.

Also add new opaque type for time odp_time_t, as it asks user to use
API and abstracts time from units. New odp_time_t requires several
additional API functions to be added:

odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
int odp_time_cmp(odp_time_t t1, odp_time_t t2);
uint64_t odp_time_to_u64(odp_time_t hdl);

Also added new definition that represents 0 ticks for time -
ODP_TIME_NULL. It can be used instead of odp_time_from_ns(0) for
comparison and initialization.

This patch changes only used time API, it doesn't change used var
names for simplicity.

This time API can be implemented with local timer counter, so
shouldn't be used between threads.

Signed-off-by: Ivan Khoronzhuk 
---
 example/generator/odp_generator.c | 12 +++
 include/odp/api/time.h| 68 ---
 test/performance/odp_pktio_perf.c | 49 +
 test/validation/pktio/pktio.c | 20 +--
 test/validation/scheduler/scheduler.c |  5 +--
 test/validation/time/time.c   | 27 +++---
 6 files changed, 114 insertions(+), 67 deletions(-)

diff --git a/example/generator/odp_generator.c 
b/example/generator/odp_generator.c
index be9597b..f84adc4 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -585,7 +585,7 @@ static void *gen_recv_thread(void *arg)
  */
 static void print_global_stats(int num_workers)
 {
-   uint64_t start, wait, diff;
+   odp_time_t start, wait, diff;
uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0;
int verbose_interval = 20;
odp_thrmask_t thrd_mask;
@@ -593,8 +593,8 @@ static void print_global_stats(int num_workers)
while (odp_thrmask_worker(_mask) < num_workers)
continue;
 
-   wait = odp_time_ns_to_cycles(verbose_interval * ODP_TIME_SEC);
-   start = odp_time_cycles();
+   wait = odp_time_from_ns(verbose_interval * ODP_TIME_SEC);
+   start = odp_time();
 
while (odp_thrmask_worker(_mask) == num_workers) {
if (args->appl.number != -1 &&
@@ -603,11 +603,11 @@ static void print_global_stats(int num_workers)
break;
}
 
-   diff = odp_time_diff_cycles(start, odp_time_cycles());
-   if (diff < wait)
+   diff = odp_time_diff(start, odp_time());
+   if (odp_time_cmp(diff, wait) > 0)
continue;
 
-   start = odp_time_cycles();
+   start = odp_time();
 
if (args->appl.mode == APPL_MODE_RCV) {
pkts = odp_atomic_load_u64();
diff --git a/include/odp/api/time.h b/include/odp/api/time.h
index b0072fc..7ed4734 100644
--- a/include/odp/api/time.h
+++ b/include/odp/api/time.h
@@ -28,14 +28,25 @@ extern "C" {
 #define ODP_TIME_MSEC 100ULL/**< Millisecond in nsec */
 #define ODP_TIME_SEC  10ULL /**< Second in nsec */
 
+/**
+ * @typedef odp_time_t
+ * ODP time stamp. Time stamp can be local, so shouldn't be shared between
+ * threads.
+ */
 
 /**
- * Current time in CPU cycles
- *
- * @return Current time in CPU cycles
+ * @def ODP_TIME_NULL
+ * Zero time stamp
  */
-uint64_t odp_time_cycles(void);
 
+/**
+ * Current time stamp.
+ *
+ * It should be hi-resolution time.
+ *
+ * @return Time stamp.
+ */
+odp_time_t odp_time(void);
 
 /**
  * Time difference
@@ -43,29 +54,60 @@ uint64_t odp_time_cycles(void);
  * @param t1First time stamp
  * @param t2Second time stamp
  *
- * @return Difference of time stamps in CPU cycles
+ * @return Difference of time stamps
  */
-uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2);
+odp_time_t odp_time_diff(odp_time_t t1, odp_time_t t2);
 
+/**
+ * Time sum
+ *
+ * @param t1Time stamp
+ * @param t2Time stamp
+ *
+ * @return Sum of time stamps
+ */
+odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
 
 /**
- * Convert CPU cycles to nanoseconds
+ * Convert time to nanoseconds
  *
- * @param cycles  Time in CPU cycles
+ * @param time  Time
  *
  * @return Time in nanoseconds
  */
-uint64_t odp_time_cycles_to_ns(uint64_t cycles);
-
+uint64_t odp_time_to_ns(odp_time_t time);
 
 /**
- * Convert nanoseconds to CPU cycles
+ * Convert nanoseconds to time
  *
  * @param ns  Time in nanoseconds
  *
- * @return Time in CPU cycles
+ * @return Time stamp
+ */
+odp_time_t odp_time_from_ns(uint64_t ns);
+
+/**
+ * Compare two times as absolute ranges
+ *
+ * @param t1

[lng-odp] [PATCHv2] helper : Fix UDP checksum computation

2015-10-22 Thread ion.grigore
From: Grigore Ion 

This patch fixes the following problems:
- checksum computation for LE platforms
- checksum is computed in the CPU endianness. The returned result
must be converted to the BE ordering when it is used to update the
UDP checksum in a packet.
- checksum computation for packets having the UDP length not a
multiple of 2.

Signed-off-by: Grigore Ion 
---
 v2:
 - patch updated to the last master (Maxim Uvarov)
 v1:
 - Move variables declaration on top of block. (Maxim Uvarov)
 - Check patch with checkpatch script.  (Maxim Uvarov) 
 - L3 header presence is tested twice. (Alexandru Badicioiu)
 - Remove unnecessary check for L3 header presence. (Bill Fischofer)
 - Modify check of odp_packet_l4_offset() return. (Bill Fischofer)

 helper/include/odp/helper/udp.h |   32 +---
 1 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/helper/include/odp/helper/udp.h b/helper/include/odp/helper/udp.h
index 06c439b..6fce3f2 100644
--- a/helper/include/odp/helper/udp.h
+++ b/helper/include/odp/helper/udp.h
@@ -44,20 +44,16 @@ typedef struct ODP_PACKED {
  * This function uses odp packet to calc checksum
  *
  * @param pkt  calculate chksum for pkt
- * @return  checksum value
+ * @return  checksum value in CPU endianness
  */
 static inline uint16_t odph_ipv4_udp_chksum(odp_packet_t pkt)
 {
-   uint32_t sum = 0;
+   uint32_t sum;
odph_udphdr_t *udph;
odph_ipv4hdr_t *iph;
-   uint16_t udplen;
-   uint8_t *buf;
+   uint16_t udplen, *buf;
 
-   if (!odp_packet_l3_offset(pkt))
-   return 0;
-
-   if (!odp_packet_l4_offset(pkt))
+   if (odp_packet_l4_offset(pkt) == ODP_PACKET_OFFSET_INVALID)
return 0;
 
iph = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
@@ -67,23 +63,21 @@ static inline uint16_t odph_ipv4_udp_chksum(odp_packet_t 
pkt)
/* 32-bit sum of all 16-bit words covered by UDP chksum */
sum = (iph->src_addr & 0x) + (iph->src_addr >> 16) +
  (iph->dst_addr & 0x) + (iph->dst_addr >> 16) +
- (uint16_t)iph->proto + udplen;
-   for (buf = (uint8_t *)udph; udplen > 1; udplen -= 2) {
-   sum += ((*buf << 8) + *(buf + 1));
-   buf += 2;
-   }
+ odp_be_to_cpu_16(iph->proto) + udph->length;
+   for (buf = (uint16_t *)((void *)udph); udplen > 1; udplen -= 2)
+   sum += *buf++;
+   if (udplen) /* If length is not a multiple of 2 bytes */
+   sum += odp_be_to_cpu_16(*((uint8_t *)buf) << 8);
 
/* Fold sum to 16 bits: add carrier to result */
-   while (sum >> 16)
-   sum = (sum & 0x) + (sum >> 16);
+   sum = (sum & 0x) + (sum >> 16);
+   sum += (sum >> 16);
 
/* 1's complement */
sum = ~sum;
 
-   /* set computation result */
-   sum = (sum == 0x0) ? 0x : sum;
-
-   return sum;
+   /* set computation result in CPU endianness*/
+   return (sum == 0x0) ? 0x : odp_be_to_cpu_16(sum);
 }
 
 /** @internal Compile time assert */
-- 
1.7.3.4

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv5 0/2] api: define pktio statistics api

2015-10-22 Thread Maxim Uvarov
v5: - remove capabilities mask

v4: - updated api with reference to rfc;
- added counter mask;
- added start()/stop() for stats counters;


Maxim Uvarov (2):
  api: define pktio statistics api
  api: pktio statistics: define start and stop

 include/odp/api/packet_io_stats.h  | 153 +
 platform/linux-generic/include/odp/packet_io.h |   1 +
 2 files changed, 154 insertions(+)
 create mode 100644 include/odp/api/packet_io_stats.h

-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v5 0/5] api: time: unbind CPU cycles from time API

2015-10-22 Thread Ivan Khoronzhuk
This seres is intended to unbind time API names from CPU "cycles".
Also remove usage of word "cycle" from appropriate places as it's
no more valid. This patch series only change API names and adds
calls required for that and doesn't add new API functionality.
API to get rate of time and delay call will be added separately as
they require to modify some examples and tests.

Since v4:
- corrected desc of time API:
  global -> local
  time stamp -> Time stamp in desc.

Since v3:
- don't use "tick" word in API names
- added opaque type odp_time_t
- added additional function: cmpr, sum, to_u64
- use "time stamp" word instead of "handle"
- described more clearly timestamps order in functions
- two new patches:
  performance: odp_pktio_perf: fix potential overflow in wait loop
  example: generator: compare ticks instead of ns in loop

Since v1, v2:
- changed series name a little bit
- added opaque type odp_time_t
- added missed spaces in printf
- removed legacy "count" words

Ivan Khoronzhuk (5):
  performance: odp_pktio_perf: fix potential overflow in wait loop
  example: generator: compare ticks instead of ns in loop
  api: time: unbind CPU cycles from time API
  linux-generic: align implementation with new time API
  test/example: avoid "cycle" word usage

 example/generator/odp_generator.c  | 14 ++---
 include/odp/api/time.h | 68 +-
 platform/linux-generic/Makefile.am |  1 +
 .../linux-generic/include/odp/plat/time_types.h| 36 
 platform/linux-generic/include/odp/time.h  |  1 +
 platform/linux-generic/odp_schedule.c  | 16 ++---
 platform/linux-generic/odp_time.c  | 62 
 test/performance/odp_pktio_perf.c  | 56 ++
 test/validation/pktio/pktio.c  | 20 +++
 test/validation/scheduler/scheduler.c  |  4 +-
 test/validation/time/time.c| 47 +++
 test/validation/time/time.h|  6 +-
 12 files changed, 228 insertions(+), 103 deletions(-)
 create mode 100644 platform/linux-generic/include/odp/plat/time_types.h

-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v5 2/5] example: generator: compare ticks instead of ns in loop

2015-10-22 Thread Ivan Khoronzhuk
It's more accurate to compare ticks instead of ns in each
iteration, so calculate wait range before entering the loop.

Signed-off-by: Ivan Khoronzhuk 
---
 example/generator/odp_generator.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/example/generator/odp_generator.c 
b/example/generator/odp_generator.c
index f80104c..be9597b 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -585,7 +585,7 @@ static void *gen_recv_thread(void *arg)
  */
 static void print_global_stats(int num_workers)
 {
-   uint64_t start, now, diff;
+   uint64_t start, wait, diff;
uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0;
int verbose_interval = 20;
odp_thrmask_t thrd_mask;
@@ -593,6 +593,7 @@ static void print_global_stats(int num_workers)
while (odp_thrmask_worker(_mask) < num_workers)
continue;
 
+   wait = odp_time_ns_to_cycles(verbose_interval * ODP_TIME_SEC);
start = odp_time_cycles();
 
while (odp_thrmask_worker(_mask) == num_workers) {
@@ -602,12 +603,9 @@ static void print_global_stats(int num_workers)
break;
}
 
-   now = odp_time_cycles();
-   diff = odp_time_diff_cycles(start, now);
-   if (odp_time_cycles_to_ns(diff) <
-   verbose_interval * ODP_TIME_SEC) {
+   diff = odp_time_diff_cycles(start, odp_time_cycles());
+   if (diff < wait)
continue;
-   }
 
start = odp_time_cycles();
 
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [PATCH v2 1/2] linux-generic: netmap: wait for the interface to become active

2015-10-22 Thread Elo, Matias (Nokia - FI/Espoo)


> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT Maxim
> Uvarov
> Sent: Thursday, October 22, 2015 2:49 PM
> To: lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [PATCH v2 1/2] linux-generic: netmap: wait for the
> interface to become active
> 
> On 10/22/2015 14:40, Matias Elo wrote:
> > Netmap interface takes a few seconds to become active after
> > setup. This caused several test applications to fail.
> > Check link status at the end of netmap_open() to fix this.
> >
> > Signed-off-by: Matias Elo 
> > ---
> >
> > v2:
> >- Rebased to master
> >- The other end of a directly attached loopback cable may come up after a
> >  small delay. Sleep once after link is detected to enable running 
> > validation
> >  tests with directly attached loopback cable. (Stuart Haslam)
> >
> >   platform/linux-generic/pktio/netmap.c | 20 +---
> >   1 file changed, 17 insertions(+), 3 deletions(-)
> >
> > diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-
> generic/pktio/netmap.c
> > index ab4667e..0dfe511 100644
> > --- a/platform/linux-generic/pktio/netmap.c
> > +++ b/platform/linux-generic/pktio/netmap.c
> > @@ -28,6 +28,7 @@ static struct nm_desc mmap_desc;  /** Used to store
> the mmap address;
> >   filled in first time, used for
> >   subsequent calls to nm_open */
> >
> > +#define NM_OPEN_RETRIES 5
> >   #define NM_INJECT_RETRIES 10
> >
> >   struct dispatch_args {
> > @@ -70,6 +71,10 @@ static int netmap_do_ioctl(pktio_entry_t *pktio_entry,
> unsigned long cmd,
> > pkt_nm->if_flags = (ifr.ifr_flags << 16) |
> > (0x & ifr.ifr_flags);
> > break;
> > +   case SIOCETHTOOL:
> > +   if (subcmd == ETHTOOL_GLINK)
> > +   return !eval.data;
> > +   break;
> > default:
> > break;
> > }
> > @@ -84,9 +89,10 @@ static int netmap_close(pktio_entry_t *pktio_entry)
> >   {
> > pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
> >
> > -   if (pkt_nm->desc != NULL)
> > +   if (pkt_nm->desc != NULL) {
> > nm_close(pkt_nm->desc);
> > -
> > +   mmap_desc.mem = NULL;
> > +   }
> > if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
> > __odp_errno = errno;
> > ODP_ERR("close(sockfd): %s\n", strerror(errno));
> > @@ -101,6 +107,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED,
> pktio_entry_t *pktio_entry,
> > char ifname[IFNAMSIZ + 7]; /* netmap: */
> > int err;
> > int sockfd;
> > +   int i;
> > pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
> >
> > if (getenv("ODP_PKTIO_DISABLE_NETMAP"))
> > @@ -155,7 +162,14 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED,
> pktio_entry_t *pktio_entry,
> > if (err)
> > goto error;
> >
> > -   return 0;
> > +   /* Wait for the link to come up */
> > +   for (i = 0; i < NM_OPEN_RETRIES; i++) {
> > +   err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL,
> ETHTOOL_GLINK);
> > +   sleep(1);
> > +   if (err == 0)
> > +   return 0;
> 
> why sleep() is between err check with return?
> 

To sleep once after the link is detected to be up. When using direct attached 
loopback cable there may
be a small delay until the opposing end's netmap interface comes up. In this 
case without the additional
sleep pktio validation tests fail.

-Matias

> Maxim.
> > +   }
> > +   ODP_ERR("%s didn't come up\n", pktio_entry->s.name);
> >
> >   error:
> > netmap_close(pktio_entry);
> 
> ___
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH] linux-generic: pool: move local caches to pool

2015-10-22 Thread Bill Fischofer
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=1851 by moving local
buffer caches to the pool itself. This enables odp_pool_destroy() to
properly flush all local caches as part of its processing.

Signed-off-by: Bill Fischofer 
---
 platform/linux-generic/include/odp_internal.h  |  1 +
 platform/linux-generic/include/odp_pool_internal.h | 13 ---
 platform/linux-generic/odp_init.c  |  5 +
 platform/linux-generic/odp_pool.c  | 25 +++---
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/platform/linux-generic/include/odp_internal.h 
b/platform/linux-generic/include/odp_internal.h
index 6f0050f..010b82f 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -52,6 +52,7 @@ int odp_shm_term_global(void);
 int odp_shm_init_local(void);
 
 int odp_pool_init_global(void);
+int odp_pool_init_local(void);
 int odp_pool_term_global(void);
 int odp_pool_term_local(void);
 
diff --git a/platform/linux-generic/include/odp_pool_internal.h 
b/platform/linux-generic/include/odp_pool_internal.h
index 136db2c..bb70159 100644
--- a/platform/linux-generic/include/odp_pool_internal.h
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -53,9 +53,14 @@ typedef struct _odp_buffer_pool_init_t {
 
 /* Local cache for buffer alloc/free acceleration */
 typedef struct local_cache_t {
-   odp_buffer_hdr_t *buf_freelist;  /* The local cache */
-   uint64_t bufallocs;  /* Local buffer alloc count */
-   uint64_t buffrees;   /* Local buffer free count */
+   union {
+   struct {
+   odp_buffer_hdr_t *buf_freelist;  /* The local cache */
+   uint64_t bufallocs;  /* Local buffer alloc count */
+   uint64_t buffrees;   /* Local buffer free count */
+   };
+   uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(uint64_t))];
+   };
 } local_cache_t;
 
 /* Use ticketlock instead of spinlock */
@@ -133,6 +138,8 @@ struct pool_entry_s {
uint32_tlow_wm;
uint32_theadroom;
uint32_ttailroom;
+
+   local_cache_t local_cache[ODP_CONFIG_MAX_THREADS] ODP_ALIGNED_CACHE;
 };
 
 typedef union pool_entry_u {
diff --git a/platform/linux-generic/odp_init.c 
b/platform/linux-generic/odp_init.c
index 48d9b20..5e19d86 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -138,6 +138,11 @@ int odp_init_local(odp_thread_type_t thr_type)
return -1;
}
 
+   if (odp_pool_init_local()) {
+   ODP_ERR("ODP pool local init failed.\n");
+   return -1;
+   }
+
if (odp_schedule_init_local()) {
ODP_ERR("ODP schedule local init failed.\n");
return -1;
diff --git a/platform/linux-generic/odp_pool.c 
b/platform/linux-generic/odp_pool.c
index 30d4b2b..d06a9d4 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/odp_pool.c
@@ -57,8 +57,8 @@ static const char SHM_DEFAULT_NAME[] = "odp_buffer_pools";
 /* Pool entry pointers (for inlining) */
 void *pool_entry_ptr[ODP_CONFIG_POOLS];
 
-/* Local cache for buffer alloc/free acceleration */
-static __thread local_cache_t local_cache[ODP_CONFIG_POOLS];
+/* Cache thread id locally for local cache performance */
+static __thread int local_id;
 
 int odp_pool_init_global(void)
 {
@@ -107,6 +107,12 @@ int odp_pool_init_global(void)
return 0;
 }
 
+int odp_pool_init_local(void)
+{
+   local_id = odp_thread_id();
+   return 0;
+}
+
 int odp_pool_term_global(void)
 {
int i;
@@ -442,6 +448,7 @@ int odp_pool_destroy(odp_pool_t pool_hdl)
 {
uint32_t pool_id = pool_handle_to_index(pool_hdl);
pool_entry_t *pool = get_pool_entry(pool_id);
+   int i;
 
if (pool == NULL)
return -1;
@@ -455,8 +462,9 @@ int odp_pool_destroy(odp_pool_t pool_hdl)
return -1;
}
 
-   /* Make sure local cache is empty */
-   flush_cache(_cache[pool_id], >s);
+   /* Make sure local caches are empty */
+   for (i = 0; i < ODP_CONFIG_MAX_THREADS; i++)
+   flush_cache(>s.local_cache[i], >s);
 
/* Call fails if pool has allocated buffers */
if (odp_atomic_load_u32(>s.bufcount) < pool->s.buf_num) {
@@ -485,8 +493,9 @@ odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size)
return ODP_BUFFER_INVALID;
 
/* Try to satisfy request from the local cache */
-   buf = (odp_anybuf_t *)(void *)get_local_buf(_cache[pool_id],
-   >s, totsize);
+   buf = (odp_anybuf_t *)
+   (void *)get_local_buf(>s.local_cache[local_id],
+ >s, totsize);
 
/* If cache is empty, satisfy request from the 

[lng-odp] [API-NEXT PATCHv6 3/4] linux-generic: tm: add tm to build

2015-10-22 Thread Bill Fischofer
From: Barry Spinney 

This commit causes the traffic_mgr to become part of the ODP linux-generic
build.

Signed-off-by: Barry Spinney 
Signed-off-by: Bill Fischofer 
---
 platform/linux-generic/Makefile.am| 13 
 platform/linux-generic/include/odp_internal.h |  2 ++
 platform/linux-generic/odp_init.c |  5 +++
 platform/linux-generic/odp_packet_flags.c | 45 +++
 4 files changed, 65 insertions(+)

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 85c976d..71b85d2 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -49,6 +49,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/ticketlock.h \
  $(srcdir)/include/odp/time.h \
  $(srcdir)/include/odp/timer.h \
+ $(srcdir)/include/odp/traffic_mngr.h \
  $(srcdir)/include/odp/version.h
 
 odpplatincludedir= $(includedir)/odp/plat
@@ -75,6 +76,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/thrmask_types.h \
  $(srcdir)/include/odp/plat/ticketlock_types.h \
  $(srcdir)/include/odp/plat/timer_types.h \
+ $(srcdir)/include/odp/plat/traffic_mngr_types.h \
  $(srcdir)/include/odp/plat/version_types.h
 
 odpapiincludedir= $(includedir)/odp/api
@@ -116,6 +118,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/ticketlock.h \
  $(top_srcdir)/include/odp/api/time.h \
  $(top_srcdir)/include/odp/api/timer.h \
+ $(top_srcdir)/include/odp/api/traffic_mngr.h \
  $(top_srcdir)/include/odp/api/version.h
 
 noinst_HEADERS = \
@@ -131,16 +134,21 @@ noinst_HEADERS = \
  ${srcdir}/include/odp_debug_internal.h \
  ${srcdir}/include/odp_forward_typedefs_internal.h \
  ${srcdir}/include/odp_internal.h \
+ ${srcdir}/include/odp_name_table_internal.h \
  ${srcdir}/include/odp_packet_internal.h \
  ${srcdir}/include/odp_packet_io_internal.h \
  ${srcdir}/include/odp_packet_io_queue.h \
  ${srcdir}/include/odp_packet_netmap.h \
  ${srcdir}/include/odp_packet_socket.h \
+ ${srcdir}/include/odp_pkt_queue_internal.h \
  ${srcdir}/include/odp_pool_internal.h \
  ${srcdir}/include/odp_queue_internal.h \
  ${srcdir}/include/odp_schedule_internal.h \
+ ${srcdir}/include/odp_sorted_list_internal.h \
  ${srcdir}/include/odp_spin_internal.h \
  ${srcdir}/include/odp_timer_internal.h \
+ ${srcdir}/include/odp_timer_wheel_internal.h \
+ ${srcdir}/include/odp_traffic_mngr_internal.h \
  ${srcdir}/include/odp_cpu_internal.h \
  ${srcdir}/Makefile.inc
 
@@ -156,6 +164,7 @@ __LIB__libodp_la_SOURCES = \
   odp_event.c \
   odp_init.c \
   odp_impl.c \
+  odp_name_table.c \
   odp_packet.c \
   odp_packet_flags.c \
   odp_packet_io.c \
@@ -164,12 +173,14 @@ __LIB__libodp_la_SOURCES = \
   pktio/netmap.c \
   pktio/socket.c \
   pktio/socket_mmap.c \
+  odp_pkt_queue.c \
   odp_pool.c \
   odp_queue.c \
   odp_rwlock.c \
   odp_rwlock_recursive.c \
   odp_schedule.c \
   odp_shared_memory.c \
+  odp_sorted_list.c \
   odp_spinlock.c \
   odp_spinlock_recursive.c \
   odp_system_info.c \
@@ -178,6 +189,8 @@ __LIB__libodp_la_SOURCES = \
   odp_ticketlock.c \
   odp_time.c \
   odp_timer.c \
+  odp_timer_wheel.c \
+  odp_traffic_mngr.c \
   odp_version.c \
   odp_weak.c \
   arch/@ARCH@/odp_cpu_cycles.c
diff --git a/platform/linux-generic/include/odp_internal.h 
b/platform/linux-generic/include/odp_internal.h
index 8a1a219..a852c5b 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -78,6 +78,8 @@ int odp_schedule_term_local(void);
 int odp_timer_init_global(void);
 int odp_timer_disarm_all(void);
 
+int odp_tm_init_global(void);
+
 void _odp_flush_caches(void);
 
 #ifdef __cplusplus
diff 

[lng-odp] [API-NEXT PATCHv6 1/4] api: tm: add tm API definitions

2015-10-22 Thread Bill Fischofer
From: Barry Spinney 

This introduces an API for configuring and using Traffic Management
systems.

The purpose of this API is as a general packet scheduling system that
accepts packets from input queues and applies strict priority
scheduling, weighted fair queuing scheduling and/or bandwidth controls
to decide which input packet should be chosen as the next output
packet and when this output packet can be sent onwards.

Signed-off-by: Barry Spinney 
Signed-off-by: Bill Fischofer 
---
 include/odp.h  |1 +
 include/odp/api/packet.h   |   69 +
 include/odp/api/traffic_mngr.h | 1611 
 .../linux-generic/include/odp/plat/packet_types.h  |   11 +
 .../include/odp/plat/traffic_mngr_types.h  |  185 +++
 platform/linux-generic/include/odp/traffic_mngr.h  |   35 +
 .../linux-generic/include/odp_packet_internal.h|5 +
 7 files changed, 1917 insertions(+)
 create mode 100644 include/odp/api/traffic_mngr.h
 create mode 100644 platform/linux-generic/include/odp/plat/traffic_mngr_types.h
 create mode 100644 platform/linux-generic/include/odp/traffic_mngr.h

diff --git a/include/odp.h b/include/odp.h
index 825c7e1..f6a6ea9 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -56,6 +56,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/packet.h b/include/odp/api/packet.h
index 5d46b7b..0680b3f 100644
--- a/include/odp/api/packet.h
+++ b/include/odp/api/packet.h
@@ -48,6 +48,26 @@ extern "C" {
  * Invalid packet segment
  */
 
+ /**
+  * @typedef odp_packet_color_t
+  * Color of packet for shaper/drop processing
+  */
+
+ /**
+  * @def ODP_PACKET_GREEN
+  * Packet is green
+  */
+
+ /**
+  * @def ODP_PACKET_YELLOW
+  * Packet is yellow
+  */
+
+ /**
+  * @def ODP_PACKET_RED
+  * Packet is red
+  */
+
 /*
  *
  * Alloc and free
@@ -700,6 +720,55 @@ odp_packet_seg_t odp_packet_last_seg(odp_packet_t pkt);
  */
 odp_packet_seg_t odp_packet_next_seg(odp_packet_t pkt, odp_packet_seg_t seg);
 
+/**
+ * Get packet color
+ *
+ * @param pkt Packet handle
+ * @return packet color
+ */
+odp_packet_color_t odp_packet_color(odp_packet_t pkt);
+
+/**
+ * Set packet color
+ *
+ * @param pkt Packet handle
+ * @param color Color to set
+ */
+void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color);
+
+/**
+ * Get drop eligible status
+ *
+ * @param pkt Packet handle
+ * @return Packet drop eligibility status
+ * @retval 0 Packet is not drop eligible
+ * @retval 1 Packet is drop
+ */
+odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt);
+
+/**
+ * Set drop eligible status
+ *
+ * @param pkt Packet handle
+ * @param status Drop eligibility status
+ */
+void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t status);
+
+/**
+ * Get shaper length adjustment
+ *
+ * @param pkt Packet handle
+ * @return Shaper adjustment (-128..127)
+ */
+int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt);
+
+/**
+ * Set shaper length adjustment
+ *
+ * @param pkt Packet handle
+ * @param adj Signed adjustment value
+ */
+void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj);
 
 /*
  *
diff --git a/include/odp/api/traffic_mngr.h b/include/odp/api/traffic_mngr.h
new file mode 100644
index 000..2459a8b
--- /dev/null
+++ b/include/odp/api/traffic_mngr.h
@@ -0,0 +1,1611 @@
+/** Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_TRAFFIC_MNGR_H_
+#define ODP_TRAFFIC_MNGR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+#include 
+
+/**
+ * @file
+ *
+ */
+
+/** @defgroup odp_traffic_mngr ODP TRAFFIC MNGR
+ * @{
+ *
+ * An API for configuring and using Traffic Management systems
+ *
+ * This file forms a simple interface for creating, configuring and using
+ * Traffic Management (TM) subsystems.  By TM subsystem it is meant a general
+ * packet scheduling system that accepts packets from input queues and applies
+ * strict priority scheduling, weighted fair queueing scheduling and/or
+ * bandwidth controls to decide which input packet should be chosen as the
+ * next output packet and when this output packet can be sent onwards.
+ *
+ * A given platform supporting this TM API could support one or more pure
+ * hardware based packet scheduling systems, one or more pure software
+ * based systems or one or more hybrid systems - where because of
+ * hardware constraints some of the packet scheduling is done in hardware
+ * and some is done in software.  In addition, there may also be additional
+ * API's beyond those described here for (a) controlling advanced capabilities
+ * supported by specific hardware, software or hybrid subsystems or (b)
+ * dealing with constraints and limitations of specific implementations.
+ * The intention here is to be the simplest API that covers the vast majority
+ * of 

[lng-odp] [PATCHv11 0/7] IPC (pktio)

2015-10-22 Thread Maxim Uvarov
v11: - removed odph_pause patch due to Petri will send patch to make it
odp api. (Anders).
 - implement pktio stop, pktio close, do helpers, fix Stuarts comments.

v10: clean up patches according to Stuart comments
(remove timeouts, add O_EXCL, do not map rings each packets and etc..)

v9: reworked patches according to Connect agreements:
- linux-generic only pktio;
- 2 separate symmetric apps with same init process;
- does not matter which app was run first;
- init process for 2 apps is the same;

https://git.linaro.org/people/maxim.uvarov/odp.git pktio_ipc_v11


Maxim Uvarov (7):
  helper: ring: update ring with shm proc argument
  linux-generic: create internal pool create function with shm flags
  helper: flag to not link ring to linked list
  helpers: remove odp_ prefix for tests source files
  helper: move ring test to helper
  linux-generic: add ipc pktio support
  linux-generic: internal ipc_pktio test

 configure.ac   |   1 -
 helper/include/odp/helper/ring.h   |   7 +-
 helper/ring.c  |  13 +-
 helper/test/.gitignore |   9 +-
 helper/test/Makefile.am|  22 +-
 helper/test/{odp_chksum.c => chksum.c} |   3 +-
 helper/test/{odp_process.c => process.c}   |   3 +-
 .../api_test/odp_ring_test.c => helper/test/ring.c | 100 +--
 helper/test/{odp_thread.c => thread.c} |   3 +-
 platform/linux-generic/Makefile.am |   3 +
 .../linux-generic/include/odp_buffer_internal.h|   3 +
 .../linux-generic/include/odp_packet_io_internal.h |  38 ++
 .../include/odp_packet_io_ipc_internal.h   |  47 ++
 platform/linux-generic/include/odp_pool_internal.h |   4 +
 platform/linux-generic/include/odp_shm_internal.h  |  21 +
 platform/linux-generic/m4/configure.m4 |   3 +-
 platform/linux-generic/odp_packet_io.c |   1 +
 platform/linux-generic/odp_pool.c  |  25 +-
 platform/linux-generic/odp_schedule.c  |   3 +-
 platform/linux-generic/odp_shared_memory.c |  14 +-
 platform/linux-generic/pktio/io_ops.c  |   1 +
 platform/linux-generic/pktio/ipc.c | 729 +
 platform/linux-generic/pktio/ring.c|   1 +
 platform/linux-generic/test/Makefile.am|   3 +-
 platform/linux-generic/test/pktio_ipc/.gitignore   |   1 +
 platform/linux-generic/test/pktio_ipc/Makefile.am  |  15 +
 platform/linux-generic/test/pktio_ipc/ipc_common.c | 137 
 platform/linux-generic/test/pktio_ipc/ipc_common.h |  87 +++
 platform/linux-generic/test/pktio_ipc/pktio_ipc1.c | 305 +
 platform/linux-generic/test/pktio_ipc/pktio_ipc2.c | 180 +
 .../linux-generic/test/pktio_ipc/pktio_ipc_run |  57 ++
 test/Makefile.am   |   2 +-
 test/api_test/.gitignore   |   2 -
 test/api_test/Makefile.am  |  13 -
 test/api_test/odp_common.c |  91 ---
 test/api_test/odp_common.h |  42 --
 36 files changed, 1762 insertions(+), 227 deletions(-)
 rename helper/test/{odp_chksum.c => chksum.c} (98%)
 rename helper/test/{odp_process.c => process.c} (96%)
 rename test/api_test/odp_ring_test.c => helper/test/ring.c (86%)
 rename helper/test/{odp_thread.c => thread.c} (96%)
 create mode 100644 platform/linux-generic/include/odp_packet_io_ipc_internal.h
 create mode 100644 platform/linux-generic/include/odp_shm_internal.h
 create mode 100644 platform/linux-generic/pktio/ipc.c
 create mode 12 platform/linux-generic/pktio/ring.c
 create mode 100644 platform/linux-generic/test/pktio_ipc/.gitignore
 create mode 100644 platform/linux-generic/test/pktio_ipc/Makefile.am
 create mode 100644 platform/linux-generic/test/pktio_ipc/ipc_common.c
 create mode 100644 platform/linux-generic/test/pktio_ipc/ipc_common.h
 create mode 100644 platform/linux-generic/test/pktio_ipc/pktio_ipc1.c
 create mode 100644 platform/linux-generic/test/pktio_ipc/pktio_ipc2.c
 create mode 100755 platform/linux-generic/test/pktio_ipc/pktio_ipc_run
 delete mode 100644 test/api_test/.gitignore
 delete mode 100644 test/api_test/Makefile.am
 delete mode 100644 test/api_test/odp_common.c
 delete mode 100644 test/api_test/odp_common.h

-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv11 7/7] linux-generic: internal ipc_pktio test

2015-10-22 Thread Maxim Uvarov
2 example ipc pktio applications create ipc pktio to each other and do
packet transfer, validation magic numbers and packets sequence counters
inside it.

Signed-off-by: Maxim Uvarov 
---
 platform/linux-generic/Makefile.am |   1 +
 platform/linux-generic/m4/configure.m4 |   3 +-
 platform/linux-generic/test/Makefile.am|   3 +-
 platform/linux-generic/test/pktio_ipc/.gitignore   |   1 +
 platform/linux-generic/test/pktio_ipc/Makefile.am  |  15 +
 platform/linux-generic/test/pktio_ipc/ipc_common.c | 137 +
 platform/linux-generic/test/pktio_ipc/ipc_common.h |  87 ++
 platform/linux-generic/test/pktio_ipc/pktio_ipc1.c | 305 +
 platform/linux-generic/test/pktio_ipc/pktio_ipc2.c | 180 
 .../linux-generic/test/pktio_ipc/pktio_ipc_run |  57 
 10 files changed, 787 insertions(+), 2 deletions(-)
 create mode 100644 platform/linux-generic/test/pktio_ipc/.gitignore
 create mode 100644 platform/linux-generic/test/pktio_ipc/Makefile.am
 create mode 100644 platform/linux-generic/test/pktio_ipc/ipc_common.c
 create mode 100644 platform/linux-generic/test/pktio_ipc/ipc_common.h
 create mode 100644 platform/linux-generic/test/pktio_ipc/pktio_ipc1.c
 create mode 100644 platform/linux-generic/test/pktio_ipc/pktio_ipc2.c
 create mode 100755 platform/linux-generic/test/pktio_ipc/pktio_ipc_run

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 834354c..fd1d61f 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -5,6 +5,7 @@ include $(top_srcdir)/platform/Makefile.inc
 
 AM_CFLAGS +=  -I$(srcdir)/include
 AM_CFLAGS +=  -I$(top_srcdir)/include
+AM_CFLAGS +=  -I$(top_srcdir)/helper
 AM_CFLAGS +=  -I$(top_srcdir)/helper/include
 
 include_HEADERS = \
diff --git a/platform/linux-generic/m4/configure.m4 
b/platform/linux-generic/m4/configure.m4
index df6dc64..58efcbc 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -23,4 +23,5 @@ m4_include([platform/linux-generic/m4/odp_pcap.m4])
 
 AC_CONFIG_FILES([platform/linux-generic/Makefile
 platform/linux-generic/test/Makefile
-platform/linux-generic/test/pktio/Makefile])
+platform/linux-generic/test/pktio/Makefile
+platform/linux-generic/test/pktio_ipc/Makefile])
diff --git a/platform/linux-generic/test/Makefile.am 
b/platform/linux-generic/test/Makefile.am
index 11648d4..773cd54 100644
--- a/platform/linux-generic/test/Makefile.am
+++ b/platform/linux-generic/test/Makefile.am
@@ -1,10 +1,11 @@
 include $(top_srcdir)/test/Makefile.inc
 TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/validation
 
-ODP_MODULES = pktio
+ODP_MODULES = pktio pktio_ipc
 
 if test_vald
 TESTS = pktio/pktio_run \
+   pktio_ipc/pktio_ipc_run \
${top_builddir}/test/validation/buffer/buffer_main$(EXEEXT) \

${top_builddir}/test/validation/classification/classification_main$(EXEEXT) \
${top_builddir}/test/validation/cpumask/cpumask_main$(EXEEXT) \
diff --git a/platform/linux-generic/test/pktio_ipc/.gitignore 
b/platform/linux-generic/test/pktio_ipc/.gitignore
new file mode 100644
index 000..d2a7ce2
--- /dev/null
+++ b/platform/linux-generic/test/pktio_ipc/.gitignore
@@ -0,0 +1 @@
+pktio_ipc
diff --git a/platform/linux-generic/test/pktio_ipc/Makefile.am 
b/platform/linux-generic/test/pktio_ipc/Makefile.am
new file mode 100644
index 000..adf6294
--- /dev/null
+++ b/platform/linux-generic/test/pktio_ipc/Makefile.am
@@ -0,0 +1,15 @@
+include $(top_srcdir)/test/Makefile.inc
+TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/validation
+
+bin_PROGRAMS = pktio_ipc1\
+   pktio_ipc2
+
+pktio_ipc1_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/example
+pktio_ipc1_LDFLAGS = $(AM_LDFLAGS) -static
+pktio_ipc2_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/example
+pktio_ipc2_LDFLAGS = $(AM_LDFLAGS) -static
+
+noinst_HEADERS = $(top_srcdir)/test/test_debug.h
+
+dist_pktio_ipc1_SOURCES = pktio_ipc1.c ipc_common.c
+dist_pktio_ipc2_SOURCES = pktio_ipc2.c ipc_common.c
diff --git a/platform/linux-generic/test/pktio_ipc/ipc_common.c 
b/platform/linux-generic/test/pktio_ipc/ipc_common.c
new file mode 100644
index 000..9168bbb
--- /dev/null
+++ b/platform/linux-generic/test/pktio_ipc/ipc_common.c
@@ -0,0 +1,137 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ipc_common.h"
+
+/** Run time in seconds */
+int run_time_sec;
+
+int ipc_odp_packet_sendall(odp_pktio_t pktio,
+  odp_packet_t pkt_tbl[], int num)
+{
+   int ret;
+   int sent = 0;
+   uint64_t start_cycle;
+   uint64_t diff;
+
+   start_cycle = odp_time_cycles();
+
+   while (sent != num) {
+   ret = odp_pktio_send(pktio, _tbl[sent], num - sent);
+   if (ret < 0)
+   

[lng-odp] [PATCHv11 2/7] linux-generic: create internal pool create function with shm flags

2015-10-22 Thread Maxim Uvarov
On init odp creates odp_sched_pool. We can not modify API to add new
parameter to odp_pool_param_t and this pool should not be shared
between different processes. To do that implemented internal linux-generic
function with parameters to created shm.
Note: create shm before and then provide it to the pool does not work
because shm argument likely will be dropped from odp_pool_create() (patch
already posted.).

Signed-off-by: Maxim Uvarov 
---
 platform/linux-generic/include/odp_pool_internal.h |  4 
 platform/linux-generic/odp_pool.c  | 11 +--
 platform/linux-generic/odp_schedule.c  |  3 +--
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/platform/linux-generic/include/odp_pool_internal.h 
b/platform/linux-generic/include/odp_pool_internal.h
index 136db2c..6781703 100644
--- a/platform/linux-generic/include/odp_pool_internal.h
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -347,6 +347,10 @@ static inline uint32_t odp_buffer_pool_tailroom(odp_pool_t 
pool)
return odp_pool_to_entry(pool)->s.tailroom;
 }
 
+odp_pool_t _pool_create(const char *name,
+   odp_pool_param_t *params,
+   uint32_t shmflags);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/odp_pool.c 
b/platform/linux-generic/odp_pool.c
index 30d4b2b..2036c2a 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/odp_pool.c
@@ -144,7 +144,9 @@ int odp_pool_term_local(void)
  * Pool creation
  */
 
-odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params)
+odp_pool_t _pool_create(const char *name,
+   odp_pool_param_t *params,
+   uint32_t shmflags)
 {
odp_pool_t pool_hdl = ODP_POOL_INVALID;
pool_entry_t *pool;
@@ -290,7 +292,7 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
 
shm = odp_shm_reserve(pool->s.name,
  pool->s.pool_size,
- ODP_PAGE_SIZE, 0);
+ ODP_PAGE_SIZE, shmflags);
if (shm == ODP_SHM_INVALID) {
POOL_UNLOCK(>s.lock);
return ODP_POOL_INVALID;
@@ -403,6 +405,11 @@ odp_pool_t odp_pool_create(const char *name, 
odp_pool_param_t *params)
return pool_hdl;
 }
 
+odp_pool_t odp_pool_create(const char *name,
+  odp_pool_param_t *params)
+{
+   return _pool_create(name, params, ODP_SHM_PROC);
+}
 
 odp_pool_t odp_pool_lookup(const char *name)
 {
diff --git a/platform/linux-generic/odp_schedule.c 
b/platform/linux-generic/odp_schedule.c
index 827fcf0..c66c177 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -140,8 +140,7 @@ int odp_schedule_init_global(void)
params.buf.num   = NUM_SCHED_CMD;
params.type  = ODP_POOL_BUFFER;
 
-   pool = odp_pool_create("odp_sched_pool", );
-
+   pool = _pool_create("odp_sched_pool", , 0);
if (pool == ODP_POOL_INVALID) {
ODP_ERR("Schedule init: Pool create failed.\n");
return -1;
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv11 3/7] helper: flag to not link ring to linked list

2015-10-22 Thread Maxim Uvarov
Add flag ODPH_RING_NO_LIST to ring to not link it to linked list.

Signed-off-by: Maxim Uvarov 
---
 helper/include/odp/helper/ring.h | 7 ---
 helper/ring.c| 3 ++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/helper/include/odp/helper/ring.h b/helper/include/odp/helper/ring.h
index 5e640a7..c3c2f6a 100644
--- a/helper/include/odp/helper/ring.h
+++ b/helper/include/odp/helper/ring.h
@@ -156,10 +156,11 @@ typedef struct odph_ring {
 } odph_ring_t;
 
 
-#define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is 
"single-producer".*/
-#define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is 
"single-consumer".*/
-#define ODPH_RING_SHM_PROC 0x0004 /* If set - ring is visible from different
+#define ODPH_RING_F_SP_ENQ (1 << 0) /* The default enqueue is 
"single-producer".*/
+#define ODPH_RING_F_SC_DEQ (1 << 1) /* The default dequeue is 
"single-consumer".*/
+#define ODPH_RING_SHM_PROC (1 << 2) /* If set - ring is visible from different
processes. Default is thread visible. */
+#define ODPH_RING_NO_LIST  (1 << 3) /* Do not link ring to linked list. */
 #define ODPH_RING_QUOT_EXCEED (1 << 31)  /* Quota exceed for burst ops */
 #define ODPH_RING_SZ_MASK  (unsigned)(0x0fff) /* Ring size mask */
 
diff --git a/helper/ring.c b/helper/ring.c
index 844abf7..e113606 100644
--- a/helper/ring.c
+++ b/helper/ring.c
@@ -199,7 +199,8 @@ odph_ring_create(const char *name, unsigned count, unsigned 
flags)
r->prod.tail = 0;
r->cons.tail = 0;
 
-   TAILQ_INSERT_TAIL(_ring_list, r, next);
+   if (!(flags & ODPH_RING_NO_LIST))
+   TAILQ_INSERT_TAIL(_ring_list, r, next);
} else {
ODPH_ERR("Cannot reserve memory\n");
}
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv11 1/7] helper: ring: update ring with shm proc argument

2015-10-22 Thread Maxim Uvarov
Signed-off-by: Maxim Uvarov 
---
 helper/include/odp/helper/ring.h | 2 ++
 helper/ring.c| 9 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/helper/include/odp/helper/ring.h b/helper/include/odp/helper/ring.h
index 65c32ad..5e640a7 100644
--- a/helper/include/odp/helper/ring.h
+++ b/helper/include/odp/helper/ring.h
@@ -158,6 +158,8 @@ typedef struct odph_ring {
 
 #define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is 
"single-producer".*/
 #define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is 
"single-consumer".*/
+#define ODPH_RING_SHM_PROC 0x0004 /* If set - ring is visible from different
+   processes. Default is thread visible. */
 #define ODPH_RING_QUOT_EXCEED (1 << 31)  /* Quota exceed for burst ops */
 #define ODPH_RING_SZ_MASK  (unsigned)(0x0fff) /* Ring size mask */
 
diff --git a/helper/ring.c b/helper/ring.c
index 3122173..844abf7 100644
--- a/helper/ring.c
+++ b/helper/ring.c
@@ -158,8 +158,14 @@ odph_ring_create(const char *name, unsigned count, 
unsigned flags)
char ring_name[ODPH_RING_NAMESIZE];
odph_ring_t *r;
size_t ring_size;
+   uint32_t shm_flag;
odp_shm_t shm;
 
+   if (flags & ODPH_RING_SHM_PROC)
+   shm_flag = ODP_SHM_PROC;
+   else
+   shm_flag = 0;
+
/* count must be a power of 2 */
if (!RING_VAL_IS_POWER_2(count) || (count > ODPH_RING_SZ_MASK)) {
ODPH_ERR("Requested size is invalid, must be power of 2, and do 
not exceed the size limit %u\n",
@@ -172,7 +178,8 @@ odph_ring_create(const char *name, unsigned count, unsigned 
flags)
 
odp_rwlock_write_lock();
/* reserve a memory zone for this ring.*/
-   shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0);
+   shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE,
+ shm_flag);
 
r = odp_shm_addr(shm);
 
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv11 6/7] linux-generic: add ipc pktio support

2015-10-22 Thread Maxim Uvarov
Signed-off-by: Maxim Uvarov 
---
 platform/linux-generic/Makefile.am |   2 +
 .../linux-generic/include/odp_buffer_internal.h|   3 +
 .../linux-generic/include/odp_packet_io_internal.h |  38 ++
 .../include/odp_packet_io_ipc_internal.h   |  47 ++
 platform/linux-generic/include/odp_shm_internal.h  |  21 +
 platform/linux-generic/odp_packet_io.c |   1 +
 platform/linux-generic/odp_pool.c  |  14 +-
 platform/linux-generic/odp_shared_memory.c |  14 +-
 platform/linux-generic/pktio/io_ops.c  |   1 +
 platform/linux-generic/pktio/ipc.c | 729 +
 platform/linux-generic/pktio/ring.c|   1 +
 11 files changed, 866 insertions(+), 5 deletions(-)
 create mode 100644 platform/linux-generic/include/odp_packet_io_ipc_internal.h
 create mode 100644 platform/linux-generic/include/odp_shm_internal.h
 create mode 100644 platform/linux-generic/pktio/ipc.c
 create mode 12 platform/linux-generic/pktio/ring.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index dfb5a91..834354c 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -151,10 +151,12 @@ __LIB__libodp_la_SOURCES = \
   odp_packet_flags.c \
   odp_packet_io.c \
   pktio/io_ops.c \
+  pktio/ipc.c \
   pktio/loop.c \
   pktio/netmap.c \
   pktio/socket.c \
   pktio/socket_mmap.c \
+  pktio/ring.c \
   odp_pool.c \
   odp_queue.c \
   odp_rwlock.c \
diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
b/platform/linux-generic/include/odp_buffer_internal.h
index 4cacca1..a078e52 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -132,6 +132,9 @@ struct odp_buffer_hdr_t {
uint32_t uarea_size; /* size of user area */
uint32_t segcount;   /* segment count */
uint32_t segsize;/* segment size */
+   /* ipc mapped process can not walk over pointers,
+* offset has to be used */
+   uint64_t ipc_addr_offset[ODP_BUFFER_MAX_SEG];
void*addr[ODP_BUFFER_MAX_SEG]; /* block addrs */
uint64_t order;  /* sequence for ordered queues */
queue_entry_t   *origin_qe;  /* ordered queue origin */
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index 4745bd5..54aa795 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -25,6 +25,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -55,6 +56,41 @@ typedef struct {
 } pkt_pcap_t;
 #endif
 
+typedefstruct {
+   /* TX */
+   struct  {
+   odph_ring_t *send; /**< ODP ring for IPC msg packets
+   indexes transmitted to shared
+   memory */
+   odph_ring_t *free; /**< ODP ring for IPC msg packets
+   indexes already processed by remote
+   process */
+   } tx;
+   /* RX */
+   struct {
+   odph_ring_t *recv; /**< ODP ring for IPC msg packets
+   indexes received from shared
+memory (from remote process) */
+   odph_ring_t *free; /**< ODP ring for IPC msg packets
+   indexes already processed by
+   current process */
+   } rx; /* slave */
+   void*pool_base; /**< Remote pool base addr */
+   void*pool_mdata_base;   /**< Remote pool mdata base 
addr */
+   uint64_tpkt_size;   /**< Packet size in remote pool 
*/
+   odp_pool_t  pool;   /**< Pool of main process */
+   enum {
+   PKTIO_TYPE_IPC_MASTER = 0, /**< Master is the process which
+   creates shm */
+   PKTIO_TYPE_IPC_SLAVE   /**< Slave is the process which
+   connects to shm */
+   } type; /**< define if it's master or slave process */
+   odp_atomic_u32_t ready; /**< 1 - pktio is ready and can recv/send
+packet, 0 - not yet ready */
+   void *pinfo;
+   

[lng-odp] [API-NEXT PATCH v2] api: pktio: improve pktio_start and stop documentation

2015-10-22 Thread Petri Savolainen
Improved documentation of open, start, stop and close calls.

Signed-off-by: Petri Savolainen 
---

v2
  * fix typo
  * modify wordings
  * add spec for pktio_close

 include/odp/api/packet_io.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..915276b 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -103,6 +103,11 @@ typedef struct odp_pktio_param_t {
  * errno set. Use odp_pktio_lookup() to obtain a handle to an already open
  * device. Packet IO parameters provide interface level configuration options.
  *
+ * This call does not activate packet receive and transmit on the interface.
+ * The interface is activated with a call to odp_pktio_start(). If not
+ * specified otherwise, any interface level configuration must not be changed
+ * when the interface is active (between start and stop calls).
+ *
  * @param devPacket IO device name
  * @param pool   Default pool from which to allocate storage for packets
  *   received over this interface, must be of type ODP_POOL_PACKET
@@ -121,6 +126,8 @@ typedef struct odp_pktio_param_t {
  *  assigned the packet to a specific CoS. The default pool specified
  *  here is applicable only for those packets that are not assigned to a
  *  more specific CoS.
+ *
+ * @see odp_pktio_start(), odp_pktio_stop(), odp_pktio_close()
  */
 odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool,
   const odp_pktio_param_t *param);
@@ -128,30 +135,51 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 /**
  * Start packet receive and transmit
  *
+ * Activate packet receive and transmit on a previously opened or stopped
+ * interface. The interface can be stopped with a call to odp_pktio_stop().
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_open(), odp_pktio_stop()
  */
 int odp_pktio_start(odp_pktio_t pktio);
 
 /**
  * Stop packet receive and transmit
  *
+ * Stop packet receive and transmit on a previously started interface. New
+ * packets are not received from or transmitted to the network. Packets already
+ * received from the network may be still available from interface and
+ * application can receive those normally. New packets may not be accepted for
+ * transmit. Packets already stored for transmit are not freed. A following
+ * odp_packet_start() call restarts packet receive and transmit.
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_start(), odp_pktio_close()
  */
 int odp_pktio_stop(odp_pktio_t pktio);
 
 /**
  * Close a packet IO interface
  *
+ * Close a stopped packet IO interface. This call frees all remaining packets
+ * stored in pktio receive and transmit side buffers. The pktio is destroyed
+ * and the handle must not be used for other calls. After a successful call,
+ * the same pktio device can be opened again with a odp_packet_open() call.
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_stop(), odp_pktio_open()
  */
 int odp_pktio_close(odp_pktio_t pktio);
 
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv11 5/7] helper: move ring test to helper

2015-10-22 Thread Maxim Uvarov
Move ring test to helper and kill not needed api_test
directory. Unfortunately odp_ring_test.c had some old
dirty code so I had to clean up it to to use cunit and
latest helper apis.

Signed-off-by: Maxim Uvarov 
---
 configure.ac   |   1 -
 helper/ring.c  |   1 +
 helper/test/Makefile.am|   6 +-
 .../api_test/odp_ring_test.c => helper/test/ring.c | 100 -
 test/Makefile.am   |   2 +-
 test/api_test/.gitignore   |   2 -
 test/api_test/Makefile.am  |  13 ---
 test/api_test/odp_common.c |  91 ---
 test/api_test/odp_common.h |  42 -
 9 files changed, 63 insertions(+), 195 deletions(-)
 rename test/api_test/odp_ring_test.c => helper/test/ring.c (86%)
 delete mode 100644 test/api_test/.gitignore
 delete mode 100644 test/api_test/Makefile.am
 delete mode 100644 test/api_test/odp_common.c
 delete mode 100644 test/api_test/odp_common.h

diff --git a/configure.ac b/configure.ac
index 5d84f92..fb34e19 100644
--- a/configure.ac
+++ b/configure.ac
@@ -308,7 +308,6 @@ AC_CONFIG_FILES([Makefile
 pkgconfig/libodphelper.pc
 scripts/Makefile
 test/Makefile
-test/api_test/Makefile
 test/performance/Makefile
 test/validation/Makefile
 test/validation/buffer/Makefile
diff --git a/helper/ring.c b/helper/ring.c
index e113606..2bd8e67 100644
--- a/helper/ring.c
+++ b/helper/ring.c
@@ -644,3 +644,4 @@ int odph_ring_dequeue_burst(odph_ring_t *r, void 
**obj_table, unsigned n)
else
return odph_ring_mc_dequeue_burst(r, obj_table, n);
 }
+
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index f6a3f83..3e0df0b 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -1,13 +1,15 @@
 include $(top_srcdir)/test/Makefile.inc
 
 AM_CFLAGS += -I$(srcdir)/common
+AM_CFLAGS += -I$(top_srcdir)/test/validation/common
 AM_LDFLAGS += -static
 
 TESTS_ENVIRONMENT += TEST_DIR=${builddir}
 
 EXECUTABLES = chksum$(EXEEXT) \
   thread$(EXEEXT) \
-  process$(EXEEXT)
+  process$(EXEEXT) \
+  ring$(EXEEXT)
 
 COMPILE_ONLY =
 
@@ -27,3 +29,5 @@ dist_thread_SOURCES = thread.c
 thread_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
 dist_process_SOURCES = process.c
 process_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
+dist_ring_SOURCES = ring.c
+ring_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
diff --git a/test/api_test/odp_ring_test.c b/helper/test/ring.c
similarity index 86%
rename from test/api_test/odp_ring_test.c
rename to helper/test/ring.c
index e8a962a..ca2199d 100644
--- a/test/api_test/odp_ring_test.c
+++ b/helper/test/ring.c
@@ -37,7 +37,6 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-
 /**
  * @file
  *
@@ -48,14 +47,24 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
+#include 
 
 #define RING_SIZE 4096
 #define MAX_BULK 32
 
-#define RING_TEST_BASIC
+enum {
+   ODP_RING_TEST_BASIC,
+   ODP_RING_TEST_STRESS,
+};
+
+/* local struct for ring_thread argument */
+typedef struct {
+   pthrd_arg thrdarg;
+   int stress_type;
+} ring_arg_t;
 
 static int test_ring_basic(odph_ring_t *r)
 {
@@ -64,24 +73,24 @@ static int test_ring_basic(odph_ring_t *r)
unsigned i, num_elems;
 
/* alloc dummy object pointers */
-   src = malloc(RING_SIZE*2*sizeof(void *));
+   src = malloc(RING_SIZE * 2 * sizeof(void *));
if (src == NULL) {
LOG_ERR("failed to allocate test ring src memory\n");
goto fail;
}
-   for (i = 0; i < RING_SIZE*2; i++)
+   for (i = 0; i < RING_SIZE * 2; i++)
src[i] = (void *)(unsigned long)i;
 
cur_src = src;
 
/* alloc some room for copied objects */
-   dst = malloc(RING_SIZE*2*sizeof(void *));
+   dst = malloc(RING_SIZE * 2 * sizeof(void *));
if (dst == NULL) {
LOG_ERR("failed to allocate test ring dst memory\n");
goto fail;
}
 
-   memset(dst, 0, RING_SIZE*2*sizeof(void *));
+   memset(dst, 0, RING_SIZE * 2 * sizeof(void *));
cur_dst = dst;
 
printf("Test SP & SC basic functions\n");
@@ -251,7 +260,7 @@ static int producer_fn(void)
void **src = NULL;
 
/* alloc dummy object pointers */
-   src = malloc(MAX_BULK*2*sizeof(void *));
+   src = malloc(MAX_BULK * 2 * sizeof(void *));
if (src == NULL) {
LOG_ERR("failed to allocate producer memory.\n");
return -1;
@@ -275,7 +284,7 @@ static int consumer_fn(void)
void **src = NULL;
 
/* alloc dummy object pointers */
-   src = 

[lng-odp] [PATCHv11 4/7] helpers: remove odp_ prefix for tests source files

2015-10-22 Thread Maxim Uvarov
Prefixed were removed for validation test suite and to
be consistent we need to do the same for helpers.

Signed-off-by: Maxim Uvarov 
---
 helper/test/.gitignore   |  9 +
 helper/test/Makefile.am  | 18 --
 helper/test/{odp_chksum.c => chksum.c}   |  3 +--
 helper/test/{odp_process.c => process.c} |  3 ++-
 helper/test/{odp_thread.c => thread.c}   |  3 ++-
 5 files changed, 18 insertions(+), 18 deletions(-)
 rename helper/test/{odp_chksum.c => chksum.c} (98%)
 rename helper/test/{odp_process.c => process.c} (96%)
 rename helper/test/{odp_thread.c => thread.c} (96%)

diff --git a/helper/test/.gitignore b/helper/test/.gitignore
index 213bc5e..0c7e81f 100644
--- a/helper/test/.gitignore
+++ b/helper/test/.gitignore
@@ -1,6 +1,7 @@
 *.trs
 *.log
-odp_chksum
-odp_process
-odp_thread
-odph_pause
+chksum
+process
+thread
+pause
+ring
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index fbf5a9b..f6a3f83 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -5,10 +5,9 @@ AM_LDFLAGS += -static
 
 TESTS_ENVIRONMENT += TEST_DIR=${builddir}
 
-EXECUTABLES = odp_chksum$(EXEEXT) \
-  odp_thread$(EXEEXT) \
-  odp_process$(EXEEXT)\
-  odph_pause$(EXEEXT)
+EXECUTABLES = chksum$(EXEEXT) \
+  thread$(EXEEXT) \
+  process$(EXEEXT)
 
 COMPILE_ONLY =
 
@@ -23,9 +22,8 @@ dist_bin_SCRIPTS =
 bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
 
 
-dist_odp_chksum_SOURCES = odp_chksum.c
-dist_odp_thread_SOURCES = odp_thread.c
-odp_thread_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
-dist_odp_process_SOURCES = odp_process.c
-odp_process_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
-odph_pause_SOURCES = odph_pause.c
+dist_chksum_SOURCES = chksum.c
+dist_thread_SOURCES = thread.c
+thread_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
+dist_process_SOURCES = process.c
+process_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
diff --git a/helper/test/odp_chksum.c b/helper/test/chksum.c
similarity index 98%
rename from helper/test/odp_chksum.c
rename to helper/test/chksum.c
index 1d417a8..c987905 100644
--- a/helper/test/odp_chksum.c
+++ b/helper/test/chksum.c
@@ -64,10 +64,9 @@ static int scan_ip(const char *buf, unsigned int *paddr)
if (paddr)
*paddr = part1 << 24 | part2 << 16 | part3 << 8 | part4;
return 1;
-   } else {
-   printf("not good ip %d:%d:%d:%d/n", part1, part2, part3, part4);
}
 
+   printf("not good ip %d:%d:%d:%d/n", part1, part2, part3, part4);
return 0;
 }
 
diff --git a/helper/test/odp_process.c b/helper/test/process.c
similarity index 96%
rename from helper/test/odp_process.c
rename to helper/test/process.c
index d3a5943..280b0ff 100644
--- a/helper/test/odp_process.c
+++ b/helper/test/process.c
@@ -53,7 +53,8 @@ int main(int argc TEST_UNUSED, char *argv[] TEST_UNUSED)
cpu = odp_cpumask_first(_mask);
printf("the first CPU:  %i\n", cpu);
 
-   /* reserve cpu 0 for the control plane so remove it from the default 
mask */
+   /* reserve cpu 0 for the control plane so remove it from
+* the default mask */
odp_cpumask_clr(_mask, 0);
num_workers = odp_cpumask_count(_mask);
(void)odp_cpumask_to_str(_mask, cpumaskstr, sizeof(cpumaskstr));
diff --git a/helper/test/odp_thread.c b/helper/test/thread.c
similarity index 96%
rename from helper/test/odp_thread.c
rename to helper/test/thread.c
index 1de30ab..87b4c57 100644
--- a/helper/test/odp_thread.c
+++ b/helper/test/thread.c
@@ -54,7 +54,8 @@ int main(int argc TEST_UNUSED, char *argv[] TEST_UNUSED)
cpu = odp_cpumask_first(_mask);
printf("the first CPU:  %i\n", cpu);
 
-   /* reserve cpu 0 for the control plane so remove it from the default 
mask */
+   /* reserve cpu 0 for the control plane so remove it from
+* the default mask */
odp_cpumask_clr(_mask, 0);
num_workers = odp_cpumask_count(_mask);
(void)odp_cpumask_to_str(_mask, cpumaskstr, sizeof(cpumaskstr));
-- 
1.9.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv3] example:generator : Fix data race condition

2015-10-22 Thread ion.grigore
From: Grigore Ion 

The counters.seq counter is used to check if the configured number of
packets was processed. There is a race condition between the counter
incrementation time and its value testing time. If code is running on
multiple CPUs it is possible the application send more packets than
expected (with number of CPUs - 1). A separate counter must be used
for the processed packets.

Signed-off-by: Grigore Ion 
---
 v2:
 - Add PATCH version information (Maxim Uvarov)
 - Check patch with checkpatch script. (Bill Fischofer)
 v3:
 - patch updated to the last master (Maxim Uvarov)

 example/generator/odp_generator.c |   14 --
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/example/generator/odp_generator.c 
b/example/generator/odp_generator.c
index 085902b..34fb226 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -68,6 +68,7 @@ static struct {
odp_atomic_u64_t ip;/**< ip packets */
odp_atomic_u64_t udp;   /**< udp packets */
odp_atomic_u64_t icmp;  /**< icmp packets */
+   odp_atomic_u64_t cnt;   /**< sent packets*/
 } counters;
 
 /** * Thread specific arguments
@@ -407,6 +408,11 @@ static void *gen_send_thread(void *arg)
for (;;) {
int err;
 
+   if (args->appl.number != -1 &&
+   odp_atomic_fetch_add_u64(, 1) >=
+   (unsigned int)args->appl.number)
+   break;
+
if (args->appl.mode == APPL_MODE_UDP)
pkt = pack_udp_pkt(thr_args->pool);
else if (args->appl.mode == APPL_MODE_PING)
@@ -438,11 +444,6 @@ static void *gen_send_thread(void *arg)
   thr_args->tmo_ev);
 
}
-   if (args->appl.number != -1 &&
-   odp_atomic_load_u64()
-   >= (unsigned int)args->appl.number) {
-   break;
-   }
}
 
/* receive number of reply pks until timeout */
@@ -597,7 +598,7 @@ static void print_global_stats(int num_workers)
 
while (odp_thrmask_worker(_mask) == num_workers) {
if (args->appl.number != -1 &&
-   odp_atomic_load_u64() >=
+   odp_atomic_load_u64() >=
(unsigned int)args->appl.number) {
break;
}
@@ -669,6 +670,7 @@ int main(int argc, char *argv[])
odp_atomic_init_u64(, 0);
odp_atomic_init_u64(, 0);
odp_atomic_init_u64(, 0);
+   odp_atomic_init_u64(, 0);
 
/* Reserve memory for args from shared mem */
shm = odp_shm_reserve("shm_args", sizeof(args_t),
-- 
1.7.3.4

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 4/7] api: atomic: clean atomic API documentation

2015-10-22 Thread Petri Savolainen
Refined and centralized comment about relaxed memory ordering.
Removed in/out doxygen tags since 'atom' pointer to an object
that application must not directly access (only through the API).

Signed-off-by: Petri Savolainen 
---
 include/odp/api/atomic.h | 112 ---
 1 file changed, 48 insertions(+), 64 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 8aacc9d..97e8639 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,10 +18,20 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_atomic ODP ATOMIC
- *  Atomic types and relaxed operations. These operations cannot be used for
- *  synchronization.
- *  @{
+/**
+ * @defgroup odp_atomic ODP ATOMIC
+ * @details
+ *  Atomic integers 
+ *
+ * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
+ * implement e.g. shared counters. If not otherwise documented, operations in
+ * this API are implemented using  RELAXED memory ordering  (see memory
+ * order descriptions in the C11 specification). Relaxed operations do not
+ * provide synchronization or ordering for other memory accesses (initiated
+ * before or after the operation), only atomicity of the operation itself is
+ * guaranteed.
+ *
+ * @{
  */
 
 /**
@@ -34,19 +44,16 @@ extern "C" {
 
 /**
  * Initialize atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to initialize the variable with
+ * @param atomPointer to atomic variable
+ * @param val Value to initialize the variable with
  */
 void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val);
 
-
 /**
  * Load value of atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable
  */
@@ -54,19 +61,17 @@ uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom);
 
 /**
  * Store value to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to store in the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
  */
 void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  *
  * @return Value of the variable before the addition
  */
@@ -74,19 +79,17 @@ uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  */
 void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be subracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subracted from the variable
  *
  * @return Value of the variable before the subtraction
  */
@@ -94,37 +97,32 @@ uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be subtracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
  */
 void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable before the increment
  */
-
 uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  */
 void odp_atomic_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Fetch and decrement atomic uint32 variable
- * @note Relaxed memory 

[lng-odp] [API-NEXT PATCH v2 3/7] api: doc: re-organize doxygen doc for synchronizer

2015-10-22 Thread Petri Savolainen
Removed module synchronizer from doxygen documentation and
introduced new modules for locks, atomics and barriers. Removed
unnecessary group tagging from internal headers, which are not
visible to doxygen anyway.

Signed-off-by: Petri Savolainen 
---
 include/odp/api/atomic.h  |  2 +-
 include/odp/api/barrier.h |  4 ++--
 include/odp/api/rwlock.h  | 19 +++
 include/odp/api/rwlock_recursive.h| 17 ++---
 include/odp/api/spinlock.h| 11 ---
 include/odp/api/spinlock_recursive.h  | 15 +--
 include/odp/api/sync.h|  2 +-
 include/odp/api/ticketlock.h  | 16 ++--
 platform/linux-generic/include/odp/atomic.h   |  2 +-
 platform/linux-generic/include/odp/barrier.h  |  8 
 .../linux-generic/include/odp/plat/atomic_types.h |  8 
 .../linux-generic/include/odp/plat/barrier_types.h|  8 
 .../include/odp/plat/rwlock_recursive_types.h | 13 +
 .../linux-generic/include/odp/plat/rwlock_types.h | 13 +
 .../include/odp/plat/spinlock_recursive_types.h   | 13 +
 .../linux-generic/include/odp/plat/spinlock_types.h   | 14 +-
 .../linux-generic/include/odp/plat/ticketlock_types.h | 13 +
 platform/linux-generic/include/odp/rwlock.h   |  8 
 platform/linux-generic/include/odp/spinlock.h |  8 
 platform/linux-generic/include/odp/sync.h |  8 
 platform/linux-generic/include/odp/ticketlock.h   |  9 -
 platform/linux-generic/include/odp_atomic_internal.h  |  9 -
 22 files changed, 58 insertions(+), 162 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index ba5c354..8aacc9d 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
+/** @defgroup odp_atomic ODP ATOMIC
  *  Atomic types and relaxed operations. These operations cannot be used for
  *  synchronization.
  *  @{
diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h
index 28310ba..8ca2647 100644
--- a/include/odp/api/barrier.h
+++ b/include/odp/api/barrier.h
@@ -18,8 +18,8 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Synchronize threads.
+/** @defgroup odp_barrier ODP BARRIER
+ *  Thread excution and memory ordering barriers.
  *  @{
  */
 
diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h
index d730a70..54f426f 100644
--- a/include/odp/api/rwlock.h
+++ b/include/odp/api/rwlock.h
@@ -17,18 +17,21 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_synchronizers ODP SYNCRONIZERS
- *  Operations on reader/writer locks.
- *  A reader/writer lock allows multiple simultaneous readers but only one
- *  writer at a time.
- *  A thread that wants write access will have to wait until there are no
- *  threads that want read access. This casues a risk for starvation.
- *  @{
+/**
+ * @defgroup odp_locks ODP LOCKS
+ * @details
+ *  Reader / writer lock (odp_rwlock_t) 
+ *
+ * A reader/writer lock allows multiple simultaneous readers but only one
+ * writer at a time. A thread that wants write access will have to wait until
+ * there are no threads that want read access. This casues a risk for
+ * starvation.
+ * @{
  */
 
 /**
  * @typedef odp_rwlock_t
- * ODP rwlock
+ * ODP reader/writer lock
  */
 
 
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
index 4c7556a..10b2f79 100644
--- a/include/odp/api/rwlock_recursive.h
+++ b/include/odp/api/rwlock_recursive.h
@@ -17,15 +17,12 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on recursive rwlocks.
- *  @{
- */
-
 /**
- * @typedef odp_rwlock_recursive_t
- * Recursive rwlock
+ * @addtogroup odp_locks
+ * @details
+ *  Recursive reader/writer lock (odp_rwlock_recursive_t) 
  *
+ * This is recursive version of the reader/writer lock.
  * A thread can read- or write-acquire a recursive read-write lock multiple
  * times without a deadlock. To release the lock, the thread must unlock it
  * the same number of times. Recursion is supported only for a pure series of
@@ -38,6 +35,12 @@ extern "C" {
  *
  * ... but this is not supported.
  *   * read_lock(); write_lock(); write_unlock(); read_unlock();
+ * @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
  */
 
 /**
diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h
index 9a5a929..154d025 100644
--- a/include/odp/api/spinlock.h
+++ b/include/odp/api/spinlock.h
@@ -18,9 +18,14 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on spin locks.
- *  @{
+/**
+ * @addtogroup odp_locks
+ * @details
+ *  Spin lock (odp_spinlock_t) 
+ *
+ 

[lng-odp] [API-NEXT PATCH v2 7/7] api: atomic: added 32 bit acquire and release

2015-10-22 Thread Petri Savolainen
Added 32 bit acquire load/cas and release store/add/sub calls.
These are the minimum set of non-relaxed calls that are needed
for building lock-free algorithms. 64 bit versions can be added
later.

Signed-off-by: Petri Savolainen 
---
 include/odp/api/atomic.h| 80 -
 platform/linux-generic/include/odp/atomic.h | 32 
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index b79a50a..316f13a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -21,7 +21,7 @@ extern "C" {
 /**
  * @defgroup odp_atomic ODP ATOMIC
  * @details
- *  Atomic integers 
+ *  Atomic integers using relaxed memory ordering 
  *
  * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
  * implement e.g. shared counters. If not otherwise documented, operations in
@@ -31,6 +31,18 @@ extern "C" {
  * before or after the operation), only atomicity of the operation itself is
  * guaranteed.
  *
+ *  Operations with other than relaxed memory ordering 
+ *
+ *  An operation with RELEASE  memory ordering 
(odp_atomic_xxx_rls_xxx())
+ * ensures that other threads loading the same atomic variable with ACQUIRE
+ * memory ordering see all stores (from the calling thread) that happened 
before
+ * this releasing store.
+ *
+ *  An operation with ACQUIRE  memory ordering 
(odp_atomic_xxx_acq_xxx())
+ * ensures that the calling thread sees all stores (done by the releasing
+ * thread) that happened before a RELEASE memory ordered store to the same
+ * atomic variable.
+ *
  * @{
  */
 
@@ -309,6 +321,72 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t 
new_min);
 int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
   uint64_t new_val);
 
+/*
+ * Operations with other than relaxed memory ordering
+ * --
+ */
+
+/**
+ * Load value of atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ *
+ * @return Value of the variable
+ */
+uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
+
+/**
+ * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
+ * Store value to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
+ */
+void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Add to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
+ */
+void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Subtract from atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
+ */
+void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index b2bc5c4..005a0cd 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -258,6 +258,38 @@ static inline void odp_atomic_min_u64(odp_atomic_u64_t 
*atom, uint64_t new_min)
}
 }
 
+static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
+{
+   return __atomic_load_n(>v, __ATOMIC_ACQUIRE);
+}
+
+static inline int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom,
+uint32_t *old_val, uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_ACQUIRE,
+  __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom,
+   uint32_t 

Re: [lng-odp] [PATCHv2 1/2] example:generator : Fix data race condition

2015-10-22 Thread Ion Grigore
Correction:
Excepting example-generetaor-Fix-UDP-checksum-computation.patch

-Original Message-
From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of Ion Grigore
Sent: Thursday, October 22, 2015 5:12 PM
To: Maxim Uvarov 
Cc: lng-odp@lists.linaro.org
Subject: Re: [lng-odp] [PATCHv2 1/2] example:generator : Fix data race condition

I resent all patches updated to the latest master, excepting 
0001-validation-pktio-Fix-UDP-checksum-computation.patch
that was merged.

Thanks,
Grig

-Original Message-
From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of Maxim 
Uvarov
Sent: Monday, October 05, 2015 2:32 PM
To: lng-odp@lists.linaro.org
Subject: Re: [lng-odp] [PATCHv2 1/2] example:generator : Fix data race condition

please update patch to the latest master.

Thanks,
Maxim.

On 10/02/15 13:39, ion.grig...@freescale.com wrote:
> From: Grigore Ion 
>
> The counters.seq counter is used to check if the configured number of 
> packets was processed. There is a race condition between the counter 
> incrementation time and its value testing time. If code is running on 
> multiple CPUs it is possible the application send more packets than 
> expected (with number of CPUs - 1). A separate counter must be used 
> for the processed packets.
>
> Signed-off-by: Grigore Ion 
> ---
>   v2:
>   - Add PATCH version information (Maxim Uvarov)
>   - Check patch with checkpatch script. (Bill Fischofer)
>
>   example/generator/odp_generator.c |   19 ++-
>   1 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/example/generator/odp_generator.c
> b/example/generator/odp_generator.c
> index d6ec758..4af82a9 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -66,6 +66,7 @@ static struct {
>   odp_atomic_u64_t ip;/**< ip packets */
>   odp_atomic_u64_t udp;   /**< udp packets */
>   odp_atomic_u64_t icmp;  /**< icmp packets */
> + odp_atomic_u64_t cnt;   /**< sent packets*/
>   } counters;
>   
>   /** * Thread specific arguments
> @@ -395,6 +396,11 @@ static void *gen_send_thread(void *arg)
>   for (;;) {
>   int err;
>   
> + if (args->appl.number != -1 &&
> + odp_atomic_fetch_add_u64(, 1) >=
> + (unsigned int)args->appl.number)
> + break;
> +
>   if (args->appl.mode == APPL_MODE_UDP)
>   pkt = pack_udp_pkt(thr_args->pool);
>   else if (args->appl.mode == APPL_MODE_PING) @@ -426,11 +432,6 
> @@ 
> static void *gen_send_thread(void *arg)
>  thr_args->tmo_ev);
>   
>   }
> - if (args->appl.number != -1 &&
> - odp_atomic_load_u64()
> - >= (unsigned int)args->appl.number) {
> - break;
> - }
>   }
>   
>   /* receive number of reply pks until timeout */ @@ -450,11 +451,10 
> @@ static void *gen_send_thread(void *arg)
>   
>   /* print info */
>   if (args->appl.mode == APPL_MODE_UDP) {
> - printf("  [%02i] total send: %ju\n",
> -thr, odp_atomic_load_u64());
> + printf("  [%02i] total send: %d\n", thr, args->appl.number);
>   } else if (args->appl.mode == APPL_MODE_PING) {
> - printf("  [%02i] total send: %ju total receive: %ju\n",
> -thr, odp_atomic_load_u64(),
> + printf("  [%02i] total send: %d total receive: %ju\n",
> +thr, args->appl.number,
>  odp_atomic_load_u64());
>   }
>   return arg;
> @@ -610,6 +610,7 @@ int main(int argc, char *argv[])
>   odp_atomic_init_u64(, 0);
>   odp_atomic_init_u64(, 0);
>   odp_atomic_init_u64(, 0);
> + odp_atomic_init_u64(, 0);
>   
>   /* Reserve memory for args from shared mem */
>   shm = odp_shm_reserve("shm_args", sizeof(args_t),

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [PATCH v2 1/2] linux-generic: netmap: wait for the interface to become active

2015-10-22 Thread Stuart Haslam
On Thu, Oct 22, 2015 at 02:40:45PM +0300, Matias Elo wrote:
> Netmap interface takes a few seconds to become active after
> setup. This caused several test applications to fail.
> Check link status at the end of netmap_open() to fix this.
> 
> Signed-off-by: Matias Elo 

For both patches

Reviewed-and-Tested-by: Stuart Haslam 

> ---
> 
> v2:
>   - Rebased to master
>   - The other end of a directly attached loopback cable may come up after a
> small delay. Sleep once after link is detected to enable running 
> validation
> tests with directly attached loopback cable. (Stuart Haslam)
> 
>  platform/linux-generic/pktio/netmap.c | 20 +---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/platform/linux-generic/pktio/netmap.c 
> b/platform/linux-generic/pktio/netmap.c
> index ab4667e..0dfe511 100644
> --- a/platform/linux-generic/pktio/netmap.c
> +++ b/platform/linux-generic/pktio/netmap.c
> @@ -28,6 +28,7 @@ static struct nm_desc mmap_desc;/** Used to store the 
> mmap address;
> filled in first time, used for
> subsequent calls to nm_open */
>  
> +#define NM_OPEN_RETRIES 5
>  #define NM_INJECT_RETRIES 10
>  
>  struct dispatch_args {
> @@ -70,6 +71,10 @@ static int netmap_do_ioctl(pktio_entry_t *pktio_entry, 
> unsigned long cmd,
>   pkt_nm->if_flags = (ifr.ifr_flags << 16) |
>   (0x & ifr.ifr_flags);
>   break;
> + case SIOCETHTOOL:
> + if (subcmd == ETHTOOL_GLINK)
> + return !eval.data;
> + break;
>   default:
>   break;
>   }
> @@ -84,9 +89,10 @@ static int netmap_close(pktio_entry_t *pktio_entry)
>  {
>   pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
>  
> - if (pkt_nm->desc != NULL)
> + if (pkt_nm->desc != NULL) {
>   nm_close(pkt_nm->desc);
> -
> + mmap_desc.mem = NULL;
> + }
>   if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
>   __odp_errno = errno;
>   ODP_ERR("close(sockfd): %s\n", strerror(errno));
> @@ -101,6 +107,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
> pktio_entry_t *pktio_entry,
>   char ifname[IFNAMSIZ + 7]; /* netmap: */
>   int err;
>   int sockfd;
> + int i;
>   pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
>  
>   if (getenv("ODP_PKTIO_DISABLE_NETMAP"))
> @@ -155,7 +162,14 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
> pktio_entry_t *pktio_entry,
>   if (err)
>   goto error;
>  
> - return 0;
> + /* Wait for the link to come up */
> + for (i = 0; i < NM_OPEN_RETRIES; i++) {
> + err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL, ETHTOOL_GLINK);
> + sleep(1);
> + if (err == 0)
> + return 0;
> + }
> + ODP_ERR("%s didn't come up\n", pktio_entry->s.name);
>  
>  error:
>   netmap_close(pktio_entry);
> -- 
> 1.9.1
> 
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [Bug 1851] odp_pool_destroy() failure

2015-10-22 Thread bugzilla-daemon
https://bugs.linaro.org/show_bug.cgi?id=1851

Bill Fischofer  changed:

   What|Removed |Added

 Status|UNCONFIRMED |IN_PROGRESS
 Ever confirmed|0   |1

--- Comment #4 from Bill Fischofer  ---
I have a fix for this issue by moving the local caches into the pool itself, as
Petri suggested, however doing so seems to cut buffer alloc/free performance in
half, which is what I feared would happen.

The issue is that odp_thread_id() becomes a super hot-spot and currently that's
not terribly performant as it involves an extra call.  I'm investigating ways
to make this inlined, which would help.

-- 
You are receiving this mail because:
You are on the CC list for the bug.___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 1/7] api: doc: remove broken doxygen reference

2015-10-22 Thread Petri Savolainen
Reference caused warning when creating doxygen documentation.

Signed-off-by: Petri Savolainen 
---
 include/odp/api/packet_io.h| 2 +-
 platform/linux-generic/include/odp/debug.h | 8 
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..c17f8fa 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -30,7 +30,7 @@ extern "C" {
  * odp_pktio_send().
  * Diagnostic messages can be enhanced by using odp_pktio_to_u64 which
  * will generate a printable reference for a pktio handle for use with
- * the logging @ref odp_ver_abt_log_dbg.
+ * the logging.
  *  @{
  */
 
diff --git a/platform/linux-generic/include/odp/debug.h 
b/platform/linux-generic/include/odp/debug.h
index 987ced2..a2e59bf 100644
--- a/platform/linux-generic/include/odp/debug.h
+++ b/platform/linux-generic/include/odp/debug.h
@@ -17,14 +17,6 @@
 extern "C" {
 #endif
 
-/** @ingroup odp_ver_abt_log_dbg
- *  @{
- */
-
-/**
- * @}
- */
-
 #include 
 
 #ifdef __cplusplus
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [API-NEXT PATCHv5 1/4] api: tm: add tm API definitions

2015-10-22 Thread Savolainen, Petri (Nokia - FI/Espoo)

> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> Bill Fischofer
> Sent: Thursday, October 22, 2015 2:48 AM
> To: lng-odp@lists.linaro.org
> Cc: Barry Spinney
> Subject: [lng-odp] [API-NEXT PATCHv5 1/4] api: tm: add tm API definitions
> 
> From: Barry Spinney 
> 
> This introduces an API for configuring and using Traffic Management
> systems.
> 
> The purpose of this API is as a general packet scheduling system that
> accepts packets from input queues and applies strict priority
> scheduling, weighted fair queuing scheduling and/or bandwidth controls
> to decide which input packet should be chosen as the next output
> packet and when this output packet can be sent onwards.
> 
> Signed-off-by: Barry Spinney 
> Signed-off-by: Bill Fischofer 
> ---
>  include/odp.h  |1 +
>  include/odp/api/packet.h   |   49 +
>  include/odp/api/traffic_mngr.h | 1610
> 
>  .../linux-generic/include/odp/plat/packet_types.h  |   11 +
>  .../include/odp/plat/traffic_mngr_types.h  |  185 +++
>  platform/linux-generic/include/odp/traffic_mngr.h  |   35 +
>  .../linux-generic/include/odp_packet_internal.h|5 +
>  7 files changed, 1896 insertions(+)
>  create mode 100644 include/odp/api/traffic_mngr.h
>  create mode 100644 platform/linux-
> generic/include/odp/plat/traffic_mngr_types.h
>  create mode 100644 platform/linux-generic/include/odp/traffic_mngr.h
> 
> diff --git a/include/odp.h b/include/odp.h
> index 825c7e1..f6a6ea9 100644
> --- a/include/odp.h
> +++ b/include/odp.h
> @@ -56,6 +56,7 @@ extern "C" {
>  #include 
>  #include 
>  #include 
> +#include 
> 
>  #ifdef __cplusplus
>  }
> diff --git a/include/odp/api/packet.h b/include/odp/api/packet.h
> index 5d46b7b..e7c52af 100644
> --- a/include/odp/api/packet.h
> +++ b/include/odp/api/packet.h
> @@ -700,6 +700,55 @@ odp_packet_seg_t odp_packet_last_seg(odp_packet_t
> pkt);
>   */
>  odp_packet_seg_t odp_packet_next_seg(odp_packet_t pkt, odp_packet_seg_t
> seg);
> 
> +/**
> + * Get packet color
> + *
> + * @param pkt Packet handle
> + * @return packet color
> + */
> +odp_packet_color_t odp_packet_color(odp_packet_t pkt);


The odp_packet_color_t type documentation should be visible here in the main 
level (packet) API file. Now it's buried inside linux-generic 
platform/linux-generic/include/odp/plat/packet_types.h

/**
 * @typedef odp_packet_color_t
 * Packet "colors"
 *
 */

ODP_PACKET_GREEN   /**< Packet is green */
ODP_PACKET_YELLOW  /**< Packet is yellow */
ODP_PACKET_RED /**< Packet is red */
ODP_PACKET_ALL_COLORS   /**< Packet is all colors */




> +/** The tm_egress_kind_e enumeration type is used to indicate the kind of
> + * egress object ("spigot") associated with this TM system.  Most of these
> + * kinds are optional - with TM_EGRESS_PKT_IO being the only mandatory
> kind.
> + * The TM_EGRESS_FN - if implemented - is useful for testing the TM
> subsystem,
> + * and users are warned that it's performance might be limited.
> + */
> +typedef enum {
> + TM_EGRESS_PKT_IO, TM_EGRESS_FN
> +} odp_tm_egress_kind_t;


Also enum values (TM_EGRESS_PKT_IO, TM_EGRESS_FN) need ODP_ prefix.



-Petri



___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 6/7] api: atomic: added atomic min and max

2015-10-22 Thread Petri Savolainen
Added atomic min and max operations. These can be used e.g.
to maintain high and low water marks of an another atomic counter.
These use relaxed memory order.

Signed-off-by: Petri Savolainen 
---
 include/odp/api/atomic.h| 44 ++
 platform/linux-generic/include/odp/atomic.h | 48 +
 2 files changed, 92 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 957d304..b79a50a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,28 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Update maximum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max);
+
+/**
+ * Update minimum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min);
+
+/**
  * Compare and swap atomic uint32 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
@@ -248,6 +270,28 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Update maximum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max);
+
+/**
+ * Update minimum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min);
+
+/**
  * Compare and swap atomic uint64 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 5b13e02..b2bc5c4 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -94,6 +94,30 @@ static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, 
uint32_t *old_val,
   __ATOMIC_RELAXED);
 }
 
+static inline void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_min))
+   break;
+   }
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -210,6 +234,30 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t 
*atom, uint64_t *old_val,
 #endif
 }
 
+static inline void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_min))
+   break;
+   }
+}
+
 /**
  * @}
  */
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 5/7] api: atomic: added cas operations

2015-10-22 Thread Petri Savolainen
Added cas operations for 32 and 64 bit atomic variables. These
use relaxed memory order (as all other operations).

Signed-off-by: Petri Savolainen 
---
 include/odp/api/atomic.h   | 37 ++
 platform/linux-generic/include/odp/atomic.h| 24 ++
 .../linux-generic/include/odp/plat/atomic_types.h  | 21 ++--
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 97e8639..957d304 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,25 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Compare and swap atomic uint32 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ *
+ */
+int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
  * Initialize atomic uint64 variable
  *
  * @param atomPointer to atomic variable
@@ -229,6 +248,24 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Compare and swap atomic uint64 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+  uint64_t new_val);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index deb4039..5b13e02 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -85,6 +85,15 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
(void)__atomic_fetch_sub(>v, 1, __ATOMIC_RELAXED);
 }
 
+static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -186,6 +195,21 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t 
*atom)
 #endif
 }
 
+static inline int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   int ret;
+   *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(, *old_val, new_val));
+   return ret;
+#else
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+#endif
+}
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/plat/atomic_types.h 
b/platform/linux-generic/include/odp/plat/atomic_types.h
index 0f6c353..ea8fc2a 100644
--- a/platform/linux-generic/include/odp/plat/atomic_types.h
+++ b/platform/linux-generic/include/odp/plat/atomic_types.h
@@ -42,6 +42,21 @@ struct odp_atomic_u32_s {
 } ODP_ALIGNED(sizeof(uint32_t)); /* Enforce alignement! */;
 
 #if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+
+/**
+ * @internal
+ * CAS operation expression for the ATOMIC_OP macro
+ */
+#define ATOMIC_CAS_OP(ret_ptr, old_val, new_val) \
+({ \
+   if (atom->v == (old_val)) { \
+   atom->v = (new_val); \
+   *(ret_ptr) = 1; \
+   } else { \
+   *(ret_ptr) = 0; \
+   } \
+})
+
 /**
  * @internal
  * Helper macro for lock-based atomic operations on 64-bit integers
@@ -51,14 +66,14 @@ struct odp_atomic_u32_s 

Re: [lng-odp] [API-NEXT/PATCHv1 1/4] validation: classification: move destroy_inq() to common file

2015-10-22 Thread Maxim Uvarov

Merged,
Maxim.

On 10/21/2015 14:13, Ivan Khoronzhuk wrote:



On 21.10.15 08:14, Balasubramanian Manoharan wrote:

Common in-queue destroy function destroy_inq() is moved to
odp_classification_common.c file

Signed-off-by: Balasubramanian Manoharan 


Reviewed-by: Ivan Khoronzhuk 


---
  .../classification/odp_classification_common.c | 27 
++
  .../classification/odp_classification_test_pmr.c   | 27 
--
  .../classification/odp_classification_tests.c  | 27 
--

  .../classification/odp_classification_testsuites.h |  2 +-
  4 files changed, 28 insertions(+), 55 deletions(-)

diff --git 
a/test/validation/classification/odp_classification_common.c 
b/test/validation/classification/odp_classification_common.c

index b975dfb..9966d5f 100644
--- a/test/validation/classification/odp_classification_common.c
+++ b/test/validation/classification/odp_classification_common.c
@@ -17,6 +17,33 @@ typedef struct cls_test_packet {
  uint32be_t seq;
  } cls_test_packet_t;

+int destroy_inq(odp_pktio_t pktio)
+{
+odp_queue_t inq;
+odp_event_t ev;
+
+inq = odp_pktio_inq_getdef(pktio);
+
+if (inq == ODP_QUEUE_INVALID) {
+CU_FAIL("attempting to destroy invalid inq");
+return -1;
+}
+
+if (0 > odp_pktio_inq_remdef(pktio))
+return -1;
+
+while (1) {
+ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
+
+if (ev != ODP_EVENT_INVALID)
+odp_event_free(ev);
+else
+break;
+}
+
+return odp_queue_destroy(inq);
+}
+
  int cls_pkt_set_seq(odp_packet_t pkt)
  {
  static uint32_t seq;
diff --git 
a/test/validation/classification/odp_classification_test_pmr.c 
b/test/validation/classification/odp_classification_test_pmr.c

index e794bda..c6b733c 100644
--- a/test/validation/classification/odp_classification_test_pmr.c
+++ b/test/validation/classification/odp_classification_test_pmr.c
@@ -17,33 +17,6 @@ static odp_pool_t pool_default;
  /** sequence number of IP packets */
  odp_atomic_u32_t seq;

-static int destroy_inq(odp_pktio_t pktio)
-{
-odp_queue_t inq;
-odp_event_t ev;
-
-inq = odp_pktio_inq_getdef(pktio);
-
-if (inq == ODP_QUEUE_INVALID) {
-CU_FAIL("attempting to destroy invalid inq");
-return -1;
-}
-
-if (0 > odp_pktio_inq_remdef(pktio))
-return -1;
-
-while (1) {
-ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
-
-if (ev != ODP_EVENT_INVALID)
-odp_buffer_free(odp_buffer_from_event(ev));
-else
-break;
-}
-
-return odp_queue_destroy(inq);
-}
-
  int classification_suite_pmr_init(void)
  {
  odp_pool_t pool;
diff --git 
a/test/validation/classification/odp_classification_tests.c 
b/test/validation/classification/odp_classification_tests.c

index fe55419..03a855e 100644
--- a/test/validation/classification/odp_classification_tests.c
+++ b/test/validation/classification/odp_classification_tests.c
@@ -22,33 +22,6 @@ static odp_pktio_t pktio_loop;
  /** sequence number of IP packets */
  odp_atomic_u32_t seq;

-static int destroy_inq(odp_pktio_t pktio)
-{
-odp_queue_t inq;
-odp_event_t ev;
-
-inq = odp_pktio_inq_getdef(pktio);
-
-if (inq == ODP_QUEUE_INVALID) {
-CU_FAIL("attempting to destroy invalid inq");
-return -1;
-}
-
-if (0 > odp_pktio_inq_remdef(pktio))
-return -1;
-
-while (1) {
-ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
-
-if (ev != ODP_EVENT_INVALID)
-odp_event_free(ev);
-else
-break;
-}
-
-return odp_queue_destroy(inq);
-}
-
  int classification_suite_init(void)
  {
  odp_pool_param_t param;
diff --git 
a/test/validation/classification/odp_classification_testsuites.h 
b/test/validation/classification/odp_classification_testsuites.h

index 33547a7..a7a8baa 100644
--- a/test/validation/classification/odp_classification_testsuites.h
+++ b/test/validation/classification/odp_classification_testsuites.h
@@ -43,6 +43,6 @@ void configure_pmr_cos(void);
  void test_pmr_cos(void);
  void configure_pktio_pmr_match_set_cos(void);
  void test_pktio_pmr_match_set_cos(void);
-
+int destroy_inq(odp_pktio_t pktio);

  #endif /* ODP_BUFFER_TESTSUITES_H_ */





___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 2/7] doc: add doxygen layout file to control group page output

2015-10-22 Thread Petri Savolainen
Group level documentation can be used for API level general
description. Layout file is needed to place detailed group
description on the top of a page. By default doxygen shows
only the brief description on top (the first sentence).

Signed-off-by: Petri Savolainen 
---
 doc/doxygen.cfg   |   1 +
 doc/doxygenlayout.xml | 195 ++
 2 files changed, 196 insertions(+)
 create mode 100644 doc/doxygenlayout.xml

diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg
index f28ec24..909f0ce 100644
--- a/doc/doxygen.cfg
+++ b/doc/doxygen.cfg
@@ -33,6 +33,7 @@ EXAMPLE_PATTERNS = *.c
 EXAMPLE_RECURSIVE = YES
 IMAGE_PATH = $(SRCDIR)/doc/images
 HTML_EXTRA_STYLESHEET = $(SRCDIR)/doc/odpdoxygen.css
+LAYOUT_FILE = $(SRCDIR)/doc/doxygenlayout.xml
 ENABLE_PREPROCESSING = YES
 MACRO_EXPANSION = YES
 EXPAND_ONLY_PREDEF = YES
diff --git a/doc/doxygenlayout.xml b/doc/doxygenlayout.xml
new file mode 100644
index 000..54467c8
--- /dev/null
+++ b/doc/doxygenlayout.xml
@@ -0,0 +1,195 @@
+
+  
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv1] validation:classification: Add fix for classification tests

2015-10-22 Thread ion.grigore
From: Grigore Ion 

odph_ipv4_csum_update should be used to update the checksum inside a pkt,
as it is used in all the other examples and tests different from
classification. Thus the prototype of the function should return void,
because the intention was to update a value not to return something. These
being said it is wrong(on LE platforms) to do a cpu_to_be conversion
and an assignment operation in classification_test(this is already done
inside).

Signed-off-by: Grigore Ion 
---
 v1:
 - patch updated to the last master (Maxim Uvarov)

 .../classification/odp_classification_tests.c  |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/test/validation/classification/odp_classification_tests.c 
b/test/validation/classification/odp_classification_tests.c
index ca81c51..da8d90c 100644
--- a/test/validation/classification/odp_classification_tests.c
+++ b/test/validation/classification/odp_classification_tests.c
@@ -252,7 +252,7 @@ odp_packet_t create_packet(bool vlan)
seqno = odp_atomic_fetch_inc_u32();
ip->id = odp_cpu_to_be_16(seqno);
ip->chksum = 0;
-   ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
+   ip->chksum = odph_ipv4_csum_update(pkt);
offset += ODPH_IPV4HDR_LEN;
 
/* udp */
@@ -458,7 +458,7 @@ void test_cls_pmr_chain(void)
parse_ipv4_string(CLS_PMR_CHAIN_SADDR, , );
ip->src_addr = odp_cpu_to_be_32(addr);
ip->chksum = 0;
-   ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
+   ip->chksum = odph_ipv4_csum_update(pkt);
 
udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
udp->src_port = odp_cpu_to_be_16(CLS_PMR_CHAIN_SPORT);
@@ -476,7 +476,7 @@ void test_cls_pmr_chain(void)
parse_ipv4_string(CLS_PMR_CHAIN_SADDR, , );
ip->src_addr = odp_cpu_to_be_32(addr);
ip->chksum = 0;
-   ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
+   ip->chksum = odph_ipv4_csum_update(pkt);
 
enqueue_loop_interface(pkt);
pkt = receive_packet(, ODP_TIME_SEC);
@@ -796,7 +796,7 @@ void test_pktio_pmr_match_set_cos(void)
parse_ipv4_string(CLS_PMR_SET_SADDR, , );
ip->src_addr = odp_cpu_to_be_32(addr);
ip->chksum = 0;
-   ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
+   ip->chksum = odph_ipv4_csum_update(pkt);
 
udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
udp->src_port = odp_cpu_to_be_16(CLS_PMR_SET_SPORT);
-- 
1.7.3.4

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [Bug 1824] Untested internal code: reorder_enq & reorder_deq

2015-10-22 Thread bugzilla-daemon
https://bugs.linaro.org/show_bug.cgi?id=1824

Bill Fischofer  changed:

   What|Removed |Added

   Assignee|petri.savolai...@linaro.org |bill.fischo...@linaro.org

-- 
You are receiving this mail because:
You are on the CC list for the bug.___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [PATCHv3 0/5] handle transmit errors correctly

2015-10-22 Thread Mike Holmes
Ping, and progress on this ?

On 14 October 2015 at 08:31, Stuart Haslam  wrote:

> Fixes bug: https://bugs.linaro.org/show_bug.cgi?id=1365
>
> This series depends on the series adding ability to mark tests
> as inactive:
>
> http://patches.opendataplane.org/patch/3273/
>
> Changes since v2:
>  - Conditionally check for ability to run test and report as
>inactive if not.
>  - dropped patch 1/7, not required after other test changes
>  - dropped patch 4/7 removing MAC print, not really related
>to this series. We should add a proper test for MAC address
>but that's unrelated and TBD.
>
> Stuart Haslam (5):
>   linux-generic: pktio: increase MTU of loop interface
>   linux-generic: pktio: handle transmit errors correctly
>   validation: pktio: pass interface index rather than name
>   validation: pktio: add support for direct receive
>   validation: pktio: test for transmit error handling
>
>  .../linux-generic/include/odp_packet_io_internal.h |   6 +
>  platform/linux-generic/pktio/loop.c|   5 +-
>  platform/linux-generic/pktio/socket.c  |  27 ++-
>  platform/linux-generic/pktio/socket_mmap.c |  96 
>  test/validation/pktio/pktio.c  | 252
> +
>  test/validation/pktio/pktio.h  |   2 +
>  6 files changed, 285 insertions(+), 103 deletions(-)
>
> --
> 2.1.1
>
> ___
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
>



-- 
Mike Holmes
Technical Manager - Linaro Networking Group
Linaro.org  *│ *Open source software for ARM SoCs
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


Re: [lng-odp] [PATCH v2 1/2] linux-generic: netmap: wait for the interface to become active

2015-10-22 Thread Mike Holmes
On 22 October 2015 at 09:12, Stuart Haslam  wrote:

> On Thu, Oct 22, 2015 at 02:40:45PM +0300, Matias Elo wrote:
> > Netmap interface takes a few seconds to become active after
> > setup. This caused several test applications to fail.
> > Check link status at the end of netmap_open() to fix this.
> >
> > Signed-off-by: Matias Elo 
>
> For both patches
>
> Reviewed-and-Tested-by: Stuart Haslam 
>
> > ---
> >
> > v2:
> >   - Rebased to master
> >   - The other end of a directly attached loopback cable may come up
> after a
> > small delay. Sleep once after link is detected to enable running
> validation
> > tests with directly attached loopback cable. (Stuart Haslam)
> >
> >  platform/linux-generic/pktio/netmap.c | 20 +---
> >  1 file changed, 17 insertions(+), 3 deletions(-)
> >
> > diff --git a/platform/linux-generic/pktio/netmap.c
> b/platform/linux-generic/pktio/netmap.c
> > index ab4667e..0dfe511 100644
> > --- a/platform/linux-generic/pktio/netmap.c
> > +++ b/platform/linux-generic/pktio/netmap.c
> > @@ -28,6 +28,7 @@ static struct nm_desc mmap_desc;/** Used to store
> the mmap address;
> > filled in first time, used for
> > subsequent calls to nm_open */
> >
> > +#define NM_OPEN_RETRIES 5
> >  #define NM_INJECT_RETRIES 10
> >
> >  struct dispatch_args {
> > @@ -70,6 +71,10 @@ static int netmap_do_ioctl(pktio_entry_t
> *pktio_entry, unsigned long cmd,
> >   pkt_nm->if_flags = (ifr.ifr_flags << 16) |
> >   (0x & ifr.ifr_flags);
> >   break;
> > + case SIOCETHTOOL:
> > + if (subcmd == ETHTOOL_GLINK)
> > + return !eval.data;
> > + break;
> >   default:
> >   break;
> >   }
> > @@ -84,9 +89,10 @@ static int netmap_close(pktio_entry_t *pktio_entry)
> >  {
> >   pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
> >
> > - if (pkt_nm->desc != NULL)
> > + if (pkt_nm->desc != NULL) {
> >   nm_close(pkt_nm->desc);
> > -
> > + mmap_desc.mem = NULL;
> > + }
> >   if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
> >   __odp_errno = errno;
> >   ODP_ERR("close(sockfd): %s\n", strerror(errno));
> > @@ -101,6 +107,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED,
> pktio_entry_t *pktio_entry,
> >   char ifname[IFNAMSIZ + 7]; /* netmap: */
> >   int err;
> >   int sockfd;
> > + int i;
> >   pkt_netmap_t *pkt_nm = _entry->s.pkt_nm;
> >
> >   if (getenv("ODP_PKTIO_DISABLE_NETMAP"))
> > @@ -155,7 +162,14 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED,
> pktio_entry_t *pktio_entry,
> >   if (err)
> >   goto error;
> >
> > - return 0;
> > + /* Wait for the link to come up */
> > + for (i = 0; i < NM_OPEN_RETRIES; i++) {
> > + err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL,
> ETHTOOL_GLINK);
>

/*
When using direct attached loopback cable there may
be a small delay until the opposing end's netmap interface comes up. In
this case without the additional
sleep pktio validation tests fail.
*/


> > + sleep(1);
> > + if (err == 0)
> > + return 0;
> > + }
> > + ODP_ERR("%s didn't come up\n", pktio_entry->s.name);
> >
> >  error:
> >   netmap_close(pktio_entry);
> > --
> > 1.9.1
> >
> ___
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
>



-- 
Mike Holmes
Technical Manager - Linaro Networking Group
Linaro.org  *│ *Open source software for ARM SoCs
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp