Re: [lng-odp] [PATCH 2/2] time: fix invalid casting on a 32-bit host
On 17.05.16 13:23, Elo, Matias (Nokia - FI/Espoo) wrote: Hi Matias, The odp_time_local and others functions are time sensitive functions, that's why it was decided to avoid copping as more as possible. The timespec is not simple "long type". Its type is arch dependent but is always 64bit. In case of 32 bit system it's defined as long long. The same for odp_time_t struct. So, at least for now it seems to be the same for both 32 and 64 bit systems. Hi Ivan, At least for 32/64-bit Ubuntu this is not the case. On a 32-bit system (Ubuntu 16.04) the size of struct timespec is 8 bytes (type is long int) and on a 64-bit system it is 16 bytes. The validation tests were failing before this patch on a 32-bit system. It's nice to see it captured by val tests, that was expected. When it comes to the performance, I wouldn't believe this patch having much of an impact. It's an inline function and the compiler should be able to optimize out the added copy operations. That's not always true. At least in case of "32/64" issue in question and when optimization is disabled. The types are different, then better to make odp_time_t to be same size of timespec. Initially, it was smth like typedef timespec odp_time_t, but new versions of Ubuntu have some problem with leaking some library internals to ODP project with such definition (not sure what it was, I'm using 14.04). Maybe better to align the size of odp_time_t struct with timespec ...? -Matias And I think Bill Fischofer knew about this while adding this ,at first glance, strange union, right Bill? Yes, it's not the best decision from style point of view, but it's fast and in case of an error is supposed to be caught by time validation tests. -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: time: remove print and add verbose faults
On 16.05.16 17:18, Maxim Uvarov wrote: On 05/16/16 17:00, Ivan Khoronzhuk wrote: Hi Maxim, I know it's a little late, but printf was here not for testing wait until. It was here to expose visually time for a second. As ODP doesn't have other accurate enough time source the printf was added to visually demonstrate 1 second. It allows to see if at least frequency of counter was chosen correctly, as it's most frequent error while time API implementation. It can be easily broken even later while simple setting of some clock divider to wrong value, usually in two times more or less. That's enough to see with human eye. I think this ability is more needed then saving of some 0.1 second. In my understanding it saves time between start() and end() measurements which can be result of not passing border check. The border check is was done with CU_ASSERT. Was it not enough? I think that if test hangs for some long time you anyway need to add some debug prints or stop it with gdb and see where exactly it was stopped. The idea not simply print every second...that's indicator that test is running also, but also to demonstrate sens of 1 second. The *_until APIs are verified with odp_time APIs checked previously, that is, one part of time API is checked with another part of time API ))... and print real second while doing thisin case of error in both parts, you will never catch an error with validation test w/o sense of time or another source. Another source is absent, so only way - print itat least it allows to see some part of possible errors. Maybe do add separate test which prints/verify odp_time and linux system time? not sure, ODP can run w/o linux, so validation test should be independent. And adding new test only increases time of testing, so better to do it in same cycle. Maxim. On 12.05.16 14:22, Maxim Uvarov wrote: Having system call inside loop couse unpredictable delay as the result wrong time diff calculation. Just removing print make hole test execution shorter on 0.1 seconds according to cunit stats. Also make verbose errors in places where we out of limit in cunit. This should be very helpful to understand DELAY_TOLERANCE value suitable for all platforms. Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/time/time.c | 35 +++ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index da456ea..f7f3d14 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -331,7 +331,6 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) for (i = 0; i < WAIT_SECONDS; i++) { wait = odp_time_sum(wait, second); odp_time_wait_until(wait); -printf("%d..", i + 1); } end_time = time(); @@ -341,8 +340,19 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) upper_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); -CU_ASSERT(odp_time_cmp(wait, lower_limit) >= 0); -CU_ASSERT(odp_time_cmp(wait, upper_limit) <= 0); +if (odp_time_cmp(wait, lower_limit) < 0) { +fprintf(stderr, "Exceed lower limit: " +"wait is %" PRIu64 ", lower_limit %" PRIu64 "\n", +odp_time_to_ns(wait), odp_time_to_ns(lower_limit)); +CU_FAIL("Exceed lower limit\n"); +} + +if (odp_time_cmp(wait, upper_limit) > 0) { +fprintf(stderr, "Exceed upper limit: " +"wait is %" PRIu64 ", upper_limit %" PRIu64 "\n", +odp_time_to_ns(wait), odp_time_to_ns(lower_limit)); +CU_FAIL("Exceed upper limit\n"); +} } void time_test_local_wait_until(void) @@ -362,10 +372,8 @@ void time_test_wait_ns(void) odp_time_t start_time, end_time, diff; start_time = odp_time_local(); -for (i = 0; i < WAIT_SECONDS; i++) { +for (i = 0; i < WAIT_SECONDS; i++) odp_time_wait_ns(ODP_TIME_SEC_IN_NS); -printf("%d..", i + 1); -} end_time = odp_time_local(); diff = odp_time_diff(end_time, start_time); @@ -375,8 +383,19 @@ void time_test_wait_ns(void) upper_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); -CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); -CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); +if (odp_time_cmp(diff, lower_limit) < 0) { +fprintf(stderr, "Exceed lower limit: " +"diff is %" PRIu64 ", lower_limit %" PRIu64 "\n", +odp_time_to_ns(diff), odp_time_to_ns(lower_limit)); +CU_FAIL("Exceed lower limit\n"); +} + +if (odp_time_cmp(diff, upper_limit) > 0) { +
Re: [lng-odp] [PATCH 2/2] time: fix invalid casting on a 32-bit host
Hi Matias, The odp_time_local and others functions are time sensitive functions, that's why it was decided to avoid copping as more as possible. The timespec is not simple "long type". Its type is arch dependent but is always 64bit. In case of 32 bit system it's defined as long long. The same for odp_time_t struct. So, at least for now it seems to be the same for both 32 and 64 bit systems. And I think Bill Fischofer knew about this while adding this ,at first glance, strange union, right Bill? Yes, it's not the best decision from style point of view, but it's fast and in case of an error is supposed to be caught by time validation tests. On 04.05.16 16:01, Matias Elo wrote: The size of 'struct timespec' may vary on different host architectures as it includes type long members. This breaks time functions on a 32-bit x86 host. Fix this by individually copying struct timespec members to odp_time_t. Signed-off-by: Matias Elo <matias@nokia.com> --- platform/linux-generic/odp_time.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 040f754..81e0522 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -11,11 +11,6 @@ #include #include -typedef union { - odp_time_t ex; - struct timespec in; -} _odp_time_t; - static odp_time_t start_time; static inline @@ -47,13 +42,17 @@ static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) static inline odp_time_t time_local(void) { int ret; - _odp_time_t time; + odp_time_t time; + struct timespec sys_time; - ret = clock_gettime(CLOCK_MONOTONIC_RAW, ); + ret = clock_gettime(CLOCK_MONOTONIC_RAW, _time); if (odp_unlikely(ret != 0)) ODP_ABORT("clock_gettime failed\n"); - return time_diff(time.ex, start_time); + time.tv_sec = sys_time.tv_sec; + time.tv_nsec = sys_time.tv_nsec; + + return time_diff(time, start_time); } static inline int time_cmp(odp_time_t t2, odp_time_t t1) @@ -195,10 +194,15 @@ uint64_t odp_time_to_u64(odp_time_t time) int odp_time_init_global(void) { int ret; - _odp_time_t time; + struct timespec time; - ret = clock_gettime(CLOCK_MONOTONIC_RAW, ); - start_time = ret ? ODP_TIME_NULL : time.ex; + ret = clock_gettime(CLOCK_MONOTONIC_RAW, ); + if (ret) { + start_time = ODP_TIME_NULL; + } else { + start_time.tv_sec = time.tv_sec; + start_time.tv_nsec = time.tv_nsec; + } return ret; } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: time: remove print and add verbose faults
Hi Maxim, I know it's a little late, but printf was here not for testing wait until. It was here to expose visually time for a second. As ODP doesn't have other accurate enough time source the printf was added to visually demonstrate 1 second. It allows to see if at least frequency of counter was chosen correctly, as it's most frequent error while time API implementation. It can be easily broken even later while simple setting of some clock divider to wrong value, usually in two times more or less. That's enough to see with human eye. I think this ability is more needed then saving of some 0.1 second. On 12.05.16 14:22, Maxim Uvarov wrote: Having system call inside loop couse unpredictable delay as the result wrong time diff calculation. Just removing print make hole test execution shorter on 0.1 seconds according to cunit stats. Also make verbose errors in places where we out of limit in cunit. This should be very helpful to understand DELAY_TOLERANCE value suitable for all platforms. Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/time/time.c | 35 +++ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index da456ea..f7f3d14 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -331,7 +331,6 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) for (i = 0; i < WAIT_SECONDS; i++) { wait = odp_time_sum(wait, second); odp_time_wait_until(wait); - printf("%d..", i + 1); } end_time = time(); @@ -341,8 +340,19 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) upper_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); - CU_ASSERT(odp_time_cmp(wait, lower_limit) >= 0); - CU_ASSERT(odp_time_cmp(wait, upper_limit) <= 0); + if (odp_time_cmp(wait, lower_limit) < 0) { + fprintf(stderr, "Exceed lower limit: " + "wait is %" PRIu64 ", lower_limit %" PRIu64 "\n", + odp_time_to_ns(wait), odp_time_to_ns(lower_limit)); + CU_FAIL("Exceed lower limit\n"); + } + + if (odp_time_cmp(wait, upper_limit) > 0) { + fprintf(stderr, "Exceed upper limit: " + "wait is %" PRIu64 ", upper_limit %" PRIu64 "\n", + odp_time_to_ns(wait), odp_time_to_ns(lower_limit)); + CU_FAIL("Exceed upper limit\n"); + } } void time_test_local_wait_until(void) @@ -362,10 +372,8 @@ void time_test_wait_ns(void) odp_time_t start_time, end_time, diff; start_time = odp_time_local(); - for (i = 0; i < WAIT_SECONDS; i++) { + for (i = 0; i < WAIT_SECONDS; i++) odp_time_wait_ns(ODP_TIME_SEC_IN_NS); - printf("%d..", i + 1); - } end_time = odp_time_local(); diff = odp_time_diff(end_time, start_time); @@ -375,8 +383,19 @@ void time_test_wait_ns(void) upper_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); - CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); - CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); + if (odp_time_cmp(diff, lower_limit) < 0) { + fprintf(stderr, "Exceed lower limit: " + "diff is %" PRIu64 ", lower_limit %" PRIu64 "\n", + odp_time_to_ns(diff), odp_time_to_ns(lower_limit)); + CU_FAIL("Exceed lower limit\n"); + } + + if (odp_time_cmp(diff, upper_limit) > 0) { + fprintf(stderr, "Exceed upper limit: " + "diff is %" PRIu64 ", upper_limit %" PRIu64 "\n", + odp_time_to_ns(diff), odp_time_to_ns(lower_limit)); + CU_FAIL("Exceed upper limit\n"); + } } static void time_test_to_u64(time_cb time) -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] odp_cpumask_default_worker() and availability of the returned CPU's
On 19.04.16 18:31, Zoltan Kiss wrote: Hi, A quick question: my understanding is that odp_cpumask_default_worker() returns the available CPU's, but it doesn't guarantee that when you start your thread's/processes they will be still available, right? It should be the applications responsibility to not start more threads than it wants on the same CPU. Also, I understood that it is not a strict requirement to have one thread per CPU, just a best practice, and it's legal to start more of them on the same CPU (just highly not advised) Even more, it returns only available CPUs for worker threads only and a thread can run on several CPUs also (like it's done already for main control thread)... CPU usage is user responsibility, and that's a problem for some API usage that bases it's calculations on per CPU registerslike odp_cpu_cycle A user should pay attention on it while configuration. Regards,usage Zoltan ___ 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] [PATCH v2] validation: time: shorten test duration
On 19.04.16 17:13, Petri Savolainen wrote: Time test duration was almost a minute on a 2.6GHz CPU. Combined local and global time monotonity tests, so that the there is only single run of the long wait loop. Shortened wait test time to 3 seconds and long loop into roughly 14 seconds on a 2.6GHz CPU. There should be enough head room to keep loop duration over 4 seconds even with higher CPU frequencies. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> But, it needs to be revised when main thread will run only on single CPU allowing odp_cpu_cycle APIs to work correctly. --- test/validation/time/time.c | 63 - test/validation/time/time.h | 3 +-- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index cb1ddef..da456ea 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -9,10 +9,11 @@ #include "time.h" #define BUSY_LOOP_CNT 3000/* used for t > min resolution */ -#define BUSY_LOOP_CNT_LONG 120 /* used for t > 4 sec */ +#define BUSY_LOOP_CNT_LONG 60 /* used for t > 4 sec */ #define MIN_TIME_RATE 32000 #define MAX_TIME_RATE 150 #define DELAY_TOLERANCE 2000/* deviation for delay */ +#define WAIT_SECONDS3 static uint64_t local_res; static uint64_t global_res; @@ -98,42 +99,45 @@ void time_test_global_conversion(void) time_test_conversion(odp_time_global_from_ns, global_res); } -static void time_test_monotony(time_cb time) +void time_test_monotony(void) { volatile uint64_t count = 0; - odp_time_t t1, t2, t3; + odp_time_t l_t1, l_t2, l_t3; + odp_time_t g_t1, g_t2, g_t3; uint64_t ns1, ns2, ns3; - t1 = time(); + l_t1 = odp_time_local(); + g_t1 = odp_time_global(); while (count < BUSY_LOOP_CNT) { count++; }; - t2 = time(); + l_t2 = odp_time_local(); + g_t2 = odp_time_global(); while (count < BUSY_LOOP_CNT_LONG) { count++; }; - t3 = time(); + l_t3 = odp_time_local(); + g_t3 = odp_time_global(); - ns1 = odp_time_to_ns(t1); - ns2 = odp_time_to_ns(t2); - ns3 = odp_time_to_ns(t3); + ns1 = odp_time_to_ns(l_t1); + ns2 = odp_time_to_ns(l_t2); + ns3 = odp_time_to_ns(l_t3); + /* Local time assertions */ CU_ASSERT(ns2 > ns1); CU_ASSERT(ns3 > ns2); -} -void time_test_local_monotony(void) -{ - time_test_monotony(odp_time_local); -} + ns1 = odp_time_to_ns(g_t1); + ns2 = odp_time_to_ns(g_t2); + ns3 = odp_time_to_ns(g_t3); -void time_test_global_monotony(void) -{ - time_test_monotony(odp_time_global); + /* Global time assertions */ + CU_ASSERT(ns2 > ns1); + CU_ASSERT(ns3 > ns2); } static void time_test_cmp(time_cb time, time_from_ns_cb time_from_ns) @@ -324,16 +328,18 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) start_time = time(); wait = start_time; - for (i = 1; i < 6; i++) { + for (i = 0; i < WAIT_SECONDS; i++) { wait = odp_time_sum(wait, second); odp_time_wait_until(wait); - printf("%d..", i); + printf("%d..", i + 1); } end_time = time(); wait = odp_time_diff(end_time, start_time); - lower_limit = time_from_ns(5 * ODP_TIME_SEC_IN_NS - DELAY_TOLERANCE); - upper_limit = time_from_ns(5 * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); + lower_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS - + DELAY_TOLERANCE); + upper_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + + DELAY_TOLERANCE); CU_ASSERT(odp_time_cmp(wait, lower_limit) >= 0); CU_ASSERT(odp_time_cmp(wait, upper_limit) <= 0); @@ -356,18 +362,18 @@ void time_test_wait_ns(void) odp_time_t start_time, end_time, diff; start_time = odp_time_local(); - for (i = 1; i < 6; i++) { + for (i = 0; i < WAIT_SECONDS; i++) { odp_time_wait_ns(ODP_TIME_SEC_IN_NS); - printf("%d..", i); + printf("%d..", i + 1); } end_time = odp_time_local(); diff = odp_time_diff(end_time, start_time); - lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS - - DELAY_TOLERANCE); - upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + - DELAY_TOLERANCE); + lower_limit = odp_time_loc
Re: [lng-odp] [PATCH] validation: time: shorten test duration
diff = odp_time_diff(end_time, start_time); - lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS - - DELAY_TOLERANCE); - upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + - DELAY_TOLERANCE); + lower_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS - +DELAY_TOLERANCE); + upper_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + +DELAY_TOLERANCE); CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); @@ -412,7 +418,6 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), ODP_TEST_INFO(time_test_local_conversion), - ODP_TEST_INFO(time_test_local_monotony), ODP_TEST_INFO(time_test_local_cmp), ODP_TEST_INFO(time_test_local_diff), ODP_TEST_INFO(time_test_local_sum), @@ -421,12 +426,12 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_to_u64), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), - ODP_TEST_INFO(time_test_global_monotony), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), ODP_TEST_INFO(time_test_global_to_u64), + ODP_TEST_INFO(time_test_monotony), ODP_TEST_INFO_NULL }; diff --git a/test/validation/time/time.h b/test/validation/time/time.h index d75b0f5..3911814 100644 --- a/test/validation/time/time.h +++ b/test/validation/time/time.h @@ -15,8 +15,6 @@ void time_test_local_res(void); void time_test_global_res(void); void time_test_local_conversion(void); void time_test_global_conversion(void); -void time_test_local_monotony(void); -void time_test_global_monotony(void); void time_test_local_cmp(void); void time_test_global_cmp(void); void time_test_local_diff(void); @@ -28,6 +26,7 @@ void time_test_global_wait_until(void); void time_test_wait_ns(void); void time_test_local_to_u64(void); void time_test_global_to_u64(void); +void time_test_monotony(void); /* test arrays: */ extern odp_testinfo_t time_suite_time[]; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: scheduler: correct pause/resume sequence
Hi Bill, What about to review this one? On 16.02.16 16:02, Ivan Khoronzhuk wrote: When test for single thread is finished the following test for many threads can be started, and for some implementations can happen that future one event can arrive to main thread, as it was requested in previous test. As result one event can be lost for rest threads. So, it's better to pause scheduling for main thread when it doesn't participate in the multi-threaded test. Also move pause/resume test closer to beginning, because it's used in tests before. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..c1b61c5 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -1000,6 +1000,8 @@ static void schedule_common(odp_schedule_sync_t sync, int num_queues, args.enable_schd_multi = enable_schd_multi; args.enable_excl_atomic = 0;/* Not needed with a single CPU */ + /* resume scheduling in case it was paused */ + odp_schedule_resume(); fill_queues(); schedule_common_(); @@ -1037,6 +1039,9 @@ static void parallel_execute(odp_schedule_sync_t sync, int num_queues, args->enable_schd_multi = enable_schd_multi; args->enable_excl_atomic = enable_excl_atomic; + /* disable receive events for main thread */ + exit_schedule_loop(); + fill_queues(args); /* Create and launch worker threads */ @@ -1249,6 +1254,9 @@ void scheduler_test_pause_resume(void) int i; int local_bufs = 0; + /* resume scheduling in case it was paused */ + odp_schedule_resume(); + queue = odp_queue_lookup("sched_0_0_n"); CU_ASSERT(queue != ODP_QUEUE_INVALID); @@ -1296,6 +1304,8 @@ void scheduler_test_pause_resume(void) } CU_ASSERT(exit_schedule_loop() == 0); + + odp_schedule_resume(); } static int create_queues(void) @@ -1556,6 +1566,7 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_num_prio), ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), + ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO(scheduler_test_parallel), ODP_TEST_INFO(scheduler_test_atomic), ODP_TEST_INFO(scheduler_test_ordered), @@ -1586,7 +1597,6 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_a), ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_o), ODP_TEST_INFO(scheduler_test_multi_1q_mt_a_excl), - ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO_NULL, }; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: time: shorten test duration
On 15.04.16 10:07, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, That could be done, but loop_time must be a float. It could replace the single long loop ... I know, it's fast write, after normalizing to ns float not needed, and it has to be done. while (count < BUSY_LOOP_CNT_LONG) { count++; }; ... after this patch is applied. I just want to get rid of the minute long wait ASAP. The loop can be tuned and verified on multiple CPUs with frequency scaling afterwards. -Petri Ok. But loop is working fine only if test runs on single-CPU-thread (We had talk about it at connect) For linux generic the main thread can run on several CPU-s by default, not CPU0. That means, loop can work only after some changes like below: Actually I wanted to fix it with patch series: https://lists.linaro.org/pipermail/lng-odp/2016-January/019734.html https://lists.linaro.org/pipermail/lng-odp/2016-January/019733.html https://lists.linaro.org/pipermail/lng-odp/2016-January/019735.html But it was leaved w/o attention from the team. It was partly responsibility of Gary, but now, even don't know who should do this. -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, April 14, 2016 5:39 PM To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com>; lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH] validation: time: shorten test duration What about to do smth like below (I didn't normalize it to ns...but that are tehnical details) uint64_t c1, c2; uint64_t loop_time; c1 = odp_cpu_cycles(); while (loop_time <= 4) { c2 = odp_cpu_cycles(); cycle_diff = odp_cpu_cycles_diff(c2, c1); loop_time += cycle_diff / odp_cpu_hz(); c1 = c2; }; On 14.04.16 17:24, Ivan Khoronzhuk wrote: On 14.04.16 17:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, I said back then that we need one test case that runs longer than 4 sec, other test cases can be shorter. This patch does that - combines long lasting tests into single >4sec run. The rationale for shorter duration is that many of us need to run 'make check' multiple times a day and the benefit from every second we can save is multiplied by the number users and test runs per user. This patch saves roughly 40 seconds per user per test run. Optimally, time validation test should be able to verify the API in a bit more than 4 seconds. Also a single, very long test case makes people wonder if the system hanged... You could add a configure option for a longer test run, but by default the time test (or any other test) should not take a minute. -Petri That's because there is no general way to get correct CPU freq, in another way it's possible to figure out needed number of loops in runtime... -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, April 14, 2016 5:00 PM To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com>; lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH] validation: time: shorten test duration Hi, Petri. As far I remember you was OK to increase time of testing on even more time. It was supposed to include future freqs...I know, for now it's not correct.. but anyway. Also I dislike the idea to combine two separate tests in one function. Yes, it makes tests faster, but doesn't reflect unit test nature. Also, Ok, you've made test shorter supposing that freq can not be fast enough to exit the 4sec range, you've saved ~ minute, but why you decrease 5 sec to 3 sec, it helps to see sense of time..and can be missed easily. On 14.04.16 14:41, Petri Savolainen wrote: Time test duration was almost a minute on a 2.6GHz CPU. Combined local and global time monotonity tests, so that the there is only single run of the long wait loop. Shortened wait test time to 3 seconds and long loop into roughly 14 seconds on a 2.6GHz CPU. There should be enough head room to keep loop duration over 4 seconds even with higher CPU frequencies. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- test/validation/time/time.c | 63 - test/validation/time/time.h | 3 +-- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index cb1ddef..5e55817 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -9,10 +9,11 @@ #include "time.h" #define BUSY_LOOP_CNT3000/* used for t > min resolution */ -#define BUSY_LOOP_CNT_LONG120 /* used for t > 4 sec */ +#define BUSY_LOOP_CNT_LONG60 /* used for t > 4 sec */ #define MIN_TIME_RATE32000 #define MAX_TIME_RATE150 #define DELAY_TOLERANCE200
Re: [lng-odp] [RFC] api: crypto capability support
* @} */ -- 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] [PATCH] validation: time: shorten test duration
What about to do smth like below (I didn't normalize it to ns...but that are tehnical details) uint64_t c1, c2; uint64_t loop_time; c1 = odp_cpu_cycles(); while (loop_time <= 4) { c2 = odp_cpu_cycles(); cycle_diff = odp_cpu_cycles_diff(c2, c1); loop_time += cycle_diff / odp_cpu_hz(); c1 = c2; }; On 14.04.16 17:24, Ivan Khoronzhuk wrote: On 14.04.16 17:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, I said back then that we need one test case that runs longer than 4 sec, other test cases can be shorter. This patch does that - combines long lasting tests into single >4sec run. The rationale for shorter duration is that many of us need to run 'make check' multiple times a day and the benefit from every second we can save is multiplied by the number users and test runs per user. This patch saves roughly 40 seconds per user per test run. Optimally, time validation test should be able to verify the API in a bit more than 4 seconds. Also a single, very long test case makes people wonder if the system hanged... You could add a configure option for a longer test run, but by default the time test (or any other test) should not take a minute. -Petri That's because there is no general way to get correct CPU freq, in another way it's possible to figure out needed number of loops in runtime... -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, April 14, 2016 5:00 PM To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com>; lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH] validation: time: shorten test duration Hi, Petri. As far I remember you was OK to increase time of testing on even more time. It was supposed to include future freqs...I know, for now it's not correct.. but anyway. Also I dislike the idea to combine two separate tests in one function. Yes, it makes tests faster, but doesn't reflect unit test nature. Also, Ok, you've made test shorter supposing that freq can not be fast enough to exit the 4sec range, you've saved ~ minute, but why you decrease 5 sec to 3 sec, it helps to see sense of time..and can be missed easily. On 14.04.16 14:41, Petri Savolainen wrote: Time test duration was almost a minute on a 2.6GHz CPU. Combined local and global time monotonity tests, so that the there is only single run of the long wait loop. Shortened wait test time to 3 seconds and long loop into roughly 14 seconds on a 2.6GHz CPU. There should be enough head room to keep loop duration over 4 seconds even with higher CPU frequencies. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- test/validation/time/time.c | 63 - test/validation/time/time.h | 3 +-- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index cb1ddef..5e55817 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -9,10 +9,11 @@ #include "time.h" #define BUSY_LOOP_CNT3000/* used for t > min resolution */ -#define BUSY_LOOP_CNT_LONG120 /* used for t > 4 sec */ +#define BUSY_LOOP_CNT_LONG60 /* used for t > 4 sec */ #define MIN_TIME_RATE32000 #define MAX_TIME_RATE150 #define DELAY_TOLERANCE2000/* deviation for delay */ +#define WAIT_SECONDS3 static uint64_t local_res; static uint64_t global_res; @@ -98,42 +99,45 @@ void time_test_global_conversion(void) time_test_conversion(odp_time_global_from_ns, global_res); } -static void time_test_monotony(time_cb time) +void time_test_monotony(void) { volatile uint64_t count = 0; -odp_time_t t1, t2, t3; +odp_time_t l_t1, l_t2, l_t3; +odp_time_t g_t1, g_t2, g_t3; uint64_t ns1, ns2, ns3; -t1 = time(); +l_t1 = odp_time_local(); +g_t1 = odp_time_global(); while (count < BUSY_LOOP_CNT) { count++; }; -t2 = time(); +l_t2 = odp_time_local(); +g_t2 = odp_time_global(); while (count < BUSY_LOOP_CNT_LONG) { count++; }; -t3 = time(); +l_t3 = odp_time_local(); +g_t3 = odp_time_global(); -ns1 = odp_time_to_ns(t1); -ns2 = odp_time_to_ns(t2); -ns3 = odp_time_to_ns(t3); +ns1 = odp_time_to_ns(l_t1); +ns2 = odp_time_to_ns(l_t2); +ns3 = odp_time_to_ns(l_t3); +/* Local time assertions */ CU_ASSERT(ns2 > ns1); CU_ASSERT(ns3 > ns2); -} -void time_test_local_monotony(void) -{ -time_test_monotony(odp_time_local); -} +ns1 = odp_time_to_ns(g_t1); +ns2 = odp_time_to_ns(g_t2); +ns3 = odp_time_to_ns(g_t3); -void time_test_global_monotony(void) -{ -time_test_monotony(odp_time_global); +/* G
Re: [lng-odp] [PATCH] validation: time: shorten test duration
On 14.04.16 17:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, I said back then that we need one test case that runs longer than 4 sec, other test cases can be shorter. This patch does that - combines long lasting tests into single >4sec run. The rationale for shorter duration is that many of us need to run 'make check' multiple times a day and the benefit from every second we can save is multiplied by the number users and test runs per user. This patch saves roughly 40 seconds per user per test run. Optimally, time validation test should be able to verify the API in a bit more than 4 seconds. Also a single, very long test case makes people wonder if the system hanged... You could add a configure option for a longer test run, but by default the time test (or any other test) should not take a minute. -Petri That's because there is no general way to get correct CPU freq, in another way it's possible to figure out needed number of loops in runtime... -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, April 14, 2016 5:00 PM To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com>; lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH] validation: time: shorten test duration Hi, Petri. As far I remember you was OK to increase time of testing on even more time. It was supposed to include future freqs...I know, for now it's not correct.. but anyway. Also I dislike the idea to combine two separate tests in one function. Yes, it makes tests faster, but doesn't reflect unit test nature. Also, Ok, you've made test shorter supposing that freq can not be fast enough to exit the 4sec range, you've saved ~ minute, but why you decrease 5 sec to 3 sec, it helps to see sense of time..and can be missed easily. On 14.04.16 14:41, Petri Savolainen wrote: Time test duration was almost a minute on a 2.6GHz CPU. Combined local and global time monotonity tests, so that the there is only single run of the long wait loop. Shortened wait test time to 3 seconds and long loop into roughly 14 seconds on a 2.6GHz CPU. There should be enough head room to keep loop duration over 4 seconds even with higher CPU frequencies. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- test/validation/time/time.c | 63 - test/validation/time/time.h | 3 +-- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index cb1ddef..5e55817 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -9,10 +9,11 @@ #include "time.h" #define BUSY_LOOP_CNT3000/* used for t > min resolution */ -#define BUSY_LOOP_CNT_LONG 120 /* used for t > 4 sec */ +#define BUSY_LOOP_CNT_LONG 60 /* used for t > 4 sec */ #define MIN_TIME_RATE32000 #define MAX_TIME_RATE150 #define DELAY_TOLERANCE 2000/* deviation for delay */ +#define WAIT_SECONDS3 static uint64_t local_res; static uint64_t global_res; @@ -98,42 +99,45 @@ void time_test_global_conversion(void) time_test_conversion(odp_time_global_from_ns, global_res); } -static void time_test_monotony(time_cb time) +void time_test_monotony(void) { volatile uint64_t count = 0; - odp_time_t t1, t2, t3; + odp_time_t l_t1, l_t2, l_t3; + odp_time_t g_t1, g_t2, g_t3; uint64_t ns1, ns2, ns3; - t1 = time(); + l_t1 = odp_time_local(); + g_t1 = odp_time_global(); while (count < BUSY_LOOP_CNT) { count++; }; - t2 = time(); + l_t2 = odp_time_local(); + g_t2 = odp_time_global(); while (count < BUSY_LOOP_CNT_LONG) { count++; }; - t3 = time(); + l_t3 = odp_time_local(); + g_t3 = odp_time_global(); - ns1 = odp_time_to_ns(t1); - ns2 = odp_time_to_ns(t2); - ns3 = odp_time_to_ns(t3); + ns1 = odp_time_to_ns(l_t1); + ns2 = odp_time_to_ns(l_t2); + ns3 = odp_time_to_ns(l_t3); + /* Local time assertions */ CU_ASSERT(ns2 > ns1); CU_ASSERT(ns3 > ns2); -} -void time_test_local_monotony(void) -{ - time_test_monotony(odp_time_local); -} + ns1 = odp_time_to_ns(g_t1); + ns2 = odp_time_to_ns(g_t2); + ns3 = odp_time_to_ns(g_t3); -void time_test_global_monotony(void) -{ - time_test_monotony(odp_time_global); + /* Global time assertions */ + CU_ASSERT(ns2 > ns1); + CU_ASSERT(ns3 > ns2); } static void time_test_cmp(time_cb time, time_from_ns_cb time_from_ns) @@ -324,16 +328,18 @@ static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) start_time = time(); wait = start_time; -
Re: [lng-odp] [PATCH] validation: time: shorten test duration
time_diff(end_time, start_time); - lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS - - DELAY_TOLERANCE); - upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + - DELAY_TOLERANCE); + lower_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS - +DELAY_TOLERANCE); + upper_limit = odp_time_local_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS + +DELAY_TOLERANCE); CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); @@ -412,7 +418,6 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), ODP_TEST_INFO(time_test_local_conversion), - ODP_TEST_INFO(time_test_local_monotony), ODP_TEST_INFO(time_test_local_cmp), ODP_TEST_INFO(time_test_local_diff), ODP_TEST_INFO(time_test_local_sum), @@ -421,12 +426,12 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_to_u64), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), - ODP_TEST_INFO(time_test_global_monotony), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), ODP_TEST_INFO(time_test_global_to_u64), + ODP_TEST_INFO(time_test_monotony), ODP_TEST_INFO_NULL }; diff --git a/test/validation/time/time.h b/test/validation/time/time.h index d75b0f5..3911814 100644 --- a/test/validation/time/time.h +++ b/test/validation/time/time.h @@ -15,8 +15,6 @@ void time_test_local_res(void); void time_test_global_res(void); void time_test_local_conversion(void); void time_test_global_conversion(void); -void time_test_local_monotony(void); -void time_test_global_monotony(void); void time_test_local_cmp(void); void time_test_global_cmp(void); void time_test_local_diff(void); @@ -28,6 +26,7 @@ void time_test_global_wait_until(void); void time_test_wait_ns(void); void time_test_local_to_u64(void); void time_test_global_to_u64(void); +void time_test_monotony(void); /* test arrays: */ extern odp_testinfo_t time_suite_time[]; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: scheduler: correct pause/resume sequence
ping On 18.02.16 17:56, Ivan Khoronzhuk wrote: ping On 16.02.16 16:02, Ivan Khoronzhuk wrote: When test for single thread is finished the following test for many threads can be started, and for some implementations can happen that future one event can arrive to main thread, as it was requested in previous test. As result one event can be lost for rest threads. So, it's better to pause scheduling for main thread when it doesn't participate in the multi-threaded test. Also move pause/resume test closer to beginning, because it's used in tests before. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..c1b61c5 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -1000,6 +1000,8 @@ static void schedule_common(odp_schedule_sync_t sync, int num_queues, args.enable_schd_multi = enable_schd_multi; args.enable_excl_atomic = 0;/* Not needed with a single CPU */ +/* resume scheduling in case it was paused */ +odp_schedule_resume(); fill_queues(); schedule_common_(); @@ -1037,6 +1039,9 @@ static void parallel_execute(odp_schedule_sync_t sync, int num_queues, args->enable_schd_multi = enable_schd_multi; args->enable_excl_atomic = enable_excl_atomic; +/* disable receive events for main thread */ +exit_schedule_loop(); + fill_queues(args); /* Create and launch worker threads */ @@ -1249,6 +1254,9 @@ void scheduler_test_pause_resume(void) int i; int local_bufs = 0; +/* resume scheduling in case it was paused */ +odp_schedule_resume(); + queue = odp_queue_lookup("sched_0_0_n"); CU_ASSERT(queue != ODP_QUEUE_INVALID); @@ -1296,6 +1304,8 @@ void scheduler_test_pause_resume(void) } CU_ASSERT(exit_schedule_loop() == 0); + +odp_schedule_resume(); } static int create_queues(void) @@ -1556,6 +1566,7 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_num_prio), ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), +ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO(scheduler_test_parallel), ODP_TEST_INFO(scheduler_test_atomic), ODP_TEST_INFO(scheduler_test_ordered), @@ -1586,7 +1597,6 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_a), ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_o), ODP_TEST_INFO(scheduler_test_multi_1q_mt_a_excl), -ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO_NULL, }; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [API-NEXT PATCH v2] doc/users-quide: correct timer API section
Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- v2..v1: - just rebased with several not important corrections doc/users-guide/users-guide.adoc | 50 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index a2e5058..69b1930 100644 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -335,11 +335,51 @@ The +odp_time_t+ opaque type represents local or global timestamps. === Timer Timers are how ODP applications measure and respond to the passage of time. -Timers are drawn from specialized pools called timer pools that have their -own abstract type (+odp_timer_pool_t+). Applications may have many timers -active at the same time and can set them to use either relative or absolute -time. When timers expire they create events of type +odp_timeout_t+, which -serve as notifications of timer expiration. +The timer API is supposed to be used when time synchronization with events is +needed and has different nature than time API has. Usually, timers require a +separate h/w module to be used for generating timeouts. Timers are drawn from +specialized pools called timer pools that have their own abstract type +(+odp_timer_pool_t+). Applications may have many timers active at the same +time and can set them to use either relative or absolute time. When timers +expire they create events of type +odp_timeout_t+, which serve as notifications +of timer expiration. The event is placed on a queue pointed while timer +allocation. + +Each timer pool can be set with it's own resolution in ns and number of +supported timers. So, timer pool can be considered as a time source with +it's own resolution and defined number of timers. All timers in timer pool +are handled with same time source with same resolution. If user needs two types +of timers with different requirements for resolution then better to create +two pools with it's own resolution, it can decrease load on hardware. + +An expiration time for the timer is set in it's own ticks, so nanoseconds have +to be converted first with conversation function +odp_timer_ns_to_tick()+, to +convert it back to ns use +odp_timer_tick_to_ns()+. Both functions require +to pass a timer pool used, as it can be sourced with it's own time source that +can have specific resolution and thus different conversion ratio. + +To set a timer to deliver a timeout event the two functions can be used: ++odp_timer_set_abs()+ and +odp_timer_set_rel()+. Both of them require an +event to be passed and a time interval in ticks of corresponding timer pool. +The expiration time for a timer can be set based on current tick value for +a timer pool taken with +odp_timer_current_tick()+, to set a timer +(absolute time) with a user-provided timeout event, the +odp_timer_set_abs()+ +can be used. An event is the event converted from timeout allocated from timeout +pool with +odp_timeout_alloc()+. The event is returned to timer queue when set +time interval has expired and can be also converted to timeout with ++odp_timeout_from_event()+, if it's needed. To free timeout the ++odp_timeout_free()+ can be used, if it's presented as event it can be freed +as event with +odp_event_free()+. + +In general, timer pool characterizes time source, and timer is characterized +with timer pool, user pointer and destination queue for delivering. The timeout +is characterized with timer, timer pool and time of expiration and is placed to +queue set while timer allocation. The timeout can be delivered only to the +destination queue of concrete timer. To get a timer generated a timeout ++odp_timeout_timer()+ can be used. + +When timer is freed it's returned to timer pool and is ready to be allocated +once again. A timer can be canceled with odp_timer_cancel. === Synchronizer Multiple threads operating in parallel typically require various -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Accesing hardware time stamps
On 18.03.16 10:50, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, Not yet, but going to do that soon. Do you need also an API for reading (sampling) the packet input HW timestamp from the interface? For example, rte_eth_timesync_read_rx_timestamp does that. I was going to add (first) only ability to the read timestamp stored in the received packet, timestamp frequency and a configuration option to enable/disable timestamping per interface (during pktio open). We have odp_time_ and odp_cpu_cycle APIs to read wall clock time and CPU cycle counters. More adcanced packet input clock (or IEEE 1588 clock) features could added later on. Yep, but odp_time API covers different h/w counter then timestamps of incoming packets. Not sure if enabale/disable API is needed. The packet timestamps don't consume CPU time in normal circumstances and they are present or not. If h/w doesn't support timestamping then it can be emulated with odp_time_*, but it's rather an exception then rule. It should be warned that packet time stamp is not comparable with time API types. And one though, maybe it can be used with time API as a different time typedislike it, as time API can consume more cycles after that, but it's possible. -Petri *From:*EXT Dominic Pigott [mailto:d...@intelligentcompute.com] *Sent:* Thursday, March 17, 2016 4:39 PM *To:* Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com> *Cc:* lng-odp <lng-odp@lists.linaro.org> *Subject:* Re: Accesing hardware time stamps Hi Petri Thanks for the answer, did you have any time to look at this further? Most modern NICs can generate the timestamps in hardware so the overhead should be low, but its vendor specific. DPDK implements a standard API in 2.1 I believe: http://dpdk.org/doc/guides/rel_notes/release_2_1.html?highlight=timestamp Regards Dom -- *From: *"Savolainen, Petri (Nokia - FI/Espoo)" <petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com>> *To: *"EXT Dominic Pigott" <d...@intelligentcompute.com <mailto:d...@intelligentcompute.com>>, "lng-odp" <lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>> *Sent: *Friday, 11 March, 2016 05:13:52 *Subject: *RE: Accesing hardware time stamps Hi, There’s not yet packet time stamping, but I’m thinking to add a 64 bit time stamp into packet metadata and have a packet input configuration option to enable/disable timestamping, since it may take lots of CPU cycles to timestamp every packet (also when application would not need it). I’ll look into it more detail at next week. -Petri *From:*lng-odp [mailto:lng-odp-boun...@lists.linaro.org] *On Behalf Of *EXT Dominic Pigott *Sent:* Thursday, March 10, 2016 1:08 PM *To:* lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> *Subject:* [lng-odp] Accesing hardware time stamps Hi, I cannot find in the documentation, but is it possible to access a packets hardware time stamp via the ODP API? Regards Dom ___ 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] [PATCH] validation: scheduler: increase delay tolerance
On 29.02.16 23:39, Bill Fischofer wrote: On Mon, Feb 29, 2016 at 11:49 AM, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: For some systems sensitive to time deviation, would be better to have some time backup while testing scheduler time, so increase it to 3 jiffies. https://bugs.linaro.org/show_bug.cgi?id=2076 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> --- test/validation/scheduler/scheduler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..cb04209 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -48,7 +48,7 @@ #define CHAOS_NDX_TO_PTR(n) ((void *)(uintptr_t)n) #define CHAOS_WAIT_FAIL (5 * ODP_TIME_SEC_IN_NS) -#define ODP_WAIT_TOLERANCE (20 * ODP_TIME_MSEC_IN_NS) +#define ODP_WAIT_TOLERANCE (60 * ODP_TIME_MSEC_IN_NS) Do we know that this is a fix or is it just a guess at a "better" number? It's based on jiffy. It definitely should pass for "normal" platforms w/o impact of Linux scheduler. As we cannot predict the load on system better to have backup, practice says that 1 jiffy is not enough in some cases. The original code used unconditional waits. If the concern is simply to avoid the possibility of indefinite stalls then why try to cut things so close? Nope. Intention here not simply catch indefinite stalls, the intention to check if time sense for scheduler is working in normal ranges. It can differ greatly in case of some incorrect initialization or calculation. This test is going to catch this. Actually, the test caught this bug, this bug is not a bug of test, it's bug of linux-generic implementation when scheduler timeout is corrupted with LK scheduler and it's nice to see this captured here. In the same way it's going to catch issues on "real" boards, where such huge impact can be only in case of incorrect timings. We could agree that a wait of one minute is sufficient to say that something definitely isn't right, but do we care what sort of jitter we may see on a run-by-run basis here? 1 minute is a very huge amount of time. Here I just increased it from 20ms on 5seconds to 60ms on 5seconds. Does it a very small error? It's about 1.2%. But it's not based on percentage currently, it's based on slices the linux kernel scheduler splits time, if you want it can be bound with 10% error for instance. I cannot test and predict this value, no one can, which delays can be on non real time systems. If platform cannot pass this test it definitely should improve it`s timing. For instance, if app decides to wait no more than 100ms, but scheduler waits 150ms, is it normal? Maybe it's normal for linux-generic, but 50ms of waste time it's big amount of time for normal cases. A one minute timeout would mean that tests would always get a result. Implementations that observe waits of that magnitude would clearly be in need of investigation while others would still pass this functional validation. Other tests generate performance numbers and if scheduling waits are unacceptably large they'd be better covered in that context. /* Test global variables */ typedef struct { -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org <mailto: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] [PATCH] validation: scheduler: increase delay tolerance
For some systems sensitive to time deviation, would be better to have some time backup while testing scheduler time, so increase it to 3 jiffies. https://bugs.linaro.org/show_bug.cgi?id=2076 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..cb04209 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -48,7 +48,7 @@ #define CHAOS_NDX_TO_PTR(n) ((void *)(uintptr_t)n) #define CHAOS_WAIT_FAIL (5 * ODP_TIME_SEC_IN_NS) -#define ODP_WAIT_TOLERANCE (20 * ODP_TIME_MSEC_IN_NS) +#define ODP_WAIT_TOLERANCE (60 * ODP_TIME_MSEC_IN_NS) /* Test global variables */ typedef struct { -- 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] doc/users-quide: improve timer API section
Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- doc/users-guide/users-guide.adoc | 49 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index ea5e6aa..108b1c8 100644 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -334,11 +334,50 @@ The +odp_time_t+ opaque type represents local or global timestamps. === Timer Timers are how ODP applications measure and respond to the passage of time. -Timers are drawn from specialized pools called timer pools that have their -own abstract type (+odp_timer_pool_t+). Applications may have many timers -active at the same time and can set them to use either relative or absolute -time. When timers expire they create events of type +odp_timeout_t+, which -serve as notifications of timer expiration. +The timer API is supposed to be used when time synchronization with events is +needed and has different nature than time API has. Timers are drawn from +specialized pools called timer pools that have their own abstract type +(+odp_timer_pool_t+). Applications may have many timers active at the same +time and can set them to use either relative or absolute time. When timers +expire they create events of type +odp_timeout_t+, which serve as notifications +of timer expiration. The event is placed on a queue pointed while timer +allocation. + +Each timer pool can be set with it's own resolution in ns and number of +supported timers. So, timer pool can be considered as time source with +it's own resolution and defined number of timers. All timers in timer pool +are handed with same time source with same resolution. If user needs two types +of timers with different requirements for resolution then better to create +two pools with it's own resolution, it can decrease load on hardware. + +An expiration time for the timer is set in it's own ticks, so nanoseconds have +to be converted first with conversation function +odp_timer_ns_to_tick()+, to +convert it back to ns use +odp_timer_tick_to_ns()+. Both functions require +to pass a timer pool used, as it can be sourced with it's own time source that +can have specific resolution. + +To set a timer to deliver a timeout event the two functions can be used: ++odp_timer_set_abs()+ and +odp_timer_set_rel()+. Both of them require an +event to be passed and a time interval in ticks of corresponding timer pool. +The expiration time for a timer can be set based on current tick value for +a timer pool taken with +odp_timer_current_tick()+, to set a timer +(absolute time) with a user-provided timeout event, the +odp_timer_set_abs()+ +can be used. An event is the event converted from timeout allocated from timeout +pool with +odp_timeout_alloc()+. The event is returned to timer queue when set +time interval has expired and can be also converted to timeout with ++odp_timeout_from_event()+, if it's needed. To free timeout the ++odp_timeout_free()+ can be used, if it's presented as event it can be freed +as event with +odp_event_free()+. + +In general, timer pool characterizes time source, and timer is characterized +with timer pool, user pointer and destination queue for delivering. The timeout +is characterized with timer, timer pool and time of expiration and is placed to +queue set while timer allocation. The timeout can be delivered only to the +destination queue of concrete timer. To get timer generated the timeout the ++odp_timeout_timer()+ can be used. + +When timer is freed it's returned to timer pool and is ready to be allocated +once again. A timer can be canceled with odp_timer_cancel. === Synchronizer Multiple threads operating in parallel typically require various -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: scheduler: correct pause/resume sequence
ping On 16.02.16 16:02, Ivan Khoronzhuk wrote: When test for single thread is finished the following test for many threads can be started, and for some implementations can happen that future one event can arrive to main thread, as it was requested in previous test. As result one event can be lost for rest threads. So, it's better to pause scheduling for main thread when it doesn't participate in the multi-threaded test. Also move pause/resume test closer to beginning, because it's used in tests before. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..c1b61c5 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -1000,6 +1000,8 @@ static void schedule_common(odp_schedule_sync_t sync, int num_queues, args.enable_schd_multi = enable_schd_multi; args.enable_excl_atomic = 0;/* Not needed with a single CPU */ + /* resume scheduling in case it was paused */ + odp_schedule_resume(); fill_queues(); schedule_common_(); @@ -1037,6 +1039,9 @@ static void parallel_execute(odp_schedule_sync_t sync, int num_queues, args->enable_schd_multi = enable_schd_multi; args->enable_excl_atomic = enable_excl_atomic; + /* disable receive events for main thread */ + exit_schedule_loop(); + fill_queues(args); /* Create and launch worker threads */ @@ -1249,6 +1254,9 @@ void scheduler_test_pause_resume(void) int i; int local_bufs = 0; + /* resume scheduling in case it was paused */ + odp_schedule_resume(); + queue = odp_queue_lookup("sched_0_0_n"); CU_ASSERT(queue != ODP_QUEUE_INVALID); @@ -1296,6 +1304,8 @@ void scheduler_test_pause_resume(void) } CU_ASSERT(exit_schedule_loop() == 0); + + odp_schedule_resume(); } static int create_queues(void) @@ -1556,6 +1566,7 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_num_prio), ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), + ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO(scheduler_test_parallel), ODP_TEST_INFO(scheduler_test_atomic), ODP_TEST_INFO(scheduler_test_ordered), @@ -1586,7 +1597,6 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_a), ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_o), ODP_TEST_INFO(scheduler_test_multi_1q_mt_a_excl), - ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO_NULL, }; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] scheduler_test_wait_time() tolerance
On 17.02.16 18:44, Mike Holmes wrote: Does this tuning need to be documented in the implementer's guide ? I thinks, no. On 17 February 2016 at 10:51, Zoltan Kiss <zoltan.k...@linaro.org <mailto:zoltan.k...@linaro.org>> wrote: On 17/02/16 15:24, Ivan Khoronzhuk wrote: Hi, Zoltan On 17.02.16 17:12, Zoltan Kiss wrote: Hi Ivan, I haven an another issue related to time API, which is related to your recent patches, particularly this code: wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS); ... /* check time correctness */ start_time = odp_time_local(); for (i = 1; i < 6; i++) { odp_schedule(, wait_time); printf("%d..", i); } end_time = odp_time_local(); diff = odp_time_diff(end_time, start_time); ... upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + ODP_WAIT_TOLERANCE); ... CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); This assert fails every now and then on ODP-DPDK, because although wait_time is 1 sec, and you call odp_schedule() 5 times, you can't really have any guarantees how long the delay lasts between the subsequent calls, or how long the printf lasts (or the function call overhead). I think we should come up with something more accurate which doesn't produce false positives like this. Regards, Zoltan That's why I'm used WAIT_TOLERANCE in 20ms. That is about 2 context switches. I've tested it on Keystone and on linux-generic. It was enough. If you are testing it on system with more load it's probably not enough. Time spent on printf and schedule calls is not comparable with such time tolerance. Did you try to figure out the real delay it takes with DPDK? Nope, it happens quite rarely in CI, and we don't have too much information about the reasons. I assume it is a momentary higher load on the system. Maybe we should increase it to be 3 or even 4 context switches. Say 40ms, in order to be not so sensitive for some systems. #define ODP_WAIT_TOLERANCE(40 * ODP_TIME_MSEC_IN_NS) Yes, that might help. ___ lng-odp mailing list lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> https://lists.linaro.org/mailman/listinfo/lng-odp -- Mike Holmes Technical Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs "Work should be fun and collborative, the rest follows" __ -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [API-NEXT PATCH] api: time: fix typo for cmp function
Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- include/odp/api/time.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/odp/api/time.h b/include/odp/api/time.h index efc5478..85692ec 100644 --- a/include/odp/api/time.h +++ b/include/odp/api/time.h @@ -119,7 +119,9 @@ odp_time_t odp_time_global_from_ns(uint64_t ns); * @param t2Second time * @param t1First time * - * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1 + * @retval <0 when t2 < t1 + * @retval 0 when t2 == t1 + * @retval >0 when t2 > t1 */ int odp_time_cmp(odp_time_t t2, odp_time_t t1); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] scheduler_test_wait_time() tolerance
Hi, Zoltan On 17.02.16 17:12, Zoltan Kiss wrote: Hi Ivan, I haven an another issue related to time API, which is related to your recent patches, particularly this code: wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS); ... /* check time correctness */ start_time = odp_time_local(); for (i = 1; i < 6; i++) { odp_schedule(, wait_time); printf("%d..", i); } end_time = odp_time_local(); diff = odp_time_diff(end_time, start_time); ... upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + ODP_WAIT_TOLERANCE); ... CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); This assert fails every now and then on ODP-DPDK, because although wait_time is 1 sec, and you call odp_schedule() 5 times, you can't really have any guarantees how long the delay lasts between the subsequent calls, or how long the printf lasts (or the function call overhead). I think we should come up with something more accurate which doesn't produce false positives like this. Regards, Zoltan That's why I'm used WAIT_TOLERANCE in 20ms. That is about 2 context switches. I've tested it on Keystone and on linux-generic. It was enough. If you are testing it on system with more load it's probably not enough. Time spent on printf and schedule calls is not comparable with such time tolerance. Did you try to figure out the real delay it takes with DPDK? Maybe we should increase it to be 3 or even 4 context switches. Say 40ms, in order to be not so sensitive for some systems. #define ODP_WAIT_TOLERANCE (40 * ODP_TIME_MSEC_IN_NS) -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: scheduler: correct pause/resume sequence
When test for single thread is finished the following test for many threads can be started, and for some implementations can happen that future one event can arrive to main thread, as it was requested in previous test. As result one event can be lost for rest threads. So, it's better to pause scheduling for main thread when it doesn't participate in the multi-threaded test. Also move pause/resume test closer to beginning, because it's used in tests before. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index dcf01c0..c1b61c5 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -1000,6 +1000,8 @@ static void schedule_common(odp_schedule_sync_t sync, int num_queues, args.enable_schd_multi = enable_schd_multi; args.enable_excl_atomic = 0;/* Not needed with a single CPU */ + /* resume scheduling in case it was paused */ + odp_schedule_resume(); fill_queues(); schedule_common_(); @@ -1037,6 +1039,9 @@ static void parallel_execute(odp_schedule_sync_t sync, int num_queues, args->enable_schd_multi = enable_schd_multi; args->enable_excl_atomic = enable_excl_atomic; + /* disable receive events for main thread */ + exit_schedule_loop(); + fill_queues(args); /* Create and launch worker threads */ @@ -1249,6 +1254,9 @@ void scheduler_test_pause_resume(void) int i; int local_bufs = 0; + /* resume scheduling in case it was paused */ + odp_schedule_resume(); + queue = odp_queue_lookup("sched_0_0_n"); CU_ASSERT(queue != ODP_QUEUE_INVALID); @@ -1296,6 +1304,8 @@ void scheduler_test_pause_resume(void) } CU_ASSERT(exit_schedule_loop() == 0); + + odp_schedule_resume(); } static int create_queues(void) @@ -1556,6 +1566,7 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_num_prio), ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), + ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO(scheduler_test_parallel), ODP_TEST_INFO(scheduler_test_atomic), ODP_TEST_INFO(scheduler_test_ordered), @@ -1586,7 +1597,6 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_a), ODP_TEST_INFO(scheduler_test_multi_mq_mt_prio_o), ODP_TEST_INFO(scheduler_test_multi_1q_mt_a_excl), - ODP_TEST_INFO(scheduler_test_pause_resume), ODP_TEST_INFO_NULL, }; -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] odp timer thoughts
On 28.01.16 20:31, Maxim Uvarov wrote: I have some thoughts and questions about timer implementation in linux-generic. Current implementation: sigev.sigev_notify = SIGEV_THREAD; sigev.sigev_notify_function = timer_notify; sigev.sigev_value.sival_ptr = tp; timer_create(CLOCK_MONOTONIC, , >timerid); timer create is usually called when timer pool is created. That is mean on the main thread, or control thread. So it can consume only time of a CPU allowed to be used by control thread. The notify function aggregates all scheduled timers from all worker threads and if some is expired then handles it. So, if main thread (control) is assigned only one CPU, the notify function can be run only on this one main thread CPU, the timer_create is executed only in main thread. It's one of the reason I've sent patch series to show how it can be done. See: https://lists.linaro.org/pipermail/lng-odp/2016-January/019734.html [lng-odp] [PATCH 0/2] linux-generic: main control thread on CPU0 [lng-odp] [PATCH 1/2] linux-generic: cpumask_task: use cpumask got at init [lng-odp] [PATCH 2/2] linux-generic: init: assign affinity for main thread The notify function cannot run as signal for each thread as it's handler of all timers in one pool and receives signals one by one. It on system notify function doesn't have enough time to finish notify function, the resolution is set incorrectly. then: timer_settime(tp->timerid, 0, , NULL); where: timer_notify(sigval_t sigval) { uint64_t prev_tick = odp_atomic_fetch_inc_u64(>cur_tick); /* Attempt to acquire the lock, check if the old value was clear */ if (odp_spinlock_trylock(>itimer_running)) { /* Scan timer array, looking for timers to expire */ (void)odp_timer_pool_expire(tp, prev_tick); odp_spinlock_unlock(>itimer_running); } } Now what I see from our test case. 1. We have bunch of workers. 2. Each worker starts timer. 3. Because it's SIGEV_THREAD on timer action new thread for notifier function started. Usually it works well. Until there is load on cpu. (something like busy loop app.) There a lot of threads just created by kernel. I.e. execution clone() call. Based that I have question I have questions which is not quite clear for me: 1. Why SIGEV_THREAD was used? 2. When each worker will run bunch of threads (timer handler), they will fight for cpu time for context switches between all that threads. Is there significant slowdown compare to one thread or signal usage? 3. What is priority of timer handler against to worker? Cpu affinity of handler thread? Should it be SHED_FIFO? I.e. do we need to specify that thread attrs? I think that creation thread each time only for increasing atomic counter is very expensive. So we can rewrite that code to use SIGEV_SIGNAL or start thread manually and SIGEV_THREAD_ID + semaphore. If we will think about core isolation, than probably we have to work with signals. Don't know if core isolation supports several threads on one core. Or even move all timer actions to separate core to not disturb worker cores. Thank you, Maxim. ___ 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] odp timer thoughts
On 28.01.16 20:31, Maxim Uvarov wrote: I have some thoughts and questions about timer implementation in linux-generic. Current implementation: sigev.sigev_notify = SIGEV_THREAD; sigev.sigev_notify_function = timer_notify; sigev.sigev_value.sival_ptr = tp; timer_create(CLOCK_MONOTONIC, , >timerid); then: timer_settime(tp->timerid, 0, , NULL); where: timer_notify(sigval_t sigval) { uint64_t prev_tick = odp_atomic_fetch_inc_u64(>cur_tick); /* Attempt to acquire the lock, check if the old value was clear */ if (odp_spinlock_trylock(>itimer_running)) { /* Scan timer array, looking for timers to expire */ (void)odp_timer_pool_expire(tp, prev_tick); odp_spinlock_unlock(>itimer_running); } } Now what I see from our test case. 1. We have bunch of workers. 2. Each worker starts timer. In case of linux-generic implementation it means simply add one more handler function for the "notify" routine, that is periodically called with resolution rate set at init while timer pool creation. It doesn't start timer. Timer is already running after creation of timer pool. 3. Because it's SIGEV_THREAD on timer action new thread for notifier function started. Usually it works well. Until there is load on cpu. (something like busy loop app.) There a lot of threads just created by kernel. I.e. execution clone() call. Based that I have question I have questions which is not quite clear for me: 1. Why SIGEV_THREAD was used? 2. When each worker will run bunch of threads (timer handler), they will fight for cpu time for context switches between all that threads. Is there significant slowdown compare to one thread or signal usage? 3. What is priority of timer handler against to worker? Cpu affinity of handler thread? Should it be SHED_FIFO? I.e. do we need to specify that thread attrs? I think that creation thread each time only for increasing atomic counter is very expensive. So we can rewrite that code to use SIGEV_SIGNAL or start thread manually and SIGEV_THREAD_ID + semaphore. If we will think about core isolation, than probably we have to work with signals. Don't know if core isolation supports several threads on one core. Or even move all timer actions to separate core to not disturb worker cores. Thank you, Maxim. ___ 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] odp timer thoughts
On 29.01.16 00:54, Bill Fischofer wrote: This is how you implement timers in HW as well. A separate HW block operates a scan loop that constantly searches for timers to expire and creates events for those who do. The rest of the system operates undisturbed. For a SW analog in manycore systems you'd have service thread(s) running on dedicated core(s) doing the same. Actually it can be emulated for linux-generic, but instead of HW block the pool of timers should be handled on one of control CPUS. Each timer pool, no matter, created on main thread or worker thread has to be created with CPU affinity according to control cpumask. Question is only which one and who decides which one, on linux-generic, let it be always CPU0, but with warn that CPU0 can be shared with a worker thread (or maybe exclude it? it was proposed several times already, but rejected). On Thu, Jan 28, 2016 at 12:41 PM, Stuart Haslam <stuart.has...@linaro.org <mailto:stuart.has...@linaro.org>> wrote: On Thu, Jan 28, 2016 at 09:31:52PM +0300, Maxim Uvarov wrote: > I have some thoughts and questions about timer implementation in > linux-generic. > > Current implementation: > > sigev.sigev_notify = SIGEV_THREAD; > sigev.sigev_notify_function = timer_notify; > sigev.sigev_value.sival_ptr = tp; >timer_create(CLOCK_MONOTONIC, , >timerid); > then: > timer_settime(tp->timerid, 0, , NULL); > > where: > timer_notify(sigval_t sigval) > { > uint64_t prev_tick = odp_atomic_fetch_inc_u64(>cur_tick); > /* Attempt to acquire the lock, check if the old value was clear */ > if (odp_spinlock_trylock(>itimer_running)) { > /* Scan timer array, looking for timers to expire */ > (void)odp_timer_pool_expire(tp, prev_tick); > odp_spinlock_unlock(>itimer_running); > } > > } > > Now what I see from our test case. > 1. We have bunch of workers. > 2. Each worker starts timer. > 3. Because it's SIGEV_THREAD on timer action new thread for notifier > function started. > > Usually it works well. Until there is load on cpu. (something like > busy loop app.) There a lot of threads > just created by kernel. I.e. execution clone() call. > > Based that I have question I have questions which is not quite clear for me: > 1. Why SIGEV_THREAD was used? > > 2. When each worker will run bunch of threads (timer handler), they > will fight for cpu time for context > switches between all that threads. Is there significant slowdown > compare to one thread or signal usage? > > 3. What is priority of timer handler against to worker? Cpu affinity > of handler thread? Should it > be SHED_FIFO? I.e. do we need to specify that thread attrs? > > I think that creation thread each time only for increasing atomic > counter is very expensive. So we can > rewrite that code to use SIGEV_SIGNAL or start thread manually and > SIGEV_THREAD_ID + semaphore. > > If we will think about core isolation, than probably we have to work > with signals. Don't know if core isolation > supports several threads on one core. Or even move all timer actions > to separate core to not disturb worker > cores. > > Thank you, > Maxim. +1 This is basically what was suggested here: https://bugs.linaro.org/show_bug.cgi?id=1615#c18 -- Stuart. ___ lng-odp mailing list lng-odp@lists.linaro.org <mailto: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] [API-NEXT PATCHv2] validation: timer: fix delay after loop
On 26.01.16 17:46, Maxim Uvarov wrote: Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/timer/timer.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index 5d89700..0bd67fb 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -405,12 +405,14 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) thr, nstale); /* Delay some more to ensure timeouts for expired timers can be -* received */ +* received. Can not use busy loop here to make background timer +* thread finish their work. */ struct timespec ts; ts.tv_sec = 0; - ts.tv_nsec = 100; /* 1ms */ + ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); + while (nstale != 0) { odp_event_t ev = odp_queue_deq(queue); if (ev != ODP_EVENT_INVALID) { -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: shmem: sync threads with barrier
It's not convenient to see reused a thread id for threads that are finished to fast. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/shmem/shmem.c | 4 1 file changed, 4 insertions(+) diff --git a/test/validation/shmem/shmem.c b/test/validation/shmem/shmem.c index 5524b5c..bb7b424 100644 --- a/test/validation/shmem/shmem.c +++ b/test/validation/shmem/shmem.c @@ -13,6 +13,8 @@ #define TEST_SHARE_FOO (0xf0f0f0f0) #define TEST_SHARE_BAR (0xf0f0f0f) +static odp_barrier_t test_barrier; + static void *run_shm_thread(void *arg) { odp_shm_info_t info; @@ -20,6 +22,7 @@ static void *run_shm_thread(void *arg) test_shared_data_t *test_shared_data; int thr; + odp_barrier_wait(_barrier); thr = odp_thread_id(); printf("Thread %i starts\n", thr); @@ -72,6 +75,7 @@ void shmem_test_odp_shm_sunnyday(void) if (thrdarg.numthrds > MAX_WORKERS) thrdarg.numthrds = MAX_WORKERS; + odp_barrier_init(test_barrier, thrdarg.numthrds); odp_cunit_thread_create(run_shm_thread, ); odp_cunit_thread_exit(); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: shmem: sync threads with barrier
see v2 On 22.01.16 20:09, Ivan Khoronzhuk wrote: It's not convenient to see reused a thread id for threads that are finished to fast. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/shmem/shmem.c | 4 1 file changed, 4 insertions(+) diff --git a/test/validation/shmem/shmem.c b/test/validation/shmem/shmem.c index 5524b5c..bb7b424 100644 --- a/test/validation/shmem/shmem.c +++ b/test/validation/shmem/shmem.c @@ -13,6 +13,8 @@ #define TEST_SHARE_FOO (0xf0f0f0f0) #define TEST_SHARE_BAR (0xf0f0f0f) +static odp_barrier_t test_barrier; + static void *run_shm_thread(void *arg) { odp_shm_info_t info; @@ -20,6 +22,7 @@ static void *run_shm_thread(void *arg) test_shared_data_t *test_shared_data; int thr; + odp_barrier_wait(_barrier); thr = odp_thread_id(); printf("Thread %i starts\n", thr); @@ -72,6 +75,7 @@ void shmem_test_odp_shm_sunnyday(void) if (thrdarg.numthrds > MAX_WORKERS) thrdarg.numthrds = MAX_WORKERS; + odp_barrier_init(test_barrier, thrdarg.numthrds); odp_cunit_thread_create(run_shm_thread, ); odp_cunit_thread_exit(); } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2] validation: shmem: sync threads with barrier
It's not convenient to see reused a thread id for threads that are finished to fast. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/shmem/shmem.c | 4 1 file changed, 4 insertions(+) diff --git a/test/validation/shmem/shmem.c b/test/validation/shmem/shmem.c index 5524b5c..08425e6 100644 --- a/test/validation/shmem/shmem.c +++ b/test/validation/shmem/shmem.c @@ -13,6 +13,8 @@ #define TEST_SHARE_FOO (0xf0f0f0f0) #define TEST_SHARE_BAR (0xf0f0f0f) +static odp_barrier_t test_barrier; + static void *run_shm_thread(void *arg) { odp_shm_info_t info; @@ -20,6 +22,7 @@ static void *run_shm_thread(void *arg) test_shared_data_t *test_shared_data; int thr; + odp_barrier_wait(_barrier); thr = odp_thread_id(); printf("Thread %i starts\n", thr); @@ -72,6 +75,7 @@ void shmem_test_odp_shm_sunnyday(void) if (thrdarg.numthrds > MAX_WORKERS) thrdarg.numthrds = MAX_WORKERS; + odp_barrier_init(_barrier, thrdarg.numthrds); odp_cunit_thread_create(run_shm_thread, ); odp_cunit_thread_exit(); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: scheduler: tune resource usage
The scheduler test should test scheduler, not resource limits. For instance, prio_num * QUEUES_PER_PRIO * 4. In case if prio_num = 16, it's easily exits the queues maximum number allowed, 16 * 16 * 4 = 1024, plus queues created for other purposes, it can be close to ODP_CONFIG_QUEUES. The same for allocated bufs num, that is prio_num * QUEUES_PER_PRIO * TEST_NUM_BUFS. It's h/w dependent, and should be in normal frames. This patch tunes resource usage in order to allow test passing for different h/w. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index ea246d4..100a627 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -9,12 +9,12 @@ #include "scheduler.h" #define MAX_WORKERS_THREADS32 -#define MSG_POOL_SIZE (4 * 1024 * 1024) -#define QUEUES_PER_PRIO16 +#define MSG_POOL_SIZE (400 * 1024) +#define QUEUES_PER_PRIO8 #define BUF_SIZE 64 -#define TEST_NUM_BUFS 100 +#define TEST_NUM_BUFS 48 #define BURST_BUF_SIZE 4 -#define NUM_BUFS_EXCL 1 +#define NUM_BUFS_EXCL 48 #define NUM_BUFS_PAUSE 1000 #define NUM_BUFS_BEFORE_PAUSE 10 -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH 1/2] linux-generic: cpumask_task: use cpumask got at init
It's not correct to read affinity each time to get worker cpumask. The affinity for main thread can be changed, but cpunum is still for old cpumask. So, better to remember at init cpumask for available cpus and then use it, thus, if main thread changed it`s affinity, the available CPUs are still the same. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp_internal.h | 3 +++ platform/linux-generic/odp_cpumask_task.c | 9 +++-- platform/linux-generic/odp_system_info.c | 22 ++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index b22f956..b795af6 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -20,6 +20,7 @@ extern "C" { #include #include +#include extern __thread int __odp_errno; @@ -30,6 +31,7 @@ typedef struct { int cache_line_size; int cpu_count; char model_str[128]; + cpu_set_t cpuset; } odp_system_info_t; struct odp_global_data_s { @@ -61,6 +63,7 @@ int _odp_term_local(enum init_stage stage); int odp_system_info_init(void); int odp_system_info_term(void); +cpu_set_t _odp_cpuset(void); int odp_thread_init_global(void); int odp_thread_init_local(odp_thread_type_t type); diff --git a/platform/linux-generic/odp_cpumask_task.c b/platform/linux-generic/odp_cpumask_task.c index 41f2bc9..43a5281 100644 --- a/platform/linux-generic/odp_cpumask_task.c +++ b/platform/linux-generic/odp_cpumask_task.c @@ -10,19 +10,16 @@ #include #include +#include #include int odp_cpumask_default_worker(odp_cpumask_t *mask, int num) { - int ret, cpu, i; + int cpu, i; cpu_set_t cpuset; - ret = pthread_getaffinity_np(pthread_self(), -sizeof(cpu_set_t), ); - if (ret != 0) - ODP_ABORT("failed to read CPU affinity value\n"); - odp_cpumask_zero(mask); + cpuset = _odp_cpuset(); /* * If no user supplied number or it's too large, then attempt diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index a948fce..395e6b7 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -24,8 +24,6 @@ #include #include - - typedef struct { const char *cpu_arch_str; int (*cpuinfo_parser)(FILE *file, odp_system_info_t *sysinfo); @@ -41,17 +39,20 @@ typedef struct { /* * Report the number of CPUs in the affinity mask of the main thread */ -static int sysconf_cpu_count(void) +static int sysconf_cpu_count(cpu_set_t *cpuset) { - cpu_set_t cpuset; + cpu_set_t tmp; int ret; + CPU_ZERO(); ret = pthread_getaffinity_np(pthread_self(), -sizeof(cpuset), ); +sizeof(cpuset), ); if (ret != 0) return 0; - return CPU_COUNT(); + *cpuset = tmp; + + return CPU_COUNT(cpuset); } #if defined __x86_64__ || defined __i386__ || defined __OCTEON__ || \ @@ -282,7 +283,7 @@ static int systemcpu(odp_system_info_t *sysinfo) { int ret; - ret = sysconf_cpu_count(); + ret = sysconf_cpu_count(>cpuset); if (ret == 0) { ODP_ERR("sysconf_cpu_count failed.\n"); return -1; @@ -320,7 +321,7 @@ static int systemcpu(odp_system_info_t *sysinfo) { int ret; - ret = sysconf_cpu_count(); + ret = sysconf_cpu_count(>cpuset); if (ret == 0) { ODP_ERR("sysconf_cpu_count failed.\n"); return -1; @@ -370,6 +371,11 @@ int odp_system_info_init(void) return 0; } +cpu_set_t _odp_cpuset(void) +{ + return odp_global_data.system_info.cpuset; +} + /* * System info termination */ -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH 0/2] linux-generic: main control thread on CPU0
This patch series is intended to run control thread on CPU0. It's increases worker thread CPU independence and allow to use local time API on main thread in correct way. Ivan Khoronzhuk (2): linux-generic: cpumask_task: use cpumask got at init linux-generic: init: assign affinity for main thread platform/linux-generic/include/odp_internal.h | 3 ++ platform/linux-generic/odp_cpumask_task.c | 9 ++--- platform/linux-generic/odp_init.c | 50 --- platform/linux-generic/odp_system_info.c | 22 +++- 4 files changed, 57 insertions(+), 27 deletions(-) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2] example: timer: free resources while termination
sent v3. On 17.12.15 19:07, Ivan Khoronzhuk wrote: Example should free resources in right order when terminates. Also it should have correct error path. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v1: Just rebase, no functional changes example/timer/odp_timer_test.c | 46 ++ 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index b7a4fd2..cb0d955 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -334,18 +334,21 @@ int main(int argc, char *argv[]) char cpumaskstr[ODP_CPUMASK_STR_SIZE]; odp_shm_t shm; test_globals_t *gbls; + int err = 0; printf("\nODP timer example starts\n"); if (odp_init_global(NULL, NULL)) { + err = 1; printf("ODP global init failed.\n"); - return -1; + goto err; } /* Init this thread. */ if (odp_init_local(ODP_THREAD_CONTROL)) { + err = 1; printf("ODP local init failed.\n"); - return -1; + goto err_global; } printf("\n"); @@ -363,14 +366,16 @@ int main(int argc, char *argv[]) shm = odp_shm_reserve("shm_test_globals", sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 0); if (ODP_SHM_INVALID == shm) { + err = 1; EXAMPLE_ERR("Error: shared mem reserve failed.\n"); - return -1; + goto err_local; } gbls = odp_shm_addr(shm); if (NULL == gbls) { + err = 1; EXAMPLE_ERR("Error: shared mem alloc failed.\n"); - return -1; + goto err_shm; } memset(gbls, 0, sizeof(test_globals_t)); @@ -407,8 +412,9 @@ int main(int argc, char *argv[]) gbls->pool = odp_pool_create("msg_pool", ); if (gbls->pool == ODP_POOL_INVALID) { + err = 1; EXAMPLE_ERR("Pool create failed.\n"); - return -1; + goto err_shm; } tparams.res_ns = gbls->args.resolution_us * ODP_TIME_USEC_IN_NS; @@ -419,8 +425,9 @@ int main(int argc, char *argv[]) tparams.clk_src = ODP_CLOCK_CPU; gbls->tp = odp_timer_pool_create("timer_pool", ); if (gbls->tp == ODP_TIMER_POOL_INVALID) { + err = 1; EXAMPLE_ERR("Timer pool create failed.\n"); - return -1; + goto err_msg_pool; } odp_timer_pool_start(); @@ -445,8 +452,9 @@ int main(int argc, char *argv[]) queue = odp_queue_create("timer_queue", ODP_QUEUE_TYPE_SCHED, ); if (queue == ODP_QUEUE_INVALID) { + err = 1; EXAMPLE_ERR("Timer queue create failed.\n"); - return -1; + goto err_timer_pool; } printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); @@ -484,7 +492,29 @@ int main(int argc, char *argv[]) /* Wait for worker threads to exit */ odph_linux_pthread_join(thread_tbl, num_workers); - printf("ODP timer test complete\n\n"); + /* free resources */ + if (odp_queue_destroy(queue)) + err = 1; +err_timer_pool: + odp_timer_pool_destroy(gbls->tp); +err_msg_pool: + if (odp_pool_destroy(gbls->pool)) + err = 1; +err_shm: + if (odp_shm_free(shm)) + err = 1; +err_local: + if (odp_term_local()) + err = 1; +err_global: + if (odp_term_global()) + err = 1; +err: + if (err) { + printf("Err: ODP timer test failed\n\n"); + return -1; + } + printf("ODP timer test complete\n\n"); return 0; } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] linux-generic: timer: limit notification about resolution incorrectness
https://bugs.linaro.org/show_bug.cgi?id=1992 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_timer.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 4bab481..01339ad 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -168,6 +168,7 @@ typedef struct odp_timer_pool_s { char name[ODP_TIMER_POOL_NAME_LEN]; odp_shm_t shm; timer_t timerid; + int notify_overrun; } odp_timer_pool; #define MAX_TIMER_POOLS 255 /* Leave one for ODP_TIMER_INVALID */ @@ -239,6 +240,7 @@ static odp_timer_pool *odp_timer_pool_new( tp->num_alloc = 0; odp_atomic_init_u32(>high_wm, 0); tp->first_free = 0; + tp->notify_overrun = 1; tp->tick_buf = (void *)((char *)odp_shm_addr(shm) + sz0); tp->timers = (void *)((char *)odp_shm_addr(shm) + sz0 + sz1); /* Initialize all odp_timer entries */ @@ -635,10 +637,14 @@ static void timer_notify(sigval_t sigval) int overrun; odp_timer_pool *tp = (odp_timer_pool *)sigval.sival_ptr; - overrun = timer_getoverrun(tp->timerid); - if (overrun) - ODP_ERR("\n\t%d ticks overrun on timer pool \"%s\", timer resolution too high\n", - overrun, tp->name); + if (tp->notify_overrun) { + overrun = timer_getoverrun(tp->timerid); + if (overrun) { + ODP_ERR("\n\t%d ticks overrun on timer pool \"%s\", timer resolution too high\n", + overrun, tp->name); + tp->notify_overrun = 0; + } + } #ifdef __ARM_ARCH odp_timer *array = >timers[0]; -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] linux-generic: timer: limit notification about resolution incorrectness
+ Stuart Haslam On 22.01.16 17:07, Ivan Khoronzhuk wrote: https://bugs.linaro.org/show_bug.cgi?id=1992 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_timer.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 4bab481..01339ad 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -168,6 +168,7 @@ typedef struct odp_timer_pool_s { char name[ODP_TIMER_POOL_NAME_LEN]; odp_shm_t shm; timer_t timerid; + int notify_overrun; } odp_timer_pool; #define MAX_TIMER_POOLS 255 /* Leave one for ODP_TIMER_INVALID */ @@ -239,6 +240,7 @@ static odp_timer_pool *odp_timer_pool_new( tp->num_alloc = 0; odp_atomic_init_u32(>high_wm, 0); tp->first_free = 0; + tp->notify_overrun = 1; tp->tick_buf = (void *)((char *)odp_shm_addr(shm) + sz0); tp->timers = (void *)((char *)odp_shm_addr(shm) + sz0 + sz1); /* Initialize all odp_timer entries */ @@ -635,10 +637,14 @@ static void timer_notify(sigval_t sigval) int overrun; odp_timer_pool *tp = (odp_timer_pool *)sigval.sival_ptr; - overrun = timer_getoverrun(tp->timerid); - if (overrun) - ODP_ERR("\n\t%d ticks overrun on timer pool \"%s\", timer resolution too high\n", - overrun, tp->name); + if (tp->notify_overrun) { + overrun = timer_getoverrun(tp->timerid); + if (overrun) { + ODP_ERR("\n\t%d ticks overrun on timer pool \"%s\", timer resolution too high\n", + overrun, tp->name); + tp->notify_overrun = 0; + } + } #ifdef __ARM_ARCH odp_timer *array = >timers[0]; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3] example: timer: free resources while termination
Example should free resources in right order when terminates. Also it should have correct error path. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v2: use less labels in one error path Since v1: Just rebase, no functional changes example/timer/odp_timer_test.c | 57 ++ 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index b7a4fd2..6d89713 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -332,20 +332,23 @@ int main(int argc, char *argv[]) odp_timer_pool_info_t tpinfo; odp_cpumask_t cpumask; char cpumaskstr[ODP_CPUMASK_STR_SIZE]; - odp_shm_t shm; - test_globals_t *gbls; + odp_shm_t shm = ODP_SHM_INVALID; + test_globals_t *gbls = NULL; + int err = 0; printf("\nODP timer example starts\n"); if (odp_init_global(NULL, NULL)) { + err = 1; printf("ODP global init failed.\n"); - return -1; + goto err_global; } /* Init this thread. */ if (odp_init_local(ODP_THREAD_CONTROL)) { + err = 1; printf("ODP local init failed.\n"); - return -1; + goto err_local; } printf("\n"); @@ -363,16 +366,20 @@ int main(int argc, char *argv[]) shm = odp_shm_reserve("shm_test_globals", sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 0); if (ODP_SHM_INVALID == shm) { + err = 1; EXAMPLE_ERR("Error: shared mem reserve failed.\n"); - return -1; + goto err; } gbls = odp_shm_addr(shm); if (NULL == gbls) { + err = 1; EXAMPLE_ERR("Error: shared mem alloc failed.\n"); - return -1; + goto err; } memset(gbls, 0, sizeof(test_globals_t)); + gbls->pool = ODP_POOL_INVALID; + gbls->tp = ODP_TIMER_POOL_INVALID; parse_args(argc, argv, >args); @@ -407,8 +414,9 @@ int main(int argc, char *argv[]) gbls->pool = odp_pool_create("msg_pool", ); if (gbls->pool == ODP_POOL_INVALID) { + err = 1; EXAMPLE_ERR("Pool create failed.\n"); - return -1; + goto err; } tparams.res_ns = gbls->args.resolution_us * ODP_TIME_USEC_IN_NS; @@ -419,8 +427,9 @@ int main(int argc, char *argv[]) tparams.clk_src = ODP_CLOCK_CPU; gbls->tp = odp_timer_pool_create("timer_pool", ); if (gbls->tp == ODP_TIMER_POOL_INVALID) { + err = 1; EXAMPLE_ERR("Timer pool create failed.\n"); - return -1; + goto err; } odp_timer_pool_start(); @@ -445,8 +454,9 @@ int main(int argc, char *argv[]) queue = odp_queue_create("timer_queue", ODP_QUEUE_TYPE_SCHED, ); if (queue == ODP_QUEUE_INVALID) { + err = 1; EXAMPLE_ERR("Timer queue create failed.\n"); - return -1; + goto err; } printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); @@ -484,7 +494,34 @@ int main(int argc, char *argv[]) /* Wait for worker threads to exit */ odph_linux_pthread_join(thread_tbl, num_workers); - printf("ODP timer test complete\n\n"); + /* free resources */ + if (odp_queue_destroy(queue)) + err = 1; +err: + + if (gbls != NULL && gbls->tp != ODP_TIMER_POOL_INVALID) + odp_timer_pool_destroy(gbls->tp); + + if (gbls != NULL && gbls->pool != ODP_TIMER_POOL_INVALID) + if (odp_pool_destroy(gbls->pool)) + err = 1; + + if (shm != ODP_SHM_INVALID) + if (odp_shm_free(shm)) + err = 1; + + if (odp_term_local()) + err = 1; +err_local: + if (odp_term_global()) + err = 1; +err_global: + if (err) { + printf("Err: ODP timer test failed\n\n"); + return -1; + } + + printf("ODP timer test complete\n\n"); return 0; } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: scheduler: tune resource usage
sent patch with corrected tag On 22.01.16 12:24, Ivan Khoronzhuk wrote: The scheduler test should test scheduler, not resource limits. For instance, prio_num * QUEUES_PER_PRIO * 4. In case if prio_num = 16, it's easily exits the queues maximum number allowed, 16 * 16 * 4 = 1024, plus queues created for other purposes, it can be close to ODP_CONFIG_QUEUES. The same for allocated bufs num, that is prio_num * QUEUES_PER_PRIO * TEST_NUM_BUFS. It's h/w dependent, and should be in normal frames. This patch tunes resource usage in order to allow test passing for different h/w. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index ea246d4..100a627 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -9,12 +9,12 @@ #include "scheduler.h" #define MAX_WORKERS_THREADS 32 -#define MSG_POOL_SIZE (4 * 1024 * 1024) -#define QUEUES_PER_PRIO16 +#define MSG_POOL_SIZE (400 * 1024) +#define QUEUES_PER_PRIO8 #define BUF_SIZE 64 -#define TEST_NUM_BUFS 100 +#define TEST_NUM_BUFS 48 #define BURST_BUF_SIZE4 -#define NUM_BUFS_EXCL 1 +#define NUM_BUFS_EXCL 48 #define NUM_BUFS_PAUSE1000 #define NUM_BUFS_BEFORE_PAUSE 10 -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: scheduler: tune resource usage
The scheduler test should test scheduler, not resource limits. For instance, prio_num * QUEUES_PER_PRIO * 4. In case if prio_num = 16, it's easily exits the queues maximum number allowed, 16 * 16 * 4 = 1024, plus queues created for other purposes, it can be close to ODP_CONFIG_QUEUES. The same for allocated bufs num, that is prio_num * QUEUES_PER_PRIO * TEST_NUM_BUFS. It's h/w dependent, and should be in normal frames. This patch tunes resource usage in order to allow test passing for different h/w. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index ea246d4..100a627 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -9,12 +9,12 @@ #include "scheduler.h" #define MAX_WORKERS_THREADS32 -#define MSG_POOL_SIZE (4 * 1024 * 1024) -#define QUEUES_PER_PRIO16 +#define MSG_POOL_SIZE (400 * 1024) +#define QUEUES_PER_PRIO8 #define BUF_SIZE 64 -#define TEST_NUM_BUFS 100 +#define TEST_NUM_BUFS 48 #define BURST_BUF_SIZE 4 -#define NUM_BUFS_EXCL 1 +#define NUM_BUFS_EXCL 48 #define NUM_BUFS_PAUSE 1000 #define NUM_BUFS_BEFORE_PAUSE 10 -- 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 PATCHv1 1/4] api: classification: add pmr create api
+ list On 22.01.16 17:46, Ivan Khoronzhuk wrote: It discussed several times when started to look at it and Bill proposed to add some cls environment. Finally, it's sent. After this change PMR is created while connection to CoSes, and it's eliminates ability to connect the same PMR to several CoSes (which may arise questions...), and maps PMR handle directly to physical rule. It greatly simplifies life for implementors. On 22.01.16 13:54, Balasubramanian Manoharan wrote: Packet match rule creation is modified to include source and destination class of service. Removes the ability to add any class of service directly with pktio. If a PMR needs to be applied at the pktio level the same should be applied to default class of service. Packet match rule destroy function is updated to removes the link between the source and destination class of service. Signed-off-by: Balasubramanian Manoharan <bala.manoha...@linaro.org> --- include/odp/api/classification.h | 74 +--- 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h index f46912e..59bd01d 100644 --- a/include/odp/api/classification.h +++ b/include/odp/api/classification.h @@ -50,7 +50,7 @@ extern "C" { /** * @def ODP_PMR_INVAL * Invalid odp_pmr_t value. - * This value is returned from odp_pmr_create() + * This value is returned from odp_cls_pmr_create() * function on failure. */ @@ -286,50 +286,33 @@ typedef struct odp_pmr_match_t { } odp_pmr_match_t; /** - * Create a packet match rule with mask and value + * Create a packet match rule between source and destination class of service. + * This packet matching rule is applied on all packets arriving at the source + * class of service and packets satisfying this PMR are sent to the destination + * class of service. * * @param[in]match packet matching rule definition + * @param[in]src_cossource CoS handle + * @param[in]dst_cosdestination CoS handle * * @returnHandle of the matching rule * @retvalODP_PMR_INVAL on failure */ -odp_pmr_t odp_pmr_create(const odp_pmr_match_t *match); - +odp_pmr_t odp_cls_pmr_create(const odp_pmr_match_t *match, odp_cos_t src_cos, + odp_cos_t dst_cos); /** - * Invalidate a packet match rule and vacate its resources + * Function to destroy a packet match rule + * Destroying a PMR removes the link between the source and destination + * class of service and this PMR will no longer be applied for packets arriving + * at the source class of service. All the resource associated with the PMR + * be release but the class of service will remain intact. * * @param[in]pmr_idIdentifier of the PMR to be destroyed * * @retval0 on success * @retval<0 on failure */ -int odp_pmr_destroy(odp_pmr_t pmr_id); - -/** - * Apply a PMR to a pktio to assign a CoS. - * - * @param[in]pmr_idPMR to be activated - * @param[in]src_pktiopktio to which this PMR is to be applied - * @param[in]dst_cosCoS to be assigned by this PMR - * - * @retval0 on success - * @retval<0 on failure - */ -int odp_pktio_pmr_cos(odp_pmr_t pmr_id, - odp_pktio_t src_pktio, odp_cos_t dst_cos); - -/** - * Cascade a PMR to refine packets from one CoS to another. - * - * @param[in]pmr_idPMR to be activated - * @param[in]src_cosCoS to be filtered - * @param[in]dst_cosCoS to be assigned to packets filtered - *from src_cos that match pmr_id. - * - * @retval0 on success - * @retval<0 on failure - */ -int odp_cos_pmr_cos(odp_pmr_t pmr_id, odp_cos_t src_cos, odp_cos_t dst_cos); +int odp_cls_pmr_destroy(odp_pmr_t pmr_id); /** * Inquire about matching terms supported by the classifier @@ -357,19 +340,24 @@ unsigned odp_pmr_terms_avail(void); * of value match rules, and the application should take care * of inspecting the return value when installing such rules, and perform * appropriate fallback action. + * This is same as odp_cls_pmr_create() except that it creates the link + * using pmr match set instead of a single PMR. * * @param[in]num_termsNumber of terms in the match rule. * @param[in]termsArray of num_terms entries, one entry per *term desired. * @param[out]pmr_set_idReturned handle to the composite rule set. + * @param[in]src_cossource CoS handle + * @param[in]dst_cosdestination CoS handle * * @returnthe number of terms elements *that have been successfully mapped to the *underlying platform classification engine * @retval<0 on failure */ -int odp_pmr_match_set_create(int num_terms, const odp_pmr_match_t *terms, - odp_
Re: [lng-odp] [API-NEXT PATCH] validation: scheduler: add timing tests for scheduled queue types
lel), + ODP_TEST_INFO(scheduler_test_atomic), + ODP_TEST_INFO(scheduler_test_ordered), ODP_TEST_INFO(scheduler_test_1q_1t_n), ODP_TEST_INFO(scheduler_test_1q_1t_a), ODP_TEST_INFO(scheduler_test_1q_1t_o), diff --git a/test/validation/scheduler/scheduler.h b/test/validation/scheduler/scheduler.h index bba79aa..cd69e92 100644 --- a/test/validation/scheduler/scheduler.h +++ b/test/validation/scheduler/scheduler.h @@ -15,6 +15,9 @@ void scheduler_test_num_prio(void); void scheduler_test_queue_destroy(void); void scheduler_test_groups(void); void scheduler_test_chaos(void); +void scheduler_test_parallel(void); +void scheduler_test_atomic(void); +void scheduler_test_ordered(void); void scheduler_test_1q_1t_n(void); void scheduler_test_1q_1t_a(void); void scheduler_test_1q_1t_o(void); -- 2.5.0 _______ 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] [API-NEXT PATCH] validation: scheduler: add timing tests for scheduled queue types
On 20.01.16 21:43, Ivan Khoronzhuk wrote: On 20.01.16 18:58, Bill Fischofer wrote: ping. On Wed, Dec 30, 2015 at 5:49 PM, Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>> wrote: Expand the existing scheduler chaos test to provide timing information for mixed queues as well as individual timings for parallel, atomic, and ordered queues. This enables implementation scheduling efficiency to be displayed by queue type. Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>> Please, decrease CHAOS_NUM_ROUNDS, say 1000. That's more then enough. Especially now, when it's multiplied on 4 with number of tests. Also, see below. --- test/validation/scheduler/scheduler.c | 51 ++- test/validation/scheduler/scheduler.h | 3 +++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 7ba6a06..d5842de 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -451,12 +451,14 @@ static void *chaos_thread(void *arg) thread_args_t *args = (thread_args_t *)arg; test_globals_t *globals = args->globals; int me = odp_thread_id(); + odp_time_t start_time, end_time, diff; if (CHAOS_DEBUG) printf("Chaos thread %d starting...\n", me); /* Wait for all threads to start */ odp_barrier_wait(>barrier); + start_time = odp_time_local(); /* Run the test */ wait = odp_schedule_wait_time(CHAOS_WAIT_FAIL); @@ -508,10 +510,16 @@ static void *chaos_thread(void *arg) odp_event_free(ev); } + end_time = odp_time_local(); + diff = odp_time_diff(end_time, start_time); + + printf("Thread %d ends, elapsed time = %" PRIu64 "us\n", + odp_thread_id(), odp_time_to_ns(diff) / 1000); + return NULL; } -void scheduler_test_chaos(void) +static void chaos_run(unsigned int qtype) { odp_pool_t pool; odp_pool_param_t params; @@ -557,11 +565,19 @@ void scheduler_test_chaos(void) qp.sched.prio = ODP_SCHED_PRIO_DEFAULT; for (i = 0; i < CHAOS_NUM_QUEUES; i++) { - qp.sched.sync = sync[i % num_sync]; - snprintf(globals->chaos_q[i].name, -sizeof(globals->chaos_q[i].name), -"chaos queue %d - %s", i, -qtypes[i % num_sync]); + if (qtype == num_sync) { + qp.sched.sync = sync[i % num_sync]; + snprintf(globals->chaos_q[i].name, +sizeof(globals->chaos_q[i].name), +"chaos queue %d - %s", i, +qtypes[i % num_sync]); + } else { + qp.sched.sync = sync[qtype]; + snprintf(globals->chaos_q[i].name, +sizeof(globals->chaos_q[i].name), +"chaos queue %d - %s", i, +qtypes[qtype]); + } unsigned int qtype_num; qtype_num = qtype == num_sync ? i % num_sync : qtype; qp.sched.sync = sync[qtype_num]; snprintf(globals->chaos_q[i].name, sizeof(globals->chaos_q[i].name), "chaos queue %d - %s", i, qtypes[qtype_num]); globals->chaos_q[i].handle = odp_queue_create(globals->chaos_q[i].name, ODP_QUEUE_TYPE_SCHED, @@ -630,6 +646,26 @@ void scheduler_test_chaos(void) CU_ASSERT(rc == 0); } +void scheduler_test_chaos(void) +{ + chaos_run(3); +} + +void scheduler_test_parallel(void) +{ + chaos_run(0); +} + +void scheduler_test_atomic(void) +{ + chaos_run(1); +} + +void scheduler_test_ordered(void) +{ + chaos_run(2); +} + static void *schedule_common_(void *arg) { thread_args_t *args = (thread_args_t *)arg; @@ -1521,6 +1557,9 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), ODP_TEST_INFO(scheduler_test_chaos), better to be after *_test_ordered test. + ODP_TEST_INFO
Re: [lng-odp] [PATCH] validation: pktio: fix check of pktio_stop() called twice
ping On 13.01.16 19:38, Ivan Khoronzhuk wrote: The odp_pktio_stop() called is supposed to return error. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 29ad4ea..1ca4979 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -737,7 +737,7 @@ void pktio_test_start_stop(void) /* Interfaces are stopped by default, * Check that stop when stopped generates an error */ ret = odp_pktio_stop(pktio[0]); - CU_ASSERT(ret <= 0); + CU_ASSERT(ret < 0); /* start first */ ret = odp_pktio_start(pktio[0]); -- 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 PATCHv3] validation: scheduler: add timing tests for scheduled queue types
On 21.01.16 00:25, Bill Fischofer wrote: Expand the existing scheduler chaos test to provide timing information for mixed queues as well as individual timings for parallel, atomic, and ordered queues. This enables implementation scheduling efficiency to be displayed by queue type. Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 41 +++ test/validation/scheduler/scheduler.h | 3 +++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 7ba6a06..ea246d4 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -41,7 +41,7 @@ #define CHAOS_NUM_QUEUES 6 #define CHAOS_NUM_BUFS_PER_QUEUE 6 -#define CHAOS_NUM_ROUNDS 5 +#define CHAOS_NUM_ROUNDS 1000 #define CHAOS_NUM_EVENTS (CHAOS_NUM_QUEUES * CHAOS_NUM_BUFS_PER_QUEUE) #define CHAOS_DEBUG (CHAOS_NUM_ROUNDS < 1000) #define CHAOS_PTR_TO_NDX(p) ((uint64_t)(uint32_t)(uintptr_t)p) @@ -451,12 +451,14 @@ static void *chaos_thread(void *arg) thread_args_t *args = (thread_args_t *)arg; test_globals_t *globals = args->globals; int me = odp_thread_id(); + odp_time_t start_time, end_time, diff; if (CHAOS_DEBUG) printf("Chaos thread %d starting...\n", me); /* Wait for all threads to start */ odp_barrier_wait(>barrier); + start_time = odp_time_local(); /* Run the test */ wait = odp_schedule_wait_time(CHAOS_WAIT_FAIL); @@ -508,10 +510,16 @@ static void *chaos_thread(void *arg) odp_event_free(ev); } + end_time = odp_time_local(); + diff = odp_time_diff(end_time, start_time); + + printf("Thread %d ends, elapsed time = %" PRIu64 "us\n", + odp_thread_id(), odp_time_to_ns(diff) / 1000); + return NULL; } -void scheduler_test_chaos(void) +static void chaos_run(unsigned int qtype) { odp_pool_t pool; odp_pool_param_t params; @@ -557,11 +565,13 @@ void scheduler_test_chaos(void) qp.sched.prio = ODP_SCHED_PRIO_DEFAULT; for (i = 0; i < CHAOS_NUM_QUEUES; i++) { - qp.sched.sync = sync[i % num_sync]; + uint32_t ndx = qtype == num_sync ? i % num_sync : qtype; + qp.sched.sync = sync[ndx]; snprintf(globals->chaos_q[i].name, sizeof(globals->chaos_q[i].name), "chaos queue %d - %s", i, -qtypes[i % num_sync]); +qtypes[ndx]); + globals->chaos_q[i].handle = odp_queue_create(globals->chaos_q[i].name, ODP_QUEUE_TYPE_SCHED, @@ -630,6 +640,26 @@ void scheduler_test_chaos(void) CU_ASSERT(rc == 0); } +void scheduler_test_parallel(void) +{ + chaos_run(0); +} + +void scheduler_test_atomic(void) +{ + chaos_run(1); +} + +void scheduler_test_ordered(void) +{ + chaos_run(2); +} + +void scheduler_test_chaos(void) +{ + chaos_run(3); +} + static void *schedule_common_(void *arg) { thread_args_t *args = (thread_args_t *)arg; @@ -1520,6 +1550,9 @@ odp_testinfo_t scheduler_suite[] = { ODP_TEST_INFO(scheduler_test_num_prio), ODP_TEST_INFO(scheduler_test_queue_destroy), ODP_TEST_INFO(scheduler_test_groups), + ODP_TEST_INFO(scheduler_test_parallel), + ODP_TEST_INFO(scheduler_test_atomic), + ODP_TEST_INFO(scheduler_test_ordered), ODP_TEST_INFO(scheduler_test_chaos), ODP_TEST_INFO(scheduler_test_1q_1t_n), ODP_TEST_INFO(scheduler_test_1q_1t_a), diff --git a/test/validation/scheduler/scheduler.h b/test/validation/scheduler/scheduler.h index bba79aa..cd69e92 100644 --- a/test/validation/scheduler/scheduler.h +++ b/test/validation/scheduler/scheduler.h @@ -15,6 +15,9 @@ void scheduler_test_num_prio(void); void scheduler_test_queue_destroy(void); void scheduler_test_groups(void); void scheduler_test_chaos(void); +void scheduler_test_parallel(void); +void scheduler_test_atomic(void); +void scheduler_test_ordered(void); void scheduler_test_1q_1t_n(void); void scheduler_test_1q_1t_a(void); void scheduler_test_1q_1t_o(void); -- 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] validation: scheduler: add timing tests for scheduled queue types
On 21.01.16 00:02, Bill Fischofer wrote: On Wed, Jan 20, 2016 at 3:36 PM, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: Seems you've missed simplification. Can you be more specific? You requested that CHAOS_NUM_ROUNDS be reduced to 1000 and the test ordering be rearranged. Did I miss something else? It's in my previous replies. Proposition to use shorter variant of if/else construct in the patch. snprintf has same format, so better to use one function. It's easier to support. || || \/ " unsigned int qtype_num; qtype_num = qtype == num_sync ? i % num_sync : qtype; qp.sched.sync = sync[qtype_num]; snprintf(globals->chaos_q[i].name, sizeof(globals->chaos_q[i].name), "chaos queue %d - %s", i, qtypes[qtype_num]); " It was replied it below || || \/ On 20.01.16 23:31, Bill Fischofer wrote: Ok, v2 submitted with requested changes. Thanks. Bill On Wed, Jan 20, 2016 at 2:24 PM, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org> <mailto:ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>>> wrote: On 20.01.16 21:43, Ivan Khoronzhuk wrote: On 20.01.16 18:58, Bill Fischofer wrote: ping. On Wed, Dec 30, 2015 at 5:49 PM, Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>>>> wrote: Expand the existing scheduler chaos test to provide timing information for mixed queues as well as individual timings for parallel, atomic, and ordered queues. This enables implementation scheduling efficiency to be displayed by queue type. Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>>>> Please, decrease CHAOS_NUM_ROUNDS, say 1000. That's more then enough. Especially now, when it's multiplied on 4 with number of tests. Also, see below. --- test/validation/scheduler/scheduler.c | 51 ++- test/validation/scheduler/scheduler.h | 3 +++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 7ba6a06..d5842de 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -451,12 +451,14 @@ static void *chaos_thread(void *arg) thread_args_t *args = (thread_args_t *)arg; test_globals_t *globals = args->globals; int me = odp_thread_id(); + odp_time_t start_time, end_time, diff; if (CHAOS_DEBUG) printf("Chaos thread %d starting...\n", me); /* Wait for all threads to start */ odp_barrier_wait(>barrier); + start_time = odp_time_local(); /* Run the test */ wait = odp_schedule_wait_time(CHAOS_WAIT_FAIL); @@ -508,10 +510,16 @@ static void *chaos_thread(void *arg) odp_event_free(ev); } + end_time = odp_time_local(); + diff = odp_time_diff(end_time, start_time); + + printf("Thread %d ends, elapsed time = %" PRIu64 "us\n", + odp_thread_id(), odp_time_to_ns(diff) / 1000); + return NULL; }
Re: [lng-odp] [PATCH] validation: pktio: use odp_time_ns() instead own function
ping On 13.01.16 19:18, Ivan Khoronzhuk wrote: Now odp_time_wait_ns() can be used. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 45c11c5..29ad4ea 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -259,17 +259,6 @@ static int default_pool_create(void) return 0; } -static void spin_wait(uint64_t ns) -{ - odp_time_t start, now, diff; - - start = odp_time_local(); - do { - now = odp_time_local(); - diff = odp_time_diff(now, start); - } while (odp_time_to_ns(diff) < ns); -} - static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_output_mode_t omode) { @@ -294,7 +283,7 @@ static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_print(pktio); if (wait_for_network) - spin_wait(ODP_TIME_SEC_IN_NS / 4); + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); return pktio; } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/2] linux-generic: define posix extension level once
On 14.01.16 11:24, Petri Savolainen wrote: Use only one definition for posix extension level. _GNU_SOURCE defines _POSIX_C_SOURCE based on glibc version, and is the only definition needed under Linux. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/Makefile.am | 1 + platform/linux-generic/arch/linux/odp_cpu_cycles.c | 2 +- .../linux-generic/include/odp/plat/time_types.h| 2 +- .../linux-generic/include/odp_posix_extensions.h | 36 ++ platform/linux-generic/odp_cpumask.c | 5 ++- platform/linux-generic/odp_cpumask_task.c | 5 ++- platform/linux-generic/odp_shared_memory.c | 3 +- platform/linux-generic/odp_system_info.c | 3 +- platform/linux-generic/odp_thread.c| 6 ++-- platform/linux-generic/odp_thrmask.c | 4 --- platform/linux-generic/odp_time.c | 2 +- platform/linux-generic/odp_timer.c | 4 +-- platform/linux-generic/pktio/loop.c| 4 --- platform/linux-generic/pktio/netmap.c | 4 +-- platform/linux-generic/pktio/pcap.c| 4 +-- platform/linux-generic/pktio/pktio_common.c| 4 --- platform/linux-generic/pktio/socket.c | 4 +-- platform/linux-generic/pktio/socket_mmap.c | 5 ++- platform/linux-generic/pktio/tap.c | 4 +-- 19 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 platform/linux-generic/include/odp_posix_extensions.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 8064193..279e5e2 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -100,6 +100,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_packet_socket.h \ ${srcdir}/include/odp_packet_tap.h \ ${srcdir}/include/odp_pool_internal.h \ + ${srcdir}/include/odp_posix_extensions.h \ ${srcdir}/include/odp_queue_internal.h \ ${srcdir}/include/odp_schedule_internal.h \ ${srcdir}/include/odp_spin_internal.h \ diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c b/platform/linux-generic/arch/linux/odp_cpu_cycles.c index 37a4d94..7509bf2 100644 --- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define _POSIX_C_SOURCE 199309L +#include #include #include diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h index 14c35f0..1b9409b 100644 --- a/platform/linux-generic/include/odp/plat/time_types.h +++ b/platform/linux-generic/include/odp/plat/time_types.h @@ -23,7 +23,7 @@ extern "C" { /** * @internal Time structure used to isolate linux-generic implementation from - * the linux timespec structure, which is dependent on _POSIX_C_SOURCE level. + * the linux timespec structure, which is dependent on POSIX extension level. */ typedef struct odp_time_t { int64_t tv_sec; /**< @internal Seconds */ diff --git a/platform/linux-generic/include/odp_posix_extensions.h b/platform/linux-generic/include/odp_posix_extensions.h new file mode 100644 index 000..4b6e335 --- /dev/null +++ b/platform/linux-generic/include/odp_posix_extensions.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_POSIX_EXTENSIONS_H +#define ODP_POSIX_EXTENSIONS_H + +/* + * This should be the only file to define POSIX extension levels. When + * extensions are needed it should be included first in each C source file. + * Header files should not include it. + */ + +/* + * Enable POSIX and GNU extensions + * + * This macro defines: + * o _BSD_SOURCE, _SVID_SOURCE, _ATFILE_SOURCE, _LARGE‐FILE64_SOURCE, + * _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE + * o _POSIX_C_SOURCE with the value: + ** 200809L since glibc v2.10 (== POSIX.1-2008 base specification) + ** 200112L before glibc v2.10 (== POSIX.1-2001 base specification) + ** 199506L before glibc v2.5 + ** 199309L before glibc v2.1 + * o _XOPEN_SOURCE with the value: + ** 700 since glibc v2.10 + ** 600 before glibc v2.10 + ** 500 before glibc v2.2 + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#endif diff --git a/platform/linux-generic/odp_cpumask.c b/platform/linux-generic/odp_cpumask.c index 5cd6a38..c5c1260 100644 --- a/platform/linux-generic/odp_cpumask.c +++ b/platform/linux-generic/odp_cpumask.c @@ -4,9 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SO
Re: [lng-odp] [PATCH 2/2] tests: harmonize posix extensions level defines
On 14.01.16 11:24, Petri Savolainen wrote: Allways use _GNU_SOURCE instead of various _POSIX_C_SOURCE defines. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/generator/odp_generator.c | 4 +++- example/ipsec/odp_ipsec.c | 6 -- example/ipsec/odp_ipsec_fwd_db.c | 4 +++- example/ipsec/odp_ipsec_sa_db.c | 4 +++- example/ipsec/odp_ipsec_sp_db.c | 4 +++- example/ipsec/odp_ipsec_stream.c | 4 +++- test/performance/odp_l2fwd.c | 4 +++- test/performance/odp_scheduling.c | 3 --- test/validation/timer/timer.c | 5 - 9 files changed, 26 insertions(+), 12 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 757dc54..10643dc 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -5,7 +5,9 @@ */ /** enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index fab1035..6426d99 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -10,9 +10,11 @@ * @example odp_example_ipsec.c ODP basic packet IO cross connect with IPsec test application */ -#define _DEFAULT_SOURCE /* enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include #include #include diff --git a/example/ipsec/odp_ipsec_fwd_db.c b/example/ipsec/odp_ipsec_fwd_db.c index 6604e3a..59cb6e4 100644 --- a/example/ipsec/odp_ipsec_fwd_db.c +++ b/example/ipsec/odp_ipsec_fwd_db.c @@ -5,7 +5,9 @@ */ /* enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c index 928c4cb..8b2d212 100644 --- a/example/ipsec/odp_ipsec_sa_db.c +++ b/example/ipsec/odp_ipsec_sa_db.c @@ -5,7 +5,9 @@ */ /* enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/example/ipsec/odp_ipsec_sp_db.c b/example/ipsec/odp_ipsec_sp_db.c index 2ce8c93..48874eb 100644 --- a/example/ipsec/odp_ipsec_sp_db.c +++ b/example/ipsec/odp_ipsec_sp_db.c @@ -5,7 +5,9 @@ */ /* enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index f750e18..9c2722e 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -5,7 +5,9 @@ */ /* enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index a85b830..eb83bdb 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -11,7 +11,9 @@ */ /** enable strtok */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c index fc6ccdc..8ec89bf 100644 --- a/test/performance/odp_scheduling.c +++ b/test/performance/odp_scheduling.c @@ -10,9 +10,6 @@ * @example odp_example.c ODP example application */ -/* enable clock_gettime */ -#define _POSIX_C_SOURCE 200112L - #include #include diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..5d89700 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -9,7 +9,10 @@ */ /* For rand_r and nanosleep */ -#define _POSIX_C_SOURCE 200112L +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include #include #include "odp_cunit_common.h" -- 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 PATCHv1 1/2] validation: increase timer expiration wait time
On 19.01.16 13:27, Maxim Uvarov wrote: On 01/19/2016 13:23, Ivan Khoronzhuk wrote: On 19.01.16 11:59, Maxim Uvarov wrote: On 01/19/2016 01:54, Ivan Khoronzhuk wrote: Maxim, in general, I had no look in this test, it was working for me and I was happy. At fast glance I have some comments. Hope you will find time to correct it. ok, some comments bellow. On 15.01.16 11:14, Maxim Uvarov wrote: Following current test logic validation test should correctly wait for all scheduled timer expirations. Setting that time to 1ms is not correct due to code above schedules timer to 1.1ms and context switch in linux takes 10ms. Problem that odp_timer_pool_destroy() does not disarm all trigered timers before freeing pool shared memory still exist. That should be covered with separate test case. Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 38 -- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..db0a5ca 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -266,6 +266,23 @@ static void handle_tmo(odp_event_t ev, bool stale, uint64_t prev_tick) } } +/* Delay to ensure timeouts for expired timers can be + * received. + * Delay time = (max timer expiration time) + + *(timer handler execution time) + + *(system overhead for thread creation and schedule + * context switches) + */ +static void _wait_for_timers_expiration(void) _wait_for* -> wait_for_* +{ +struct timespec ts; + +ts.tv_sec = 0; +ts.tv_nsec = 50 * ODP_TIME_MSEC_IN_NS; +if (nanosleep(, NULL) < 0) +CU_FAIL_FATAL("nanosleep failed"); +} + use time API here odp_time_wait_ns(50 * ODP_TIME_MSEC_IN_NS()); Maybe better to correct it with separate preparation patch. /* @private Worker thread entrypoint which performs timer alloc/set/cancel/free * tests */ static void *worker_entrypoint(void *arg TEST_UNUSED) @@ -305,7 +322,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) uint64_t tck = odp_timer_current_tick(tp) + 1 + odp_timer_ns_to_tick(tp, (rand_r() % RANGE_MS) -* 100ULL); +* ODP_TIME_MSEC_IN_NS); odp_timer_set_t rc; rc = odp_timer_set_abs(tt[i].tim, tck, [i].ev); if (rc != ODP_TIMER_SUCCESS) { @@ -351,7 +368,8 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) /* Timer active => reset */ nreset++; uint64_t tck = 1 + odp_timer_ns_to_tick(tp, - (rand_r() % RANGE_MS) * 100ULL); + (rand_r() % RANGE_MS) * + ODP_TIME_MSEC_IN_NS); ...it's not related to the patch, but maybe as preparation patch would be normal to replace rand_r() usage on odp_random_data()... odp_timer_set_t rc; uint64_t cur_tick; /* Loop until we manage to read cur_tick and set a @@ -372,11 +390,8 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) tt[i].tick = cur_tick + tck; } } -struct timespec ts; -ts.tv_sec = 0; -ts.tv_nsec = 100; /* 1ms */ -if (nanosleep(, NULL) < 0) -CU_FAIL_FATAL("nanosleep failed"); + +_wait_for_timers_expiration(); You've changed step here from 1ms to 50ms, but didn't change comment under loop. It's not seen here, but after this description is not correct. ... Also, delay is increased but step in the loop is still supposed 1ms. The line below should be changed also: for (ms = 0; ms < 7 * RANGE_MS / 10; ms++) { ms += 50ms, but pay attention, maybe there is reason to tune (7 * RANGE_MS / 10) a little. But really I not fully understand why we need to increase step here. IMHO, it's better to decrease it here. If in some case timeout is delivered to early it should be caught, but if it's a little to late - it's normal. Test simply checks if timeouts are received in right order and are not to early. Simply increasing delay here in 50 times and not tuning iteration number you increased time for receiving events in the loop. The events are spread in 2000 ms, and you are lucky to fit in this range by doing like this. To increase time for receiving events better to increase iteration number in: for (ms = 0; ms < 7 * RANGE_MS / 10; ms++) { to fit 2000 ms interval. That's enough to receive all events and no need to change polling timeout. Here we are talking about that bug: https://bugs.linaro.org/show_bug.cgi?id=1940 As I understand timer step does not make sense. timer_delete() returns 0 that means that kernel confirmed that it deleted that timer. But there actually timer is in flight and we should wait some sm
Re: [lng-odp] [API-NEXT PATCH] validation: timer: increase cyle timeout to prevent timer segfault
On 19.01.16 20:13, Maxim Uvarov wrote: On 01/19/2016 19:56, Ivan Khoronzhuk wrote: On 19.01.16 17:02, Ivan Khoronzhuk wrote: On 19.01.16 16:16, Maxim Uvarov wrote: On 01/19/2016 16:47, Ivan Khoronzhuk wrote: On 19.01.16 15:11, Ivan Khoronzhuk wrote: Maxim. On 19.01.16 14:59, Maxim Uvarov wrote: Increase after loop delay to: 10/10 - 7/10 = 3/10. 3/10 * 2000 + some 50ms = 650ms (instead of 1ms) to make sure that timer hanles expired. This patch can be considered as temporary fix for timer test to prevent It's not temporary fix and should be considered as fix of after-loop delay. segfault. More detailed fix will be later. Suggested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..f533f05 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -374,7 +374,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) } struct timespec ts; ts.tv_sec = 0; -ts.tv_nsec = 100; /* 1ms */ +ts.tv_nsec = 65000; /* 650ms */ It's not correct place for delay. You've increased polling period in the main loop. I meant after-loop delay (line 408). And this delay is RANGE_MS dependent, it can be different when changed. use: ts.tv_nsec = 3 * RANGE_MS / 10 + 50; /* time to receive the rest of events */ And if you tested it, please add tested-by. ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; No, that does not work. First patch works. Maxim. Unfortunately I cannot reproduce the issue on my PC at all. Did you test it with my last comment: ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; <- multiplied on ? If yes then probably you need to split /* Cancel and free all timers */ loop. 1. Cancel timers. 2. wait delay in question 3. delete timers. It's also interesting to know when the event is arrived. before main test loop set in some global var: start = odp_time_global(); printf("start time of testing: %", odp_time_to_ns(start)); ... loop and in notify routine while crash get this value: event_time = odp_time_global(); printf("start time of testing: %", odp_time_to_ns(event_time)); Then compare, the difference should be more than 2050ms. If it less, then we cannot call timer_getoverrun() if timer is canceled. And this is a problem then. It it's more then 2sec -> timings are set incorrectly. But anyway, this patch and patch for replacing on time API (odp_time_wait_ns) have to be added. I believe that intention of creator of this test was to wait on correct period, 1ms - it's hard typo. Ok, I will test that. We also find that changing nanosleep to odp time sleep solves problem. But it's still unclear why. Let's continue debug it tomorrow. I just think to remove random things from the test. That should increase constantly fail / pass result repetition. randomness should be present after debugging, but replaced on odp_random_data. nsleep should be present till the end of debugging. Maxim. Also I propose to add preliminary patch to replace timespec on ODP time API. if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); } ___ 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] [API-NEXT PATCH] validation: timer: increase cyle timeout to prevent timer segfault
Maxim. On 19.01.16 14:59, Maxim Uvarov wrote: Increase after loop delay to: 10/10 - 7/10 = 3/10. 3/10 * 2000 + some 50ms = 650ms (instead of 1ms) to make sure that timer hanles expired. This patch can be considered as temporary fix for timer test to prevent It's not temporary fix and should be considered as fix of after-loop delay. segfault. More detailed fix will be later. Suggested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..f533f05 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -374,7 +374,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) } struct timespec ts; ts.tv_sec = 0; - ts.tv_nsec = 100; /* 1ms */ + ts.tv_nsec = 65000; /* 650ms */ It's not correct place for delay. You've increased polling period in the main loop. I meant after-loop delay (line 408). And this delay is RANGE_MS dependent, it can be different when changed. use: ts.tv_nsec = 3 * RANGE_MS / 10 + 50; /* time to receive the rest of events */ And if you tested it, please add tested-by. Also I propose to add preliminary patch to replace timespec on ODP time API. if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); } -- 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] validation: timer: increase cyle timeout to prevent timer segfault
On 19.01.16 15:11, Ivan Khoronzhuk wrote: Maxim. On 19.01.16 14:59, Maxim Uvarov wrote: Increase after loop delay to: 10/10 - 7/10 = 3/10. 3/10 * 2000 + some 50ms = 650ms (instead of 1ms) to make sure that timer hanles expired. This patch can be considered as temporary fix for timer test to prevent It's not temporary fix and should be considered as fix of after-loop delay. segfault. More detailed fix will be later. Suggested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..f533f05 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -374,7 +374,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) } struct timespec ts; ts.tv_sec = 0; -ts.tv_nsec = 100; /* 1ms */ +ts.tv_nsec = 65000; /* 650ms */ It's not correct place for delay. You've increased polling period in the main loop. I meant after-loop delay (line 408). And this delay is RANGE_MS dependent, it can be different when changed. use: ts.tv_nsec = 3 * RANGE_MS / 10 + 50; /* time to receive the rest of events */ And if you tested it, please add tested-by. ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; Also I propose to add preliminary patch to replace timespec on ODP time API. if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); } -- 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] validation: timer: increase cyle timeout to prevent timer segfault
On 19.01.16 16:16, Maxim Uvarov wrote: On 01/19/2016 16:47, Ivan Khoronzhuk wrote: On 19.01.16 15:11, Ivan Khoronzhuk wrote: Maxim. On 19.01.16 14:59, Maxim Uvarov wrote: Increase after loop delay to: 10/10 - 7/10 = 3/10. 3/10 * 2000 + some 50ms = 650ms (instead of 1ms) to make sure that timer hanles expired. This patch can be considered as temporary fix for timer test to prevent It's not temporary fix and should be considered as fix of after-loop delay. segfault. More detailed fix will be later. Suggested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..f533f05 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -374,7 +374,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) } struct timespec ts; ts.tv_sec = 0; -ts.tv_nsec = 100; /* 1ms */ +ts.tv_nsec = 65000; /* 650ms */ It's not correct place for delay. You've increased polling period in the main loop. I meant after-loop delay (line 408). And this delay is RANGE_MS dependent, it can be different when changed. use: ts.tv_nsec = 3 * RANGE_MS / 10 + 50; /* time to receive the rest of events */ And if you tested it, please add tested-by. ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; No, that does not work. First patch works. Maxim. Unfortunately I cannot reproduce the issue on my PC at all. Did you test it with my last comment: ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; <- multiplied on ? If yes then probably you need to split /* Cancel and free all timers */ loop. 1. Cancel timers. 2. wait delay in question 3. delete timers. Also I propose to add preliminary patch to replace timespec on ODP time API. if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); } ___ 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] [API-NEXT PATCH] validation: timer: increase cyle timeout to prevent timer segfault
On 19.01.16 17:02, Ivan Khoronzhuk wrote: On 19.01.16 16:16, Maxim Uvarov wrote: On 01/19/2016 16:47, Ivan Khoronzhuk wrote: On 19.01.16 15:11, Ivan Khoronzhuk wrote: Maxim. On 19.01.16 14:59, Maxim Uvarov wrote: Increase after loop delay to: 10/10 - 7/10 = 3/10. 3/10 * 2000 + some 50ms = 650ms (instead of 1ms) to make sure that timer hanles expired. This patch can be considered as temporary fix for timer test to prevent It's not temporary fix and should be considered as fix of after-loop delay. segfault. More detailed fix will be later. Suggested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- test/validation/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index dda5e4c..f533f05 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -374,7 +374,7 @@ static void *worker_entrypoint(void *arg TEST_UNUSED) } struct timespec ts; ts.tv_sec = 0; -ts.tv_nsec = 100; /* 1ms */ +ts.tv_nsec = 65000; /* 650ms */ It's not correct place for delay. You've increased polling period in the main loop. I meant after-loop delay (line 408). And this delay is RANGE_MS dependent, it can be different when changed. use: ts.tv_nsec = 3 * RANGE_MS / 10 + 50; /* time to receive the rest of events */ And if you tested it, please add tested-by. ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; No, that does not work. First patch works. Maxim. Unfortunately I cannot reproduce the issue on my PC at all. Did you test it with my last comment: ts.tv_nsec = (3 * RANGE_MS / 10 + 50) * ODP_TIME_MSEC_IN_NS; <- multiplied on ? If yes then probably you need to split /* Cancel and free all timers */ loop. 1. Cancel timers. 2. wait delay in question 3. delete timers. It's also interesting to know when the event is arrived. before main test loop set in some global var: start = odp_time_global(); printf("start time of testing: %", odp_time_to_ns(start)); ... loop and in notify routine while crash get this value: event_time = odp_time_global(); printf("start time of testing: %", odp_time_to_ns(event_time)); Then compare, the difference should be more than 2050ms. If it less, then we cannot call timer_getoverrun() if timer is canceled. And this is a problem then. It it's more then 2sec -> timings are set incorrectly. But anyway, this patch and patch for replacing on time API (odp_time_wait_ns) have to be added. I believe that intention of creator of this test was to wait on correct period, 1ms - it's hard typo. Also I propose to add preliminary patch to replace timespec on ODP time API. if (nanosleep(, NULL) < 0) CU_FAIL_FATAL("nanosleep failed"); } ___ 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] [PATCH v6] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v5: - add res instead of "1" while wrap - get cycle stamps a multiple of res instead direct valuues. - move resolution test before diff test Since v3: - modified log "wrap is not detected" - increased try num for diff to match 16 seconds - decreased try num for resolution to match 1 second - allow resolution to be up to max / 1024 - correct wrap detection for resolution Since v2: - added c <= max - replaced etalon on tmp - added msg about skip - handled resolution wrap # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch validation_tests_corrections # Changes to be committed: # modified: platform/linux-keystone2/odp_crypto.c # modified: test/validation/system/system.c # # Changes not staged for commit: # modified: platform/linux-keystone2/odp_schedule.c # # Untracked files: # .checkpatch-camelcase.git.81a3df4 # example/traffic_mgmt/ # test/validation/system/system.c | 125 test/validation/system/system.h | 4 ++ 2 files changed, 129 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..7f54338 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,9 @@ #include "test_debug.h" #include "system.h" +#define DIFF_TRY_NUM 160 +#define RES_TRY_NUM10 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +43,124 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t res; + uint64_t c2, c1, max; + + max = odp_cpu_cycles_max(); + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < max / 1024); + + for (i = 0; i < RES_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 % res == 0); + CU_ASSERT(c2 % res == 0); + } +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1, c3, max; + uint64_t tmp, diff, res; + + res = odp_cpu_cycles_resolution(); + max = odp_cpu_cycles_max(); + + /* check resolution for wrap */ + c1 = max - 2 * res; + do + c2 = odp_cpu_cycles(); + while (c1 < c2); + + diff = odp_cpu_cycles_diff(c1, c1); + CU_ASSERT(diff == 0); + + /* wrap */ + tmp = c2 + (max - c1) + res; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + CU_ASSERT(diff % res == 0); + + /* no wrap, revert args */ + tmp = c1 - c2; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + CU_ASSERT(diff % res == 0); + + c3 = odp_cpu_cycles(); + for (i = 0; i < DIFF_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + CU_ASSERT(c1 % res == 0); + CU_ASSERT(c2 % res == 0); + CU_ASSERT(c1 <= max && c2 <= max); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (max - c1) + res; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + CU_ASSERT(diff % res == 0); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap was detected, no need to continue */ + if (i < DIFF_TRY_NUM) + return; + + /* wrap has to be detected if possible */ + CU_ASSERT(max > UINT32_MAX); + CU_ASSERT((max - c3) > UINT32_MAX); + + printf("wrap was not detected..."); +} + void system_test_odp_sys_cache_lin
Re: [lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls
v6 is sent. On 18.01.16 14:58, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Monday, January 18, 2016 2:24 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls On 18.01.16 13:37, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Friday, January 15, 2016 5:07 PM To: lng-odp@lists.linaro.org Cc: Savolainen, Petri (Nokia - FI/Espoo); Ivan Khoronzhuk Subject: [lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 130 test/validation/system/system.h | 4 ++ 2 files changed, 134 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..f59c570 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,9 @@ #include "test_debug.h" #include "system.h" +#define DIFF_TRY_NUM 160 +#define RES_TRY_NUM10 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +43,129 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1, c3; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; As noted before, '+1' in the equation holds only if resolution is 1. The equation should be: diff = c2 + (odp_cpu_cycles_max() - c1) + odp_cpu_cycles_resolution(); It would be also more readable if c1 is always the first sample and c2 the second (c1 = 100, c2 = 39 in this test case). In one case it's used directly in other in reverse order, no see reason to assign it once again. The reason is readability. Since it's not a performance target, it's better to assign values again and highlight what is being tested (100 -> 39 vs. 39 -> 100). Also, if reader compares the reference implementation to the test case, it's confusing when c1 and c2 have been swapped. return c2 + (odp_cpu_cycles_max() - c1) + 1 (the resolution); VS. tmp = c1 + (odp_cpu_cycles_max() - c2) + res; -Petri And I'll delete it at all and use the following instead: /* check resolution for wrap */ c1 = max - 2 * res; do c2 = odp_cpu_cycles(); while (c2 < c1); and use it for different cases: diff = odp_cpu_cycles_diff(c1, c1); CU_ASSERT(diff == 0); tmp = c2 - c1; // here c1 is supposed to be after c2, but in order to not read this values again... diff = odp_cpu_cycles_diff(c2, c1); CU_ASSERT(diff == tmp); rest = diff % res; CU_ASSERT(rest == 0); tmp = c1 + (odp_cpu_cycles_max() - c2) + res; diff = odp_cpu_cycles_diff(c1, c2); CU_ASSERT(diff == tmp); rest = diff % res; CU_ASSERT(rest == 0); Max: 90 Res: 10 Valid values: 0, 10, 20, ..., 80, 90 c1 = 90 c2 = 0 c2 max c1 res diff = 0 + (90 - 90) + 10 = 10 -Petri + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c3 = odp_cpu_cycles(); + + /* must handle one wrap */ + for (i = 0; i < DIFF_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified
Re: [lng-odp] [PATCH] validation: pktio: fix check of pktio_stop() called twice
ping On 13.01.16 19:38, Ivan Khoronzhuk wrote: The odp_pktio_stop() called is supposed to return error. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 29ad4ea..1ca4979 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -737,7 +737,7 @@ void pktio_test_start_stop(void) /* Interfaces are stopped by default, * Check that stop when stopped generates an error */ ret = odp_pktio_stop(pktio[0]); - CU_ASSERT(ret <= 0); + CU_ASSERT(ret < 0); /* start first */ ret = odp_pktio_start(pktio[0]); -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: pktio: use odp_time_ns() instead own function
ping On 13.01.16 19:18, Ivan Khoronzhuk wrote: Now odp_time_wait_ns() can be used. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 45c11c5..29ad4ea 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -259,17 +259,6 @@ static int default_pool_create(void) return 0; } -static void spin_wait(uint64_t ns) -{ - odp_time_t start, now, diff; - - start = odp_time_local(); - do { - now = odp_time_local(); - diff = odp_time_diff(now, start); - } while (odp_time_to_ns(diff) < ns); -} - static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_output_mode_t omode) { @@ -294,7 +283,7 @@ static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_print(pktio); if (wait_for_network) - spin_wait(ODP_TIME_SEC_IN_NS / 4); + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); return pktio; } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: pktio: assign MAC address if one loop pktio is used
ping On 14.01.16 12:56, Ivan Khoronzhuk wrote: In case of one loop pktio the MAC address is not set in the packets but should be. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 536ef6c..a756af4 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -830,11 +830,21 @@ void pktio_test_start_stop(void) pktio_init_packet(pkt); if (num_ifaces > 1) { pktio_pkt_set_macs(pkt, pktio[0], pktio[1]); - if (pktio_fixup_checksums(pkt) != 0) { - odp_packet_free(pkt); - break; - } + } else { + uint32_t len; + odph_ethhdr_t *eth; + + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, ); + ret = odp_pktio_mac_addr(pktio[0], +>dst, sizeof(eth->dst)); + CU_ASSERT(ret == ODPH_ETHADDR_LEN); } + + if (pktio_fixup_checksums(pkt) != 0) { + odp_packet_free(pkt); + break; + } + tx_ev[alloc] = odp_packet_to_event(pkt); } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: pktio: don't continue if packet with > MTU is sent
ping On 15.01.16 17:55, Stuart Haslam wrote: On Fri, Jan 15, 2016 at 05:53:20PM +0200, Ivan Khoronzhuk wrote: On 15.01.16 17:51, Stuart Haslam wrote: On Wed, Jan 13, 2016 at 06:46:57PM +0200, Ivan Khoronzhuk wrote: If packet with size > MTU is sent the test can crash farther, so better to stop here. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Stuart Haslam <stuart.has...@linaro.org> Reviewed-by? Err, yup, wrong macro, I meant.. Reviewed-by: Stuart Haslam <stuart.has...@linaro.org> --- test/validation/pktio/pktio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 8121f1e..45c11c5 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -968,7 +968,7 @@ void pktio_test_send_failure(void) * 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); + CU_ASSERT_FATAL(ret == long_pkt_idx); CU_ASSERT(odp_errno() == 0); info_rx.id = pktio_rx; -- 1.9.1 -- Regards, Ivan Khoronzhuk -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls
On 18.01.16 13:37, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Friday, January 15, 2016 5:07 PM To: lng-odp@lists.linaro.org Cc: Savolainen, Petri (Nokia - FI/Espoo); Ivan Khoronzhuk Subject: [lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 130 test/validation/system/system.h | 4 ++ 2 files changed, 134 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..f59c570 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,9 @@ #include "test_debug.h" #include "system.h" +#define DIFF_TRY_NUM 160 +#define RES_TRY_NUM10 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +43,129 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1, c3; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; As noted before, '+1' in the equation holds only if resolution is 1. The equation should be: diff = c2 + (odp_cpu_cycles_max() - c1) + odp_cpu_cycles_resolution(); It would be also more readable if c1 is always the first sample and c2 the second (c1 = 100, c2 = 39 in this test case). In one case it's used directly in other in reverse order, no see reason to assign it once again. And I'll delete it at all and use the following instead: /* check resolution for wrap */ c1 = max - 2 * res; do c2 = odp_cpu_cycles(); while (c2 < c1); and use it for different cases: diff = odp_cpu_cycles_diff(c1, c1); CU_ASSERT(diff == 0); tmp = c2 - c1; // here c1 is supposed to be after c2, but in order to not read this values again... diff = odp_cpu_cycles_diff(c2, c1); CU_ASSERT(diff == tmp); rest = diff % res; CU_ASSERT(rest == 0); tmp = c1 + (odp_cpu_cycles_max() - c2) + res; diff = odp_cpu_cycles_diff(c1, c2); CU_ASSERT(diff == tmp); rest = diff % res; CU_ASSERT(rest == 0); Max: 90 Res: 10 Valid values: 0, 10, 20, ..., 80, 90 c1 = 90 c2 = 0 c2 max c1 res diff = 0 + (90 - 90) + 10 = 10 -Petri + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c3 = odp_cpu_cycles(); + + /* must handle one wrap */ + for (i = 0; i < DIFF_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap was detected, no need to continue */ + if (i < DIFF_TRY_NUM) + return; + + CU_ASSERT(odp_cpu_cycles_max() > UINT32_MAX); + CU_ASSERT((odp_cpu_cycles_max() - c3) > UINT32_MAX); + + printf("wrap was not detected..."); +} + +void system_test_odp_cpu_cycles_resolution(void) For this function I'll delete diff at all and move the test before diff test. +{ + int i; + uint64_t rest; + uint64_t res, diff; + uint64_t c2, c1, max; + + max = odp_cpu_cycles_max(); + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < max / 1024); + + /* check resolution for wrap */ + c1
Re: [lng-odp] [PATCHv19 9/9] linux-generic: internal ipc_pktio test
run_time_sec); +break; +} +} + +/* recv some packets and change MAGIC to MAGIC_2 */ +pkts = odp_pktio_recv(ipc_pktio, pkt_tbl, MAX_PKT_BURST); +if (pkts <= 0) +continue; + +for (i = 0; i < pkts; i++) { +odp_packet_t pkt = pkt_tbl[i]; +pkt_head_t head; +size_t off; + +off = odp_packet_l4_offset(pkt); +if (off == ODP_PACKET_OFFSET_INVALID) +EXAMPLE_ABORT("invalid l4 offset\n"); + +off += ODPH_UDPHDR_LEN; +ret = odp_packet_copydata_out(pkt, off, sizeof(head), + ); +if (ret) +EXAMPLE_ABORT("unable copy out head data"); + +if (head.magic != TEST_SEQ_MAGIC) +EXAMPLE_ABORT("Wrong head magic!"); + +/* Modify magic number in packet */ +head.magic = TEST_SEQ_MAGIC_2; +ret = odp_packet_copydata_in(pkt, off, sizeof(head), + ); +if (ret) +EXAMPLE_ABORT("unable to copy in head data"); +} + +/* send all packets back */ +ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, pkts); +if (ret < 0) +EXAMPLE_ABORT("can not send packets\n"); +stat_pkts += pkts; + +/* alloc packet from local pool, set magic to ALLOC_MAGIC, + * and send it.*/ +alloc_pkt = odp_packet_alloc(pool, SHM_PKT_POOL_BUF_SIZE); +if (alloc_pkt != ODP_PACKET_INVALID) { +pkt_head_t head; +size_t off; + +odp_packet_l4_offset_set(alloc_pkt, 30); + +head.magic = TEST_ALLOC_MAGIC; + +off = odp_packet_l4_offset(alloc_pkt); +off += ODPH_UDPHDR_LEN; +ret = odp_packet_copydata_in(alloc_pkt, off, + sizeof(head), + ); +if (ret) +EXAMPLE_ABORT("unable to copy in head data"); + +pkt_tbl[0] = alloc_pkt; +ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, 1); +if (ret < 0) +EXAMPLE_ABORT("can not send packets\n"); +stat_pkts += 1; +} +} + +/* cleanup and exit */ +ret = odp_pktio_stop(ipc_pktio); +if (ret) { +EXAMPLE_DBG("odp_pktio_stop error %d\n", ret); +return -1; +} + +exit: +ret = odp_pktio_close(ipc_pktio); +if (ret) { +EXAMPLE_DBG("odp_pktio_close error %d\n", ret); +return -1; +} + +ret = odp_pool_destroy(pool); +if (ret) +EXAMPLE_DBG("pool_destroy error %d\n", ret); + +return stat_pkts > 1000 ? 0 : -1; +} + +int main(int argc, char *argv[]) +{ +/* Parse and store the application arguments */ +parse_args(argc, argv); + +if (odp_init_global(NULL, NULL)) { +EXAMPLE_ERR("Error: ODP global init failed.\n"); +exit(EXIT_FAILURE); +} + +/* Init this thread */ +if (odp_init_local(ODP_THREAD_CONTROL)) { +EXAMPLE_ERR("Error: ODP local init failed.\n"); +exit(EXIT_FAILURE); +} + +return ipc_second_process(); +} diff --git a/platform/linux-generic/test/pktio_ipc/pktio_ipc_run b/platform/linux-generic/test/pktio_ipc/pktio_ipc_run new file mode 100755 index 000..1e41e8b --- /dev/null +++ b/platform/linux-generic/test/pktio_ipc/pktio_ipc_run @@ -0,0 +1,68 @@ +#!/bin/sh +# +# Copyright (c) 2015, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier:BSD-3-Clause +# + +# directories where test binary can be found: +# -in the validation dir when running make check (intree or out of tree) +# -in the script directory, when running after 'make install', or +# -in the validation when running standalone (./pktio_ipc_run) intree. +# -in the current directory. +# running stand alone out of tree requires setting PATH +PATH=./pktio_ipc:$PATH +PATH=$(dirname $0):$PATH +PATH=$(dirname $0)/../../../../platform/linux-generic/test/pktio_ipc:$PATH +PATH=.:$PATH + +run() +{ +local ret=0 + +echo " run pktio_ipc1 then pktio_ipc2 " +pktio_ipc1${EXEEXT} -t 30 & +IPC_PID=$! + +pktio_ipc2${EXEEXT} -t 10 +ret=$? +# pktio_ipc1 should do clean up and exit just +# after pktio_ipc2 exited. If it does not happen +# kill him in test. +sleep 1 +kill ${IPC_PID} 2>&1 > /dev/null +if [ $? -eq 0 ]; then +rm -rf /dev/shm/ipc_pktio_* 2>&1 > /dev/null +rm -rf /dev/shm/packet_pool2 2>&1 > /dev/null The fact that this is needed is still a problem. +fi + +if [ $ret -ne 0 ]; then +echo "!!!First stage FAILED $ret!!!" +exit $ret +else +echo "First stage PASSED" +fi + +echo " run pktio_ipc2 then pktio_ipc1 " +pktio_ipc2${EXEEXT} -t 10 & +IPC_PID=$! + +pktio_ipc1${EXEEXT} -t 20 +ret=$? +kill ${IPC_PID} 2>&1 || true + +if [ $ret -ne 0 ]; then +echo "!!! FAILED !!!" +exit $ret +else +echo "Second stage PASSED" +fi + +echo "!!!PASSED!!!" +exit 0 +} + +case "$1" in +*) run ;; +esac -- 1.9.1 ___ 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] [API-NEXT PATCHv1 2/2] linux-generic/validation: wait for timer handler completiion after timer deletion
On 15.01.16 11:14, Maxim Uvarov wrote: Add test case based on previous seg fault code that pool destroy does not fail if there are some timers in fight. Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- platform/linux-generic/odp_timer.c | 15 ++- test/validation/timer/timer.c | 15 +++ test/validation/timer/timer.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index b8f34fb..95fe130 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -259,6 +259,16 @@ static odp_timer_pool *odp_timer_pool_new( return tp; } +static void _finalyze_timers_handlers(void) +{ + struct timespec ts; + + ts.tv_sec = 0; + ts.tv_nsec = 50 * ODP_TIME_MSEC_IN_NS; + if (nanosleep(, NULL) < 0) + ODP_ABORT("nanosleep failed"); +} + For linux generic maybe that's OK, but why not odp_time API static void odp_timer_pool_del(odp_timer_pool *tp) { odp_spinlock_lock(>lock); @@ -270,8 +280,11 @@ static void odp_timer_pool_del(odp_timer_pool *tp) /* timer pool which is still in use */ ODP_ABORT("%s: timers in use\n", tp->name); } - if (tp->param.clk_src == ODP_CLOCK_CPU) + if (tp->param.clk_src == ODP_CLOCK_CPU) { itimer_fini(tp); + _finalyze_timers_handlers(); + } + Why are you sure that it's still receiving events after finish. Did you catch it? int rc = odp_shm_free(tp->shm); if (rc != 0) ODP_ABORT("Failed to free shared memory (%d)\n", rc); diff --git a/test/validation/timer/timer.c b/test/validation/timer/timer.c index db0a5ca..879ff67 100644 --- a/test/validation/timer/timer.c +++ b/test/validation/timer/timer.c @@ -22,6 +22,9 @@ /** @private Number of timers per thread */ #define NTIMERS 2000 +/** @private Dont wait for timers completition */ +static int dont_wait_for_timer_comp; + /** @private Barrier for thread synchronisation */ static odp_barrier_t test_barrier; @@ -277,6 +280,9 @@ static void _wait_for_timers_expiration(void) { struct timespec ts; + if (dont_wait_for_timer_comp) + return; + Pay attention, you've skipped not only "wait for timers expiration". you also deleted delay in polling loop, decreased in the same time timeout for receiving events, as result at the end of the test the number of timeouts in the flight will be much more. That will increase contrast of fail/true tests...presented here. ts.tv_sec = 0; ts.tv_nsec = 50 * ODP_TIME_MSEC_IN_NS; if (nanosleep(, NULL) < 0) @@ -539,11 +545,20 @@ void timer_test_odp_timer_all(void) CU_PASS("ODP timer test"); } +/* @private Timer test case entrypoint */ +void timer_test_destroy_pool_with_scheduled_timers(void) +{ + dont_wait_for_timer_comp = 1; + timer_test_odp_timer_all(); + dont_wait_for_timer_comp = 0; +} + odp_testinfo_t timer_suite[] = { ODP_TEST_INFO(timer_test_timeout_pool_alloc), ODP_TEST_INFO(timer_test_timeout_pool_free), ODP_TEST_INFO(timer_test_odp_timer_cancel), ODP_TEST_INFO(timer_test_odp_timer_all), + ODP_TEST_INFO(timer_test_destroy_pool_with_scheduled_timers), Is it supposed to be before timer_test_odp_timer_all()? Or test can continue after seg fault? :-|. IMHO, no need in it. ODP_TEST_INFO_NULL, }; diff --git a/test/validation/timer/timer.h b/test/validation/timer/timer.h index 46ea8d7..4f805b4 100644 --- a/test/validation/timer/timer.h +++ b/test/validation/timer/timer.h @@ -14,6 +14,7 @@ void timer_test_timeout_pool_alloc(void); void timer_test_timeout_pool_free(void); void timer_test_odp_timer_cancel(void); void timer_test_odp_timer_all(void); +void timer_test_destroy_pool_with_scheduled_timers(void); /* test arrays: */ extern odp_testinfo_t timer_suite[]; -- 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 PATCHv1 1/2] validation: increase timer expiration wait time
t; PRIu32 " stale timeout(s) after odp_timer_free()\n", thr, nstale); - /* Delay some more to ensure timeouts for expired timers can be -* received */ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 100; /* 1ms */ - if (nanosleep(, NULL) < 0) - CU_FAIL_FATAL("nanosleep failed"); + _wait_for_timers_expiration(); + while (nstale != 0) { odp_event_t ev = odp_queue_deq(queue); if (ev != ODP_EVENT_INVALID) { -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2] validation: system: add validation tests for odp_cpu_cycles_* calls
On 15.01.16 13:54, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of EXT Ivan Khoronzhuk Sent: Friday, January 15, 2016 11:16 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2] validation: system: add validation tests for odp_cpu_cycles_* calls https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 118 test/validation/system/system.h | 4 ++ 2 files changed, 122 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..4a382ac 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,118 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 < max1 && c2 < max1); c <= max c can be also max. It's the maximum (valid) value before it wraps back to zero. Yep. +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t etalon, diff; Etalon is not a common pick for a variable name. I think 'tmp' should be OK for this purpose. Ok. + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + etalon = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + etalon = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == etalon); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) + return; A debug message should be logged for this check. Either assert or warn that rest of the test cases will be skipped. Ok. + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + etalon = c2 - c1; + else + etalon = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t c2, c1; + uint64_t res, diff; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another Max: 90 Res: 10 c2 max c1 res 0 + (90 - 90) + 10 = 10 Resolution should hold also during a wrap. The cycles_diff implementation needs an update if resolution is >1. The test under may or may not wrap (depends on timing). -Petri Ok. Will set c1 = MAX - 2*res. c2 = odp_cpu_cycles(); diff = odp_cpu_cycles_diff(c2, c1); rest = diff % res; CU_ASSERT(rest == 0); And also increase TRY NUM as in test for diff. +* case resolution is set incorrectly +*/ + for (i = 0; i < 10; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +205,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_
[lng-odp] [PATCH v3] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v2: - added c <= max - replaced etalon on tmp - added msg about skip - handled resolution wrap test/validation/system/system.c | 133 test/validation/system/system.h | 4 ++ 2 files changed, 137 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..2cf5d29 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,133 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) { + printf("wrap detection is skipped..."); + return; + } + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t res, diff; + uint64_t c2, c1, max; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < 500); + + /* check resolution for wrap */ + max = odp_cpu_cycles_max(); + c1 = max - 2 * res; + c2 = odp_cpu_cycles(); + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another +* case resolution is set incorrectly +*/ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +220,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 869aaff..0c263f2 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -17,6 +17,10 @@ void sys
Re: [lng-odp] [PATCH v3] validation: system: add validation tests for odp_cpu_cycles_* calls
On 15.01.16 15:34, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Friday, January 15, 2016 2:33 PM To: lng-odp@lists.linaro.org Cc: Savolainen, Petri (Nokia - FI/Espoo); Ivan Khoronzhuk Subject: [lng-odp] [PATCH v3] validation: system: add validation tests for odp_cpu_cycles_* calls https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v2: - added c <= max - replaced etalon on tmp - added msg about skip - handled resolution wrap test/validation/system/system.c | 133 test/validation/system/system.h | 4 ++ 2 files changed, 137 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..2cf5d29 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,133 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) { + printf("wrap detection is skipped..."); Sorry about another iteration, but after thinking this again... np. Maybe it's better to run the test under in any case and print into the log if wrap was tested or not. Missing the wrap is the common case with 64 bit cpu counters. Ok. + return; + } + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); Wrap depends on CPU frequency. On low freq it may take a long time. May be it's better to just print warning if wrap was not tested. Ok. +} + +void system_test_odp_cpu_cycles_resolution(void) This resolution test case could be combined with previous one, so that we don't have to wait two times 8 sec (on every 'make check'). In previous test I'm going to increase TRY_NUM to match 16seconds due to low frequency in some cases. But I like resolution test with loop also. Here no need to wait so long time, anyway resolution while wrap is verified before loop. And in loop, decrease TRY_NUM to 10, thus it'll take ~ 1 second. +{ + int i; + uint64_t rest; + uint64_t res, diff; + uint64_t c2, c1, max; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < 500); Resolution could be larger than 500 cycles, but it cannot be larger than max cycles (or some fraction of that e.g. max / 1024). Ok. max / 1024; -Petri + + /* check resolution for wrap */ + max = odp_cpu_cycles_max(); + c1 = max - 2 * res; + c2 = odp_cpu_cycles(); here can happen that c2 is between c1 and max. I should take it into account also. + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + /* +* must be a multiple of resolution in +* wh
[lng-odp] [PATCH v4] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v3: - modified log "wrap is not detected" - increased try num for diff to match 16 seconds - decreased try num for resolution to match 1 second - allow resolution to be up to max / 1024 - correct wrap detection for resolution Since v2: - added c <= max - replaced etalon on tmp - added msg about skip - handled resolution wrap test/validation/system/system.c | 139 test/validation/system/system.h | 4 ++ 2 files changed, 143 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..400889c 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,9 @@ #include "test_debug.h" #include "system.h" +#define DIFF_TRY_NUM 160 +#define RES_TRY_NUM10 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +43,138 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1, c3; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c3 = odp_cpu_cycles(); + + /* must handle one wrap */ + for (i = 0; i < DIFF_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap was detected, no need to continue */ + if (i < DIFF_TRY_NUM) + return; + + CU_ASSERT(odp_cpu_cycles_max() > UINT32_MAX); + CU_ASSERT((odp_cpu_cycles_max() - c3) > UINT32_MAX); + + printf("wrap was not detected..."); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t res, diff; + uint64_t c2, c1, max; + + max = odp_cpu_cycles_max(); + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < max / 1024); + + /* check resolution for wrap */ + c1 = max - 2 * res; + do + c2 = odp_cpu_cycles(); + while (c1 < c2); + + diff = odp_cpu_cycles_diff(c1, c2); + rest = diff % res; + CU_ASSERT(rest == 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another +* case resolution is set incorrectly +*/ + for (i = 0; i < RES_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +226,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST
[lng-odp] [PATCH v5] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 130 test/validation/system/system.h | 4 ++ 2 files changed, 134 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..f59c570 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,9 @@ #include "test_debug.h" #include "system.h" +#define DIFF_TRY_NUM 160 +#define RES_TRY_NUM10 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +43,129 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 <= max1 && c2 <= max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1, c3; + uint64_t tmp, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + tmp = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + tmp = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == tmp); + + c3 = odp_cpu_cycles(); + + /* must handle one wrap */ + for (i = 0; i < DIFF_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + tmp = c2 - c1; + else + tmp = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == tmp); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap was detected, no need to continue */ + if (i < DIFF_TRY_NUM) + return; + + CU_ASSERT(odp_cpu_cycles_max() > UINT32_MAX); + CU_ASSERT((odp_cpu_cycles_max() - c3) > UINT32_MAX); + + printf("wrap was not detected..."); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t res, diff; + uint64_t c2, c1, max; + + max = odp_cpu_cycles_max(); + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + CU_ASSERT(res < max / 1024); + + /* check resolution for wrap */ + c1 = max - 2 * res; + do + c2 = odp_cpu_cycles(); + while (c1 < c2); + + diff = odp_cpu_cycles_diff(c1, c2); + rest = diff % res; + CU_ASSERT(rest == 0); + + for (i = 0; i < RES_TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +217,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 869aaff..0c263f2 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -17,6 +17,10 @@ void system_test_odp_sys_cpu_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_sys_cpu_hz(void); +void system_test_odp_cpu_cycles_max(void); +void system_test_odp_cpu_cycles(void); +void system_test_odp_cpu_cycles_diff(void
Re: [lng-odp] [PATCH] validation: pktio: don't continue if packet with > MTU is sent
On 15.01.16 17:51, Stuart Haslam wrote: On Wed, Jan 13, 2016 at 06:46:57PM +0200, Ivan Khoronzhuk wrote: If packet with size > MTU is sent the test can crash farther, so better to stop here. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Stuart Haslam <stuart.has...@linaro.org> Reviewed-by? --- test/validation/pktio/pktio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 8121f1e..45c11c5 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -968,7 +968,7 @@ void pktio_test_send_failure(void) * 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); + CU_ASSERT_FATAL(ret == long_pkt_idx); CU_ASSERT(odp_errno() == 0); info_rx.id = pktio_rx; -- 1.9.1 -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [API-NEXT PATCH v2 1/3] validation: cls: adopt for supported l3 PMR
The classification tests should use supported l3 PMR where it's not important. For validating concrete PMRs the separate test exists. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/classification/classification.h| 6 +-- .../classification/odp_classification_basic.c | 4 +- .../classification/odp_classification_common.c | 52 ++ .../classification/odp_classification_tests.c | 25 +-- .../classification/odp_classification_testsuites.h | 2 + 5 files changed, 69 insertions(+), 20 deletions(-) diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index 5728cc5..5508af7 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -31,18 +31,18 @@ #define CLS_PMR_CHAIN_SRC 2 #define CLS_PMR_CHAIN_DST 3 #define CLS_PMR_CHAIN_SADDR"10.0.0.5/32" -#define CLS_PMR_CHAIN_SPORT3000 +#define CLS_PMR_CHAIN_PORT 3000 /* Config values for PMR */ #define TEST_PMR 1 #define CLS_PMR4 -#define CLS_PMR_SPORT 4000 +#define CLS_PMR_PORT 4000 /* Config values for PMR SET */ #define TEST_PMR_SET 1 #define CLS_PMR_SET5 #define CLS_PMR_SET_SADDR "10.0.0.6/32" -#define CLS_PMR_SET_SPORT 5000 +#define CLS_PMR_SET_PORT 5000 /* Config values for CoS L2 Priority */ #define TEST_L2_QOS1 diff --git a/test/validation/classification/odp_classification_basic.c b/test/validation/classification/odp_classification_basic.c index f0b7a42..81077b6 100644 --- a/test/validation/classification/odp_classification_basic.c +++ b/test/validation/classification/odp_classification_basic.c @@ -78,7 +78,7 @@ void classification_test_create_pmr_match(void) val = 1024; mask = 0x; - match.term = ODP_PMR_TCP_SPORT; + match.term = find_first_supported_l3_pmr(); match.val = match.mask = match.val_sz = sizeof(val); @@ -99,7 +99,7 @@ void classification_test_destroy_pmr(void) val = 1024; mask = 0x; - match.term = ODP_PMR_TCP_SPORT; + match.term = find_first_supported_l3_pmr(); match.val = match.mask = match.val_sz = sizeof(val); diff --git a/test/validation/classification/odp_classification_common.c b/test/validation/classification/odp_classification_common.c index 89fdb89..bb937dc 100644 --- a/test/validation/classification/odp_classification_common.c +++ b/test/validation/classification/odp_classification_common.c @@ -313,3 +313,55 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, return pkt; } + +odp_pmr_term_t find_first_supported_l3_pmr(void) +{ + unsigned long long cap; + odp_pmr_term_t term = ODP_PMR_TCP_DPORT; + + /* choose supported PMR */ + cap = odp_pmr_terms_cap(); + if (cap & (1 << ODP_PMR_UDP_SPORT)) + term = ODP_PMR_UDP_SPORT; + else if (cap & (1 << ODP_PMR_UDP_DPORT)) + term = ODP_PMR_UDP_DPORT; + else if (cap & (1 << ODP_PMR_TCP_SPORT)) + term = ODP_PMR_TCP_SPORT; + else if (cap & (1 << ODP_PMR_TCP_DPORT)) + term = ODP_PMR_TCP_DPORT; + else + CU_FAIL("Implementations doesn't support any TCP/UDP PMR"); + + return term; +} + +int set_first_supported_pmr_port(odp_packet_t pkt, uint16_t port) +{ + odph_udphdr_t *udp; + odph_tcphdr_t *tcp; + odp_pmr_term_t term; + + udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); + tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); + port = odp_cpu_to_be_16(port); + term = find_first_supported_l3_pmr(); + switch (term) { + case ODP_PMR_UDP_SPORT: + udp->src_port = port; + break; + case ODP_PMR_UDP_DPORT: + udp->dst_port = port; + break; + case ODP_PMR_TCP_DPORT: + tcp->dst_port = port; + break; + case ODP_PMR_TCP_SPORT: + tcp->src_port = port; + break; + default: + CU_FAIL("Unsupported L3 term"); + return -1; + } + + return 0; +} diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index e11c3d8..a118728 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -10,6 +10,7 @@ #include #include #include +#include static odp_cos_t cos_list[CLS_ENTRIES]; static odp_pmr_t pmr_list[CLS_ENTRIES]; @@ -195,9 +196,9 @@ void configure_cls_pmr_chain(void) pmr_list[CLS_PMR_CHAIN_SRC] = odp_pmr_create();
[lng-odp] [API-NEXT PATCH v2 3/3] validation: cls: use correct MAC addresses
If pktio is in not promisc mode, a packet should contain correct MAC address. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 57 ++ 1 file changed, 57 insertions(+) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 25960c9..9e6a9e2 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -156,6 +156,7 @@ void classification_test_pmr_term_tcp_dport(void) odp_pool_t pool; odp_pool_t pool_recv; odp_pmr_match_t match; + odph_ethhdr_t *eth; val = CLS_DEFAULT_DPORT; mask = 0x; @@ -200,6 +201,9 @@ void classification_test_pmr_term_tcp_dport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); @@ -220,6 +224,9 @@ void classification_test_pmr_term_tcp_dport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1); @@ -266,6 +273,7 @@ void classification_test_pmr_term_tcp_sport(void) char cosname[ODP_COS_NAME_LEN]; odp_cls_cos_param_t cls_param; odp_pmr_match_t match; + odph_ethhdr_t *eth; val = CLS_DEFAULT_SPORT; mask = 0x; @@ -309,6 +317,9 @@ void classification_test_pmr_term_tcp_sport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); @@ -327,6 +338,9 @@ void classification_test_pmr_term_tcp_sport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1); @@ -373,6 +387,7 @@ void classification_test_pmr_term_udp_dport(void) char cosname[ODP_COS_NAME_LEN]; odp_pmr_match_t match; odp_cls_cos_param_t cls_param; + odph_ethhdr_t *eth; val = CLS_DEFAULT_DPORT; mask = 0x; @@ -416,6 +431,9 @@ void classification_test_pmr_term_udp_dport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); @@ -435,6 +453,9 @@ void classification_test_pmr_term_udp_dport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1); @@ -481,6 +502,7 @@ void classification_test_pmr_term_udp_sport(void) char cosname[ODP_COS_NAME_LEN]; odp_pmr_match_t match; odp_cls_cos_param_t cls_param; + odph_ethhdr_t *eth; val = CLS_DEFAULT_SPORT; mask = 0x; @@ -524,6 +546,9 @@ void classification_test_pmr_term_udp_sport(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt
[lng-odp] [API-NEXT PATCH v2 2/3] validation: cls: assign default CoS before creating chain
There is no big difference when to assign default CoS to pktio, but in usual case it's done before creating any chain, if it's needed to be checked it can be done in separate test. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 51 +- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 7f36f55..25960c9 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -166,6 +166,9 @@ void classification_test_pmr_term_tcp_dport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_TCP_DPORT; match.val = match.mask = @@ -193,8 +196,6 @@ void classification_test_pmr_term_tcp_dport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -275,6 +276,9 @@ void classification_test_pmr_term_tcp_sport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_TCP_SPORT; match.val = match.mask = @@ -301,8 +305,6 @@ void classification_test_pmr_term_tcp_sport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -381,6 +383,9 @@ void classification_test_pmr_term_udp_dport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_UDP_DPORT; match.val = match.mask = @@ -407,8 +412,6 @@ void classification_test_pmr_term_udp_dport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -488,6 +491,9 @@ void classification_test_pmr_term_udp_sport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_UDP_SPORT; match.val = match.mask = @@ -514,8 +520,6 @@ void classification_test_pmr_term_udp_sport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -593,6 +597,9 @@ void classification_test_pmr_term_ipproto(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_IPPROTO; match.val = match.mask = @@ -619,8 +626,6 @@ void classification_test_pmr_term_ipproto(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -694,6 +699,9 @@ void classification_test_pmr_term_dmac(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_DMAC; match.val = match.mask = @@ -720,8 +728,6 @@ void classification_test_pmr_term_dmac(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT
Re: [lng-odp] [PATCH] linux-generic: init: handle local/global init/term cleanly
On 14.01.16 23:21, Bill Fischofer wrote: Restructure odp_init_global() and odp_init_local() so that they recover cleanly if initialization fails. At exit any partial initialization is reversed so that system is in the same state as before the failing call was made. This includes adding dummy termination calls for functions that do not require explicit cleanup for symmetry and future-proofing. Note: This patch partially addresses the issues identified by Bug https://bugs.linaro.org/show_bug.cgi?id=1706 Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp_internal.h | 24 ++- platform/linux-generic/odp_init.c | 239 ++ platform/linux-generic/odp_system_info.c | 8 + platform/linux-generic/odp_time.c | 7 +- platform/linux-generic/odp_timer.c| 5 + 5 files changed, 209 insertions(+), 74 deletions(-) diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 113b700..b22f956 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -38,9 +38,29 @@ struct odp_global_data_s { odp_system_info_t system_info; }; +enum init_stage { + NO_INIT = 0,/* No init stages completed */ + TIME_INIT = 1, + SYSINFO_INIT = 2, + SHM_INIT = 3, + THREAD_INIT = 4, + POOL_INIT = 5, + QUEUE_INIT = 6, + SCHED_INIT = 7, + PKTIO_INIT = 8, + TIMER_INIT = 9, + CRYPTO_INIT = 10, + CLASSIFICATION_INIT = 11, + ALL_INIT = 12 /* All init stages completed */ +}; + extern struct odp_global_data_s odp_global_data; +int _odp_term_global(enum init_stage stage); +int _odp_term_local(enum init_stage stage); + int odp_system_info_init(void); +int odp_system_info_term(void); int odp_thread_init_global(void); int odp_thread_init_local(odp_thread_type_t type); @@ -75,9 +95,11 @@ int odp_schedule_init_local(void); int odp_schedule_term_local(void); int odp_timer_init_global(void); +int odp_timer_term_global(void); int odp_timer_disarm_all(void); -int odp_time_global_init(void); +int odp_time_init_global(void); +int odp_time_term_global(void); void _odp_flush_caches(void); diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index ea99742..3a990d2 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -14,6 +14,7 @@ struct odp_global_data_s odp_global_data; int odp_init_global(const odp_init_t *params, const odp_platform_init_t *platform_params ODP_UNUSED) { + enum init_stage stage = NO_INIT; odp_global_data.log_fn = odp_override_log; odp_global_data.abort_fn = odp_override_abort; @@ -24,105 +25,170 @@ int odp_init_global(const odp_init_t *params, odp_global_data.abort_fn = params->abort_fn; } - if (odp_time_global_init()) { + if (odp_time_init_global()) { ODP_ERR("ODP time init failed.\n"); - return -1; + goto init_failed; } + stage = TIME_INIT; if (odp_system_info_init()) { ODP_ERR("ODP system_info init failed.\n"); - return -1; + goto init_failed; } + stage = SYSINFO_INIT; if (odp_shm_init_global()) { ODP_ERR("ODP shm init failed.\n"); - return -1; + goto init_failed; } + stage = SHM_INIT; if (odp_thread_init_global()) { ODP_ERR("ODP thread init failed.\n"); - return -1; + goto init_failed; } + stage = THREAD_INIT; if (odp_pool_init_global()) { ODP_ERR("ODP pool init failed.\n"); - return -1; + goto init_failed; } + stage = POOL_INIT; if (odp_queue_init_global()) { ODP_ERR("ODP queue init failed.\n"); - return -1; + goto init_failed; } + stage = QUEUE_INIT; if (odp_schedule_init_global()) { ODP_ERR("ODP schedule init failed.\n"); - return -1; + goto init_failed; } + stage = SCHED_INIT; if (odp_pktio_init_global()) { ODP_ERR("ODP packet io init failed.\n"); - return -1; + goto init_failed; } + stage = PKTIO_INIT; if (odp_timer_init_global()) { ODP_ERR("ODP timer init failed.\n"); - return -1; + goto init_failed; } + stage = TIMER_INIT; if (odp_crypto_init_global()) {
Re: [lng-odp] [PATCH] validation: pktio: reduce stdout noise
On 15.01.16 18:18, Stuart Haslam wrote: Printing the pktio info every time a pktio is opened generates a load of noise on stdout and makes it difficult to see the status of individual test cases. Signed-off-by: Stuart Haslam <stuart.has...@linaro.org> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Log goes from this: http://people.linaro.org/~stuart.haslam/pktio1.log To this: http://people.linaro.org/~stuart.haslam/pktio2.log test/validation/pktio/pktio.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index b3732bb..9c8c871 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -293,10 +293,6 @@ static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_to_u64(pktio) != odp_pktio_to_u64(ODP_PKTIO_INVALID)); - /* Print pktio debug info and test that the odp_pktio_print() function -* is implemented. */ - if (pktio != ODP_PKTIO_INVALID) - odp_pktio_print(pktio); if (wait_for_network) spin_wait(ODP_TIME_SEC_IN_NS / 4); @@ -734,6 +730,24 @@ void pktio_test_lookup(void) CU_ASSERT(odp_pktio_lookup(iface_name[0]) == ODP_PKTIO_INVALID); } +static void pktio_test_print(void) +{ + odp_pktio_t pktio; + int i; + + for (i = 0; i < num_ifaces; ++i) { + pktio = create_pktio(i, ODP_PKTIN_MODE_POLL, +ODP_PKTOUT_MODE_SEND); + CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); + + /* Print pktio debug info and test that the +* odp_pktio_print() function is implemented. */ + odp_pktio_print(pktio); + + CU_ASSERT(odp_pktio_close(pktio) == 0); + } +} + void pktio_test_inq(void) { odp_pktio_t pktio; @@ -1217,6 +1231,7 @@ int pktio_suite_term(void) odp_testinfo_t pktio_suite_unsegmented[] = { ODP_TEST_INFO(pktio_test_open), ODP_TEST_INFO(pktio_test_lookup), + ODP_TEST_INFO(pktio_test_print), ODP_TEST_INFO(pktio_test_inq), ODP_TEST_INFO(pktio_test_poll_queue), ODP_TEST_INFO(pktio_test_poll_multi), -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] linux-generic: pktio: remove unwanted initialisation
On 15.01.16 17:45, Stuart Haslam wrote: Remove an unwanted initialisation and fix a bad indentation which crept in during a merge. forgot to add signed-off Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/pktio/loop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 47745ad..95644c4 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -57,7 +57,6 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[], odp_packet_hdr_t *pkt_hdr; odp_packet_t pkt; - nbr = 0; qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq); nbr = queue_deq_multi(qentry, hdr_tbl, len); @@ -71,7 +70,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[], if (0 > _odp_packet_classifier(pktio_entry, pkt)) pkts[j++] = pkt; } - nbr = j; + nbr = j; } else { for (i = 0; i < nbr; ++i) { pkts[i] = _odp_packet_from_buffer(odp_hdr_to_buf -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 118 test/validation/system/system.h | 4 ++ 2 files changed, 122 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..4a382ac 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,118 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 < max1 && c2 < max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t etalon, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + etalon = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + etalon = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == etalon); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) + return; + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + etalon = c2 - c1; + else + etalon = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t c2, c1; + uint64_t res, diff; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another +* case resolution is set incorrectly +*/ + for (i = 0; i < 10; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +205,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 869aaff..0c263f2 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -17,6 +17,10 @@ void system_test_odp_sys_cpu_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_sys_cpu_hz(void); +void system_test_odp_cpu_cycles_max(void); +void system_test_odp_cpu_cycles(void); +void system_test_odp_cpu_cycles_diff(void); +void system_test_odp_cpu_cycles_resolution(void); /* test arrays: */ extern odp_testinfo_t system_suite[]; -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2] validation: system: add validation tests for odp_cpu_cycles_* calls
Hi, Petri This patch contains validation tests for API you've recently added. Could you please review it. On 15.01.16 11:16, Ivan Khoronzhuk wrote: https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 118 test/validation/system/system.h | 4 ++ 2 files changed, 122 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..4a382ac 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,118 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t c2, c1; + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(1000); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c1 < max1 && c2 < max1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t etalon, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + etalon = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + etalon = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == etalon); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) + return; + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + etalon = c2 - c1; + else + etalon = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t c2, c1; + uint64_t res, diff; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another +* case resolution is set incorrectly +*/ + for (i = 0; i < 10; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +205,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 869aaff..0c263f2 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -17,6 +17,10 @@ void system_test_odp_sys_cpu_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_sys_cpu_hz(void); +void system_test_odp_cpu_cycles_max(void); +void system_test_odp_cpu_cycles(void); +void system_test_odp_cpu_cycles_diff(void); +void system_test_odp_cpu_cycles_resolution(void); /* test arrays: */ extern odp_testinfo_t system_suite[]; -- Regards, Ivan
[lng-odp] [PATCH v6] example: time: add test of global time API on monotony
This test example uses linux helper functions to schedule worker threads in order to check global time monotony between the threads. Each thread receives event from it's own queue, checks global time on correctness, writes in the buffer new current global time, chooses randomly next thread queue, sends event and waits on next event on it's own queue. Using for each thread it's own queue guarantees that event is read by not the same thread that sends it. When global time source is correct the time received with event by a thread must be less than read on the moment of receiving. Reviewed-and-tested-by: Bill Fischofer <bill.fischo...@linaro.org> Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Since v5: - align strings to be less than 80 chars - added parentheses in macros definition Since v4: - convert time to ns only while printing log Since v3: - defined log entry size Since v2: -added binary to .gitignore Since v1: - replaced many includes on odp.h - corrected a little error path - increased num of iterations - rebased on ODPv1.6 configure.ac| 1 + example/Makefile.am | 2 +- example/time/.gitignore | 1 + example/time/Makefile.am| 10 ++ example/time/time_global_test.c | 358 5 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 example/time/.gitignore create mode 100644 example/time/Makefile.am create mode 100644 example/time/time_global_test.c diff --git a/configure.ac b/configure.ac index 2626fd7..b284384 100644 --- a/configure.ac +++ b/configure.ac @@ -338,6 +338,7 @@ AC_CONFIG_FILES([Makefile example/generator/Makefile example/ipsec/Makefile example/packet/Makefile +example/time/Makefile example/timer/Makefile helper/Makefile helper/test/Makefile diff --git a/example/Makefile.am b/example/Makefile.am index 353f397..39d9b01 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1 +1 @@ -SUBDIRS = classifier generator ipsec packet timer +SUBDIRS = classifier generator ipsec packet time timer diff --git a/example/time/.gitignore b/example/time/.gitignore new file mode 100644 index 000..3106aea --- /dev/null +++ b/example/time/.gitignore @@ -0,0 +1 @@ +odp_time_global_test diff --git a/example/time/Makefile.am b/example/time/Makefile.am new file mode 100644 index 000..915593a --- /dev/null +++ b/example/time/Makefile.am @@ -0,0 +1,10 @@ +include $(top_srcdir)/example/Makefile.inc + +bin_PROGRAMS = odp_time_global_test$(EXEEXT) +odp_time_global_test_LDFLAGS = $(AM_LDFLAGS) -static +odp_time_global_test_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/example + +noinst_HEADERS = \ + $(top_srcdir)/example/example_debug.h + +dist_odp_time_global_test_SOURCES = time_global_test.c diff --git a/example/time/time_global_test.c b/example/time/time_global_test.c new file mode 100644 index 000..df0826c --- /dev/null +++ b/example/time/time_global_test.c @@ -0,0 +1,358 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define MAX_WORKERS32 +#define ITERATION_NUM 2048 +#define LOG_BASE 8 +#define LOG_ENTRY_SIZE 19 +#define LOG_LINE_SIZE (LOG_BASE * LOG_ENTRY_SIZE + 1) + +#define QUEUE_NAME_PREFIX "thread_queue_" + +typedef struct { + odp_time_t timestamp; + int id; +} timestamp_event_t; + +typedef struct { + uint8_t thr; + uint8_t id; + odp_time_t time; +} log_entry_t; + +typedef struct { + uint32_t iteration_num; + odp_atomic_u32_t iteration_counter; + odp_atomic_u32_t id_counter; + odp_atomic_u32_t log_counter; + odp_atomic_u32_t err_counter; + odp_barrier_t start_barrier; + odp_barrier_t end_barrier; + int thread_num; + log_entry_t *log; + int log_enries_num; +} test_globals_t; + +static void print_log(test_globals_t *gbls) +{ + uint32_t err_num; + int i, j, k, pad; + char line[LOG_LINE_SIZE]; + + memset(line, '-', LOG_LINE_SIZE - 1); + line[LOG_LINE_SIZE - 1] = 0; + for (i = 1; i <= gbls->thread_num; i++) { + printf("\n history of %d buffer, time,ns (thread) \n%s\n", + i, line); + + /* print log for buffer */ + k = 0; + for (j = 0; j < gbls->log_enries_num; j++) + if (gbls->log[j].id == i) { + printf("%10" PRIu64 " (%-3d)", + odp_time_to_ns(gbls->log[j].time), + gbls->log[j].thr); + + if (!(++k % LOG_BASE)) +
Re: [lng-odp] [PATCH 0/5] validation: cls: correct tests a little
On 14.01.16 07:51, Bala Manoharan wrote: Hi Ivan, It would be better if you can send this patch on API-NEXT branch as I said before I am working on API proposal to modify odp_pmr_create() function syntax and it would be easy if we could modify your changes to API-NEXT and then we can move it to master branch. Ok, I'll base it on api-next. The patch 3 in your series is not applying on the master branch. Further comments on each patch series. Regards, Bala Regards, Bala On 12 January 2016 at 23:41, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: This patch series corrects classification tests to be a little bit adoptive. Ivan Khoronzhuk (5): validation: cls: adopt for supported l3 PMR validation: cls: assign default CoS before creating chain validation: cls: test_pmr: don't create default input queue validation: cls: use correct MAC addresses validation: cls: split pmr chain test test/validation/classification/classification.h| 28 +-- .../classification/odp_classification_basic.c | 4 +- .../classification/odp_classification_common.c | 52 ++ .../classification/odp_classification_test_pmr.c | 205 - .../classification/odp_classification_tests.c | 127 ++--- .../classification/odp_classification_testsuites.h | 2 + 6 files changed, 203 insertions(+), 215 deletions(-) -- 1.9.1 -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: pktio: assign MAC address if one loop pktio is used
In case of one loop pktio the MAC address is not set in the packets but should be. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 536ef6c..a756af4 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -830,11 +830,21 @@ void pktio_test_start_stop(void) pktio_init_packet(pkt); if (num_ifaces > 1) { pktio_pkt_set_macs(pkt, pktio[0], pktio[1]); - if (pktio_fixup_checksums(pkt) != 0) { - odp_packet_free(pkt); - break; - } + } else { + uint32_t len; + odph_ethhdr_t *eth; + + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, ); + ret = odp_pktio_mac_addr(pktio[0], +>dst, sizeof(eth->dst)); + CU_ASSERT(ret == ODPH_ETHADDR_LEN); } + + if (pktio_fixup_checksums(pkt) != 0) { + odp_packet_free(pkt); + break; + } + tx_ev[alloc] = odp_packet_to_event(pkt); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [RFC PATCH] api: packet_io: return headroom when set new one
On 14.01.16 14:03, Bala Manoharan wrote: Maximum headroom is defined in ODP_PACKET_MAX_HEADROOM and is an implementation specific value and will not be greater than uint32/2. Having said that the current definition of headroom in ODP is that it will not exceed a single segment meaning the headroom will NOT overflow by adding an empty segment before. Regarding returning the previous allocated headroom, IMO it is a stale value and is of no significance to the existing application. If you have any use-case in mind for returning previous headroom pls share. Regards, Bala at least one usecase it's testing, when the same pktio can be used farther after testing/changing headroom call. Yes, it can be tested with own pktio, but it's simpler. For instance, like it's done in classification_test_pktio_set_headroom)_ test case. By a big account, headroom has to be restored. On 13 January 2016 at 22:29, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: It can be used to restore headroom later. Does it possible a headroom to be > sizeof(int32)/2? Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- include/odp/api/packet_io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index cf92751..7b9d82a 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -356,12 +356,12 @@ int odp_pktio_skip_set(odp_pktio_t pktio, uint32_t offset); * Must not exceed the implementation * defined ODP_PACKET_MAX_HEADROOM. * - * @retval 0 on success + * @retval prevoius headroom * @retval <0 on failure * * @note Optional. */ -int odp_pktio_headroom_set(odp_pktio_t pktio, uint32_t headroom); +int32_t odp_pktio_headroom_set(odp_pktio_t pktio, int32_t headroom); /** * Get printable value for an odp_pktio_t -- 1.9.1 ___ 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] [PATCH] validation: system: add validation tests for odp_cpu_cycles_* calls
https://bugs.linaro.org/show_bug.cgi?id=1906 Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/system/system.c | 111 test/validation/system/system.h | 4 ++ 2 files changed, 115 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 7dc2cc0..8edbd04 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -10,6 +10,8 @@ #include "test_debug.h" #include "system.h" +#define TRY_NUM80 + void system_test_odp_version_numbers(void) { int char_ok = 0; @@ -40,6 +42,111 @@ void system_test_odp_cpu_count(void) CU_ASSERT(0 < cpus); } +void system_test_odp_cpu_cycles_max(void) +{ + uint64_t max1, max2; + + max1 = odp_cpu_cycles_max(); + odp_time_wait_ns(100); + max2 = odp_cpu_cycles_max(); + + CU_ASSERT(max1 >= UINT32_MAX / 2); + CU_ASSERT(max1 == max2); +} + +void system_test_odp_cpu_cycles(void) +{ + uint64_t c2, c1; + + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); +} + +void system_test_odp_cpu_cycles_diff(void) +{ + int i; + uint64_t c2, c1; + uint64_t etalon, diff; + + c2 = 100; + c1 = 39; + + diff = odp_cpu_cycles_diff(c2, c2); + CU_ASSERT(diff == 0); + + etalon = c2 - c1; + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + etalon = c1 + (odp_cpu_cycles_max() - c2) + 1; + diff = odp_cpu_cycles_diff(c1, c2); + CU_ASSERT(diff == etalon); + + c1 = odp_cpu_cycles(); + if (!(odp_cpu_cycles_max() <= UINT32_MAX || + (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) + return; + + /* must handle one wrap */ + for (i = 0; i < TRY_NUM; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + CU_ASSERT(c2 != c1); + + if (c2 > c1) + etalon = c2 - c1; + else + etalon = c2 + (odp_cpu_cycles_max() - c1) + 1; + + diff = odp_cpu_cycles_diff(c2, c1); + CU_ASSERT(diff == etalon); + + /* wrap is detected and verified */ + if (c2 < c1) + break; + } + + /* wrap has to be detected */ + CU_ASSERT(i < TRY_NUM); +} + +void system_test_odp_cpu_cycles_resolution(void) +{ + int i; + uint64_t rest; + uint64_t c2, c1; + uint64_t res, diff; + + res = odp_cpu_cycles_resolution(); + CU_ASSERT(res != 0); + + /* +* must be a multiple of resolution in +* whole interval till wrap, in another +* case resolution is set in correctly +*/ + for (i = 0; i < 10; i++) { + c1 = odp_cpu_cycles(); + odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i); + c2 = odp_cpu_cycles(); + + diff = odp_cpu_cycles_diff(c2, c1); + rest = diff % res; + CU_ASSERT(rest == 0); + + rest = c1 % res; + CU_ASSERT(rest == 0); + + rest = c2 % res; + CU_ASSERT(rest == 0); + } +} + void system_test_odp_sys_cache_line_size(void) { uint64_t cache_size; @@ -91,6 +198,10 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_sys_page_size), ODP_TEST_INFO(system_test_odp_sys_huge_page_size), ODP_TEST_INFO(system_test_odp_sys_cpu_hz), + ODP_TEST_INFO(system_test_odp_cpu_cycles_max), + ODP_TEST_INFO(system_test_odp_cpu_cycles), + ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 869aaff..0c263f2 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -17,6 +17,10 @@ void system_test_odp_sys_cpu_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_sys_cpu_hz(void); +void system_test_odp_cpu_cycles_max(void); +void system_test_odp_cpu_cycles(void); +void system_test_odp_cpu_cycles_diff(void); +void system_test_odp_cpu_cycles_resolution(void); /* test arrays: */ extern odp_testinfo_t system_suite[]; -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 5/5] validation: cls: split pmr chain test
On 14.01.16 07:55, Bala Manoharan wrote: The idea behind this suite is to have a mechanism to test the behaviour of the system after applying all the different PMR, default CoS, error CoS and L2 and L3 CoS values. your suggested changes tests each and every configuration individually which defeats the idea of the suite. There is a dedicated suite to test individual PMR values behaviour. Regards, Bala Maybe, but it's hard to figure out what is broken, especially when some parts are not supported or implemented. In case of splitting it's possible to see what doesn't work, I can drop this patch but IMHO, one test includes a lot of different units that has not been tested before, like error CoS, default CoS (it was created but not tested), CoS with L2 pr...And now all in one chunk...one broken and seems like all are broken. It can be leaved like this but it should be tested separately. On 12 January 2016 at 23:41, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: These tests are simple classification tests and better to see results for each of them separately. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/classification/classification.h| 22 --- .../classification/odp_classification_tests.c | 72 -- 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index f363812..6d2e55f 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -13,7 +13,6 @@ #define SHM_PKT_BUF_SIZE1024 /* Config values for Default CoS */ -#define TEST_DEFAULT 1 #defineCLS_DEFAULT 0 #define CLS_DEFAULT_SADDR "10.0.0.1/32" #define CLS_DEFAULT_DADDR "10.0.0.100/32" @@ -21,29 +20,24 @@ #define CLS_DEFAULT_DPORT 2048 /* Config values for Error CoS */ -#define TEST_ERROR 1 #define CLS_ERROR 1 /* Config values for PMR_CHAIN */ -#define TEST_PMR_CHAIN 1 #define CLS_PMR_CHAIN_SRC 2 #define CLS_PMR_CHAIN_DST 3 #define CLS_PMR_CHAIN_SADDR"10.0.0.5/32" #define CLS_PMR_CHAIN_PORT 3000 /* Config values for PMR */ -#define TEST_PMR 1 #define CLS_PMR4 #define CLS_PMR_PORT 4000 /* Config values for PMR SET */ -#define TEST_PMR_SET 1 #define CLS_PMR_SET5 #define CLS_PMR_SET_SADDR "10.0.0.6/32" #define CLS_PMR_SET_PORT 5000 /* Config values for CoS L2 Priority */ -#define TEST_L2_QOS1 #define CLS_L2_QOS_0 6 #define CLS_L2_QOS_MAX 5 @@ -68,8 +62,20 @@ void classification_test_pktio_set_skip(void); void classification_test_pktio_set_headroom(void); void classification_test_pmr_terms_avail(void); void classification_test_pmr_terms_cap(void); -void classification_test_pktio_configure(void); -void classification_test_pktio_test(void); + +void classification_test_configure_pktio_default_cos(void); +void classification_test_configure_pktio_error_cos(void); +void classification_test_configure_cls_pmr_chain(void); +void classification_test_configure_cos_with_l2_priority(void); +void classification_test_configure_pmr_cos(void); +void classification_test_configure_pktio_pmr_match_set_cos(void); + +void classification_test_pktio_default_cos(void); +void classification_test_pktio_error_cos(void); +void classification_test_cls_pmr_chain(void); +void classification_test_cos_with_l2_priority(void); +void classification_test_pmr_cos(void); +void classification_test_pktio_pmr_match_set_cos(void); void classification_test_pmr_term_tcp_dport(void); void classification_test_pmr_term_tcp_sport(void); diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index 34fc570..482e2d0 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -133,7 +133,7 @@ cls_create_packet(bool vlan, odp_atomic_u32_t *seq, bool flag_udp) return pkt; } -void configure_cls_pmr_chain(void) +void classification_test_configure_cls_pmr_chain(void) { /* PKTIO --> PMR_SRC(SRC IP ADDR) --> PMR_DST (TCP SPORT) */ @@ -230,7 +230,7 @@ void configure_cls_pmr_chain(void) CU_ASSERT(retval == 0); } -void test_cls_pmr_chain(void) +void classification_test_cls_pmr_chain(void) { odp_packet_t pkt; odph_ipv4hdr_t *ip; @@ -284,7 +284,7 @@ void test_cls_pmr_chain(void) odp_packet_free(pkt); } -void configure_pktio_default_cos(void) +void classification_test_configure_pktio_default_cos(void) { int retval; odp_queue_param_t qparam; @@ -318,7 +318,7 @@ void configure_pktio_def
Re: [lng-odp] [PATCH 3/5] validation: cls: test_pmr: don't create default input queue
On 14.01.16 07:52, Bala Manoharan wrote: This patch does not apply maybe you need to rebase to HEAD. Regards, Bala Regards, Bala I will re-base, but this patch still has questions. Like, do we need to assign default input queue if it's not supposed to be used and completely replaced by default CoS? Also, seems I forgot to start pktio afterwards. But when I started it, I see that linux-generic implementation doesn't pass the test, strange. What is going on? My board passes it correctly. On 12 January 2016 at 23:41, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: There is no need to create default input queue for pktio if default CoS is assigned. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 54 -- 1 file changed, 54 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 75d2a95..0b3f279 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -55,39 +55,6 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) return pktio; } -int create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype) -{ - odp_queue_param_t qparam; - odp_queue_t inq_def; - char inq_name[ODP_QUEUE_NAME_LEN]; - - odp_queue_param_init(); - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; - qparam.sched.group = ODP_SCHED_GROUP_ALL; - - snprintf(inq_name, sizeof(inq_name), "inq-pktio-%" PRIu64, -odp_pktio_to_u64(pktio)); - inq_def = odp_queue_lookup(inq_name); - if (inq_def == ODP_QUEUE_INVALID) - inq_def = odp_queue_create( - inq_name, - ODP_QUEUE_TYPE_PKTIN, - qtype == ODP_QUEUE_TYPE_POLL ? NULL : ); - - CU_ASSERT_FATAL(inq_def != ODP_QUEUE_INVALID); - - if (0 > odp_pktio_inq_setdef(pktio, inq_def)) - return -1; - - if (odp_pktio_start(pktio)) { - fprintf(stderr, "unable to start loop\n"); - return -1; - } - - return 0; -} - void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, odp_queue_t *queue, odp_pool_t *pool) { @@ -163,8 +130,6 @@ void classification_test_pmr_term_tcp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -237,7 +202,6 @@ void classification_test_pmr_term_tcp_dport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); odp_pool_destroy(pool); @@ -273,8 +237,6 @@ void classification_test_pmr_term_tcp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -344,7 +306,6 @@ void classification_test_pmr_term_tcp_sport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); odp_queue_destroy(queue); @@ -380,8 +341,6 @@ void classification_test_pmr_term_udp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -452,7 +411,6 @@ void classification_test_pmr_term_udp_dport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); odp_pool_destroy(default_pool); @@ -488,8 +446,6 @@ void classification_test_pmr_term_udp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -559,7 +515,6 @@ void classification_test_pmr_term_udp_sport(void) odp_cos_des
Re: [lng-odp] [PATCH 4/5] validation: cls: use correct MAC addresses
On 14.01.16 07:59, Bala Manoharan wrote: The idea of having to create pktio in each and every test case is to create robustness in test cases and have them as independent from each other as possible. In classification when you remove a CoS rule it is not expected to see the changes immediately some systems will have latency and the packets might be classified using stale rules. So it is better to destroy and re-create pktio interface for each test cases. Regards, Bala Regards, Bala Agree. Initially I've done like proposed, but then look in odp_classification_tests.c, and see that mostly common pktio_loop is used. I will correct to set MAC addresses for each test, but odp_classification_tests.c should be sophisticated also, later. On 12 January 2016 at 23:41, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: If pktion is in not promisc mode, a packet should contain correct MAC address. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 158 ++--- .../classification/odp_classification_tests.c | 30 +++- 2 files changed, 96 insertions(+), 92 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 0b3f279..bb69794 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -13,22 +13,11 @@ #include static odp_pool_t pkt_pool; +static odp_pktio_t pktio_loop; /** sequence number of IP packets */ odp_atomic_u32_t seq; -int classification_suite_pmr_init(void) -{ - pkt_pool = pool_create("classification_pmr_pool"); - if (ODP_POOL_INVALID == pkt_pool) { - fprintf(stderr, "Packet pool creation failed.\n"); - return -1; - } - - odp_atomic_init_u32(, 0); - return 0; -} - odp_pktio_t create_pktio(odp_queue_type_t q_type) { odp_pktio_t pktio; @@ -55,6 +44,35 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) return pktio; } +int classification_suite_pmr_init(void) +{ + pkt_pool = pool_create("classification_pmr_pool"); + if (ODP_POOL_INVALID == pkt_pool) { + fprintf(stderr, "Packet pool creation failed.\n"); + return -1; + } + + pktio_loop = create_pktio(ODP_QUEUE_TYPE_SCHED); + + odp_atomic_init_u32(, 0); + return 0; +} + +static odp_packet_t +cls_create_packet(bool vlan, odp_atomic_u32_t *seq, bool flag_udp) +{ + odp_packet_t pkt; + odph_ethhdr_t *eth; + + pkt = create_packet(pkt_pool, vlan, seq, flag_udp); + + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio_loop, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio_loop, eth->dst.addr, ODPH_ETHADDR_LEN); + + return pkt; +} + void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, odp_queue_t *queue, odp_pool_t *pool) { @@ -93,6 +111,11 @@ int classification_suite_pmr_term(void) { int retcode = 0; + if (odp_pktio_close(pktio_loop)) { + fprintf(stderr, "unable to close pktio_loop.\n"); + retcode = -1; + } + if (0 != odp_pool_destroy(pkt_pool)) { fprintf(stderr, "pkt_pool destroy failed.\n"); retcode = -1; @@ -109,7 +132,6 @@ void classification_test_pmr_term_tcp_dport(void) uint16_t val; uint16_t mask; int retval; - odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; odp_queue_t default_queue; @@ -128,10 +150,7 @@ void classification_test_pmr_term_tcp_dport(void) mask = 0x; seqno = 0; - pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - - configure_default_cos(pktio, _cos, + configure_default_cos(pktio_loop, _cos, _queue, _pool); match.term = ODP_PMR_TCP_DPORT; @@ -158,10 +177,10 @@ void classification_test_pmr_term_tcp_dport(void) cos = odp_cls_cos_create(cosname, _param); CU_ASSERT(cos != ODP_COS_INVALID); - retval = odp_pktio_pmr_cos(pmr, pktio, cos); + retval = odp_pktio_pmr_cos(pmr, pktio_loop, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pkt_pool, false, , false); + pkt = cls_create_packet(false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -169,7 +188,7 @@ void classification_test_pmr_term_tcp_dport(void) tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); - enqueue_pktio_inter
[lng-odp] [RFC PATCH] api: packet_io: return headroom when set new one
It can be used to restore headroom later. Does it possible a headroom to be > sizeof(int32)/2? Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- include/odp/api/packet_io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index cf92751..7b9d82a 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -356,12 +356,12 @@ int odp_pktio_skip_set(odp_pktio_t pktio, uint32_t offset); * Must not exceed the implementation * defined ODP_PACKET_MAX_HEADROOM. * - * @retval 0 on success + * @retval prevoius headroom * @retval <0 on failure * * @note Optional. */ -int odp_pktio_headroom_set(odp_pktio_t pktio, uint32_t headroom); +int32_t odp_pktio_headroom_set(odp_pktio_t pktio, int32_t headroom); /** * Get printable value for an odp_pktio_t -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: pktio: use odp_time_ns() instead own function
Now odp_time_wait_ns() can be used. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 45c11c5..29ad4ea 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -259,17 +259,6 @@ static int default_pool_create(void) return 0; } -static void spin_wait(uint64_t ns) -{ - odp_time_t start, now, diff; - - start = odp_time_local(); - do { - now = odp_time_local(); - diff = odp_time_diff(now, start); - } while (odp_time_to_ns(diff) < ns); -} - static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_output_mode_t omode) { @@ -294,7 +283,7 @@ static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_print(pktio); if (wait_for_network) - spin_wait(ODP_TIME_SEC_IN_NS / 4); + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); return pktio; } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH] validation: pktio: fix check of pktio_stop() called twice
The odp_pktio_stop() called is supposed to return error. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/pktio/pktio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index 29ad4ea..1ca4979 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -737,7 +737,7 @@ void pktio_test_start_stop(void) /* Interfaces are stopped by default, * Check that stop when stopped generates an error */ ret = odp_pktio_stop(pktio[0]); - CU_ASSERT(ret <= 0); + CU_ASSERT(ret < 0); /* start first */ ret = odp_pktio_start(pktio[0]); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH 0/5] validation: cls: correct tests a little
This patch series corrects classification tests to be a little bit adoptive. Ivan Khoronzhuk (5): validation: cls: adopt for supported l3 PMR validation: cls: assign default CoS before creating chain validation: cls: test_pmr: don't create default input queue validation: cls: use correct MAC addresses validation: cls: split pmr chain test test/validation/classification/classification.h| 28 +-- .../classification/odp_classification_basic.c | 4 +- .../classification/odp_classification_common.c | 52 ++ .../classification/odp_classification_test_pmr.c | 205 - .../classification/odp_classification_tests.c | 127 ++--- .../classification/odp_classification_testsuites.h | 2 + 6 files changed, 203 insertions(+), 215 deletions(-) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH 2/5] validation: cls: assign default CoS before creating chain
There is no big difference when to assign default CoS to pktio, but in usual case it's done before creating any chain, if it's needed to be also checked it can be done in separate test. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 35 +- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 6644b53..75d2a95 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -166,6 +166,9 @@ void classification_test_pmr_term_tcp_dport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_TCP_DPORT; match.val = match.mask = @@ -193,8 +196,6 @@ void classification_test_pmr_term_tcp_dport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -275,6 +276,9 @@ void classification_test_pmr_term_tcp_sport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_TCP_SPORT; match.val = match.mask = @@ -301,8 +305,6 @@ void classification_test_pmr_term_tcp_sport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -381,6 +383,9 @@ void classification_test_pmr_term_udp_dport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_UDP_DPORT; match.val = match.mask = @@ -407,8 +412,6 @@ void classification_test_pmr_term_udp_dport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -488,6 +491,9 @@ void classification_test_pmr_term_udp_sport(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_UDP_SPORT; match.val = match.mask = @@ -514,8 +520,6 @@ void classification_test_pmr_term_udp_sport(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -593,6 +597,9 @@ void classification_test_pmr_term_ipproto(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_IPPROTO; match.val = match.mask = @@ -619,8 +626,6 @@ void classification_test_pmr_term_ipproto(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false, , true); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -694,6 +699,9 @@ static void classification_test_pmr_pool_set(void) retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); CU_ASSERT(retval == 0); + configure_default_cos(pktio, _cos, + _queue, _pool); + match.term = ODP_PMR_IPPROTO; match.val = match.mask = @@ -727,8 +735,6 @@ static void classification_test_pmr_pool_set(void) retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - configure_default_cos(pktio, _cos, - _queue, _pool); pkt = create_packet(pkt_pool, false,
[lng-odp] [PATCH 3/5] validation: cls: test_pmr: don't create default input queue
There is no need to create default input queue for pktio if default CoS is assigned. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 54 -- 1 file changed, 54 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 75d2a95..0b3f279 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -55,39 +55,6 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) return pktio; } -int create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype) -{ - odp_queue_param_t qparam; - odp_queue_t inq_def; - char inq_name[ODP_QUEUE_NAME_LEN]; - - odp_queue_param_init(); - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; - qparam.sched.group = ODP_SCHED_GROUP_ALL; - - snprintf(inq_name, sizeof(inq_name), "inq-pktio-%" PRIu64, -odp_pktio_to_u64(pktio)); - inq_def = odp_queue_lookup(inq_name); - if (inq_def == ODP_QUEUE_INVALID) - inq_def = odp_queue_create( - inq_name, - ODP_QUEUE_TYPE_PKTIN, - qtype == ODP_QUEUE_TYPE_POLL ? NULL : ); - - CU_ASSERT_FATAL(inq_def != ODP_QUEUE_INVALID); - - if (0 > odp_pktio_inq_setdef(pktio, inq_def)) - return -1; - - if (odp_pktio_start(pktio)) { - fprintf(stderr, "unable to start loop\n"); - return -1; - } - - return 0; -} - void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, odp_queue_t *queue, odp_pool_t *pool) { @@ -163,8 +130,6 @@ void classification_test_pmr_term_tcp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -237,7 +202,6 @@ void classification_test_pmr_term_tcp_dport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); odp_pool_destroy(pool); @@ -273,8 +237,6 @@ void classification_test_pmr_term_tcp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -344,7 +306,6 @@ void classification_test_pmr_term_tcp_sport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); odp_queue_destroy(queue); @@ -380,8 +341,6 @@ void classification_test_pmr_term_udp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -452,7 +411,6 @@ void classification_test_pmr_term_udp_dport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); odp_pool_destroy(default_pool); @@ -488,8 +446,6 @@ void classification_test_pmr_term_udp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -559,7 +515,6 @@ void classification_test_pmr_term_udp_sport(void) odp_cos_destroy(cos); odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); - destroy_inq(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); odp_queue_destroy(queue); @@ -594,8 +549,6 @@ void classification_test_pmr_term_ipproto(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT(retval == 0); configure_default_cos(pktio, _cos, _queue, _pool); @@ -660,7 +613,6 @@ void classificati
[lng-odp] [PATCH 5/5] validation: cls: split pmr chain test
These tests are simple classification tests and better to see results for each of them separately. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/classification/classification.h| 22 --- .../classification/odp_classification_tests.c | 72 -- 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index f363812..6d2e55f 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -13,7 +13,6 @@ #define SHM_PKT_BUF_SIZE1024 /* Config values for Default CoS */ -#define TEST_DEFAULT 1 #defineCLS_DEFAULT 0 #define CLS_DEFAULT_SADDR "10.0.0.1/32" #define CLS_DEFAULT_DADDR "10.0.0.100/32" @@ -21,29 +20,24 @@ #define CLS_DEFAULT_DPORT 2048 /* Config values for Error CoS */ -#define TEST_ERROR 1 #define CLS_ERROR 1 /* Config values for PMR_CHAIN */ -#define TEST_PMR_CHAIN 1 #define CLS_PMR_CHAIN_SRC 2 #define CLS_PMR_CHAIN_DST 3 #define CLS_PMR_CHAIN_SADDR"10.0.0.5/32" #define CLS_PMR_CHAIN_PORT 3000 /* Config values for PMR */ -#define TEST_PMR 1 #define CLS_PMR4 #define CLS_PMR_PORT 4000 /* Config values for PMR SET */ -#define TEST_PMR_SET 1 #define CLS_PMR_SET5 #define CLS_PMR_SET_SADDR "10.0.0.6/32" #define CLS_PMR_SET_PORT 5000 /* Config values for CoS L2 Priority */ -#define TEST_L2_QOS1 #define CLS_L2_QOS_0 6 #define CLS_L2_QOS_MAX 5 @@ -68,8 +62,20 @@ void classification_test_pktio_set_skip(void); void classification_test_pktio_set_headroom(void); void classification_test_pmr_terms_avail(void); void classification_test_pmr_terms_cap(void); -void classification_test_pktio_configure(void); -void classification_test_pktio_test(void); + +void classification_test_configure_pktio_default_cos(void); +void classification_test_configure_pktio_error_cos(void); +void classification_test_configure_cls_pmr_chain(void); +void classification_test_configure_cos_with_l2_priority(void); +void classification_test_configure_pmr_cos(void); +void classification_test_configure_pktio_pmr_match_set_cos(void); + +void classification_test_pktio_default_cos(void); +void classification_test_pktio_error_cos(void); +void classification_test_cls_pmr_chain(void); +void classification_test_cos_with_l2_priority(void); +void classification_test_pmr_cos(void); +void classification_test_pktio_pmr_match_set_cos(void); void classification_test_pmr_term_tcp_dport(void); void classification_test_pmr_term_tcp_sport(void); diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index 34fc570..482e2d0 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -133,7 +133,7 @@ cls_create_packet(bool vlan, odp_atomic_u32_t *seq, bool flag_udp) return pkt; } -void configure_cls_pmr_chain(void) +void classification_test_configure_cls_pmr_chain(void) { /* PKTIO --> PMR_SRC(SRC IP ADDR) --> PMR_DST (TCP SPORT) */ @@ -230,7 +230,7 @@ void configure_cls_pmr_chain(void) CU_ASSERT(retval == 0); } -void test_cls_pmr_chain(void) +void classification_test_cls_pmr_chain(void) { odp_packet_t pkt; odph_ipv4hdr_t *ip; @@ -284,7 +284,7 @@ void test_cls_pmr_chain(void) odp_packet_free(pkt); } -void configure_pktio_default_cos(void) +void classification_test_configure_pktio_default_cos(void) { int retval; odp_queue_param_t qparam; @@ -318,7 +318,7 @@ void configure_pktio_default_cos(void) CU_ASSERT(retval == 0); } -void test_pktio_default_cos(void) +void classification_test_pktio_default_cos(void) { odp_packet_t pkt; odp_queue_t queue; @@ -344,7 +344,7 @@ void test_pktio_default_cos(void) odp_packet_free(pkt); } -void configure_pktio_error_cos(void) +void classification_test_configure_pktio_error_cos(void) { int retval; odp_queue_param_t qparam; @@ -380,7 +380,7 @@ void configure_pktio_error_cos(void) CU_ASSERT(retval == 0); } -void test_pktio_error_cos(void) +void classification_test_pktio_error_cos(void) { odp_queue_t queue; odp_packet_t pkt; @@ -434,7 +434,7 @@ void classification_test_pktio_set_headroom(void) CU_ASSERT(retval < 0); } -void configure_cos_with_l2_priority(void) +void classification_test_configure_cos_with_l2_priority(void) { uint8_t num_qos = CLS_L2_QOS_MAX; odp_cos_t cos_tbl[CLS_L2_QOS_MAX]; @@ -487,7 +487,7 @@ void configure_cos_with_l2_priority(void) CU_ASSERT(
[lng-odp] [PATCH 1/5] validation: cls: adopt for supported l3 PMR
The classification tests should use supported l3 PMR where it's not important. For validating concrete PMRs the separate test exists. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/classification/classification.h| 6 +-- .../classification/odp_classification_basic.c | 4 +- .../classification/odp_classification_common.c | 52 ++ .../classification/odp_classification_tests.c | 25 +-- .../classification/odp_classification_testsuites.h | 2 + 5 files changed, 69 insertions(+), 20 deletions(-) diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index a186339..f363812 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -29,18 +29,18 @@ #define CLS_PMR_CHAIN_SRC 2 #define CLS_PMR_CHAIN_DST 3 #define CLS_PMR_CHAIN_SADDR"10.0.0.5/32" -#define CLS_PMR_CHAIN_SPORT3000 +#define CLS_PMR_CHAIN_PORT 3000 /* Config values for PMR */ #define TEST_PMR 1 #define CLS_PMR4 -#define CLS_PMR_SPORT 4000 +#define CLS_PMR_PORT 4000 /* Config values for PMR SET */ #define TEST_PMR_SET 1 #define CLS_PMR_SET5 #define CLS_PMR_SET_SADDR "10.0.0.6/32" -#define CLS_PMR_SET_SPORT 5000 +#define CLS_PMR_SET_PORT 5000 /* Config values for CoS L2 Priority */ #define TEST_L2_QOS1 diff --git a/test/validation/classification/odp_classification_basic.c b/test/validation/classification/odp_classification_basic.c index f0b7a42..81077b6 100644 --- a/test/validation/classification/odp_classification_basic.c +++ b/test/validation/classification/odp_classification_basic.c @@ -78,7 +78,7 @@ void classification_test_create_pmr_match(void) val = 1024; mask = 0x; - match.term = ODP_PMR_TCP_SPORT; + match.term = find_first_supported_l3_pmr(); match.val = match.mask = match.val_sz = sizeof(val); @@ -99,7 +99,7 @@ void classification_test_destroy_pmr(void) val = 1024; mask = 0x; - match.term = ODP_PMR_TCP_SPORT; + match.term = find_first_supported_l3_pmr(); match.val = match.mask = match.val_sz = sizeof(val); diff --git a/test/validation/classification/odp_classification_common.c b/test/validation/classification/odp_classification_common.c index afcea45..b1c1750 100644 --- a/test/validation/classification/odp_classification_common.c +++ b/test/validation/classification/odp_classification_common.c @@ -299,3 +299,55 @@ odp_packet_t create_packet(odp_pool_t pool, bool vlan, return pkt; } + +odp_pmr_term_e find_first_supported_l3_pmr(void) +{ + odp_pmr_term_e term; + unsigned long long cap; + + /* choose supported PMR */ + cap = odp_pmr_terms_cap(); + if (cap & (1 << ODP_PMR_UDP_SPORT)) + term = ODP_PMR_UDP_SPORT; + else if (cap & (1 << ODP_PMR_UDP_DPORT)) + term = ODP_PMR_UDP_DPORT; + else if (cap & (1 << ODP_PMR_TCP_SPORT)) + term = ODP_PMR_TCP_SPORT; + else if (cap & (1 << ODP_PMR_TCP_DPORT)) + term = ODP_PMR_TCP_DPORT; + else + CU_FAIL("Implementations doesn't support any TCP/UDP PMR"); + + return term; +} + +int set_first_supported_pmr_port(odp_packet_t pkt, uint16_t port) +{ + odph_udphdr_t *udp; + odph_tcphdr_t *tcp; + odp_pmr_term_e term; + + udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); + tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); + port = odp_cpu_to_be_16(port); + term = find_first_supported_l3_pmr(); + switch (term) { + case ODP_PMR_UDP_SPORT: + udp->src_port = port; + break; + case ODP_PMR_UDP_DPORT: + udp->dst_port = port; + break; + case ODP_PMR_TCP_DPORT: + tcp->dst_port = port; + break; + case ODP_PMR_TCP_SPORT: + tcp->src_port = port; + break; + default: + CU_FAIL("Unsupported L3 term"); + return -1; + } + + return 0; +} diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index e11c3d8..a118728 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -10,6 +10,7 @@ #include #include #include +#include static odp_cos_t cos_list[CLS_ENTRIES]; static odp_pmr_t pmr_list[CLS_ENTRIES]; @@ -195,9 +196,9 @@ void configure_cls_pmr_chain(void) pmr_list[CLS_PMR_CHAIN_SRC] = odp_pmr_create(); CU_ASSERT_FAT
[lng-odp] [PATCH 4/5] validation: cls: use correct MAC addresses
If pktion is in not promisc mode, a packet should contain correct MAC address. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- .../classification/odp_classification_test_pmr.c | 158 ++--- .../classification/odp_classification_tests.c | 30 +++- 2 files changed, 96 insertions(+), 92 deletions(-) diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 0b3f279..bb69794 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -13,22 +13,11 @@ #include static odp_pool_t pkt_pool; +static odp_pktio_t pktio_loop; /** sequence number of IP packets */ odp_atomic_u32_t seq; -int classification_suite_pmr_init(void) -{ - pkt_pool = pool_create("classification_pmr_pool"); - if (ODP_POOL_INVALID == pkt_pool) { - fprintf(stderr, "Packet pool creation failed.\n"); - return -1; - } - - odp_atomic_init_u32(, 0); - return 0; -} - odp_pktio_t create_pktio(odp_queue_type_t q_type) { odp_pktio_t pktio; @@ -55,6 +44,35 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) return pktio; } +int classification_suite_pmr_init(void) +{ + pkt_pool = pool_create("classification_pmr_pool"); + if (ODP_POOL_INVALID == pkt_pool) { + fprintf(stderr, "Packet pool creation failed.\n"); + return -1; + } + + pktio_loop = create_pktio(ODP_QUEUE_TYPE_SCHED); + + odp_atomic_init_u32(, 0); + return 0; +} + +static odp_packet_t +cls_create_packet(bool vlan, odp_atomic_u32_t *seq, bool flag_udp) +{ + odp_packet_t pkt; + odph_ethhdr_t *eth; + + pkt = create_packet(pkt_pool, vlan, seq, flag_udp); + + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio_loop, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio_loop, eth->dst.addr, ODPH_ETHADDR_LEN); + + return pkt; +} + void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, odp_queue_t *queue, odp_pool_t *pool) { @@ -93,6 +111,11 @@ int classification_suite_pmr_term(void) { int retcode = 0; + if (odp_pktio_close(pktio_loop)) { + fprintf(stderr, "unable to close pktio_loop.\n"); + retcode = -1; + } + if (0 != odp_pool_destroy(pkt_pool)) { fprintf(stderr, "pkt_pool destroy failed.\n"); retcode = -1; @@ -109,7 +132,6 @@ void classification_test_pmr_term_tcp_dport(void) uint16_t val; uint16_t mask; int retval; - odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; odp_queue_t default_queue; @@ -128,10 +150,7 @@ void classification_test_pmr_term_tcp_dport(void) mask = 0x; seqno = 0; - pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - - configure_default_cos(pktio, _cos, + configure_default_cos(pktio_loop, _cos, _queue, _pool); match.term = ODP_PMR_TCP_DPORT; @@ -158,10 +177,10 @@ void classification_test_pmr_term_tcp_dport(void) cos = odp_cls_cos_create(cosname, _param); CU_ASSERT(cos != ODP_COS_INVALID); - retval = odp_pktio_pmr_cos(pmr, pktio, cos); + retval = odp_pktio_pmr_cos(pmr, pktio_loop, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pkt_pool, false, , false); + pkt = cls_create_packet(false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -169,7 +188,7 @@ void classification_test_pmr_term_tcp_dport(void) tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); - enqueue_pktio_interface(pkt, pktio); + enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(, ODP_TIME_SEC_IN_NS); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); @@ -181,7 +200,7 @@ void classification_test_pmr_term_tcp_dport(void) odp_packet_free(pkt); /* Other packets are delivered to default queue */ - pkt = create_packet(pkt_pool, false, , false); + pkt = cls_create_packet(false, , false); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -189,7 +208,7 @@ void classification_test_pmr_term_tcp_dport(void) tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1); - enqueue_pktio_interface(pkt, pktio); + enqueue_pktio_interface(pkt, pktio_loop);
[lng-odp] [PATCH v3 0/3] correct limits validation
This series corrects limits based on resolution. Since v2: - remove return Since v1: - no functional changes - replaceed "[lng-odp] [PATCH 1/3] validation: time: initialize resolution vars" on "validation: time: store local and global resolution" from Nicolas Ivan Khoronzhuk (2): validation: time: round up resolution validation: time: increase limit to check to 2 res Nicolas Morey-Chaisemartin (1): validation: time: store local and global resolution test/validation/time/time.c | 31 --- 1 file changed, 16 insertions(+), 15 deletions(-) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3 1/3] validation: time: store local and global resolution
From: Nicolas Morey-Chaisemartin <nmo...@kalray.eu> Computation were done on a local variable and never stored back to the global value so both local_res and global_res were always 0. Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Signed-off-by: Nicolas Morey-Chaisemartin <nmo...@kalray.eu> --- test/validation/time/time.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index 8b469b0..b4e53ec 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -31,7 +31,7 @@ void time_test_constants(void) CU_ASSERT(ns == ODP_TIME_USEC_IN_NS); } -static void time_test_res(time_res_cb time_res, uint64_t res) +static void time_test_res(time_res_cb time_res, uint64_t *res) { uint64_t rate; @@ -39,18 +39,18 @@ static void time_test_res(time_res_cb time_res, uint64_t res) CU_ASSERT(rate > MIN_TIME_RATE); CU_ASSERT(rate < MAX_TIME_RATE); - res = ODP_TIME_SEC_IN_NS / rate; - res = res ? res : 1; + *res = ODP_TIME_SEC_IN_NS / rate; + *res = *res ? *res : 1; } void time_test_local_res(void) { - time_test_res(odp_time_local_res, local_res); + time_test_res(odp_time_local_res, _res); } void time_test_global_res(void) { - time_test_res(odp_time_global_res, global_res); + time_test_res(odp_time_global_res, _res); } /* check that related conversions come back to the same value */ -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3 2/3] validation: time: round up resolution
While division the resolution can have fractional part, so better to round it up, when it's needed. Reviewed-by: Bill Fischofer <bill.fischo...@linaro.org> Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/time/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index b4e53ec..d0d198a 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -40,7 +40,8 @@ static void time_test_res(time_res_cb time_res, uint64_t *res) CU_ASSERT(rate < MAX_TIME_RATE); *res = ODP_TIME_SEC_IN_NS / rate; - *res = *res ? *res : 1; + if (ODP_TIME_SEC_IN_NS % rate) + (*res)++; } void time_test_local_res(void) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3 3/3] validation: time: increase limit to check to 2 res
In places of two conversions the error can be up to 2 resolutions, so increase validation range to 2 res. Reviewed-by: Bill Fischofer <bill.fischo...@linaro.org> Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/time/time.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/validation/time/time.c b/test/validation/time/time.c index d0d198a..a64bff6 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -215,8 +215,8 @@ static void time_test_diff(time_cb time, ns = ns2 - ns1; nsdiff = odp_time_to_ns(diff); - upper_limit = ns + res; - lower_limit = ns - res; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); /* test timestamp and interval diff */ @@ -228,8 +228,8 @@ static void time_test_diff(time_cb time, CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0); nsdiff = odp_time_to_ns(diff); - upper_limit = ns + res; - lower_limit = ns - res; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); /* test interval diff */ @@ -241,8 +241,8 @@ static void time_test_diff(time_cb time, CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0); nsdiff = odp_time_to_ns(diff); - upper_limit = ns + res; - lower_limit = ns - res; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); /* same time has to diff to 0 */ @@ -283,8 +283,8 @@ static void time_test_sum(time_cb time, CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0); nssum = odp_time_to_ns(sum); - upper_limit = ns + res; - lower_limit = ns - res; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit)); /* sum intervals */ @@ -296,8 +296,8 @@ static void time_test_sum(time_cb time, CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0); nssum = odp_time_to_ns(sum); - upper_limit = ns + res; - lower_limit = ns - res; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit)); /* test on 0 */ -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp