This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via 180f1403b12beab32715f10839d3248e7fecb46d (commit) via cf51a0805a265b74128cb1dd30acfa292240a28f (commit) via bd1207ff72490a5000ab66281e0d10f566e0877d (commit) via 42c37a8506151debd9be885d055b2c4dc8a93c1c (commit) via 8c6880ee093af5ed6bf2af54a1acadc7b2ba895f (commit) via 321e53c0405ab300585ad66693a24942eefef62b (commit) via 90103b8a5dd627b8680e2fd7ff8380e6a4707ced (commit) from c9f7b34c7f0a4cadfabbd6733e3420a8adb8c322 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 180f1403b12beab32715f10839d3248e7fecb46d Author: Matias Elo matias.elo@nokia.com Date: Mon Feb 3 10:52:56 2020 +0200
validation: packet: prevent test trying to allocate zero length packets
Test packet_test_free_sp() would end up trying to allocate invalid zero length packets if pool_capa.pkt.max_len was zero.
The following packet_alloc_multi() call would then loop indefinitely since error return value was not checked.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/test/validation/api/packet/packet.c b/test/validation/api/packet/packet.c index 6f020d820..b7dfb59f3 100644 --- a/test/validation/api/packet/packet.c +++ b/test/validation/api/packet/packet.c @@ -341,7 +341,7 @@ static int packet_alloc_multi(odp_pool_t pool, uint32_t pkt_len, CU_ASSERT(ret >= 0); CU_ASSERT(ret <= num - total); total += ret; - } while (total < num && ret); + } while (total < num && ret > 0);
return total; } @@ -430,7 +430,7 @@ static void packet_test_free_sp(void) odp_pool_param_t params; uint32_t len = packet_len;
- if (pool_capa.pkt.max_len < len) + if (pool_capa.pkt.max_len && pool_capa.pkt.max_len < len) len = pool_capa.pkt.max_len;
odp_pool_param_init(¶ms);
commit cf51a0805a265b74128cb1dd30acfa292240a28f Author: Matias Elo matias.elo@nokia.com Date: Wed Jan 29 10:16:46 2020 +0200
example: switch: add signal handler for SIGINT
Add signal handler to perform clean exit.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index d21ed61d2..ccb975f6c 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -10,6 +10,7 @@ #include <unistd.h> #include <stdlib.h> #include <inttypes.h> +#include <signal.h>
#include <odp_api.h> #include <odp/helper/odph_api.h> @@ -149,6 +150,13 @@ typedef struct { /** Global pointer to args */ static args_t *gbl_args;
+static void sig_handler(int signo ODP_UNUSED) +{ + if (gbl_args == NULL) + return; + gbl_args->exit_threads = 1; +} + /** * Calculate MAC table index using Ethernet address hash * @@ -416,7 +424,8 @@ static int print_speed_stats(int num_workers, stats_t (*thr_stats)[MAX_PKTIOS], PRIu64 " rx drops, %" PRIu64 " tx drops\n", rx_pkts_tot, tx_pkts_tot, rx_drops_tot, tx_drops_tot);
- } while (loop_forever || (elapsed < duration)); + } while (!gbl_args->exit_threads && + (loop_forever || (elapsed < duration)));
return rx_pkts_tot >= 100 ? 0 : -1; } @@ -976,6 +985,8 @@ int main(int argc, char **argv) odp_init_t init_param; odph_odpthread_params_t thr_params;
+ signal(SIGINT, sig_handler); + /* Let helper collect its own arguments (e.g. --odph_proc) */ argc = odph_parse_options(argc, argv); if (odph_options(&helper_options)) { @@ -1160,6 +1171,5 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); }
- printf("Exit: %d\n\n", ret); return ret; }
commit bd1207ff72490a5000ab66281e0d10f566e0877d Author: Matias Elo matias.elo@nokia.com Date: Tue Jan 28 16:40:17 2020 +0200
example: switch: detect invalid and broadcast ethernet addresses
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index a31a19cd8..d21ed61d2 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -66,6 +66,12 @@ typedef struct { char *if_str; /**< Storage for interface names */ } appl_args_t;
+typedef enum frame_type_t { + FRAME_UNICAST, + FRAME_BROADCAST, + FRAME_INVALID +} frame_type_t; + /** * Statistics */ @@ -497,6 +503,34 @@ static inline void broadcast_packet(odp_packet_t pkt, thread_args_t *thr_arg, } }
+/** + * Check Ethernet frame for broadcast/invalid addresses + * + * @param eth Pointer to an Ethernet header + * + * @retval Ethernet frame_type_t + */ +static frame_type_t check_frame(odph_ethhdr_t *eth) +{ + static uint8_t broadcast_addr[ODPH_ETHADDR_LEN] = {0xff, 0xff, 0xff, + 0xff, 0xff, 0xff}; + static uint8_t null_addr[ODPH_ETHADDR_LEN] = {0, 0, 0, 0, 0, 0}; + + /* Drop invalid frames */ + if (odp_unlikely(!memcmp(eth->src.addr, broadcast_addr, + ODPH_ETHADDR_LEN) || + !memcmp(eth->dst.addr, null_addr, + ODPH_ETHADDR_LEN) || + !memcmp(eth->src.addr, null_addr, + ODPH_ETHADDR_LEN))) { + return FRAME_INVALID; + } + if (!memcmp(eth->dst.addr, broadcast_addr, ODPH_ETHADDR_LEN)) + return FRAME_BROADCAST; + + return FRAME_UNICAST; +} + /** * Forward packets to correct output buffers * @@ -520,23 +554,33 @@ static inline void forward_packets(odp_packet_t pkt_tbl[], unsigned int num, unsigned int i; unsigned int buf_id; uint8_t port_out = 0; + int frame_type;
for (i = 0; i < num; i++) { pkt = pkt_tbl[i];
if (!odp_packet_has_eth(pkt)) { + thr_arg->stats[port_in]->s.rx_drops++; odp_packet_free(pkt); continue; }
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ /* Check Ethernet frame type */ + frame_type = check_frame(eth); + if (odp_unlikely(frame_type == FRAME_INVALID)) { + thr_arg->stats[port_in]->s.rx_drops++; + odp_packet_free(pkt); + continue; + } + /* Update source address MAC table entry */ mac_table_update(ð->src, port_in, cur_tick);
- /* Lookup destination MAC address */ - if (!mac_table_get(ð->dst, &port_out, cur_tick)) { - /* If address was not found, broadcast packet */ + /* Broadcast frame is necessary */ + if (frame_type == FRAME_BROADCAST || + !mac_table_get(ð->dst, &port_out, cur_tick)) { broadcast_packet(pkt, thr_arg, port_in); continue; }
commit 42c37a8506151debd9be885d055b2c4dc8a93c1c Author: Matias Elo matias.elo@nokia.com Date: Tue Jan 28 16:22:53 2020 +0200
example: switch: print packet drop statistics
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index 07fd9eb77..a31a19cd8 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -346,6 +346,8 @@ static int print_speed_stats(int num_workers, stats_t (*thr_stats)[MAX_PKTIOS], uint64_t tx_pkts_prev[MAX_PKTIOS] = {0}; uint64_t rx_pkts_tot; uint64_t tx_pkts_tot; + uint64_t rx_drops_tot; + uint64_t tx_drops_tot; uint64_t rx_pps; uint64_t tx_pps; int i, j; @@ -364,11 +366,13 @@ static int print_speed_stats(int num_workers, stats_t (*thr_stats)[MAX_PKTIOS], do { uint64_t rx_pkts[MAX_PKTIOS] = {0}; uint64_t tx_pkts[MAX_PKTIOS] = {0}; - uint64_t rx_drops = 0; - uint64_t tx_drops = 0; + uint64_t rx_drops[MAX_PKTIOS] = {0}; + uint64_t tx_drops[MAX_PKTIOS] = {0};
rx_pkts_tot = 0; tx_pkts_tot = 0; + rx_drops_tot = 0; + tx_drops_tot = 0;
sleep(timeout); elapsed += timeout; @@ -377,8 +381,8 @@ static int print_speed_stats(int num_workers, stats_t (*thr_stats)[MAX_PKTIOS], for (j = 0; j < num_ifaces; j++) { rx_pkts[j] += thr_stats[i][j].s.rx_packets; tx_pkts[j] += thr_stats[i][j].s.tx_packets; - rx_drops += thr_stats[i][j].s.rx_drops; - tx_drops += thr_stats[i][j].s.tx_drops; + rx_drops[j] += thr_stats[i][j].s.rx_drops; + tx_drops[j] += thr_stats[i][j].s.tx_drops; } }
@@ -390,18 +394,21 @@ static int print_speed_stats(int num_workers, stats_t (*thr_stats)[MAX_PKTIOS], tx_pps = (tx_pkts[j] - tx_pkts_prev[j]) / timeout; printf(" Port %d: %" PRIu64 " rx pps, %" PRIu64 " tx pps, %" PRIu64 " rx pkts, %" PRIu64 - " tx pkts\n", j, rx_pps, tx_pps, rx_pkts[j], - tx_pkts[j]); + " tx pkts, %" PRIu64 " rx drops, %" PRIu64 + " tx drops\n", j, rx_pps, tx_pps, rx_pkts[j], + tx_pkts[j], rx_drops[j], tx_drops[j]);
rx_pkts_prev[j] = rx_pkts[j]; tx_pkts_prev[j] = tx_pkts[j]; rx_pkts_tot += rx_pkts[j]; tx_pkts_tot += tx_pkts[j]; + rx_drops_tot += rx_drops[j]; + tx_drops_tot += tx_drops[j]; }
printf("Total: %" PRIu64 " rx pkts, %" PRIu64 " tx pkts, %" PRIu64 " rx drops, %" PRIu64 " tx drops\n", rx_pkts_tot, - tx_pkts_tot, rx_drops, tx_drops); + tx_pkts_tot, rx_drops_tot, tx_drops_tot);
} while (loop_forever || (elapsed < duration));
commit 8c6880ee093af5ed6bf2af54a1acadc7b2ba895f Author: Matias Elo matias.elo@nokia.com Date: Mon Jan 27 17:10:14 2020 +0200
example: switch: add 5 minute aging time to mac table entries
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index b73d8a50c..07fd9eb77 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, Linaro Limited + * Copyright (c) 2020, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -34,6 +35,9 @@ /** Number of MAC table entries. Must match to hash length. */ #define MAC_TBL_SIZE UINT16_MAX
+/** Aging time for MAC table entries in minutes. Must be <= UINT8_MAX. */ +#define AGING_TIME 5 + /** Get rid of path in filename - only for unix-type paths using '/' */ #define NO_PATH(file_name) (strrchr((file_name), '/') ? \ strrchr((file_name), '/') + 1 : (file_name)) @@ -43,6 +47,7 @@ typedef union { struct { odph_ethaddr_t mac; /**< Ethernet MAC address */ uint8_t port; /**< Port index */ + uint8_t tick; /**< Tick of the latest received packet */ } s;
uint64_t u64; @@ -154,16 +159,30 @@ static inline uint16_t calc_mac_tbl_idx(odph_ethaddr_t *mac) return (uint16_t)(hash & 0xFFFF); }
+/** + * Calculate diff between ticks and take care of value wrap + */ +static inline uint8_t diff_ticks(uint8_t t2, uint8_t t1) +{ + if (t1 < t2) + return t2 - t1; + else if (t1 > t2) + return UINT8_MAX + t2 - t1; + return 0; +} + /** * Get Ethernet address port index from MAC table * * @param mac Pointer to Ethernet address * @param port[out] Pointer to port index for output + * @param cur_tick Current tick * - * @retval 0 on success - * @retval -1 on failure + * @retval 1 on entry found + * @retval 0 on entry not found or expired */ -static inline int mac_table_get(odph_ethaddr_t *mac, uint8_t *port) +static inline int mac_table_get(odph_ethaddr_t *mac, uint8_t *port, + uint8_t cur_tick) { mac_tbl_entry_t entry; uint16_t idx; @@ -173,10 +192,13 @@ static inline int mac_table_get(odph_ethaddr_t *mac, uint8_t *port) entry.u64 = odp_atomic_load_u64(&gbl_args->mac_tbl[idx]);
if (memcmp(mac->addr, entry.s.mac.addr, ODPH_ETHADDR_LEN)) - return -1; + return 0; + + if (odp_unlikely(diff_ticks(cur_tick, entry.s.tick) > AGING_TIME)) + return 0;
*port = entry.s.port; - return 0; + return 1; }
/** @@ -184,18 +206,24 @@ static inline int mac_table_get(odph_ethaddr_t *mac, uint8_t *port) * * @param mac Pointer to Ethernet address * @param port Pointer to port index + * @param cur_tick Current tick */ -static inline void mac_table_put(odph_ethaddr_t *mac, uint8_t port) +static inline void mac_table_update(odph_ethaddr_t *mac, uint8_t port, + uint8_t cur_tick) { mac_tbl_entry_t entry; uint16_t idx;
idx = calc_mac_tbl_idx(mac); + entry.u64 = odp_atomic_load_u64(&gbl_args->mac_tbl[idx]);
- entry.s.mac = *mac; - entry.s.port = port; - - odp_atomic_store_u64(&gbl_args->mac_tbl[idx], entry.u64); + if (memcmp(entry.s.mac.addr, mac->addr, ODPH_ETHADDR_LEN) || + entry.s.port != port || entry.s.tick != cur_tick) { + entry.s.mac = *mac; + entry.s.port = port; + entry.s.tick = cur_tick; + odp_atomic_store_u64(&gbl_args->mac_tbl[idx], entry.u64); + } }
/** @@ -474,15 +502,16 @@ static inline void broadcast_packet(odp_packet_t pkt, thread_args_t *thr_arg, * @param num Number of packets in the array * @param thr_arg Thread arguments * @param port_in Input port index + * @param cur_tick Current tick */ static inline void forward_packets(odp_packet_t pkt_tbl[], unsigned int num, - thread_args_t *thr_arg, uint8_t port_in) + thread_args_t *thr_arg, uint8_t port_in, + uint8_t cur_tick) { odp_packet_t pkt; odph_ethhdr_t *eth; unsigned int i; unsigned int buf_id; - int ret; uint8_t port_out = 0;
for (i = 0; i < num; i++) { @@ -495,16 +524,11 @@ static inline void forward_packets(odp_packet_t pkt_tbl[], unsigned int num,
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
- /* Lookup source MAC address */ - ret = mac_table_get(ð->src, &port_out); - - /* Update for address table if necessary */ - if (ret < 0 || port_out != port_in) - mac_table_put(ð->src, port_in); + /* Update source address MAC table entry */ + mac_table_update(ð->src, port_in, cur_tick);
/* Lookup destination MAC address */ - ret = mac_table_get(ð->dst, &port_out); - if (ret < 0) { + if (!mac_table_get(ð->dst, &port_out, cur_tick)) { /* If address was not found, broadcast packet */ broadcast_packet(pkt, thr_arg, port_in); continue; @@ -583,6 +607,9 @@ static int run_worker(void *arg) odp_packet_t pkt_tbl[MAX_PKT_BURST]; odp_pktin_queue_t pktin; odp_pktout_queue_t pktout; + odp_time_t time_prev; + odp_time_t minute; + uint8_t cur_tick; unsigned int num_pktio; unsigned int pktio = 0; uint8_t port_in; @@ -595,7 +622,13 @@ static int run_worker(void *arg)
odp_barrier_wait(&gbl_args->barrier);
+ minute = odp_time_local_from_ns(ODP_TIME_MIN_IN_NS); + time_prev = odp_time_local(); + cur_tick = (odp_time_to_ns(time_prev) / ODP_TIME_MIN_IN_NS) % UINT8_MAX; + while (!gbl_args->exit_threads) { + odp_time_t time_cur; + odp_time_t time_diff; int sent; unsigned int drops;
@@ -611,10 +644,20 @@ static int run_worker(void *arg) if (odp_unlikely(pkts <= 0)) continue;
+ time_cur = odp_time_local(); + time_diff = odp_time_diff(time_cur, time_prev); + + if (odp_unlikely(odp_time_cmp(time_diff, minute))) { + /* Tick stored as 8 bit value */ + cur_tick = (odp_time_to_ns(time_cur) / + ODP_TIME_MIN_IN_NS) % UINT8_MAX; + time_prev = time_cur; + } + thr_args->stats[port_in]->s.rx_packets += pkts;
/* Sort packets to thread local tx buffers */ - forward_packets(pkt_tbl, pkts, thr_args, port_in); + forward_packets(pkt_tbl, pkts, thr_args, port_in, cur_tick);
/* Empty all thread local tx buffers */ for (port_out = 0; port_out < gbl_args->appl.if_count;
commit 321e53c0405ab300585ad66693a24942eefef62b Author: Matias Elo matias.elo@nokia.com Date: Tue Jan 28 13:25:18 2020 +0200
test: sched_latency: increase number of scheduling rounds
Increase the default number of scheduling rounds to 100M. The number of scheduling rounds can now be configured with '-d' command line option.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/test/performance/odp_sched_latency.c b/test/performance/odp_sched_latency.c index 7bb31e77c..c726074c5 100644 --- a/test/performance/odp_sched_latency.c +++ b/test/performance/odp_sched_latency.c @@ -26,8 +26,8 @@
#define MAX_QUEUES 4096 /**< Maximum number of queues */ #define EVENT_POOL_SIZE (1024 * 1024) /**< Event pool size */ -#define TEST_ROUNDS (4 * 1024 * 1024) /**< Test rounds for each thread */ -#define MAIN_THREAD 1 /**< Thread ID performing maintenance tasks */ +#define TEST_ROUNDS 10 /**< Test rounds for each thread (millions) */ +#define MAIN_THREAD 1 /**< Thread ID performing maintenance tasks */
/* Default values for command line arguments */ #define SAMPLE_EVENT_PER_PRIO 0 /**< Allocate a separate sample event for @@ -75,6 +75,7 @@ typedef struct { typedef struct { unsigned int cpu_count; /**< CPU count */ odp_schedule_sync_t sync_type; /**< Scheduler sync type */ + int test_rounds; /**< Number of test rounds (millions) */ int warm_up_rounds; /**< Number of warm-up rounds */ struct { int queues; /**< Number of scheduling queues */ @@ -334,7 +335,7 @@ static void print_results(test_globals_t *globals) /** * Measure latency of scheduled ODP events * - * Schedule and enqueue events until 'TEST_ROUNDS' events have been processed. + * Schedule and enqueue events until 'test_rounds' events have been processed. * Scheduling latency is measured only from type 'SAMPLE' events. Other events * are simply enqueued back to the scheduling queues. * @@ -360,12 +361,13 @@ static int test_schedule(int thr, test_globals_t *globals) test_stat_t *stats; int dst_idx; int warm_up_rounds = globals->args.warm_up_rounds; + uint64_t test_rounds = globals->args.test_rounds * 1000000;
memset(&globals->core_stat[thr], 0, sizeof(core_stat_t)); globals->core_stat[thr].prio[HI_PRIO].min = UINT64_MAX; globals->core_stat[thr].prio[LO_PRIO].min = UINT64_MAX;
- for (i = 0; i < TEST_ROUNDS; i++) { + for (i = 0; i < test_rounds; i++) { ev = odp_schedule(&src_queue, ODP_SCHED_WAIT);
buf = odp_buffer_from_event(ev); @@ -505,6 +507,7 @@ static void usage(void) "Usage: ./odp_sched_latency [options]\n" "Optional OPTIONS:\n" " -c, --count <number> CPU count, 0=all available, default=1\n" + " -d, --duration <number> Test duration in scheduling rounds (millions), default=%d, min=1\n" " -l, --lo-prio-queues <number> Number of low priority scheduled queues\n" " -t, --hi-prio-queues <number> Number of high priority scheduled queues\n" " -m, --lo-prio-events-per-queue <number> Number of events per low priority queue\n" @@ -522,7 +525,7 @@ static void usage(void) " 2: ODP_SCHED_SYNC_ORDERED\n" " -w, --warm-up <number> Number of warm-up rounds, default=%d, min=1\n" " -h, --help Display help and exit.\n\n" - , WARM_UP_ROUNDS); + , TEST_ROUNDS, WARM_UP_ROUNDS); }
/** @@ -553,9 +556,10 @@ static void parse_args(int argc, char *argv[], test_args_t *args) {NULL, 0, NULL, 0} };
- static const char *shortopts = "+c:s:l:t:m:n:o:p:rw:h"; + static const char *shortopts = "+c:d:s:l:t:m:n:o:p:rw:h";
args->cpu_count = 1; + args->test_rounds = TEST_ROUNDS; args->warm_up_rounds = WARM_UP_ROUNDS; args->sync_type = ODP_SCHED_SYNC_PARALLEL; args->sample_per_prio = SAMPLE_EVENT_PER_PRIO; @@ -576,6 +580,9 @@ static void parse_args(int argc, char *argv[], test_args_t *args) case 'c': args->cpu_count = atoi(optarg); break; + case 'd': + args->test_rounds = atoi(optarg); + break; case 'l': args->prio[LO_PRIO].queues = atoi(optarg); break; @@ -631,6 +638,8 @@ static void parse_args(int argc, char *argv[], test_args_t *args) args->prio[LO_PRIO].queues = MAX_QUEUES; if (args->prio[HI_PRIO].queues > MAX_QUEUES) args->prio[HI_PRIO].queues = MAX_QUEUES; + if (args->test_rounds < 1) + args->test_rounds = 1; if (!args->prio[HI_PRIO].queues && !args->prio[LO_PRIO].queues) { printf("No queues configured\n"); usage();
commit 90103b8a5dd627b8680e2fd7ff8380e6a4707ced Author: Matias Elo matias.elo@nokia.com Date: Tue Jan 28 11:30:14 2020 +0200
test: sched_latency: increase number of warm-up rounds
Increase the default number of warm-up rounds to 100 to avoid possible extra latency caused by scheduler startup.
The number of warm-up rounds can now be configured with '-w' command line option.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Petri Savolainen petri.savolainen@nokia.com
diff --git a/test/performance/odp_sched_latency.c b/test/performance/odp_sched_latency.c index 2bdc4b356..7bb31e77c 100644 --- a/test/performance/odp_sched_latency.c +++ b/test/performance/odp_sched_latency.c @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, Linaro Limited + * Copyright (c) 2020, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -35,6 +36,7 @@ #define LO_PRIO_EVENTS 32 /**< Number of low priority events */ #define HI_PRIO_QUEUES 16 /**< Number of high priority queues */ #define LO_PRIO_QUEUES 64 /**< Number of low priority queues */ +#define WARM_UP_ROUNDS 100 /**< Number of warm-up rounds */
#define EVENTS_PER_HI_PRIO_QUEUE 0 /**< Alloc HI_PRIO_QUEUES x HI_PRIO_EVENTS events */ @@ -54,7 +56,7 @@ ODP_STATIC_ASSERT(LO_PRIO_QUEUES <= MAX_QUEUES, "Too many LO priority queues");
/** Test event types */ typedef enum { - WARM_UP, /**< Warm up event */ + WARM_UP, /**< Warm-up event */ COOL_DOWN,/**< Last event on queue */ TRAFFIC, /**< Event used only as traffic load */ SAMPLE /**< Event used to measure latency */ @@ -66,12 +68,14 @@ typedef struct { event_type_t type; /**< Message type */ int src_idx[NUM_PRIOS]; /**< Source ODP queue */ int prio; /**< Source queue priority */ + int warm_up_rounds; /**< Number of completed warm-up rounds */ } test_event_t;
/** Test arguments */ typedef struct { unsigned int cpu_count; /**< CPU count */ odp_schedule_sync_t sync_type; /**< Scheduler sync type */ + int warm_up_rounds; /**< Number of warm-up rounds */ struct { int queues; /**< Number of scheduling queues */ int events; /**< Number of events */ @@ -218,9 +222,10 @@ static int enqueue_events(int prio, int num_queues, int num_events, memset(event, 0, sizeof(test_event_t));
/* Latency isn't measured from the first processing - * round. */ + * rounds. */ if (num_samples > 0) { event->type = WARM_UP; + event->warm_up_rounds = 0; num_samples--; } else { event->type = TRAFFIC; @@ -354,6 +359,7 @@ static int test_schedule(int thr, test_globals_t *globals) test_event_t *event; test_stat_t *stats; int dst_idx; + int warm_up_rounds = globals->args.warm_up_rounds;
memset(&globals->core_stat[thr], 0, sizeof(core_stat_t)); globals->core_stat[thr].prio[HI_PRIO].min = UINT64_MAX; @@ -383,10 +389,13 @@ static int test_schedule(int thr, test_globals_t *globals) event->prio = !event->prio; }
- if (odp_unlikely(event->type == WARM_UP)) - event->type = SAMPLE; - else + if (odp_unlikely(event->type == WARM_UP)) { + event->warm_up_rounds++; + if (event->warm_up_rounds >= warm_up_rounds) + event->type = SAMPLE; + } else { stats->events++; + }
/* Move event to next queue */ dst_idx = event->src_idx[event->prio] + 1; @@ -511,8 +520,9 @@ static void usage(void) " 0: ODP_SCHED_SYNC_PARALLEL (default)\n" " 1: ODP_SCHED_SYNC_ATOMIC\n" " 2: ODP_SCHED_SYNC_ORDERED\n" + " -w, --warm-up <number> Number of warm-up rounds, default=%d, min=1\n" " -h, --help Display help and exit.\n\n" - ); + , WARM_UP_ROUNDS); }
/** @@ -538,13 +548,15 @@ static void parse_args(int argc, char *argv[], test_args_t *args) {"hi-prio-events", required_argument, NULL, 'p'}, {"sample-per-prio", no_argument, NULL, 'r'}, {"sync", required_argument, NULL, 's'}, + {"warm-up", required_argument, NULL, 'w'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} };
- static const char *shortopts = "+c:s:l:t:m:n:o:p:rh"; + static const char *shortopts = "+c:s:l:t:m:n:o:p:rw:h";
args->cpu_count = 1; + args->warm_up_rounds = WARM_UP_ROUNDS; args->sync_type = ODP_SCHED_SYNC_PARALLEL; args->sample_per_prio = SAMPLE_EVENT_PER_PRIO; args->prio[LO_PRIO].queues = LO_PRIO_QUEUES; @@ -598,6 +610,9 @@ static void parse_args(int argc, char *argv[], test_args_t *args) case 'r': args->sample_per_prio = 1; break; + case 'w': + args->warm_up_rounds = atoi(optarg); + break; case 'h': usage(); exit(EXIT_SUCCESS);
-----------------------------------------------------------------------
Summary of changes: example/switch/odp_switch.c | 166 ++++++++++++++++++++++++++++------- test/performance/odp_sched_latency.c | 46 +++++++--- test/validation/api/packet/packet.c | 4 +- 3 files changed, 172 insertions(+), 44 deletions(-)
hooks/post-receive