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

2015-10-23 Thread Stuart Haslam
On Thu, Oct 22, 2015 at 11:48:41AM -0400, Mike Holmes wrote:
> Ping, and progress on this ?
> 

Waiting for review.

It needs a rebase now though, v4 coming up...

> 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


[lng-odp] [PATCH v5 2/6] test: l2fwd: add option to select scheduler queue type

2015-10-23 Thread Matias Elo
Previously only atomic scheduler queues where supported.
This was a bottleneck when the number of worker threads was
increased. Added an option to choose scheduler queue sync
mode (none, atomic, ordered).

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 94 
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 652c024..c50ca20 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -41,25 +41,19 @@
 #define SHM_PKT_POOL_BUF_SIZE  1856
 
 /** @def MAX_PKT_BURST
- * @brief Maximum number of packet bursts
+ * @brief Maximum number of packet in a burst
  */
 #define MAX_PKT_BURST  16
 
-/** @def APPL_MODE_PKT_BURST
- * @brief The application will handle pakcets in bursts
+/**
+ * Packet input mode
  */
-#define APPL_MODE_PKT_BURST0
-
-/** @def APPL_MODE_PKT_QUEUE
- * @brief The application will handle packets in queues
- */
-#define APPL_MODE_PKT_QUEUE1
-
-/** @def PRINT_APPL_MODE(x)
- * @brief Macro to print the current status of how the application handles
- * packets.
- */
-#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x))
+typedef enum pkt_in_mode_t {
+   DIRECT_RECV,
+   SCHED_NONE,
+   SCHED_ATOMIC,
+   SCHED_ORDERED,
+} pkt_in_mode_t;
 
 /** Get rid of path in filename - only for unix-type paths using '/' */
 #define NO_PATH(file_name) (strrchr((file_name), '/') ? \
@@ -71,7 +65,7 @@ typedef struct {
int cpu_count;
int if_count;   /**< Number of interfaces to be used */
char **if_names;/**< Array of pointers to interface names */
-   int mode;   /**< Packet IO mode */
+   pkt_in_mode_t mode; /**< Packet input mode */
int time;   /**< Time in seconds to run. */
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
@@ -206,11 +200,11 @@ static inline int lookup_dest_port(odp_packet_t pkt)
 }
 
 /**
- * Packet IO worker thread using bursts from/to IO resources
+ * Packet IO worker thread accessing IO resources directly
  *
  * @param arg  thread arguments of type 'thread_args_t *'
  */
-static void *pktio_ifburst_thread(void *arg)
+static void *pktio_direct_recv_thread(void *arg)
 {
int thr;
thread_args_t *thr_args;
@@ -231,7 +225,7 @@ static void *pktio_ifburst_thread(void *arg)
pktio_dst = gbl_args->pktios[dst_idx];
 
printf("[%02i] srcif:%s dstif:%s spktio:%02" PRIu64
-  " dpktio:%02" PRIu64 " BURST mode\n",
+  " dpktio:%02" PRIu64 " DIRECT RECV mode\n",
   thr,
   gbl_args->appl.if_names[src_idx],
   gbl_args->appl.if_names[dst_idx],
@@ -278,13 +272,11 @@ static void *pktio_ifburst_thread(void *arg)
  *
  * @param dev Name of device to open
  * @param pool Pool to associate with device for packet RX/TX
- * @param mode Packet processing mode for this device (BURST or QUEUE)
  *
  * @return The handle of the created pktio object.
  * @retval ODP_PKTIO_INVALID if the create fails.
  */
-static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool,
-   int mode)
+static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool)
 {
char inq_name[ODP_QUEUE_NAME_LEN];
odp_queue_param_t qparam;
@@ -292,10 +284,11 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool,
odp_pktio_t pktio;
int ret;
odp_pktio_param_t pktio_param;
+   odp_schedule_sync_t  sync_mode;
 
odp_pktio_param_init(_param);
 
-   if (mode == APPL_MODE_PKT_BURST)
+   if (gbl_args->appl.mode == DIRECT_RECV)
pktio_param.in_mode = ODP_PKTIN_MODE_RECV;
else
pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
@@ -309,13 +302,20 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool,
printf("created pktio %" PRIu64 " (%s)\n",
   odp_pktio_to_u64(pktio), dev);
 
-   /* no further setup needed for burst mode */
-   if (mode == APPL_MODE_PKT_BURST)
+   /* no further setup needed for direct receive mode */
+   if (gbl_args->appl.mode == DIRECT_RECV)
return pktio;
 
+   if (gbl_args->appl.mode == SCHED_ATOMIC)
+   sync_mode = ODP_SCHED_SYNC_ATOMIC;
+   else if (gbl_args->appl.mode == SCHED_ORDERED)
+   sync_mode = ODP_SCHED_SYNC_ORDERED;
+   else
+   sync_mode = ODP_SCHED_SYNC_NONE;
+
odp_queue_param_init();
qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
-   qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
+   qparam.sched.sync  = sync_mode;
qparam.sched.group = ODP_SCHED_GROUP_ALL;
snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def",
 

[lng-odp] [PATCH v5 3/6] test: l2fwd: fix crash when accuracy is set to 0

2015-10-23 Thread Matias Elo
Application crashes if accuracy option is set to zero
(division by zero). Disable statistics printing if accuracy
<= 0.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 59 +++-
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index c50ca20..fc60ebe 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -346,41 +346,56 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool)
  *
  */
 static int print_speed_stats(int num_workers, stats_t **thr_stats,
- int duration, int timeout)
+int duration, int timeout)
 {
-   uint64_t pkts, pkts_prev = 0, pps, drops, maximum_pps = 0;
-   int i, elapsed = 0;
+   uint64_t pkts = 0;
+   uint64_t pkts_prev = 0;
+   uint64_t pps;
+   uint64_t drops;
+   uint64_t maximum_pps = 0;
+   int i;
+   int elapsed = 0;
+   int stats_enabled = 0;
int loop_forever = (duration == 0);
 
+   if (timeout > 0)
+   stats_enabled = 1;
+
/* Wait for all threads to be ready*/
odp_barrier_wait();
 
do {
-   pkts = 0;
-   drops = 0;
+   if (stats_enabled) {
+   pkts = 0;
+   drops = 0;
 
-   sleep(timeout);
+   sleep(timeout);
 
-   for (i = 0; i < num_workers; i++) {
-   pkts += thr_stats[i]->packets;
-   drops += thr_stats[i]->drops;
+   for (i = 0; i < num_workers; i++) {
+   pkts += thr_stats[i]->packets;
+   drops += thr_stats[i]->drops;
+   }
+   pps = (pkts - pkts_prev) / timeout;
+   if (pps > maximum_pps)
+   maximum_pps = pps;
+   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
+  maximum_pps);
+
+   printf(" %" PRIu64 " total drops\n", drops);
+
+   elapsed += timeout;
+   pkts_prev = pkts;
+   } else {
+   sleep(1);
+   elapsed += 1;
}
-   pps = (pkts - pkts_prev) / timeout;
-   if (pps > maximum_pps)
-   maximum_pps = pps;
-   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
-  maximum_pps);
-
-   printf(" %" PRIu64 " total drops\n", drops);
-
-   elapsed += timeout;
-   pkts_prev = pkts;
} while (loop_forever || (elapsed < duration));
 
-   printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
-  maximum_pps);
+   if (stats_enabled)
+   printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
+  maximum_pps);
 
-   return pkts > 100 ? 0 : -1;
+   return 0;
 }
 
 /**
-- 
1.9.1

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


[lng-odp] [PATCH v5 5/6] test: l2fwd: add option to disable filling eth addresses

2015-10-23 Thread Matias Elo
By default every packet's source MAC address is filled to
match the output port. Add option to disable this to enable
testing packet forwarding without touching the packets.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index b250304..b28db31 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -70,6 +70,7 @@ typedef struct {
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
int dst_change; /**< Change destination eth addresses > */
+   int src_change; /**< Change source eth addresses > */
 } appl_args_t;
 
 static int exit_threads;   /**< Break workers loop if set to 1 */
@@ -628,11 +629,16 @@ static void fill_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num, int dst_port)
odph_ethhdr_t *eth;
unsigned i;
 
+   if (!gbl_args->appl.dst_change && !gbl_args->appl.src_change)
+   return;
+
for (i = 0; i < num; ++i) {
pkt = pkt_tbl[i];
if (odp_packet_has_eth(pkt)) {
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
-   eth->src = gbl_args->port_eth_addr[dst_port];
+
+   if (gbl_args->appl.src_change)
+   eth->src = gbl_args->port_eth_addr[dst_port];
 
if (gbl_args->appl.dst_change)
eth->dst = gbl_args->dst_eth_addr[dst_port];
@@ -661,15 +667,17 @@ static void parse_args(int argc, char *argv[], 
appl_args_t *appl_args)
{"interface", required_argument, NULL, 'i'},
{"mode", required_argument, NULL, 'm'},
{"dst_change", required_argument, NULL, 'd'},
+   {"src_change", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
appl_args->time = 0; /* loop forever if time to run is 0 */
appl_args->accuracy = 1; /* get and print pps stats second */
+   appl_args->src_change = 1; /* change eth src address by default */
 
while (1) {
-   opt = getopt_long(argc, argv, "+c:+t:+a:i:m:d:h",
+   opt = getopt_long(argc, argv, "+c:+t:+a:i:m:d:s:h",
  longopts, _index);
 
if (opt == -1)
@@ -739,6 +747,9 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
case 'd':
appl_args->dst_change = atoi(optarg);
break;
+   case 's':
+   appl_args->src_change = atoi(optarg);
+   break;
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
@@ -824,6 +835,8 @@ static void usage(char *progname)
   "  (default is 1 second).\n"
   "  -d, --dst_change  0: Don't change packets' dst eth addresses 
(default)\n"
   "1: Change packets' dst eth addresses\n"
+  "  -s, --src_change  0: Don't change packets' src eth 
addresses\n"
+  "1: Change packets' src eth addresses 
(default)\n"
   "  -h, --help   Display help and exit.\n\n"
   " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
   "ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
-- 
1.9.1

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


[lng-odp] [PATCH v5 4/6] test: l2fwd: add support for using odd number of ports

2015-10-23 Thread Matias Elo
Previously only even numbers of ports were supported. Added
support for odd numbers of ports (including 1). Src-dst port
mappings are saved during initialization to minimize per
packet operations.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index fc60ebe..b250304 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -106,6 +106,8 @@ typedef struct {
odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port default output queues */
odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
+   /** Table of dst ports */
+   int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
 
 /** Global pointer to args */
@@ -115,6 +117,7 @@ static odp_barrier_t barrier;
 
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
+static inline int find_dest_port(int port);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
 static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
   int dst_port);
@@ -181,6 +184,8 @@ static void *pktio_queue_thread(void *arg)
 
 /**
  * Lookup the destination port for a given packet
+ *
+ * @param pkt  ODP packet handle
  */
 static inline int lookup_dest_port(odp_packet_t pkt)
 {
@@ -196,7 +201,25 @@ static inline int lookup_dest_port(odp_packet_t pkt)
if (src_idx == -1)
LOG_ABORT("Failed to determine pktio input\n");
 
-   return (src_idx % 2 == 0) ? src_idx + 1 : src_idx - 1;
+   return gbl_args->dst_port[src_idx];
+}
+
+/**
+ * Find the destination port for a given input port
+ *
+ * @param port  Input port index
+ */
+static inline int find_dest_port(int port)
+{
+   /* Even number of ports */
+   if (gbl_args->appl.if_count % 2 == 0)
+   return (port % 2 == 0) ? port + 1 : port - 1;
+
+   /* Odd number of ports */
+   if (port == gbl_args->appl.if_count - 1)
+   return 0;
+   else
+   return port + 1;
 }
 
 /**
@@ -220,7 +243,7 @@ static void *pktio_direct_recv_thread(void *arg)
*thr_args->stats = stats;
 
src_idx = thr_args->src_idx;
-   dst_idx = (src_idx % 2 == 0) ? src_idx+1 : src_idx-1;
+   dst_idx = gbl_args->dst_port[src_idx];
pktio_src = gbl_args->pktios[src_idx];
pktio_dst = gbl_args->pktios[dst_idx];
 
@@ -463,11 +486,6 @@ int main(int argc, char *argv[])
num_workers);
exit(EXIT_FAILURE);
}
-   if (gbl_args->appl.if_count % 2 != 0) {
-   LOG_ERR("Error: interface count %d is odd in fwd appl.\n",
-   gbl_args->appl.if_count);
-   exit(EXIT_FAILURE);
-   }
 
/* Create packet pool */
odp_pool_param_init();
@@ -510,6 +528,9 @@ int main(int argc, char *argv[])
gbl_args->dst_eth_addr[i] = new_addr;
}
 
+   /* Save interface destination port */
+   gbl_args->dst_port[i] = find_dest_port(i);
+
ret = odp_pktio_start(pktio);
if (ret) {
LOG_ERR("Error: unable to start %s\n",
-- 
1.9.1

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


Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and stop

2015-10-23 Thread Ivan Khoronzhuk



On 23.10.15 13:35, Savolainen, Petri (Nokia - FI/Espoo) wrote:


I think these are not generally needed or supported. It's better to add a 
parameter into odp_pktio_param_t.


It's needed.
The main reason for that the same statistic module can be used by different
pktios, so if it's used for one of them it cannot be used by other, to allow
it for first it should be disable for second. For instance 2 statistic modules
are shared between 4 eth ports, etc.



For example,

typedef enum odp_pktio_stats_mode_t {

/** Need basic statistics on this interface */
ODP_PKTIO_STATS_BASIC = 0,
/** Don't need any statistics on this interface */
ODP_PKTIO_STATS_DISABLED
} odp_pktio_stats_mode_t;


-Petri




-Original Message-
From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
Maxim Uvarov
Sent: Thursday, October 22, 2015 1:45 PM
To: lng-odp@lists.linaro.org
Subject: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and
stop

Define pktio stats start/stop functions for case when same
statistic module is used by different pktios, so if it's used
for one of them it cannot be used by other, to allow it for
first it should be disable for second. For instance 2 statistic
modules are shared between 4 eth ports, etc.

Signed-off-by: Maxim Uvarov 
---
  include/odp/api/packet_io_stats.h | 20 
  1 file changed, 20 insertions(+)

diff --git a/include/odp/api/packet_io_stats.h
b/include/odp/api/packet_io_stats.h
index 1bff9ca..03f060e 100644
--- a/include/odp/api/packet_io_stats.h
+++ b/include/odp/api/packet_io_stats.h
@@ -123,6 +123,26 @@ int odp_pktio_stats(odp_pktio_t pktio,
  int odp_pktio_stats_reset(odp_pktio_t pktio);

  /**
+ * Start statistics for pktio handle
+ *
+ * @param  pktioPacket IO handle
+ * @retval  0 on success
+ * @retval <0 on failure
+ *
+ */
+int odp_pktio_stats_start(odp_pktio_t pktio);
+
+/**
+ * Stop statistics for pktio handle
+ *
+ * @param  pktioPacket IO handle
+ * @retval  0 on success
+ * @retval <0 on failure
+ *
+ */
+int odp_pktio_stats_stop(odp_pktio_t pktio);
+
+/**
   * @}
   */

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



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


Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and stop

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

User tells to the implementation on open() which interfaces needed statistics. 
As long as implementation has enough stat resources open() succeeds. When all 
stats are gone and user still ask for stats, open() fails. Implementation user 
manual documents this limitation (how many interfaces can be opened with stats 
enabled and in which combination).

-Petri


> -Original Message-
> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
> Sent: Friday, October 23, 2015 2:00 PM
> To: Savolainen, Petri (Nokia - FI/Espoo); EXT Maxim Uvarov; lng-
> o...@lists.linaro.org
> Subject: Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start
> and stop
> 
> 
> 
> On 23.10.15 13:35, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> >
> > I think these are not generally needed or supported. It's better to add a
> parameter into odp_pktio_param_t.
> 
> It's needed.
> The main reason for that the same statistic module can be used by different
> pktios, so if it's used for one of them it cannot be used by other, to
> allow
> it for first it should be disable for second. For instance 2 statistic
> modules
> are shared between 4 eth ports, etc.
> 
> >
> > For example,
> >
> > typedef enum odp_pktio_stats_mode_t {
> >
> > /** Need basic statistics on this interface */
> > ODP_PKTIO_STATS_BASIC = 0,
> > /** Don't need any statistics on this interface */
> > ODP_PKTIO_STATS_DISABLED
> > } odp_pktio_stats_mode_t;
> >
> >
> > -Petri
> >
> >
> >
> >> -Original Message-
> >> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> >> Maxim Uvarov
> >> Sent: Thursday, October 22, 2015 1:45 PM
> >> To: lng-odp@lists.linaro.org
> >> Subject: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and
> >> stop
> >>
> >> Define pktio stats start/stop functions for case when same
> >> statistic module is used by different pktios, so if it's used
> >> for one of them it cannot be used by other, to allow it for
> >> first it should be disable for second. For instance 2 statistic
> >> modules are shared between 4 eth ports, etc.
> >>
> >> Signed-off-by: Maxim Uvarov 
> >> ---
> >>   include/odp/api/packet_io_stats.h | 20 
> >>   1 file changed, 20 insertions(+)
> >>
> >> diff --git a/include/odp/api/packet_io_stats.h
> >> b/include/odp/api/packet_io_stats.h
> >> index 1bff9ca..03f060e 100644
> >> --- a/include/odp/api/packet_io_stats.h
> >> +++ b/include/odp/api/packet_io_stats.h
> >> @@ -123,6 +123,26 @@ int odp_pktio_stats(odp_pktio_t pktio,
> >>   int odp_pktio_stats_reset(odp_pktio_t pktio);
> >>
> >>   /**
> >> + * Start statistics for pktio handle
> >> + *
> >> + * @param pktioPacket IO handle
> >> + * @retval  0 on success
> >> + * @retval <0 on failure
> >> + *
> >> + */
> >> +int odp_pktio_stats_start(odp_pktio_t pktio);
> >> +
> >> +/**
> >> + * Stop statistics for pktio handle
> >> + *
> >> + * @param pktioPacket IO handle
> >> + * @retval  0 on success
> >> + * @retval <0 on failure
> >> + *
> >> + */
> >> +int odp_pktio_stats_stop(odp_pktio_t pktio);
> >> +
> >> +/**
> >>* @}
> >>*/
> >>
> >> --
> >> 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
> >
> 
> --
> Regards,
> Ivan Khoronzhuk
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCHv4 2/5] linux-generic: pktio: handle transmit errors correctly

2015-10-23 Thread Stuart Haslam
Errors which occur while sending packets via odp_pktio_send() aren't
handled correctly or even consistently across the two socket based
implementations.

The problems being addressed are;

 - calls may block indefinitely in certain error conditions (mmsg)
 - packets may be freed and reported as being sent correctly even though
   they weren't really sent (mmap)
 - return value doesn't always accurately reflect number of packets sent
 - inconsistent use of __odp_errno

Signed-off-by: Stuart Haslam 
---
 .../linux-generic/include/odp_packet_io_internal.h |  6 ++
 platform/linux-generic/pktio/socket.c  | 27 +++---
 platform/linux-generic/pktio/socket_mmap.c | 96 +++---
 3 files changed, 70 insertions(+), 59 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index 4745bd5..1a1118c 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -32,6 +32,12 @@ extern "C" {
 
 #define PKTIO_NAME_LEN 256
 
+/** Determine if a socket read/write error should be reported. Transient errors
+ *  that simply require the caller to retry are ignored, the _send/_recv APIs
+ *  are non-blocking and it is the caller's responsibility to retry if the
+ *  requested number of packets were not handled. */
+#define SOCK_ERR_REPORT(e) (e != EAGAIN && e != EWOULDBLOCK && e != EINTR)
+
 /* Forward declaration */
 struct pktio_if_ops;
 
diff --git a/platform/linux-generic/pktio/socket.c 
b/platform/linux-generic/pktio/socket.c
index a95b9a8..9525665 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -393,9 +393,7 @@ static int sock_mmsg_send(pktio_entry_t *pktio_entry,
struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_TX][ODP_BUFFER_MAX_SEG];
int ret;
int sockfd;
-   unsigned i;
-   unsigned sent_msgs = 0;
-   unsigned flags;
+   unsigned n, i;
 
if (odp_unlikely(len > ODP_PACKET_SOCKET_MAX_BURST_TX))
return -1;
@@ -409,17 +407,24 @@ static int sock_mmsg_send(pktio_entry_t *pktio_entry,
iovecs[i]);
}
 
-   flags = MSG_DONTWAIT;
-   for (i = 0; i < len; i += sent_msgs) {
-   ret = sendmmsg(sockfd, [i], len - i, flags);
-   sent_msgs = ret > 0 ? (unsigned)ret : 0;
-   flags = 0;  /* blocking for next rounds */
+   for (i = 0; i < len; ) {
+   ret = sendmmsg(sockfd, [i], len - i, MSG_DONTWAIT);
+   if (odp_unlikely(ret <= -1)) {
+   if (i == 0 && SOCK_ERR_REPORT(errno)) {
+   __odp_errno = errno;
+   ODP_ERR("sendmmsg(): %s\n", strerror(errno));
+   return -1;
+   }
+   break;
+   }
+
+   i += ret;
}
 
-   for (i = 0; i < len; i++)
-   odp_packet_free(pkt_table[i]);
+   for (n = 0; n < i; ++n)
+   odp_packet_free(pkt_table[n]);
 
-   return len;
+   return i;
 }
 
 /*
diff --git a/platform/linux-generic/pktio/socket_mmap.c 
b/platform/linux-generic/pktio/socket_mmap.c
index ba773a3..3f2f91e 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -174,49 +174,70 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct 
ring *ring,
 {
union frame_map ppd;
uint32_t pkt_len;
-   unsigned frame_num, next_frame_num;
+   unsigned first_frame_num, frame_num, frame_count;
int ret;
-   unsigned i = 0;
+   uint8_t *buf;
+   unsigned n, i = 0;
+   unsigned nb_tx = 0;
+   int send_errno;
 
-   frame_num = ring->frame_num;
+   first_frame_num = ring->frame_num;
+   frame_num = first_frame_num;
+   frame_count = ring->rd_num;
 
while (i < len) {
-   if (mmap_tx_kernel_ready(ring->rd[frame_num].iov_base)) {
-   ppd.raw = ring->rd[frame_num].iov_base;
+   ppd.raw = ring->rd[frame_num].iov_base;
+   if (!odp_unlikely(mmap_tx_kernel_ready(ppd.raw)))
+   break;
 
-   next_frame_num = (frame_num + 1) % ring->rd_num;
+   pkt_len = odp_packet_len(pkt_table[i]);
+   ppd.v2->tp_h.tp_snaplen = pkt_len;
+   ppd.v2->tp_h.tp_len = pkt_len;
 
-   pkt_len = odp_packet_len(pkt_table[i]);
-   ppd.v2->tp_h.tp_snaplen = pkt_len;
-   ppd.v2->tp_h.tp_len = pkt_len;
+   buf = (uint8_t *)ppd.raw + TPACKET2_HDRLEN -
+  sizeof(struct sockaddr_ll);
+   odp_packet_copydata_out(pkt_table[i], 0, pkt_len, buf);
 
-   

[lng-odp] [PATCHv4 3/5] validation: pktio: pass interface index rather than name

2015-10-23 Thread Stuart Haslam
Avoid the need to pass the interface name to the create_pktio() function
as it can be derived from the index which must also be passed. This
means the caller can't make the mistake of passing a mismatched name and
index - there was one instance of this which is now fixed.

Signed-off-by: Stuart Haslam 
---
 test/validation/pktio/pktio.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index a746b9a..14c1f5e 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -250,11 +250,11 @@ static int default_pool_create(void)
return 0;
 }
 
-static odp_pktio_t create_pktio(const char *iface, odp_queue_type_t q_type,
-   int num)
+static odp_pktio_t create_pktio(int iface_idx, odp_queue_type_t q_type)
 {
odp_pktio_t pktio;
odp_pktio_param_t pktio_param;
+   const char *iface = iface_name[iface_idx];
 
odp_pktio_param_init(_param);
 
@@ -263,7 +263,7 @@ static odp_pktio_t create_pktio(const char *iface, 
odp_queue_type_t q_type,
else
pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
 
-   pktio = odp_pktio_open(iface, pool[num], _param);
+   pktio = odp_pktio_open(iface, pool[iface_idx], _param);
if (pktio == ODP_PKTIO_INVALID)
pktio = odp_pktio_lookup(iface);
CU_ASSERT(pktio != ODP_PKTIO_INVALID);
@@ -461,7 +461,7 @@ static void test_txrx(odp_queue_type_t q_type, int num_pkts)
io = [i];
 
io->name = iface_name[i];
-   io->id   = create_pktio(iface_name[i], q_type, i);
+   io->id   = create_pktio(i, q_type);
if (io->id == ODP_PKTIO_INVALID) {
CU_FAIL("failed to open iface");
return;
@@ -521,7 +521,7 @@ void pktio_test_mtu(void)
int ret;
int mtu;
 
-   odp_pktio_t pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 
0);
+   odp_pktio_t pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
mtu = odp_pktio_mtu(pktio);
@@ -537,7 +537,7 @@ void pktio_test_promisc(void)
 {
int ret;
 
-   odp_pktio_t pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 
0);
+   odp_pktio_t pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
ret = odp_pktio_promisc_mode_set(pktio, 1);
@@ -565,7 +565,7 @@ void pktio_test_mac(void)
int ret;
odp_pktio_t pktio;
 
-   pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 0);
+   pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
printf("testing mac for %s\n", iface_name[0]);
@@ -593,7 +593,7 @@ void pktio_test_inq_remdef(void)
uint64_t wait;
int i;
 
-   pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 0);
+   pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
CU_ASSERT(create_inq(pktio, ODP_QUEUE_TYPE_POLL) == 0);
inq = odp_pktio_inq_getdef(pktio);
@@ -621,7 +621,7 @@ void pktio_test_open(void)
 
/* test the sequence open->close->open->close() */
for (i = 0; i < 2; ++i) {
-   pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 0);
+   pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
CU_ASSERT(odp_pktio_close(pktio) == 0);
}
@@ -660,7 +660,7 @@ void pktio_test_inq(void)
 {
odp_pktio_t pktio;
 
-   pktio = create_pktio(iface_name[0], ODP_QUEUE_TYPE_SCHED, 0);
+   pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
CU_ASSERT(create_inq(pktio, ODP_QUEUE_TYPE_POLL) == 0);
@@ -679,7 +679,7 @@ static void pktio_test_start_stop(void)
uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC);
 
for (i = 0; i < num_ifaces; i++) {
-   pktio[i] = create_pktio(iface_name[i], ODP_QUEUE_TYPE_SCHED, 0);
+   pktio[i] = create_pktio(i, ODP_QUEUE_TYPE_SCHED);
CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID);
create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
}
-- 
2.1.1

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


Re: [lng-odp] [PATCH v5 3/6] test: l2fwd: fix crash when accuracy is set to 0

2015-10-23 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: Friday, October 23, 2015 1:03 PM
> To: lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [PATCH v5 3/6] test: l2fwd: fix crash when accuracy is 
> set to
> 0
> 
> On 10/23/2015 11:42, Matias Elo wrote:
> > Application crashes if accuracy option is set to zero
> > (division by zero). Disable statistics printing if accuracy
> > <= 0.
> >
> > Signed-off-by: Matias Elo 
> > ---
> >   test/performance/odp_l2fwd.c | 59 +++
> -
> >   1 file changed, 37 insertions(+), 22 deletions(-)
> >
> > diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
> > index c50ca20..fc60ebe 100644
> > --- a/test/performance/odp_l2fwd.c
> > +++ b/test/performance/odp_l2fwd.c
> > @@ -346,41 +346,56 @@ static odp_pktio_t create_pktio(const char *dev,
> odp_pool_t pool)
> >*
> >*/
> >   static int print_speed_stats(int num_workers, stats_t **thr_stats,
> > - int duration, int timeout)
> > +int duration, int timeout)
> >   {
> > -   uint64_t pkts, pkts_prev = 0, pps, drops, maximum_pps = 0;
> > -   int i, elapsed = 0;
> > +   uint64_t pkts = 0;
> > +   uint64_t pkts_prev = 0;
> > +   uint64_t pps;
> > +   uint64_t drops;
> > +   uint64_t maximum_pps = 0;
> > +   int i;
> > +   int elapsed = 0;
> > +   int stats_enabled = 0;
> > int loop_forever = (duration == 0);
> >
> > +   if (timeout > 0)
> > +   stats_enabled = 1;
> > +
> > /* Wait for all threads to be ready*/
> > odp_barrier_wait();
> >
> > do {
> > -   pkts = 0;
> > -   drops = 0;
> > +   if (stats_enabled) {
> > +   pkts = 0;
> > +   drops = 0;
> >
> > -   sleep(timeout);
> > +   sleep(timeout);
> >
> > -   for (i = 0; i < num_workers; i++) {
> > -   pkts += thr_stats[i]->packets;
> > -   drops += thr_stats[i]->drops;
> > +   for (i = 0; i < num_workers; i++) {
> > +   pkts += thr_stats[i]->packets;
> > +   drops += thr_stats[i]->drops;
> > +   }
> > +   pps = (pkts - pkts_prev) / timeout;
> > +   if (pps > maximum_pps)
> > +   maximum_pps = pps;
> > +   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
> > +  maximum_pps);
> > +
> > +   printf(" %" PRIu64 " total drops\n", drops);
> > +
> > +   elapsed += timeout;
> > +   pkts_prev = pkts;
> > +   } else {
> > +   sleep(1);
> > +   elapsed += 1;
> > }
> > -   pps = (pkts - pkts_prev) / timeout;
> > -   if (pps > maximum_pps)
> > -   maximum_pps = pps;
> > -   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
> > -  maximum_pps);
> > -
> > -   printf(" %" PRIu64 " total drops\n", drops);
> > -
> > -   elapsed += timeout;
> > -   pkts_prev = pkts;
> > } while (loop_forever || (elapsed < duration));
> >
> > -   printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
> > -  maximum_pps);
> > +   if (stats_enabled)
> > +   printf("TEST RESULT: %" PRIu64 " maximum packets per
> second.\n",
> > +  maximum_pps);
> >
> > -   return pkts > 100 ? 0 : -1;
> > +   return 0;
> 
> My comment was not fixed. l2fwd run should return 0 if we think it
> worked well, -1 if there was errors (like no packets,
> or l2fwd does not operate properly).
> 

Missed that message completely (still getting used to a new Outlook version). 
I'll submit new version soon.

-Matias

> Maxim.
> 
> >   }
> >
> >   /**
> 
> ___
> 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] m4: valgrind fix confgure output

2015-10-23 Thread Mike Holmes
Signed-off-by: Mike Holmes 
---
 m4/ax_valgrind_check.m4 | 2 --
 1 file changed, 2 deletions(-)

diff --git a/m4/ax_valgrind_check.m4 b/m4/ax_valgrind_check.m4
index ff05f56..ccee86b 100644
--- a/m4/ax_valgrind_check.m4
+++ b/m4/ax_valgrind_check.m4
@@ -59,7 +59,6 @@
 
 AC_DEFUN([AX_VALGRIND_CHECK],[
dnl Check for --enable-valgrind
-   AC_MSG_CHECKING([whether to enable Valgrind on the unit tests])
AC_ARG_ENABLE([valgrind],
  [AS_HELP_STRING([--enable-valgrind], [Whether to enable 
Valgrind on the unit tests])],
  [enable_valgrind=$enableval],[enable_valgrind=])
@@ -74,7 +73,6 @@ AC_DEFUN([AX_VALGRIND_CHECK],[
 
AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"])
AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])
-   AC_MSG_RESULT([$enable_valgrind])
 
# Check for Valgrind tools we care about.
m4_define([valgrind_tool_list],[[memcheck], [helgrind], [drd], 
[exp-sgcheck]])
-- 
2.5.0

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


Re: [lng-odp] [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c hash functions

2015-10-23 Thread Maxim Uvarov

Somehow that email inside previous version thread it's hard to follow it.

I have few notes:

1. version should be remove from long log  and put under "---" in email.

2. doxygen:
/opt/Linaro/odp2.git/include/odp/api/hash.h:73: warning: argument 
'crc_param' of command @param is not found in the argument list of 
odp_hash_crc_gen64(const void *data, uint32_t data_len, uint64_t 
init_val, odp_hash_crc_param_t *param, uint64_t *crc)
/opt/Linaro/odp2.git/include/odp/api/hash.h:73: warning: The following 
parameters of odp_hash_crc_gen64(const void *data, uint32_t data_len, 
uint64_t init_val, odp_hash_crc_param_t *param, uint64_t *crc) are not 
documented:

  parameter 'param'

3. It will be good to include test coverage tests cases for make check.

Thanks,
Maxim.


On 10/23/2015 16:09, Savolainen, Petri (Nokia - FI/Espoo) wrote:

Ping. Why this has not been merged yet.



-Original Message-
From: Savolainen, Petri (Nokia - FI/Espoo)
Sent: Thursday, October 15, 2015 11:08 AM
To: 'EXT Peng'; lng-odp@lists.linaro.org
Cc: Peng
Subject: RE: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c
hash functions


Reviewed-by: Petri Savolainen 



-Original Message-
From: EXT Peng [mailto:xnhp0...@icloud.com]
Sent: Thursday, October 15, 2015 10:51 AM
To: lng-odp@lists.linaro.org
Cc: Savolainen, Petri (Nokia - FI/Espoo); Peng
Subject: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c

hash

functions

From: Peng 

v2: Add copyright license.
v3: APIs: crc32c, crc32 and generic CRC hash impl
 linux-generic: add impl for crc32c.
v4: linux-generic:
 change odp_crc32c_1word to crc32c_u32,
 change odp_crc32c_2words to crc32c_u64,
 drop inline decorator for odp_hash_crc32c.
 change copyrights to 2015.
v5: linux-generic:
 add copyrights to 2015 for linux-generic headers

Signed-off-by: Peng 
---
  include/odp.h |   1 +
  include/odp/api/hash.h|  98 ++
  platform/linux-generic/Makefile.am|   3 +
  platform/linux-generic/include/odp/hash.h |  34 +++
  platform/linux-generic/odp_hash.c | 487
++
  5 files changed, 623 insertions(+)
  create mode 100644 include/odp/api/hash.h
  create mode 100644 platform/linux-generic/include/odp/hash.h
  create mode 100644 platform/linux-generic/odp_hash.c

diff --git a/include/odp.h b/include/odp.h
index 825c7e1..da57da8 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -24,6 +24,7 @@ extern "C" {
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
diff --git a/include/odp/api/hash.h b/include/odp/api/hash.h
new file mode 100644
index 000..59466c1
--- /dev/null
+++ b/include/odp/api/hash.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP Hash functions
+ */
+
+#ifndef ODP_API_HASH_H_
+#define ODP_API_HASH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+/** @defgroup odp_hash ODP HASH FUNCTIONS
+ *  ODP Hash functions
+ *  @{
+ */
+
+/**
+* Calculate CRC-32
+*
+* Calculates CRC-32 over the data. The polynomial is 0x04c11db7.
+*
+* @param data   Pointer to data
+* @param data_len   Data length in bytes
+* @param init_val   CRC generator initialization value
+*
+* @return CRC32 value
+*/
+uint32_t odp_hash_crc32(const void *data, uint32_t data_len, uint32_t
init_val);
+
+/**
+* Calculate CRC-32C
+*
+* Calculates CRC-32C (a.k.a. CRC-32 Castagnoli) over the data.
+* The polynomial is 0x1edc6f41.
+*
+* @param data   Pointer to data
+* @param data_len   Data length in bytes
+* @param init_val   CRC generator initialization value
+*
+* @return CRC32C value
+*/
+uint32_t odp_hash_crc32c(const void *data, uint32_t data_len,
+uint32_t init_val);
+
+/**
+* CRC parameters
+*
+* Supports CRCs up to 64 bits
+*/
+typedef struct odp_hash_crc_param_t {
+   /** CRC width in bits */
+   uint32_t width;
+   /** Polynomial (stored in 'width' LSB bits) */
+   uint64_t poly;
+   /** 0: don't reflect, 1: reflect bits in input bytes */
+   odp_bool_t reflect_in;
+   /** 0: don't reflect, 1: reflect bits in output bytes */
+   odp_bool_t reflect_out;
+   /** XOR this value to CRC output (stored in 'width' LSB bits) */
+   uint64_t xor_out;
+} odp_hash_crc_param_t;
+
+/**
+* Calculate up to 64 bit CRC using the given parameters
+*
+* Calculates CRC over the data using the given parameters.
+*
+* @param data   Pointer to data
+* @param data_len   Data length in bytes
+* @param init_val   CRC generator initialization value
+* @param crc_param  CRC parameters
+* @param crcPointer for CRC output
+*
+* @return 0 on success, <0 on failure (e.g. not supported algorithm)
+*/
+int odp_hash_crc_gen64(const void *data, uint32_t data_len,
+  uint64_t 

[lng-odp] [PATCHv4 4/5] validation: pktio: add support for direct receive

2015-10-23 Thread Stuart Haslam
Add a couple of tests for receiving packets directly via
odp_pktio_recv().

Signed-off-by: Stuart Haslam 
---
 test/validation/pktio/pktio.c | 101 ++
 test/validation/pktio/pktio.h |   2 +
 2 files changed, 65 insertions(+), 38 deletions(-)

diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index 14c1f5e..5fe8293 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -34,6 +34,7 @@ typedef struct {
odp_pktio_t id;
odp_queue_t outq;
odp_queue_t inq;
+   odp_pktio_input_mode_t in_mode;
 } pktio_info_t;
 
 /** magic number and sequence at start of UDP payload */
@@ -250,7 +251,7 @@ static int default_pool_create(void)
return 0;
 }
 
-static odp_pktio_t create_pktio(int iface_idx, odp_queue_type_t q_type)
+static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t mode)
 {
odp_pktio_t pktio;
odp_pktio_param_t pktio_param;
@@ -258,10 +259,7 @@ static odp_pktio_t create_pktio(int iface_idx, 
odp_queue_type_t q_type)
 
odp_pktio_param_init(_param);
 
-   if (q_type == ODP_QUEUE_TYPE_POLL)
-   pktio_param.in_mode = ODP_PKTIN_MODE_POLL;
-   else
-   pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+   pktio_param.in_mode = mode;
 
pktio = odp_pktio_open(iface, pool[iface_idx], _param);
if (pktio == ODP_PKTIO_INVALID)
@@ -348,33 +346,41 @@ static odp_event_t queue_deq_wait_time(odp_queue_t queue, 
uint64_t ns)
return ODP_EVENT_INVALID;
 }
 
-static odp_packet_t wait_for_packet(odp_queue_t queue,
+static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
uint32_t seq, uint64_t ns)
 {
uint64_t start, now, diff;
odp_event_t ev;
-   odp_packet_t pkt = ODP_PACKET_INVALID;
+   odp_packet_t pkt;
uint64_t wait;
 
start = odp_time_cycles();
wait = odp_schedule_wait_time(ns);
 
do {
-   if (queue != ODP_QUEUE_INVALID &&
-   odp_queue_type(queue) == ODP_QUEUE_TYPE_POLL)
-   ev = queue_deq_wait_time(queue, ns);
-   else
-   ev  = odp_schedule(NULL, wait);
-
-   if (ev != ODP_EVENT_INVALID) {
-   if (odp_event_type(ev) == ODP_EVENT_PACKET) {
-   pkt = odp_packet_from_event(ev);
-   if (pktio_pkt_seq(pkt) == seq)
-   return pkt;
+   pkt = ODP_PACKET_INVALID;
+
+   if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV) {
+   odp_pktio_recv(pktio_rx->id, , 1);
+   } else {
+   if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
+   ev = queue_deq_wait_time(pktio_rx->inq, ns);
+   else
+   ev = odp_schedule(NULL, wait);
+
+   if (ev != ODP_EVENT_INVALID) {
+   if (odp_event_type(ev) == ODP_EVENT_PACKET)
+   pkt = odp_packet_from_event(ev);
+   else
+   odp_event_free(ev);
}
+   }
 
-   /* not interested in this event */
-   odp_event_free(ev);
+   if (pkt != ODP_PACKET_INVALID) {
+   if (pktio_pkt_seq(pkt) == seq)
+   return pkt;
+
+   odp_packet_free(pkt);
}
 
now = odp_time_cycles();
@@ -438,7 +444,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, 
pktio_info_t *pktio_b,
 
/* and wait for them to arrive back */
for (i = 0; i < num_pkts; ++i) {
-   rx_pkt = wait_for_packet(pktio_b->inq, tx_seq[i], ODP_TIME_SEC);
+   rx_pkt = wait_for_packet(pktio_b, tx_seq[i], ODP_TIME_SEC);
 
if (rx_pkt == ODP_PACKET_INVALID)
break;
@@ -450,7 +456,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, 
pktio_info_t *pktio_b,
CU_ASSERT(i == num_pkts);
 }
 
-static void test_txrx(odp_queue_type_t q_type, int num_pkts)
+static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
 {
int ret, i, if_b;
pktio_info_t pktios[MAX_NUM_IFACES];
@@ -461,17 +467,21 @@ static void test_txrx(odp_queue_type_t q_type, int 
num_pkts)
io = [i];
 
io->name = iface_name[i];
-   io->id   = create_pktio(i, q_type);
+   io->id   = create_pktio(i, in_mode);
if (io->id == ODP_PKTIO_INVALID) {
CU_FAIL("failed to open iface");
return;
}
-   create_inq(io->id, q_type);
io->outq = 

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

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

--- Comment #6 from carl.wal...@nokia.com ---
I applied your patch and it seems to be working just fine. I did not test
performance though. Thanks a lot!

-- 
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 v6 6/6] test: l2fwd: word copy ethernet addresses

2015-10-23 Thread Matias Elo
Optimize ethernet address filling by using word copy.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 57 ++--
 1 file changed, 45 insertions(+), 12 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index fb5f656..4e371a1 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -92,6 +92,14 @@ typedef struct {
 } thread_args_t;
 
 /**
+ * Optimized type for storing ethernet addresses
+ */
+typedef union {
+   uint8_t u8[6];
+   uint16_t u16[3];
+} eth_addr_t;
+
+/**
  * Grouping of all global data
  */
 typedef struct {
@@ -102,9 +110,9 @@ typedef struct {
/** Table of pktio handles */
odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
-   odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   eth_addr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ethernet addresses */
-   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   eth_addr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port default output queues */
odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ports */
@@ -433,7 +441,7 @@ int main(int argc, char *argv[])
odp_shm_t shm;
odp_cpumask_t cpumask;
char cpumaskstr[ODP_CPUMASK_STR_SIZE];
-   odph_ethaddr_t new_addr;
+   eth_addr_t new_addr;
odp_pktio_t pktio;
odp_pool_param_t params;
int ret;
@@ -508,7 +516,7 @@ int main(int argc, char *argv[])
gbl_args->pktios[i] = pktio;
 
/* Save interface ethernet address */
-   if (odp_pktio_mac_addr(pktio, gbl_args->port_eth_addr[i].addr,
+   if (odp_pktio_mac_addr(pktio, gbl_args->port_eth_addr[i].u8,
   ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
LOG_ERR("Error: interface ethernet address unknown\n");
exit(EXIT_FAILURE);
@@ -521,9 +529,9 @@ int main(int argc, char *argv[])
/* Save destination eth address */
if (gbl_args->appl.dst_change) {
/* 02:00:00:00:00:XX */
-   memset(_addr, 0, sizeof(odph_ethaddr_t));
-   new_addr.addr[0] = 0x02;
-   new_addr.addr[5] = i;
+   memset(_addr, 0, sizeof(eth_addr_t));
+   new_addr.u8[0] = 0x02;
+   new_addr.u8[5] = i;
gbl_args->dst_eth_addr[i] = new_addr;
}
 
@@ -615,6 +623,24 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned 
len)
 }
 
 /**
+ * Word copy ethernet address
+ *
+ * @param to   Destination memory address
+ * @param from Source memory address
+ */
+static void copy_eth_addr(uint16_t *to, uint16_t *from)
+{
+   uint16_t fw0, fw1, fw2;
+
+   fw0 = from[0];
+   fw1 = from[1];
+   fw2 = from[2];
+   to[0] = fw0;
+   to[1] = fw1;
+   to[2] = fw2;
+}
+
+/**
  * Fill packets' eth addresses according to the destination port
  *
  * @param pkt_tbl  Array of packets
@@ -626,6 +652,8 @@ static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned 
num, int dst_port)
odp_packet_t pkt;
odph_ethhdr_t *eth;
unsigned i;
+   uint16_t *to;
+   uint16_t *from;
 
if (!gbl_args->appl.dst_change && !gbl_args->appl.src_change)
return;
@@ -635,11 +663,16 @@ static void fill_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num, int dst_port)
if (odp_packet_has_eth(pkt)) {
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 
-   if (gbl_args->appl.src_change)
-   eth->src = gbl_args->port_eth_addr[dst_port];
-
-   if (gbl_args->appl.dst_change)
-   eth->dst = gbl_args->dst_eth_addr[dst_port];
+   if (gbl_args->appl.src_change) {
+   from = gbl_args->port_eth_addr[dst_port].u16;
+   to = (uint16_t *)eth->src.addr;
+   copy_eth_addr(to, from);
+   }
+   if (gbl_args->appl.dst_change) {
+   from = gbl_args->dst_eth_addr[dst_port].u16;
+   to = (uint16_t *)eth->dst.addr;
+   copy_eth_addr(to, from);
+   }
}
}
 }
-- 
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] linux-generic: config: add missing syntax to enable doxygen

2015-10-23 Thread Bill Fischofer
Enable doxygen to document platform-specific config values

Signed-off-by: Bill Fischofer 
---
 platform/linux-generic/include/odp/config.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/platform/linux-generic/include/odp/config.h 
b/platform/linux-generic/include/odp/config.h
index a130e68..d800914 100644
--- a/platform/linux-generic/include/odp/config.h
+++ b/platform/linux-generic/include/odp/config.h
@@ -17,6 +17,11 @@
 extern "C" {
 #endif
 
+/** @defgroup odp_config ODP CONFIG
+ * Platform-specific configuration limits
+ * @{
+ */
+
 /**
  * Maximum number of pools
  */
@@ -184,6 +189,10 @@ static inline int odp_config_shm_blocks(void)
 
 #include 
 
+/**
+ * @}
+ */
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.1.4

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


[lng-odp] [Bug 1864] New: Missing header file in install directory

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

Bug ID: 1864
   Summary: Missing header file in install directory
   Product: OpenDataPlane - linux- generic reference
   Version: unspecified
  Hardware: Other
OS: Linux
Status: UNCONFIRMED
  Severity: blocker
  Priority: ---
 Component: Build system
  Assignee: anders.rox...@linaro.org
  Reporter: pasi.orp...@nokia.com
CC: lng-odp@lists.linaro.org

Overview: Including cpumask_types.h header file from odp install dir to code
produces compiling error:

.../odp_install/include/odp/plat/cpumask_types.h:26:33: fatal error:
odp_config_internal.h: No such file or directory
 #include 

Steps to Reproduce: Minimized, easy-to-follow steps that will trigger the bug.
Include any special setup steps.
1. Include cpumask_types.h from odp install directory to code   
2. Compile
3. Compilation fails due to missing header file
...

Actual Results: Fails to compile.

Expected Results: Compiles without errors.

Additional Information:
This is the only internal header file that is used in the install directory
header files so I'm guessing there should be no internal header references
there.

Bug encountered using ODP-linux-generic git commit:
"
Commit: 40b6dc037322a5b21dcf91b60592051eaf3ea7d8 [40b6dc0]
Parents: 015cc6f5e8
Author: Bill Fischofer 
Date: 14. lokakuuta 2015 14:51:05
Committer: Maxim Uvarov 
Commit Date: 22. lokakuuta 2015 15:46:22
Labels: HEAD, origin/master, origin/HEAD, master
validation: use odp_pktio_param_init() API

Signed-off-by: Bill Fischofer 
Signed-off-by: Maxim Uvarov 
"

-- 
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 v6 4/6] test: l2fwd: add support for using odd number of ports

2015-10-23 Thread Matias Elo
Previously only even numbers of ports were supported. Added
support for odd numbers of ports (including 1). Src-dst port
mappings are saved during initialization to minimize per
packet operations.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index b49a271..1385291 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -106,6 +106,8 @@ typedef struct {
odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port default output queues */
odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
+   /** Table of dst ports */
+   int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
 
 /** Global pointer to args */
@@ -115,6 +117,7 @@ static odp_barrier_t barrier;
 
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
+static inline int find_dest_port(int port);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
 static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
   int dst_port);
@@ -181,6 +184,8 @@ static void *pktio_queue_thread(void *arg)
 
 /**
  * Lookup the destination port for a given packet
+ *
+ * @param pkt  ODP packet handle
  */
 static inline int lookup_dest_port(odp_packet_t pkt)
 {
@@ -196,7 +201,25 @@ static inline int lookup_dest_port(odp_packet_t pkt)
if (src_idx == -1)
LOG_ABORT("Failed to determine pktio input\n");
 
-   return (src_idx % 2 == 0) ? src_idx + 1 : src_idx - 1;
+   return gbl_args->dst_port[src_idx];
+}
+
+/**
+ * Find the destination port for a given input port
+ *
+ * @param port  Input port index
+ */
+static inline int find_dest_port(int port)
+{
+   /* Even number of ports */
+   if (gbl_args->appl.if_count % 2 == 0)
+   return (port % 2 == 0) ? port + 1 : port - 1;
+
+   /* Odd number of ports */
+   if (port == gbl_args->appl.if_count - 1)
+   return 0;
+   else
+   return port + 1;
 }
 
 /**
@@ -220,7 +243,7 @@ static void *pktio_direct_recv_thread(void *arg)
*thr_args->stats = stats;
 
src_idx = thr_args->src_idx;
-   dst_idx = (src_idx % 2 == 0) ? src_idx+1 : src_idx-1;
+   dst_idx = gbl_args->dst_port[src_idx];
pktio_src = gbl_args->pktios[src_idx];
pktio_dst = gbl_args->pktios[dst_idx];
 
@@ -461,11 +484,6 @@ int main(int argc, char *argv[])
num_workers);
exit(EXIT_FAILURE);
}
-   if (gbl_args->appl.if_count % 2 != 0) {
-   LOG_ERR("Error: interface count %d is odd in fwd appl.\n",
-   gbl_args->appl.if_count);
-   exit(EXIT_FAILURE);
-   }
 
/* Create packet pool */
odp_pool_param_init();
@@ -508,6 +526,9 @@ int main(int argc, char *argv[])
gbl_args->dst_eth_addr[i] = new_addr;
}
 
+   /* Save interface destination port */
+   gbl_args->dst_port[i] = find_dest_port(i);
+
ret = odp_pktio_start(pktio);
if (ret) {
LOG_ERR("Error: unable to start %s\n",
-- 
1.9.1

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


[lng-odp] [PATCH v6 5/6] test: l2fwd: add option to disable filling eth addresses

2015-10-23 Thread Matias Elo
By default every packet's source MAC address is filled to
match the output port. Add option to disable this to enable
testing packet forwarding without touching the packets.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 1385291..fb5f656 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -70,6 +70,7 @@ typedef struct {
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
int dst_change; /**< Change destination eth addresses > */
+   int src_change; /**< Change source eth addresses > */
 } appl_args_t;
 
 static int exit_threads;   /**< Break workers loop if set to 1 */
@@ -626,11 +627,16 @@ static void fill_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num, int dst_port)
odph_ethhdr_t *eth;
unsigned i;
 
+   if (!gbl_args->appl.dst_change && !gbl_args->appl.src_change)
+   return;
+
for (i = 0; i < num; ++i) {
pkt = pkt_tbl[i];
if (odp_packet_has_eth(pkt)) {
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
-   eth->src = gbl_args->port_eth_addr[dst_port];
+
+   if (gbl_args->appl.src_change)
+   eth->src = gbl_args->port_eth_addr[dst_port];
 
if (gbl_args->appl.dst_change)
eth->dst = gbl_args->dst_eth_addr[dst_port];
@@ -659,15 +665,17 @@ static void parse_args(int argc, char *argv[], 
appl_args_t *appl_args)
{"interface", required_argument, NULL, 'i'},
{"mode", required_argument, NULL, 'm'},
{"dst_change", required_argument, NULL, 'd'},
+   {"src_change", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
appl_args->time = 0; /* loop forever if time to run is 0 */
appl_args->accuracy = 1; /* get and print pps stats second */
+   appl_args->src_change = 1; /* change eth src address by default */
 
while (1) {
-   opt = getopt_long(argc, argv, "+c:+t:+a:i:m:d:h",
+   opt = getopt_long(argc, argv, "+c:+t:+a:i:m:d:s:h",
  longopts, _index);
 
if (opt == -1)
@@ -737,6 +745,9 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
case 'd':
appl_args->dst_change = atoi(optarg);
break;
+   case 's':
+   appl_args->src_change = atoi(optarg);
+   break;
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
@@ -822,6 +833,8 @@ static void usage(char *progname)
   "  (default is 1 second).\n"
   "  -d, --dst_change  0: Don't change packets' dst eth addresses 
(default)\n"
   "1: Change packets' dst eth addresses\n"
+  "  -s, --src_change  0: Don't change packets' src eth 
addresses\n"
+  "1: Change packets' src eth addresses 
(default)\n"
   "  -h, --help   Display help and exit.\n\n"
   " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
   "ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
-- 
1.9.1

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


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

2015-10-23 Thread Mike Holmes
On 23 October 2015 at 03:00, Petri Savolainen 
wrote:

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

Reviewed-by: Mike Holmes 


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

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

2015-10-23 Thread Mike Holmes
On 23 October 2015 at 08:40, Christophe Milard  wrote:

> Well, I agree that the test environment should not prevent API
> improvement: The test environment should simply follow the API as it moves.
> I see no problem with this change as long as the test environment follows
> it. I do see a problem, though, if it does not... What structure should the
> test environment have then? none?
>


This is an api-next patch so it could go in and wait for the follow-up, but
history is starting to show that doing this is starting to leave api-next
changes floating that cannot be merged to master because no one addresses
the gating items. If we take this in I think we need to make a bug to
address the follow up.




>
> On 23 October 2015 at 14:35, Savolainen, Petri (Nokia - FI/Espoo) <
> petri.savolai...@nokia.com> wrote:
>
>>
>>
>>
>>
>> *From:* EXT Mike Holmes [mailto:mike.hol...@linaro.org]
>> *Sent:* Friday, October 23, 2015 3:22 PM
>> *To:* Savolainen, Petri (Nokia - FI/Espoo)
>> *Cc:* lng-odp
>> *Subject:* Re: [lng-odp] [API-NEXT PATCH v3 3/7] api: doc: re-organize
>> doxygen doc for synchronizer
>>
>>
>>
>>
>>
>>
>>
>> On 23 October 2015 at 03:00, Petri Savolainen 
>> wrote:
>>
>> Removed module synchronizer from doxygen documentation and
>> introduced new modules for locks, atomics and barriers.
>>
>>
>>
>> This ripples though the to the validation directory structure which is
>> 1:1 in sync with the module definitions.
>>
>> We should move them at the same time.
>>
>>
>>
>> This improves a lot documentation readability. It’s nice that validation
>> suites are named with the same names, but it’s not technically mandatory.
>> API doc readability is number one goal (visible to all users), validation
>> suite development is second (visible to implementers). Majority of people
>> need well documented API and examples, and not validation tests (if they
>> believe vendor on API compatibility).
>>
>>
>>
>> -Petri
>>
>>
>>
>> ___
>> 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] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c hash functions

2015-10-23 Thread Savolainen, Petri (Nokia - FI/Espoo)
Ping. Why this has not been merged yet.


> -Original Message-
> From: Savolainen, Petri (Nokia - FI/Espoo)
> Sent: Thursday, October 15, 2015 11:08 AM
> To: 'EXT Peng'; lng-odp@lists.linaro.org
> Cc: Peng
> Subject: RE: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c
> hash functions
> 
> 
> Reviewed-by: Petri Savolainen 
> 
> 
> > -Original Message-
> > From: EXT Peng [mailto:xnhp0...@icloud.com]
> > Sent: Thursday, October 15, 2015 10:51 AM
> > To: lng-odp@lists.linaro.org
> > Cc: Savolainen, Petri (Nokia - FI/Espoo); Peng
> > Subject: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c
> hash
> > functions
> >
> > From: Peng 
> >
> > v2: Add copyright license.
> > v3: APIs: crc32c, crc32 and generic CRC hash impl
> > linux-generic: add impl for crc32c.
> > v4: linux-generic:
> > change odp_crc32c_1word to crc32c_u32,
> > change odp_crc32c_2words to crc32c_u64,
> > drop inline decorator for odp_hash_crc32c.
> > change copyrights to 2015.
> > v5: linux-generic:
> > add copyrights to 2015 for linux-generic headers
> >
> > Signed-off-by: Peng 
> > ---
> >  include/odp.h |   1 +
> >  include/odp/api/hash.h|  98 ++
> >  platform/linux-generic/Makefile.am|   3 +
> >  platform/linux-generic/include/odp/hash.h |  34 +++
> >  platform/linux-generic/odp_hash.c | 487
> > ++
> >  5 files changed, 623 insertions(+)
> >  create mode 100644 include/odp/api/hash.h
> >  create mode 100644 platform/linux-generic/include/odp/hash.h
> >  create mode 100644 platform/linux-generic/odp_hash.c
> >
> > diff --git a/include/odp.h b/include/odp.h
> > index 825c7e1..da57da8 100644
> > --- a/include/odp.h
> > +++ b/include/odp.h
> > @@ -24,6 +24,7 @@ extern "C" {
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > diff --git a/include/odp/api/hash.h b/include/odp/api/hash.h
> > new file mode 100644
> > index 000..59466c1
> > --- /dev/null
> > +++ b/include/odp/api/hash.h
> > @@ -0,0 +1,98 @@
> > +/* Copyright (c) 2015, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier:BSD-3-Clause
> > + */
> > +
> > +/**
> > + * @file
> > + *
> > + * ODP Hash functions
> > + */
> > +
> > +#ifndef ODP_API_HASH_H_
> > +#define ODP_API_HASH_H_
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +#include 
> > +
> > +/** @defgroup odp_hash ODP HASH FUNCTIONS
> > + *  ODP Hash functions
> > + *  @{
> > + */
> > +
> > +/**
> > +* Calculate CRC-32
> > +*
> > +* Calculates CRC-32 over the data. The polynomial is 0x04c11db7.
> > +*
> > +* @param data   Pointer to data
> > +* @param data_len   Data length in bytes
> > +* @param init_val   CRC generator initialization value
> > +*
> > +* @return CRC32 value
> > +*/
> > +uint32_t odp_hash_crc32(const void *data, uint32_t data_len, uint32_t
> > init_val);
> > +
> > +/**
> > +* Calculate CRC-32C
> > +*
> > +* Calculates CRC-32C (a.k.a. CRC-32 Castagnoli) over the data.
> > +* The polynomial is 0x1edc6f41.
> > +*
> > +* @param data   Pointer to data
> > +* @param data_len   Data length in bytes
> > +* @param init_val   CRC generator initialization value
> > +*
> > +* @return CRC32C value
> > +*/
> > +uint32_t odp_hash_crc32c(const void *data, uint32_t data_len,
> > +uint32_t init_val);
> > +
> > +/**
> > +* CRC parameters
> > +*
> > +* Supports CRCs up to 64 bits
> > +*/
> > +typedef struct odp_hash_crc_param_t {
> > +   /** CRC width in bits */
> > +   uint32_t width;
> > +   /** Polynomial (stored in 'width' LSB bits) */
> > +   uint64_t poly;
> > +   /** 0: don't reflect, 1: reflect bits in input bytes */
> > +   odp_bool_t reflect_in;
> > +   /** 0: don't reflect, 1: reflect bits in output bytes */
> > +   odp_bool_t reflect_out;
> > +   /** XOR this value to CRC output (stored in 'width' LSB bits) */
> > +   uint64_t xor_out;
> > +} odp_hash_crc_param_t;
> > +
> > +/**
> > +* Calculate up to 64 bit CRC using the given parameters
> > +*
> > +* Calculates CRC over the data using the given parameters.
> > +*
> > +* @param data   Pointer to data
> > +* @param data_len   Data length in bytes
> > +* @param init_val   CRC generator initialization value
> > +* @param crc_param  CRC parameters
> > +* @param crcPointer for CRC output
> > +*
> > +* @return 0 on success, <0 on failure (e.g. not supported algorithm)
> > +*/
> > +int odp_hash_crc_gen64(const void *data, uint32_t data_len,
> > +  uint64_t init_val, odp_hash_crc_param_t *param,
> > +  uint64_t *crc);
> > +
> > +/**
> > + * @}
> > + */
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif
> > diff --git a/platform/linux-generic/Makefile.am b/platform/linux-
> > generic/Makefile.am
> > index 202ec6a..083e8d9 100644
> > --- 

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

2015-10-23 Thread Mike Holmes
On 23 October 2015 at 03:00, Petri Savolainen 
wrote:

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

Reviewed-by: Mike Holmes 



> ---
>  doc/doxygen.cfg   |   1 +
>  doc/doxygenlayout.xml | 193
> ++
>  2 files changed, 194 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..90e189a
> --- /dev/null
> +++ b/doc/doxygenlayout.xml
> @@ -0,0 +1,193 @@
> +
> +  
> +  
> +
> +
> +
> +
> +  
> +  
> +
> +
> +  
> +  
> +  
> +  
> +
> +
> +  
> +  
> +
> +
> +  
> +
> +  
> +  
> +
> +
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +
> +
> +  
> +
> +  
> +  
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +
> +
> +  
> +
> +  
> +  
> +
> +
> +
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +  
> +
> +  
> +  
> +
> +
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +  
> +
> +
> +  
> +
> +  
> +  
> +
> +
> +
> +  
> +  
> +
> +
> +  
> +
> --
> 2.6.2
>
> ___
> 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


[lng-odp] [PATCH v6 1/6] test: l2fwd: add option to change destination eth addresses

2015-10-23 Thread Matias Elo
 If the application is being run on a host connected to a
 switch, not changing the ethernet destination may cause
 loops. Added an option to change the destination ethernet
 address. The destination addresses follow the format
 02:00:00:00:00:XX where the final octet is the output
 port number.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 46 ++--
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index f5e4b66..652c024 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -75,6 +75,7 @@ typedef struct {
int time;   /**< Time in seconds to run. */
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
+   int dst_change; /**< Change destination eth addresses > */
 } appl_args_t;
 
 static int exit_threads;   /**< Break workers loop if set to 1 */
@@ -107,6 +108,8 @@ typedef struct {
odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   /** Table of dst ethernet addresses */
+   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port default output queues */
odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
@@ -119,8 +122,8 @@ static odp_barrier_t barrier;
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-  int dst_port);
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
+  int dst_port);
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
 static void print_info(char *progname, appl_args_t *appl_args);
 static void usage(char *progname);
@@ -165,7 +168,7 @@ static void *pktio_queue_thread(void *arg)
 
dst_port = lookup_dest_port(pkt);
 
-   fill_src_eth_addrs(, 1, dst_port);
+   fill_eth_addrs(, 1, dst_port);
 
/* Enqueue the packet for output */
outq_def = gbl_args->outq_def[dst_port];
@@ -244,7 +247,7 @@ static void *pktio_ifburst_thread(void *arg)
/* Drop packets with errors */
pkts_ok = drop_err_pkts(pkt_tbl, pkts);
if (pkts_ok > 0) {
-   fill_src_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
+   fill_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
 
int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok);
 
@@ -393,6 +396,7 @@ int main(int argc, char *argv[])
odp_shm_t shm;
odp_cpumask_t cpumask;
char cpumaskstr[ODP_CPUMASK_STR_SIZE];
+   odph_ethaddr_t new_addr;
odp_pktio_t pktio;
odp_pool_param_t params;
int ret;
@@ -483,6 +487,15 @@ int main(int argc, char *argv[])
if (gbl_args->appl.mode == APPL_MODE_PKT_QUEUE)
gbl_args->outq_def[i] = odp_pktio_outq_getdef(pktio);
 
+   /* Save destination eth address */
+   if (gbl_args->appl.dst_change) {
+   /* 02:00:00:00:00:XX */
+   memset(_addr, 0, sizeof(odph_ethaddr_t));
+   new_addr.addr[0] = 0x02;
+   new_addr.addr[5] = i;
+   gbl_args->dst_eth_addr[i] = new_addr;
+   }
+
ret = odp_pktio_start(pktio);
if (ret) {
LOG_ERR("Error: unable to start %s\n",
@@ -568,14 +581,13 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned 
len)
 }
 
 /**
- * Fill packets' eth src addresses according to the destination port
+ * Fill packets' eth addresses according to the destination port
  *
  * @param pkt_tbl  Array of packets
  * @param num  Number of packets in the array
  * @param dst_port Destination port
  */
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-  int dst_port)
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num, int dst_port)
 {
odp_packet_t pkt;
odph_ethhdr_t *eth;
@@ -586,6 +598,9 @@ static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num,
if (odp_packet_has_eth(pkt)) {
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
eth->src = gbl_args->port_eth_addr[dst_port];
+
+   if (gbl_args->appl.dst_change)
+   eth->dst = gbl_args->dst_eth_addr[dst_port];
}
}
 }
@@ -608,9 +623,10 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
  

[lng-odp] [PATCH v6 0/6] l2fwd test improvements

2015-10-23 Thread Matias Elo
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)

v5:
- Moved ethernet address word copy to a helper function (Maxim Ulvanov)

v6:
- Fixed print_speed_stats() return value (Maxim Ulvanov)

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 | 264 ++-
 1 file changed, 185 insertions(+), 79 deletions(-)

-- 
1.9.1

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


[lng-odp] [PATCH v6 2/6] test: l2fwd: add option to select scheduler queue type

2015-10-23 Thread Matias Elo
Previously only atomic scheduler queues where supported.
This was a bottleneck when the number of worker threads was
increased. Added an option to choose scheduler queue sync
mode (none, atomic, ordered).

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 94 
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 652c024..c50ca20 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -41,25 +41,19 @@
 #define SHM_PKT_POOL_BUF_SIZE  1856
 
 /** @def MAX_PKT_BURST
- * @brief Maximum number of packet bursts
+ * @brief Maximum number of packet in a burst
  */
 #define MAX_PKT_BURST  16
 
-/** @def APPL_MODE_PKT_BURST
- * @brief The application will handle pakcets in bursts
+/**
+ * Packet input mode
  */
-#define APPL_MODE_PKT_BURST0
-
-/** @def APPL_MODE_PKT_QUEUE
- * @brief The application will handle packets in queues
- */
-#define APPL_MODE_PKT_QUEUE1
-
-/** @def PRINT_APPL_MODE(x)
- * @brief Macro to print the current status of how the application handles
- * packets.
- */
-#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x))
+typedef enum pkt_in_mode_t {
+   DIRECT_RECV,
+   SCHED_NONE,
+   SCHED_ATOMIC,
+   SCHED_ORDERED,
+} pkt_in_mode_t;
 
 /** Get rid of path in filename - only for unix-type paths using '/' */
 #define NO_PATH(file_name) (strrchr((file_name), '/') ? \
@@ -71,7 +65,7 @@ typedef struct {
int cpu_count;
int if_count;   /**< Number of interfaces to be used */
char **if_names;/**< Array of pointers to interface names */
-   int mode;   /**< Packet IO mode */
+   pkt_in_mode_t mode; /**< Packet input mode */
int time;   /**< Time in seconds to run. */
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
@@ -206,11 +200,11 @@ static inline int lookup_dest_port(odp_packet_t pkt)
 }
 
 /**
- * Packet IO worker thread using bursts from/to IO resources
+ * Packet IO worker thread accessing IO resources directly
  *
  * @param arg  thread arguments of type 'thread_args_t *'
  */
-static void *pktio_ifburst_thread(void *arg)
+static void *pktio_direct_recv_thread(void *arg)
 {
int thr;
thread_args_t *thr_args;
@@ -231,7 +225,7 @@ static void *pktio_ifburst_thread(void *arg)
pktio_dst = gbl_args->pktios[dst_idx];
 
printf("[%02i] srcif:%s dstif:%s spktio:%02" PRIu64
-  " dpktio:%02" PRIu64 " BURST mode\n",
+  " dpktio:%02" PRIu64 " DIRECT RECV mode\n",
   thr,
   gbl_args->appl.if_names[src_idx],
   gbl_args->appl.if_names[dst_idx],
@@ -278,13 +272,11 @@ static void *pktio_ifburst_thread(void *arg)
  *
  * @param dev Name of device to open
  * @param pool Pool to associate with device for packet RX/TX
- * @param mode Packet processing mode for this device (BURST or QUEUE)
  *
  * @return The handle of the created pktio object.
  * @retval ODP_PKTIO_INVALID if the create fails.
  */
-static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool,
-   int mode)
+static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool)
 {
char inq_name[ODP_QUEUE_NAME_LEN];
odp_queue_param_t qparam;
@@ -292,10 +284,11 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool,
odp_pktio_t pktio;
int ret;
odp_pktio_param_t pktio_param;
+   odp_schedule_sync_t  sync_mode;
 
odp_pktio_param_init(_param);
 
-   if (mode == APPL_MODE_PKT_BURST)
+   if (gbl_args->appl.mode == DIRECT_RECV)
pktio_param.in_mode = ODP_PKTIN_MODE_RECV;
else
pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
@@ -309,13 +302,20 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool,
printf("created pktio %" PRIu64 " (%s)\n",
   odp_pktio_to_u64(pktio), dev);
 
-   /* no further setup needed for burst mode */
-   if (mode == APPL_MODE_PKT_BURST)
+   /* no further setup needed for direct receive mode */
+   if (gbl_args->appl.mode == DIRECT_RECV)
return pktio;
 
+   if (gbl_args->appl.mode == SCHED_ATOMIC)
+   sync_mode = ODP_SCHED_SYNC_ATOMIC;
+   else if (gbl_args->appl.mode == SCHED_ORDERED)
+   sync_mode = ODP_SCHED_SYNC_ORDERED;
+   else
+   sync_mode = ODP_SCHED_SYNC_NONE;
+
odp_queue_param_init();
qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
-   qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
+   qparam.sched.sync  = sync_mode;
qparam.sched.group = ODP_SCHED_GROUP_ALL;
snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def",
 

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

2015-10-23 Thread Mike Holmes
On 23 October 2015 at 03:00, Petri Savolainen 
wrote:

> Reference caused warning when creating doxygen documentation.
>
> Signed-off-by: Petri Savolainen 
>

Reviewed-by: Mike Holmes 



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



-- 
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] [API-NEXT PATCH v3 3/7] api: doc: re-organize doxygen doc for synchronizer

2015-10-23 Thread Christophe Milard
As long as the test-environment follows up (within a reasonable time), I am
fine.


On 23 October 2015 at 14:52, Savolainen, Petri (Nokia - FI/Espoo) <
petri.savolai...@nokia.com> wrote:

>
>
>
>
> *From:* EXT Mike Holmes [mailto:mike.hol...@linaro.org]
> *Sent:* Friday, October 23, 2015 3:43 PM
> *To:* Christophe Milard
> *Cc:* Savolainen, Petri (Nokia - FI/Espoo); lng-odp
> *Subject:* Re: [lng-odp] [API-NEXT PATCH v3 3/7] api: doc: re-organize
> doxygen doc for synchronizer
>
>
>
>
>
>
>
> On 23 October 2015 at 08:40, Christophe Milard <
> christophe.mil...@linaro.org> wrote:
>
> Well, I agree that the test environment should not prevent API
> improvement: The test environment should simply follow the API as it moves.
> I see no problem with this change as long as the test environment follows
> it. I do see a problem, though, if it does not... What structure should the
> test environment have then? none?
>
>
>
>
>
> This is an api-next patch so it could go in and wait for the follow-up,
> but history is starting to show that doing this is starting to leave
> api-next changes floating that cannot be merged to master because no one
> addresses the gating items. If we take this in I think we need to make a
> bug to address the follow up.
>
>
>
> It fine to report a bug. Missing validation tests are easier to track with
> code coverage tools, etc. I choose to fix broken API documentation logic
> instead of just copying it (which would have been less work for us all).
>
> -Petri
>
>
>
>
>
>
>
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v6 3/6] test: l2fwd: fix crash when accuracy is set to 0

2015-10-23 Thread Matias Elo
Application crashes if accuracy option is set to zero
(division by zero). Disable statistics printing if accuracy
<= 0.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index c50ca20..b49a271 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -346,12 +346,22 @@ static odp_pktio_t create_pktio(const char *dev, 
odp_pool_t pool)
  *
  */
 static int print_speed_stats(int num_workers, stats_t **thr_stats,
- int duration, int timeout)
+int duration, int timeout)
 {
-   uint64_t pkts, pkts_prev = 0, pps, drops, maximum_pps = 0;
-   int i, elapsed = 0;
+   uint64_t pkts = 0;
+   uint64_t pkts_prev = 0;
+   uint64_t pps;
+   uint64_t drops;
+   uint64_t maximum_pps = 0;
+   int i;
+   int elapsed = 0;
+   int stats_enabled = 1;
int loop_forever = (duration == 0);
 
+   if (timeout <= 0)
+   stats_enabled = 0;
+   timeout = 1;
+
/* Wait for all threads to be ready*/
odp_barrier_wait();
 
@@ -365,20 +375,23 @@ static int print_speed_stats(int num_workers, stats_t 
**thr_stats,
pkts += thr_stats[i]->packets;
drops += thr_stats[i]->drops;
}
-   pps = (pkts - pkts_prev) / timeout;
-   if (pps > maximum_pps)
-   maximum_pps = pps;
-   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
-  maximum_pps);
+   if (stats_enabled) {
+   pps = (pkts - pkts_prev) / timeout;
+   if (pps > maximum_pps)
+   maximum_pps = pps;
+   printf("%" PRIu64 " pps, %" PRIu64 " max pps, ",  pps,
+  maximum_pps);
 
-   printf(" %" PRIu64 " total drops\n", drops);
+   printf(" %" PRIu64 " total drops\n", drops);
 
+   pkts_prev = pkts;
+   }
elapsed += timeout;
-   pkts_prev = pkts;
} while (loop_forever || (elapsed < duration));
 
-   printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
-  maximum_pps);
+   if (stats_enabled)
+   printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
+  maximum_pps);
 
return pkts > 100 ? 0 : -1;
 }
-- 
1.9.1

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


[lng-odp] [PATCHv4 1/5] linux-generic: pktio: increase MTU of loop interface

2015-10-23 Thread Stuart Haslam
There's no need to enforce an artificial MTU for the loop interface.
Previously this value was reported but not enforced.

Signed-off-by: Stuart Haslam 
---
 platform/linux-generic/pktio/loop.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/platform/linux-generic/pktio/loop.c 
b/platform/linux-generic/pktio/loop.c
index 22f0475..4a66c1c 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -20,8 +20,6 @@
 
 #include 
 
-/* MTU to be reported for the "loop" interface */
-#define PKTIO_LOOP_MTU 1500
 /* MAC address for the "loop" interface */
 static const char pktio_loop_mac[] = {0x02, 0xe9, 0x34, 0x80, 0x73, 0x01};
 
@@ -83,7 +81,8 @@ static int loopback_send(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_tbl[],
 
 static int loopback_mtu_get(pktio_entry_t *pktio_entry ODP_UNUSED)
 {
-   return PKTIO_LOOP_MTU;
+   /* the loopback interface imposes no maximum transmit size limit */
+   return INT_MAX;
 }
 
 static int loopback_mac_addr_get(pktio_entry_t *pktio_entry ODP_UNUSED,
-- 
2.1.1

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


Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and stop

2015-10-23 Thread Ivan Khoronzhuk



On 23.10.15 14:18, Savolainen, Petri (Nokia - FI/Espoo) wrote:




-Original Message-
From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
Sent: Friday, October 23, 2015 2:12 PM
To: Savolainen, Petri (Nokia - FI/Espoo); EXT Maxim Uvarov; lng-
o...@lists.linaro.org
Subject: Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start
and stop



On 23.10.15 14:03, Savolainen, Petri (Nokia - FI/Espoo) wrote:


User tells to the implementation on open() which interfaces needed

statistics.

  As long as implementation has enough stat resources open() succeeds.
  When all stats are gone and user still ask for stats, open() fails.
Implementation user manual documents this limitation (how many interfaces

can be

  opened with stats enabled and in which combination).

-Petri


Is it absolutely required for pktio to have statistic?
If no, then I can disable statistic for pktio after some test and use it
for another port.
And closing pktio is not needed


It's not very useful to gather statistics part time.

If someone will find it usefull it can be added.
It doesn't corrupt any part of existent API.


 Either you need stats from an interface and want to count all packets (define 
ODP_PKTIO_STATS_BASIC),
or you don’t need those at all (define ODP_PKTIO_STATS_DISABLED).
 What is the use case to time slice stats counting between two interfaces and 
potentially see zero packets on both,
 while packets are actually send and received (while you are measuring the 
other interface).

Any comparison. Just using limited number of stat modules with pktios,
number of pktios can be more, like in my case.



-Petri





-Original Message-
From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
Sent: Friday, October 23, 2015 2:00 PM
To: Savolainen, Petri (Nokia - FI/Espoo); EXT Maxim Uvarov; lng-
o...@lists.linaro.org
Subject: Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start
and stop



On 23.10.15 13:35, Savolainen, Petri (Nokia - FI/Espoo) wrote:


I think these are not generally needed or supported. It's better to add

a

parameter into odp_pktio_param_t.

It's needed.
The main reason for that the same statistic module can be used by

different

pktios, so if it's used for one of them it cannot be used by other, to
allow
it for first it should be disable for second. For instance 2 statistic
modules
are shared between 4 eth ports, etc.



For example,

typedef enum odp_pktio_stats_mode_t {

/** Need basic statistics on this interface */
ODP_PKTIO_STATS_BASIC = 0,
/** Don't need any statistics on this interface */
ODP_PKTIO_STATS_DISABLED
} odp_pktio_stats_mode_t;


-Petri




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


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

2015-10-23 Thread Christophe Milard
Well, I agree that the test environment should not prevent API improvement:
The test environment should simply follow the API as it moves. I see no
problem with this change as long as the test environment follows it. I do
see a problem, though, if it does not... What structure should the test
environment have then? none?

On 23 October 2015 at 14:35, Savolainen, Petri (Nokia - FI/Espoo) <
petri.savolai...@nokia.com> wrote:

>
>
>
>
> *From:* EXT Mike Holmes [mailto:mike.hol...@linaro.org]
> *Sent:* Friday, October 23, 2015 3:22 PM
> *To:* Savolainen, Petri (Nokia - FI/Espoo)
> *Cc:* lng-odp
> *Subject:* Re: [lng-odp] [API-NEXT PATCH v3 3/7] api: doc: re-organize
> doxygen doc for synchronizer
>
>
>
>
>
>
>
> On 23 October 2015 at 03:00, Petri Savolainen 
> wrote:
>
> Removed module synchronizer from doxygen documentation and
> introduced new modules for locks, atomics and barriers.
>
>
>
> This ripples though the to the validation directory structure which is 1:1
> in sync with the module definitions.
>
> We should move them at the same time.
>
>
>
> This improves a lot documentation readability. It’s nice that validation
> suites are named with the same names, but it’s not technically mandatory.
> API doc readability is number one goal (visible to all users), validation
> suite development is second (visible to implementers). Majority of people
> need well documented API and examples, and not validation tests (if they
> believe vendor on API compatibility).
>
>
>
> -Petri
>
>
>
> ___
> 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] [PATCHv4 0/5] handle transmit errors correctly

2015-10-23 Thread Stuart Haslam
Fixes bug: https://bugs.linaro.org/show_bug.cgi?id=1365

Changes since v3:
 - Rebased
 - Fix comment typo in 5/5

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  | 250 +
 test/validation/pktio/pktio.h  |   2 +
 6 files changed, 284 insertions(+), 102 deletions(-)

-- 
2.1.1

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


Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and stop

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

I think these are not generally needed or supported. It's better to add a 
parameter into odp_pktio_param_t.

For example, 

typedef enum odp_pktio_stats_mode_t {

/** Need basic statistics on this interface */
ODP_PKTIO_STATS_BASIC = 0,
/** Don't need any statistics on this interface */
ODP_PKTIO_STATS_DISABLED
} odp_pktio_stats_mode_t;


-Petri



> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> Maxim Uvarov
> Sent: Thursday, October 22, 2015 1:45 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start and
> stop
> 
> Define pktio stats start/stop functions for case when same
> statistic module is used by different pktios, so if it's used
> for one of them it cannot be used by other, to allow it for
> first it should be disable for second. For instance 2 statistic
> modules are shared between 4 eth ports, etc.
> 
> Signed-off-by: Maxim Uvarov 
> ---
>  include/odp/api/packet_io_stats.h | 20 
>  1 file changed, 20 insertions(+)
> 
> diff --git a/include/odp/api/packet_io_stats.h
> b/include/odp/api/packet_io_stats.h
> index 1bff9ca..03f060e 100644
> --- a/include/odp/api/packet_io_stats.h
> +++ b/include/odp/api/packet_io_stats.h
> @@ -123,6 +123,26 @@ int odp_pktio_stats(odp_pktio_t pktio,
>  int odp_pktio_stats_reset(odp_pktio_t pktio);
> 
>  /**
> + * Start statistics for pktio handle
> + *
> + * @parampktioPacket IO handle
> + * @retval  0 on success
> + * @retval <0 on failure
> + *
> + */
> +int odp_pktio_stats_start(odp_pktio_t pktio);
> +
> +/**
> + * Stop statistics for pktio handle
> + *
> + * @parampktioPacket IO handle
> + * @retval  0 on success
> + * @retval <0 on failure
> + *
> + */
> +int odp_pktio_stats_stop(odp_pktio_t pktio);
> +
> +/**
>   * @}
>   */
> 
> --
> 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] [PATCHv5 2/2] api: pktio statistics: define start and stop

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


> -Original Message-
> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
> Sent: Friday, October 23, 2015 2:12 PM
> To: Savolainen, Petri (Nokia - FI/Espoo); EXT Maxim Uvarov; lng-
> o...@lists.linaro.org
> Subject: Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start
> and stop
> 
> 
> 
> On 23.10.15 14:03, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> >
> > User tells to the implementation on open() which interfaces needed
> statistics.
> >  As long as implementation has enough stat resources open() succeeds.
> >  When all stats are gone and user still ask for stats, open() fails.
> >Implementation user manual documents this limitation (how many interfaces
> can be
> >  opened with stats enabled and in which combination).
> >
> > -Petri
> 
> Is it absolutely required for pktio to have statistic?
> If no, then I can disable statistic for pktio after some test and use it
> for another port.
> And closing pktio is not needed

It's not very useful to gather statistics part time. Either you need stats from 
an interface and want to count all packets (define ODP_PKTIO_STATS_BASIC), or 
you don’t need those at all (define ODP_PKTIO_STATS_DISABLED). What is the use 
case to time slice stats counting between two interfaces and potentially see 
zero packets on both, while packets are actually send and received (while you 
are measuring the other interface).

-Petri


> 
> >> -Original Message-
> >> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
> >> Sent: Friday, October 23, 2015 2:00 PM
> >> To: Savolainen, Petri (Nokia - FI/Espoo); EXT Maxim Uvarov; lng-
> >> o...@lists.linaro.org
> >> Subject: Re: [lng-odp] [PATCHv5 2/2] api: pktio statistics: define start
> >> and stop
> >>
> >>
> >>
> >> On 23.10.15 13:35, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> >>>
> >>> I think these are not generally needed or supported. It's better to add
> a
> >> parameter into odp_pktio_param_t.
> >>
> >> It's needed.
> >> The main reason for that the same statistic module can be used by
> different
> >> pktios, so if it's used for one of them it cannot be used by other, to
> >> allow
> >> it for first it should be disable for second. For instance 2 statistic
> >> modules
> >> are shared between 4 eth ports, etc.
> >>
> >>>
> >>> For example,
> >>>
> >>> typedef enum odp_pktio_stats_mode_t {
> >>>
> >>> /** Need basic statistics on this interface */
> >>> ODP_PKTIO_STATS_BASIC = 0,
> >>> /** Don't need any statistics on this interface */
> >>> ODP_PKTIO_STATS_DISABLED
> >>> } odp_pktio_stats_mode_t;
> >>>
> >>>
> >>> -Petri
> >>>
> >>>
___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


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

2015-10-23 Thread Mike Holmes
On 23 October 2015 at 03:00, Petri Savolainen 
wrote:

> Removed module synchronizer from doxygen documentation and
> introduced new modules for locks, atomics and barriers.


This ripples though the to the validation directory structure which is 1:1
in sync with the module definitions.
We should move them at the same time.



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

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

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


From: EXT Mike Holmes [mailto:mike.hol...@linaro.org]
Sent: Friday, October 23, 2015 3:22 PM
To: Savolainen, Petri (Nokia - FI/Espoo)
Cc: lng-odp
Subject: Re: [lng-odp] [API-NEXT PATCH v3 3/7] api: doc: re-organize doxygen 
doc for synchronizer



On 23 October 2015 at 03:00, Petri Savolainen 
> wrote:
Removed module synchronizer from doxygen documentation and
introduced new modules for locks, atomics and barriers.

This ripples though the to the validation directory structure which is 1:1 in 
sync with the module definitions.
We should move them at the same time.

This improves a lot documentation readability. It’s nice that validation suites 
are named with the same names, but it’s not technically mandatory. API doc 
readability is number one goal (visible to all users), validation suite 
development is second (visible to implementers). Majority of people need well 
documented API and examples, and not validation tests (if they believe vendor 
on API compatibility).

-Petri

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


[lng-odp] [PATCHv4 5/5] validation: pktio: test for transmit error handling

2015-10-23 Thread Stuart Haslam
Test that transmit errors are handled correctly by attempting to send a
packet larger than the MTU of the interface.

Signed-off-by: Stuart Haslam 
---
 test/validation/pktio/pktio.c | 151 +-
 1 file changed, 148 insertions(+), 3 deletions(-)

diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index 5fe8293..6320b77 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -21,6 +21,7 @@
 #define MAX_NUM_IFACES 2
 #define TEST_SEQ_INVALID   ((uint32_t)~0)
 #define TEST_SEQ_MAGIC 0x92749451
+#define TX_BATCH_LEN   4
 
 /** interface names used for testing */
 static const char *iface_name[MAX_NUM_IFACES];
@@ -507,7 +508,7 @@ void pktio_test_poll_queue(void)
 
 void pktio_test_poll_multi(void)
 {
-   test_txrx(ODP_PKTIN_MODE_POLL, 4);
+   test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN);
 }
 
 void pktio_test_sched_queue(void)
@@ -517,7 +518,7 @@ void pktio_test_sched_queue(void)
 
 void pktio_test_sched_multi(void)
 {
-   test_txrx(ODP_PKTIN_MODE_SCHED, 4);
+   test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN);
 }
 
 void pktio_test_recv(void)
@@ -527,7 +528,7 @@ void pktio_test_recv(void)
 
 void pktio_test_recv_multi(void)
 {
-   test_txrx(ODP_PKTIN_MODE_RECV, 4);
+   test_txrx(ODP_PKTIN_MODE_RECV, TX_BATCH_LEN);
 }
 
 void pktio_test_jumbo(void)
@@ -801,6 +802,146 @@ static void pktio_test_start_stop(void)
}
 }
 
+/*
+ * This is a pre-condition check that the pktio_test_send_failure()
+ * test case can be run. If the TX interface MTU is larger that the
+ * biggest packet we can allocate then the test won't be able to
+ * attempt to send packets larger than the MTU, so skip the test.
+ */
+static int pktio_check_send_failure(void)
+{
+   odp_pktio_t pktio_tx;
+   int mtu;
+   odp_pktio_param_t pktio_param;
+   int iface_idx = 0;
+   const char *iface = iface_name[iface_idx];
+
+   memset(_param, 0, sizeof(pktio_param));
+
+   pktio_param.in_mode = ODP_PKTIN_MODE_RECV;
+
+   pktio_tx = odp_pktio_open(iface, pool[iface_idx], _param);
+   if (pktio_tx == ODP_PKTIO_INVALID) {
+   fprintf(stderr, "%s: failed to open pktio\n", __func__);
+   return 0;
+   }
+
+   /* read the MTU from the transmit interface */
+   mtu = odp_pktio_mtu(pktio_tx);
+
+   odp_pktio_close(pktio_tx);
+
+   return (mtu <= ODP_CONFIG_PACKET_BUF_LEN_MAX - 32);
+}
+
+static void pktio_test_send_failure(void)
+{
+   odp_pktio_t pktio_tx, pktio_rx;
+   odp_packet_t pkt_tbl[TX_BATCH_LEN];
+   uint32_t pkt_seq[TX_BATCH_LEN];
+   int ret, mtu, i, alloc_pkts;
+   odp_pool_param_t pool_params;
+   odp_pool_t pkt_pool;
+   int long_pkt_idx = TX_BATCH_LEN / 2;
+   pktio_info_t info_rx;
+
+   pktio_tx = create_pktio(0, ODP_PKTIN_MODE_RECV);
+   if (pktio_tx == ODP_PKTIO_INVALID) {
+   CU_FAIL("failed to open pktio");
+   return;
+   }
+
+   /* read the MTU from the transmit interface */
+   mtu = odp_pktio_mtu(pktio_tx);
+
+   ret = odp_pktio_start(pktio_tx);
+   CU_ASSERT_FATAL(ret == 0);
+
+   /* configure the pool so that we can generate test packets larger
+* than the interface MTU */
+   memset(_params, 0, sizeof(pool_params));
+   pool_params.pkt.len = mtu + 32;
+   pool_params.pkt.seg_len = pool_params.pkt.len;
+   pool_params.pkt.num = TX_BATCH_LEN + 1;
+   pool_params.type= ODP_POOL_PACKET;
+   pkt_pool = odp_pool_create("pkt_pool_oversize", _params);
+   CU_ASSERT_FATAL(pkt_pool != ODP_POOL_INVALID);
+
+   if (num_ifaces > 1) {
+   pktio_rx = create_pktio(1, ODP_PKTIN_MODE_RECV);
+   ret = odp_pktio_start(pktio_rx);
+   CU_ASSERT_FATAL(ret == 0);
+   } else {
+   pktio_rx = pktio_tx;
+   }
+
+   /* generate a batch of packets with a single overly long packet
+* in the middle */
+   for (i = 0; i < TX_BATCH_LEN; ++i) {
+   uint32_t pkt_len;
+
+   if (i == long_pkt_idx)
+   pkt_len = pool_params.pkt.len;
+   else
+   pkt_len = PKT_LEN_NORMAL;
+
+   pkt_tbl[i] = odp_packet_alloc(pkt_pool, pkt_len);
+   if (pkt_tbl[i] == ODP_PACKET_INVALID)
+   break;
+
+   pkt_seq[i] = pktio_init_packet(pkt_tbl[i]);
+   if (pkt_seq[i] == TEST_SEQ_INVALID)
+   break;
+   }
+   alloc_pkts = i;
+
+   if (alloc_pkts == TX_BATCH_LEN) {
+   /* try to send the batch with the long packet in the middle,
+* the initial short packets should be sent successfully */
+   odp_errno_zero();
+   ret = odp_pktio_send(pktio_tx, pkt_tbl, TX_BATCH_LEN);
+   CU_ASSERT(ret == long_pkt_idx);
+ 

[lng-odp] [API-NEXT PATCHv6] api: define pktio statistics api

2015-10-23 Thread Maxim Uvarov
Signed-off-by: Maxim Uvarov 
---
 v6: fix Petris comments

 include/odp/api/packet_io.h   |   2 +
 include/odp/api/packet_io_stats.h | 141 ++
 2 files changed, 143 insertions(+)
 create mode 100644 include/odp/api/packet_io_stats.h

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..ca8777c 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -18,6 +18,8 @@
 extern "C" {
 #endif
 
+#include 
+
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
  *
diff --git a/include/odp/api/packet_io_stats.h 
b/include/odp/api/packet_io_stats.h
new file mode 100644
index 000..148ad8d
--- /dev/null
+++ b/include/odp/api/packet_io_stats.h
@@ -0,0 +1,141 @@
+/* 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
+
+/** @addtogroup 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 ifHCInUcastPkts in RFC 2863, RFC 3635.
+*/
+   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 ifInDiscards in RFC 2863.
+*/
+   uint64_t in_discards;
+
+   /**
+* The sum for this interface of AlignmentErrors, FCSErrors, 
FrameTooLongs,
+* InternalMacReceiveErrors. See ifInErrors 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 ifInUnknownProtos in RFC 2863, RFC 3635.
+*/
+   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 ifHCOutOctets 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 ifHCOutUcastPkts 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 ifOutErrors in RFC 3635.
+*/
+   uint64_t out_errors;
+} odp_pktio_stats_t;
+
+/**
+ * Get statistics for pktio handle
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] statsOutput 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,
+

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

2015-10-23 Thread Savolainen, Petri (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 1:45 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [PATCHv5 1/2] api: define pktio statistics api
> 
> 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

This file does not define the group, but adds documentation into it

@addtogroup 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;

Add empty lines between variables and documentation. Otherwise it's hard to see 
code from documentation.



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

I think you can always point to 3635, which then points to 2863 (if needed).

If previous variable refers to ifHCInOctets, then this should refers to 
ifHCInUcastPkts.


> +  */
> + 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 

Re: [lng-odp] [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c hash functions

2015-10-23 Thread HePeng
Hi, Maxim

> 在 2015年10月23日,下午11:40,Maxim Uvarov  写道:
> 
> Somehow that email inside previous version thread it's hard to follow it.

I am having troubles in using git send-email to reply to specific emails, even 
I’ve 
tried using —reply-to message-id, the email is sent as a new thread. 

We will soon revise the current version and present a new one.

Thanks. 

> 
> I have few notes:
> 
> 1. version should be remove from long log  and put under "---" in email.
> 
> 2. doxygen:
> /opt/Linaro/odp2.git/include/odp/api/hash.h:73: warning: argument 'crc_param' 
> of command @param is not found in the argument list of 
> odp_hash_crc_gen64(const void *data, uint32_t data_len, uint64_t init_val, 
> odp_hash_crc_param_t *param, uint64_t *crc)
> /opt/Linaro/odp2.git/include/odp/api/hash.h:73: warning: The following 
> parameters of odp_hash_crc_gen64(const void *data, uint32_t data_len, 
> uint64_t init_val, odp_hash_crc_param_t *param, uint64_t *crc) are not 
> documented:
>  parameter 'param'
> 
> 3. It will be good to include test coverage tests cases for make check.
> 
> Thanks,
> Maxim.
> 
> 
> On 10/23/2015 16:09, Savolainen, Petri (Nokia - FI/Espoo) wrote:
>> Ping. Why this has not been merged yet.
>> 
>> 
>>> -Original Message-
>>> From: Savolainen, Petri (Nokia - FI/Espoo)
>>> Sent: Thursday, October 15, 2015 11:08 AM
>>> To: 'EXT Peng'; lng-odp@lists.linaro.org
>>> Cc: Peng
>>> Subject: RE: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c
>>> hash functions
>>> 
>>> 
>>> Reviewed-by: Petri Savolainen 
>>> 
>>> 
 -Original Message-
 From: EXT Peng [mailto:xnhp0...@icloud.com]
 Sent: Thursday, October 15, 2015 10:51 AM
 To: lng-odp@lists.linaro.org
 Cc: Savolainen, Petri (Nokia - FI/Espoo); Peng
 Subject: [PATCH] [API-NEXT PATCH v5] api: hash: Added crc32 and crc32c
>>> hash
 functions
 
 From: Peng 
 
 v2: Add copyright license.
 v3: APIs: crc32c, crc32 and generic CRC hash impl
 linux-generic: add impl for crc32c.
 v4: linux-generic:
 change odp_crc32c_1word to crc32c_u32,
 change odp_crc32c_2words to crc32c_u64,
 drop inline decorator for odp_hash_crc32c.
 change copyrights to 2015.
 v5: linux-generic:
 add copyrights to 2015 for linux-generic headers
 
 Signed-off-by: Peng 
 ---
  include/odp.h |   1 +
  include/odp/api/hash.h|  98 ++
  platform/linux-generic/Makefile.am|   3 +
  platform/linux-generic/include/odp/hash.h |  34 +++
  platform/linux-generic/odp_hash.c | 487
 ++
  5 files changed, 623 insertions(+)
  create mode 100644 include/odp/api/hash.h
  create mode 100644 platform/linux-generic/include/odp/hash.h
  create mode 100644 platform/linux-generic/odp_hash.c
 
 diff --git a/include/odp.h b/include/odp.h
 index 825c7e1..da57da8 100644
 --- a/include/odp.h
 +++ b/include/odp.h
 @@ -24,6 +24,7 @@ extern "C" {
  #include 
  #include 
  #include 
 +#include 
  #include 
  #include 
  #include 
 diff --git a/include/odp/api/hash.h b/include/odp/api/hash.h
 new file mode 100644
 index 000..59466c1
 --- /dev/null
 +++ b/include/odp/api/hash.h
 @@ -0,0 +1,98 @@
 +/* Copyright (c) 2015, Linaro Limited
 + * All rights reserved.
 + *
 + * SPDX-License-Identifier:   BSD-3-Clause
 + */
 +
 +/**
 + * @file
 + *
 + * ODP Hash functions
 + */
 +
 +#ifndef ODP_API_HASH_H_
 +#define ODP_API_HASH_H_
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +#include 
 +
 +/** @defgroup odp_hash ODP HASH FUNCTIONS
 + *  ODP Hash functions
 + *  @{
 + */
 +
 +/**
 +* Calculate CRC-32
 +*
 +* Calculates CRC-32 over the data. The polynomial is 0x04c11db7.
 +*
 +* @param data   Pointer to data
 +* @param data_len   Data length in bytes
 +* @param init_val   CRC generator initialization value
 +*
 +* @return CRC32 value
 +*/
 +uint32_t odp_hash_crc32(const void *data, uint32_t data_len, uint32_t
 init_val);
 +
 +/**
 +* Calculate CRC-32C
 +*
 +* Calculates CRC-32C (a.k.a. CRC-32 Castagnoli) over the data.
 +* The polynomial is 0x1edc6f41.
 +*
 +* @param data   Pointer to data
 +* @param data_len   Data length in bytes
 +* @param init_val   CRC generator initialization value
 +*
 +* @return CRC32C value
 +*/
 +uint32_t odp_hash_crc32c(const void *data, uint32_t data_len,
 +   uint32_t init_val);
 +
 +/**
 +* CRC parameters
 +*
 +* Supports CRCs up to 64 bits
 +*/
 +typedef struct odp_hash_crc_param_t {
 +  /** 

[lng-odp] [Bug 1449] odp_timer_test core dump

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

--- Comment #11 from Ivan Khoronzhuk  ---
Will send patch series soon to add fixes and corrections eliminating resolution
impact demonstrated by previous comment and decreasing impact of schedule
delays.

-- 
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 v3 6/7] api: atomic: added atomic min and max

2015-10-23 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 v3 7/7] api: atomic: added 32 bit acquire and release

2015-10-23 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 

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

2015-10-23 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 

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

2015-10-23 Thread Savolainen, Petri (Nokia - FI/Espoo)
Sent out v3 which corrects these two issues.

-Petri


From: EXT Mike Holmes [mailto:mike.hol...@linaro.org]
Sent: Thursday, October 22, 2015 5:15 PM
To: Savolainen, Petri (Nokia - FI/Espoo)
Cc: lng-odp
Subject: Re: [lng-odp] [API-NEXT PATCH v2 2/7] doc: add doxygen layout file to 
control group page output

I like this change, the layout was bothering me also.

On 22 October 2015 at 09:59, Petri Savolainen 
> wrote:
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 @@
+
+  


+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+

Delete this duplicate in the group view

+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
--
2.6.2

___
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


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

2015-10-23 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


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

2015-10-23 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 v3 2/7] doc: add doxygen layout file to control group page output

2015-10-23 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 | 193 ++
 2 files changed, 194 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..90e189a
--- /dev/null
+++ b/doc/doxygenlayout.xml
@@ -0,0 +1,193 @@
+
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
-- 
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 v3 5/7] api: atomic: added cas operations

2015-10-23 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] [RFC API-NEXT PATCH 0/6] Multiple queue packet IO API

2015-10-23 Thread Alexandru Badicioiu
On 22 October 2015 at 18:06, 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);
>  - "poll" (poll poll pktio via default input queue associated with the
> pktio);
>  - "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.
>
> 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.  We can add
> hw_queue_id parameter to existing odp_pktio_recv() alternatively (same way
> as
> DPDK does with rte_eth_rx_burst()).  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.
> [Alex]
>
Hi Nikita,
I understand your reasoning but ODP Packet I/O (pktio) is _not_ (yet?) a
NIC abstraction. The fact is that in current ODP design ingress queues are
"connected" to the pktio device by the configuration of classifier or as
default/error CoS queues. Classifier can be changed dynamically, e.g,
adding or removing CoSes or queues without stopping/re-configuring the
pktio device. I don't see in DPDK such features in PMD, all queues are
configured and setup at initialization time and they don't change
thereafter.


> --
>
> 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
>
> On Mon, Oct 19, 2015 at 08:17:17PM +0300, Alexandru Badicioiu wrote:
> >
> >
> > On 19 October 2015 at 19:16, Nikita Kalyazin <[1]n.kalya...@samsung.com>
> wrote:
> >
> > Hi Stuart,
> >
> >
> > Thanks for your feedback.
> >
> > > One thing that is missing here is a method for the application to
> > > configure how packets are distributed, i.e. which fields in the
> packet
> > > are used when calculating the flow hash (not necessarily the hash
> > > algorithm itself, that can be implementation defined).
> > >
> > > For example with the netmap implementation here, if you have a
> > > compatible interface, I assume the user can control distribution
> to RX
> > > queues using something like;
> > >
> > >   ethtool --config-ntuple rx-flow-hash esp4
> > >
> > > But it would be better if this were configurable via the ODP API.
> Petri
> > > had a suggestion a while back related to this to add a structure
> to the
> > > odp_pktio_params_t;
> > >
> > > enum odp_pktio_input_hash {
> > >   /** No specific fields defined */
> > >   ODP_PKTIN_HASH_NONE = 0,
> > >   /** IPv4/v6 addresses */
> > >   ODP_PKTIN_HASH_IP,
> > >   /** UDP ports and IPv4/v6 addresses */
> > >   ODP_PKTIN_HASH_UDP_IP,
> > >   /** TCP ports and IPv4/v6 addresses */
> > >   ODP_PKTIN_HASH_TCP_IP
> > > };
> > Thanks, I plan to think about it.
> > Btw, NICs provide wide variety of settings regarding distribution of
> > packets across the queues.  Is it supposed to extend the proposed
> > structure to support more flexible configuration?
> >
> > > How about:
> > >
> > > int odp_pktio_inq_create(odp_pktio_t pktio, const char *name,
> > >  

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

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


> -Original Message-
> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
> Sent: Thursday, October 22, 2015 3:02 PM
> To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo)
> Cc: Ivan Khoronzhuk
> Subject: [lng-odp] [API-NEXT PATCH v5 3/5] api: time: unbind CPU cycles
> from time API
> 
> 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 */


New name for these could be XXX_IN_NS
ODP_TIME_SEC_IN_NS  10ULL /**< Second in nsec */


> 
> +/**
> + * @typedef odp_time_t
> + * ODP time stamp. Time stamp can be local, so shouldn't be shared between
> + * threads.
> + */


It's OK to implement local time first, but I'd define it so that global time is 
easy to add later.

/**
 * @typedef odp_time_t
 * ODP time stamp. Time stamp can be represent a time stamp from local or 
global time source.
 * A local time stamp must not be shared between threads. API calls work 
correctly only when
 * all time stamps for input are from the same time source.
 */

In case of 64 bit time stamps, implementation can either define odp_time_t as a 
small struct or use couple of MSB bits for flags (e.g. time stamp would wrap in 
290 years instead of 580 years)


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

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

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

Signed-off-by: Matias Elo 
---

v3:
- Rebased to master
- Added sleep comment to netmap_open() (Mike Holmes)

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

diff --git a/platform/linux-generic/pktio/netmap.c 
b/platform/linux-generic/pktio/netmap.c
index ab4667e..b93dbfd 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,19 @@ 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);
+   /* nm_open() causes the physical link to reset. When using a
+* direct attached loopback cable there may be a small delay
+* until the opposing end's interface comes back up again. 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


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

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


Bill, did you run 'make doxygen-html'?

Not sure if @def ODP_PACKET_GREEN works when it's actually an enum. Anyway,
it's in the correct file now.

-Petri



> -Original Message-
> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT
> Bill Fischofer
> Sent: Thursday, October 22, 2015 11:44 PM
> To: lng-odp@lists.linaro.org
> Cc: Barry Spinney
> Subject: [lng-odp] [API-NEXT PATCHv6 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   |   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 

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

2015-10-23 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
> Bill Fischofer
> Sent: Friday, October 23, 2015 12:19 AM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [PATCH] linux-generic: pool: move local caches to pool
> 
> 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 

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

2015-10-23 Thread Ivan Khoronzhuk

Hi, Petri
Thanks for the reply.

On 23.10.15 10:57, Savolainen, Petri (Nokia - FI/Espoo) wrote:




-Original Message-
From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org]
Sent: Thursday, October 22, 2015 3:02 PM
To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo)
Cc: Ivan Khoronzhuk
Subject: [lng-odp] [API-NEXT PATCH v5 3/5] api: time: unbind CPU cycles
from time API

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



New name for these could be XXX_IN_NS
ODP_TIME_SEC_IN_NS  10ULL /**< Second in nsec */

Ok.
As was suggested, I will add it in separate patchset.






+/**
+ * @typedef odp_time_t
+ * ODP time stamp. Time stamp can be local, so shouldn't be shared between
+ * threads.
+ */



It's OK to implement local time first, but I'd define it so that global time is 
easy to add later.


I propose to split it by API, and don't use same function for that.
It allows to free casual time API from redundancy required by global time and 
different types of time.
Requirements for global time API:
- it must be 64-bit value, it's hard to imagine 32-bit source to compare with 
different threads.
- it must be wall time (in another case we cannot compare it)
- it never overflow (as it wall time) and if so, no need in _diff, _sum, _cmr 
functions, as we can do direct operations with 64-bit value
- it can require additional synchronization in implementation, so can be slower.
- we can get wall time as in "ticks", as in "ns" and directly compare it in 
appropriate units.

For local time it's not required to be wall 

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

2015-10-23 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 
---
 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 b93dbfd..092fa30 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);
@@ -220,7 +226,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;
@@ -241,8 +247,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;
@@ -264,6 +270,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 v5 0/6] l2fwd test improvements

2015-10-23 Thread Matias Elo
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)

v5:
- Moved ethernet address word copy to a helper function (Maxim Ulvanov)

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 | 286 +--
 1 file changed, 197 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] [PATCH v5 1/6] test: l2fwd: add option to change destination eth addresses

2015-10-23 Thread Matias Elo
 If the application is being run on a host connected to a
 switch, not changing the ethernet destination may cause
 loops. Added an option to change the destination ethernet
 address. The destination addresses follow the format
 02:00:00:00:00:XX where the final octet is the output
 port number.

Signed-off-by: Matias Elo 
---
 test/performance/odp_l2fwd.c | 46 ++--
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index f5e4b66..652c024 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -75,6 +75,7 @@ typedef struct {
int time;   /**< Time in seconds to run. */
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
+   int dst_change; /**< Change destination eth addresses > */
 } appl_args_t;
 
 static int exit_threads;   /**< Break workers loop if set to 1 */
@@ -107,6 +108,8 @@ typedef struct {
odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   /** Table of dst ethernet addresses */
+   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port default output queues */
odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
@@ -119,8 +122,8 @@ static odp_barrier_t barrier;
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-  int dst_port);
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
+  int dst_port);
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
 static void print_info(char *progname, appl_args_t *appl_args);
 static void usage(char *progname);
@@ -165,7 +168,7 @@ static void *pktio_queue_thread(void *arg)
 
dst_port = lookup_dest_port(pkt);
 
-   fill_src_eth_addrs(, 1, dst_port);
+   fill_eth_addrs(, 1, dst_port);
 
/* Enqueue the packet for output */
outq_def = gbl_args->outq_def[dst_port];
@@ -244,7 +247,7 @@ static void *pktio_ifburst_thread(void *arg)
/* Drop packets with errors */
pkts_ok = drop_err_pkts(pkt_tbl, pkts);
if (pkts_ok > 0) {
-   fill_src_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
+   fill_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
 
int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok);
 
@@ -393,6 +396,7 @@ int main(int argc, char *argv[])
odp_shm_t shm;
odp_cpumask_t cpumask;
char cpumaskstr[ODP_CPUMASK_STR_SIZE];
+   odph_ethaddr_t new_addr;
odp_pktio_t pktio;
odp_pool_param_t params;
int ret;
@@ -483,6 +487,15 @@ int main(int argc, char *argv[])
if (gbl_args->appl.mode == APPL_MODE_PKT_QUEUE)
gbl_args->outq_def[i] = odp_pktio_outq_getdef(pktio);
 
+   /* Save destination eth address */
+   if (gbl_args->appl.dst_change) {
+   /* 02:00:00:00:00:XX */
+   memset(_addr, 0, sizeof(odph_ethaddr_t));
+   new_addr.addr[0] = 0x02;
+   new_addr.addr[5] = i;
+   gbl_args->dst_eth_addr[i] = new_addr;
+   }
+
ret = odp_pktio_start(pktio);
if (ret) {
LOG_ERR("Error: unable to start %s\n",
@@ -568,14 +581,13 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned 
len)
 }
 
 /**
- * Fill packets' eth src addresses according to the destination port
+ * Fill packets' eth addresses according to the destination port
  *
  * @param pkt_tbl  Array of packets
  * @param num  Number of packets in the array
  * @param dst_port Destination port
  */
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-  int dst_port)
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num, int dst_port)
 {
odp_packet_t pkt;
odph_ethhdr_t *eth;
@@ -586,6 +598,9 @@ static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num,
if (odp_packet_has_eth(pkt)) {
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
eth->src = gbl_args->port_eth_addr[dst_port];
+
+   if (gbl_args->appl.dst_change)
+   eth->dst = gbl_args->dst_eth_addr[dst_port];
}
}
 }
@@ -608,9 +623,10 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)