Re: [lng-odp] [API-NEXT/PATCHv5] validation: classification: added additional suite to test individual PMRs
_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); /* Incorrect IpV4 version */ ip->ver_ihl = 8 << 4 | ODPH_IPV4HDR_IHL_MIN; ip->chksum = 0; - enqueue_loop_interface(pkt); + enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(, ODP_TIME_SEC); + CU_ASSERT(pkt != ODP_PACKET_INVALID); /* Error packet should be received in error queue */ CU_ASSERT(queue == queue_list[CLS_ERROR]); odp_packet_free(pkt); @@ -666,19 +452,21 @@ void test_cos_with_l2_priority(void) odph_ethhdr_t *ethhdr; odph_vlanhdr_t *vlan; odp_queue_t queue; - uint32_t seq; + uint32_t seqno = 0; uint8_t i; for (i = 0; i < CLS_L2_QOS_MAX; i++) { - pkt = create_packet(true); - seq = cls_pkt_get_seq(pkt); + pkt = create_packet(pool_default, true, , true); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); vlan = (odph_vlanhdr_t *)(>type); vlan->tci = odp_cpu_to_be_16(i << 13); - enqueue_loop_interface(pkt); + enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(, ODP_TIME_SEC); + CU_ASSERT(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_L2_QOS_0 + i]); - CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); } } @@ -732,16 +520,18 @@ void test_pmr_cos(void) odp_packet_t pkt; odph_udphdr_t *udp; odp_queue_t queue; - uint32_t seq; + uint32_t seqno = 0; - pkt = create_packet(false); - seq = cls_pkt_get_seq(pkt); + pkt = create_packet(pool_default, false, , true); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->src_port = odp_cpu_to_be_16(CLS_PMR_SPORT); - enqueue_loop_interface(pkt); + enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(, ODP_TIME_SEC); + CU_ASSERT(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR]); - CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); } @@ -807,10 +597,12 @@ void test_pktio_pmr_match_set_cos(void) odph_udphdr_t *udp; odp_packet_t pkt; odp_queue_t queue; - uint32_t seq; + uint32_t seqno = 0; + + pkt = create_packet(pool_default, false, , true); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); - pkt = create_packet(false); - seq = cls_pkt_get_seq(pkt); ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); parse_ipv4_string(CLS_PMR_SET_SADDR, , ); ip->src_addr = odp_cpu_to_be_32(addr); @@ -819,10 +611,11 @@ void test_pktio_pmr_match_set_cos(void) udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->src_port = odp_cpu_to_be_16(CLS_PMR_SET_SPORT); - enqueue_loop_interface(pkt); + enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(, ODP_TIME_SEC); + CU_ASSERT(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR_SET]); - CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); } diff --git a/test/validation/classification/odp_classification_testsuites.h b/test/validation/classification/odp_classification_testsuites.h index 37c019d..33547a7 100644 --- a/test/validation/classification/odp_classification_testsuites.h +++ b/test/validation/classification/odp_classification_testsuites.h @@ -13,11 +13,24 @@ extern CU_TestInfo classification_suite[]; extern CU_TestInfo classification_suite_basic[]; +extern CU_TestInfo classification_suite_pmr[]; int classification_suite_init(void); int classification_suite_term(void); -odp_packet_t create_packet(bool vlan); +int classification_suite_pmr_term(void); +int classification_suite_pmr_init(void); + +odp_packet_t create_packet(odp_pool_t pool, bool vlan, + odp_atomic_u32_t *seq, bool udp); +int cls_pkt_set_seq(odp_packet_t pkt); +uint32_t cls_pkt_get_seq(odp_packet_t pkt); +odp_pktio_t create_pktio(odp_queue_type_t q_type); +odp_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype); +int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t *mask); +void enqueue_pktio_interface(odp_packet_t pkt, odp_pktio_t pktio); +odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns); +odp_queue_t queue_create(char *queuename, bool sched); void configure_pktio_default_cos(void); void test_pktio_default_cos(void); void configure_pktio_error_cos(void); -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] pktio statistic counters
Please, no Camel casemaybe we can duplicate the struct with names and use convenient one. On 15.10.15 15:12, Mike Holmes wrote: On 15 October 2015 at 13:01, Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>> wrote: If we're going to follow RFC MIB specifications we should use the field names as specified in the RFCs. We already need to update the checkpatch rules to allow camel case since CUnit uses that anyway. We can simply have a recommendation that ODP doesn't use camel case except in cases like these. It actually helps highlight the fact that these are externally specified names rather than ODP names. Agree on using RFC names and I think checkpatch already ignores "MiB", but a patch to add Cunit exceptions is a good idea Bill On Thu, Oct 15, 2015 at 6:09 AM, Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com>> wrote: Hi, These RFCs could be the ones we are looking for pktio interface level counters. https://tools.ietf.org/html/rfc3635 https://tools.ietf.org/html/rfc2863 https://tools.ietf.org/html/rfc2819 The editor tool can be used to double check which RFC is the lastest... https://www.rfc-editor.org/info/rfc3635 https://www.rfc-editor.org/info/rfc2863 The counters could be these, but in 64 bit version in ODP API. For example, ifInOctets would be specified as typedef struct { uint64_t in_octets; uint64_t in_ucastpkts; ... } odp_pktio_stat_counters_t; ifInOctets ifInUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutDiscards ifOutErrors ifInOctets The number of octets in valid MAC frames received on this interface, including the MAC header and FCS. This does include the number of octets in valid MAC Control frames received on this Interface ifInUcastPkts Refer to [RFC2863]. Note that this does not include MAC Control frames ... -Petri ___ 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 <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 __ ___ 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] [API-NEXT PATCH v4 5/5] test/example: avoid "cycle" word usage
The word "cycle" is left from old API time names. The "cycle" is ambiguous word, especially when it can be used for other purposes. So better to use "tick" or "time" word or just "t" symbol. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 35 ++--- test/validation/scheduler/scheduler.c | 5 ++--- test/validation/time/time.c | 42 +-- test/validation/time/time.h | 6 ++--- 4 files changed, 43 insertions(+), 45 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 6e001a3..e78616c 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -106,7 +106,7 @@ struct tx_stats_s { uint64_t tx_cnt;/* Packets transmitted */ uint64_t alloc_failures;/* Packet allocation failures */ uint64_t enq_failures; /* Enqueue failures */ - odp_time_t idle_cycles; /* Idle cycle count in TX loop */ + odp_time_t idle_ticks; /* Idle ticks count in TX loop */ }; typedef union tx_stats_u { @@ -305,8 +305,8 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - odp_time_t start_cycles, cur_cycles, send_duration; - odp_time_t burst_start_cycles, burst_gap_cycles; + odp_time_t start_time, cur_time, send_duration; + odp_time_t burst_start_time, burst_gap; uint32_t batch_len; int unsent_pkts = 0; odp_event_t tx_event[BATCH_LEN_MAX]; @@ -328,36 +328,35 @@ static void *run_thread_tx(void *arg) if (outq == ODP_QUEUE_INVALID) LOG_ABORT("Failed to get output queue for thread %d\n", thr_id); - burst_gap_cycles = odp_time_from_ns( + burst_gap = odp_time_from_ns( ODP_TIME_SEC / (targs->pps / targs->batch_len)); send_duration = odp_time_from_ns(targs->duration * ODP_TIME_SEC); odp_barrier_wait(>tx_barrier); - cur_cycles = odp_time(); - start_cycles = cur_cycles; - burst_start_cycles = odp_time_diff(burst_gap_cycles, cur_cycles); - while (odp_time_diff(start_cycles, cur_cycles) < send_duration) { + cur_time = odp_time(); + start_time = cur_time; + burst_start_time = odp_time_diff(burst_gap, cur_time); + while (odp_time_diff(start_time, cur_time) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; - if (odp_time_diff(burst_start_cycles, cur_cycles) - < burst_gap_cycles) { - cur_cycles = odp_time(); + if (odp_time_diff(burst_start_time, cur_time) < burst_gap) { + cur_time = odp_time(); if (!odp_time_cmp(ODP_TIME_NULL, idle_start)) - idle_start = cur_cycles; + idle_start = cur_time; continue; } if (odp_time_cmp(ODP_TIME_NULL, idle_start)) { - odp_time_t diff = odp_time_diff(idle_start, cur_cycles); + odp_time_t diff = odp_time_diff(idle_start, cur_time); - stats->s.idle_cycles = - odp_time_sum(diff, stats->s.idle_cycles); + stats->s.idle_ticks = + odp_time_sum(diff, stats->s.idle_ticks); idle_start = ODP_TIME_NULL; } - burst_start_cycles += burst_gap_cycles; + burst_start_time += burst_gap; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) @@ -368,14 +367,14 @@ static void *run_thread_tx(void *arg) stats->s.enq_failures += unsent_pkts; stats->s.tx_cnt += tx_cnt; - cur_cycles = odp_time(); + cur_time = odp_time(); } VPRINT(" %02d: TxPkts %-8"PRIu64" EnqFail %-6"PRIu64 " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n", thr_id, stats->s.tx_cnt, stats->s.enq_failures, stats->s.alloc_failures, - odp_time_to_ns(stats->s.idle_cycles) / (uint64_t)ODP_TIME_MSEC); + odp_time_to_ns(stats->s.idle_ticks) / (uint64_t)ODP_TIME_MSEC); return NULL; } diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 96e0781..8d8a0a5 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -465,11 +465,10 @@ static void *schedule_common_(void *arg) CU_ASSERT
Re: [lng-odp] [API-NEXT/PATCHv5] validation: classification: added additional suite to test individual PMRs
On 15.10.15 16:39, Bala Manoharan wrote: Hi Ivan, Thanks for pointing out the issues. Since this patch is merged I will create a bug and add the missing points. Pls provide your inputs on the comments. On 15 October 2015 at 16:53, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: Hi, Bala Just compared this version with requirements for v2 and saw some mistmaches. I didn't analize it deeply, seemply checked what was needed to be changed. See comments below. Sorry, I haven't found v4, and haven't revewed v3. On 14.10.15 08:03, Balasubramanian Manoharan wrote: Additional test suite is added to classification validation suite to test individual PMRs. This suite will test the defined PMRs by configuring pktio separately for every test case. Fixes: https://bugs.linaro.org/show_bug.cgi?id=1542 https://bugs.linaro.org/show_bug.cgi?id=1544 https://bugs.linaro.org/show_bug.cgi?id=1545 https://bugs.linaro.org/show_bug.cgi?id=1546 Signed-off-by: Balasubramanian Manoharan <bala.manoha...@linaro.org> --- v5: rebase on latest api-next helper/include/odp/helper/tcp.h| 1 + test/validation/classification/Makefile.am | 2 + test/validation/classification/classification.c| 5 + test/validation/classification/classification.h| 44 ++ .../classification/odp_classification_common.c | 252 + .../classification/odp_classification_test_pmr.c | 579 + .../classification/odp_classification_tests.c | 309 ++- .../classification/odp_classification_testsuites.h | 15 +- 8 files changed, 948 insertions(+), 259 deletions(-) create mode 100644 test/validation/classification/odp_classification_common.c create mode 100644 test/validation/classification/odp_classification_test_pmr.c diff --git a/helper/include/odp/helper/tcp.h b/helper/include/odp/helper/tcp.h index defe422..42f0cbe 100644 --- a/helper/include/odp/helper/tcp.h +++ b/helper/include/odp/helper/tcp.h @@ -26,6 +26,7 @@ extern "C" { * @{ */ +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */ /** TCP header */ typedef struct ODP_PACKED { diff --git a/test/validation/classification/Makefile.am b/test/validation/classification/Makefile.am index 5881665..4235309 100644 --- a/test/validation/classification/Makefile.am +++ b/test/validation/classification/Makefile.am @@ -3,6 +3,8 @@ include ../Makefile.inc noinst_LTLIBRARIES = libtestclassification.la libtestclassification_la_SOURCES = odp_classification_basic.c \ odp_classification_tests.c \ + odp_classification_test_pmr.c \ + odp_classification_common.c \ classification.c bin_PROGRAMS = classification_main$(EXEEXT) diff --git a/test/validation/classification/classification.c b/test/validation/classification/classification.c index d0fef93..6641893 100644 --- a/test/validation/classification/classification.c +++ b/test/validation/classification/classification.c @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = { { .pName = "classification basic", .pTests = classification_suite_basic, }, + { .pName = "classification pmr tests", + .pTests = classification_suite_pmr, + .pInitFunc = classification_suite_pmr_init, + .pCleanupFunc = classification_suite_pmr_term, + }, { .pName = "classification tests", .pTests = classification_suite, .pInitFunc = classification_suite_init, diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index d2847e5..de9c37e 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -9,6 +9,50 @@ #include +#define SHM_PKT_NUM_BUFS32 +#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" +#define CLS_DEFAULT_SPORT 1024 +#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_SPORT3000 + +/* Config values for PMR */ +#define TEST_PMR 1 +#define CLS_PMR4 +#define CLS_PMR_SPORT 4000 + +/* Config values for PMR SET */ +#define TEST_PMR_SET 1 +#define CLS_PMR_SET5 +#define C
Re: [lng-odp] [PATCH RFC] Revert "platform: Makefile.inc: use `` instead of != for compatibility with older versions of Make"
It shouldn't depend on catalog the project is built. On 15.10.15 18:10, Ivan Khoronzhuk wrote: This reverts commit a9cc0fc700a4a8b9589404a18136b01974ca4aa3. This revert helps me to revert messages like: "fatal: No names found, cannot describe anything." in case if I build ODP outside of source catalog by: ../../odp/configure --enable-test-perf --enable-test-vald make Seems it's connected with nesting `...`. Is someone going to fix it? --- platform/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/Makefile.inc b/platform/Makefile.inc index f64e37c..f232daa 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -12,6 +12,6 @@ lib_LTLIBRARIES = $(LIB)/libodp.la AM_LDFLAGS += -version-number '$(ODP_LIBSO_VERSION)' -GIT_DESC = `$(top_srcdir)/scripts/git_hash.sh` +GIT_DESC !=$(top_srcdir)/scripts/git_hash.sh AM_CFLAGS += "-DGIT_HASH=$(GIT_DESC)" AM_CFLAGS += -DPLATFORM=${with_platform} -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH RFC] Revert "platform: Makefile.inc: use `` instead of != for compatibility with older versions of Make"
I build it at api-next and see this: ... fatal: No names found, cannot describe anything. CC odp_system_info.lo fatal: No names found, cannot describe anything. CC odp_thread.lo fatal: No names found, cannot describe anything. CC odp_thrmask.lo CC odp_ticketlock.lo CC odp_timer.lo CC odp_time.lo fatal: No names found, cannot describe anything. fatal: No names found, cannot describe anything. fatal: No names found, cannot describe anything. fatal: No names found, cannot describe anything. CC odp_version.lo fatal: No names found, cannot describe anything. CC odp_weak.lo fatal: No names found, cannot describe anything. CC pktio/io_ops.lo CC pktio/loop.lo fatal: No names found, cannot describe anything. fatal: No names found, cannot describe anything. CC pktio/netmap.lo fatal: No names found, cannot describe anything. CC pktio/socket.lo fatal: No names found, cannot describe anything. CC pktio/socket_mmap.lo fatal: No names found, cannot describe anything. CC arch/x86/odp_cpu_cycles.lo fatal: No names found, cannot describe anything. ... I had a talk with Maxim at connect and he was surprised. We tried several methods with modifing dirs. When I've used $() instead of `` it helped but broke smth else... On 15.10.15 18:20, Nicolas Morey-Chaisemartin wrote: Maybe changing the directory before running git_hash.sh would fix your issue and keep the old make working ? Something like This was fixed some time ago: commit 06537738ea438c3e339fc269dedb4ed6c5e48f07 Author: Anders Roxell <anders.rox...@linaro.org> Date: Fri Aug 14 15:25:05 2015 +0200 scripts/git_hash: fix build from tar source Signed-off-by: Anders Roxell <anders.rox...@linaro.org> Reviewed-and-tested-by: Mike Holmes <mike.hol...@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> Call to git_hash now adds a path to top_srcdir and handles non git dir On 10/15/2015 05:10 PM, Ivan Khoronzhuk wrote: This reverts commit a9cc0fc700a4a8b9589404a18136b01974ca4aa3. This revert helps me to revert messages like: "fatal: No names found, cannot describe anything." in case if I build ODP outside of source catalog by: ../../odp/configure --enable-test-perf --enable-test-vald make Seems it's connected with nesting `...`. Is someone going to fix it? --- platform/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/Makefile.inc b/platform/Makefile.inc index f64e37c..f232daa 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -12,6 +12,6 @@ lib_LTLIBRARIES = $(LIB)/libodp.la AM_LDFLAGS += -version-number '$(ODP_LIBSO_VERSION)' -GIT_DESC = `$(top_srcdir)/scripts/git_hash.sh` +GIT_DESC !=$(top_srcdir)/scripts/git_hash.sh AM_CFLAGS += "-DGIT_HASH=$(GIT_DESC)" AM_CFLAGS += -DPLATFORM=${with_platform} -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH RFC] Revert "platform: Makefile.inc: use `` instead of != for compatibility with older versions of Make"
This reverts commit a9cc0fc700a4a8b9589404a18136b01974ca4aa3. This revert helps me to revert messages like: "fatal: No names found, cannot describe anything." in case if I build ODP outside of source catalog by: ../../odp/configure --enable-test-perf --enable-test-vald make Seems it's connected with nesting `...`. Is someone going to fix it? --- platform/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/Makefile.inc b/platform/Makefile.inc index f64e37c..f232daa 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -12,6 +12,6 @@ lib_LTLIBRARIES = $(LIB)/libodp.la AM_LDFLAGS += -version-number '$(ODP_LIBSO_VERSION)' -GIT_DESC = `$(top_srcdir)/scripts/git_hash.sh` +GIT_DESC !=$(top_srcdir)/scripts/git_hash.sh AM_CFLAGS += "-DGIT_HASH=$(GIT_DESC)" AM_CFLAGS += -DPLATFORM=${with_platform} -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] scripts/git_hash: fix out of tree build
On 15.10.15 18:36, Nicolas Morey-Chaisemartin wrote: Git hash was modified to handled non git builds but when building out of tree, it detects a .git folder but do not change to this folder to run git command. Signed-off-by: Nicolas Morey-Chaisemartin <nmo...@kalray.eu> Tested-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- scripts/git_hash.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/git_hash.sh b/scripts/git_hash.sh index 6cfec2f..e15094e 100755 --- a/scripts/git_hash.sh +++ b/scripts/git_hash.sh @@ -8,8 +8,8 @@ ROOTDIR=${1} CUSTOM_STR=${CUSTOM_STR:-https://git.linaro.org/lng/odp.git} if [ -d ${ROOTDIR}/.git ]; then - hash=$(git describe | tr -d "\n") - if git diff-index --name-only HEAD &>/dev/null ; then + hash=$(git --git-dir=${ROOTDIR}/.git describe | tr -d "\n") + if git --git-dir=${ROOTDIR}/.git diff-index --name-only HEAD &>/dev/null ; then dirty=-dirty fi -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] pktio statistic counters
On 15.10.15 19:51, Ivan Khoronzhuk wrote: On 15.10.15 19:31, Mike Holmes wrote: On 15 October 2015 at 14:04, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: Please, no Camel casemaybe we can duplicate the struct with names and use convenient one. So we adopt a standard that is bigger than out own and not its naming convention ? Feels presumptuous :) Yep. Yep - Feels presumptuous :) On 15.10.15 15:12, Mike Holmes wrote: On 15 October 2015 at 13:01, Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>>> wrote: If we're going to follow RFC MIB specifications we should use the field names as specified in the RFCs. We already need to update the checkpatch rules to allow camel case since CUnit uses that anyway. We can simply have a recommendation that ODP doesn't use camel case except in cases like these. It actually helps highlight the fact that these are externally specified names rather than ODP names. Agree on using RFC names and I think checkpatch already ignores "MiB", but a patch to add Cunit exceptions is a good idea Bill On Thu, Oct 15, 2015 at 6:09 AM, Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com> <mailto:petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com>>> wrote: Hi, These RFCs could be the ones we are looking for pktio interface level counters. https://tools.ietf.org/html/rfc3635 https://tools.ietf.org/html/rfc2863 https://tools.ietf.org/html/rfc2819 The editor tool can be used to double check which RFC is the lastest... https://www.rfc-editor.org/info/rfc3635 https://www.rfc-editor.org/info/rfc2863 The counters could be these, but in 64 bit version in ODP API. For example, ifInOctets would be specified as typedef struct { uint64_t in_octets; uint64_t in_ucastpkts; ... } odp_pktio_stat_counters_t; ifInOctets ifInUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutDiscards ifOutErrors ifInOctets The number of octets in valid MAC frames received on this interface, including the MAC header and FCS. This does include the number of octets in valid MAC Control frames received on this Interface ifInUcastPkts Refer to [RFC2863]. Note that this does not include MAC Control frames ... -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> <mailto: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 <mailto:lng-odp@lists.linaro.org> <mailto: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 __ ___ 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 -- Mike Holmes Technical Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs __ -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] pktio statistic counters
On 15.10.15 19:31, Mike Holmes wrote: On 15 October 2015 at 14:04, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: Please, no Camel casemaybe we can duplicate the struct with names and use convenient one. So we adopt a standard that is bigger than out own and not its naming convention ? Feels presumptuous :) Yep. On 15.10.15 15:12, Mike Holmes wrote: On 15 October 2015 at 13:01, Bill Fischofer <bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org> <mailto:bill.fischo...@linaro.org <mailto:bill.fischo...@linaro.org>>> wrote: If we're going to follow RFC MIB specifications we should use the field names as specified in the RFCs. We already need to update the checkpatch rules to allow camel case since CUnit uses that anyway. We can simply have a recommendation that ODP doesn't use camel case except in cases like these. It actually helps highlight the fact that these are externally specified names rather than ODP names. Agree on using RFC names and I think checkpatch already ignores "MiB", but a patch to add Cunit exceptions is a good idea Bill On Thu, Oct 15, 2015 at 6:09 AM, Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com> <mailto:petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com>>> wrote: Hi, These RFCs could be the ones we are looking for pktio interface level counters. https://tools.ietf.org/html/rfc3635 https://tools.ietf.org/html/rfc2863 https://tools.ietf.org/html/rfc2819 The editor tool can be used to double check which RFC is the lastest... https://www.rfc-editor.org/info/rfc3635 https://www.rfc-editor.org/info/rfc2863 The counters could be these, but in 64 bit version in ODP API. For example, ifInOctets would be specified as typedef struct { uint64_t in_octets; uint64_t in_ucastpkts; ... } odp_pktio_stat_counters_t; ifInOctets ifInUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutDiscards ifOutErrors ifInOctets The number of octets in valid MAC frames received on this interface, including the MAC header and FCS. This does include the number of octets in valid MAC Control frames received on this Interface ifInUcastPkts Refer to [RFC2863]. Note that this does not include MAC Control frames ... -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> <mailto: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 <mailto:lng-odp@lists.linaro.org> <mailto: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 __ ___ 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 -- Mike Holmes Technical Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs __ -- 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 2/2] linux-generic: cpu: fix cycle lost while cycle counter overflow
When counter reaches it's counter value, the next clock cycle will cause it to roll over to zero. As result the counter spends 1 additional cycle to switch from UINT64_MAX to 0, it should be taken into account with diff function. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp_cpu_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/include/odp_cpu_internal.h b/platform/linux-generic/include/odp_cpu_internal.h index 28a0a84..5eeabef 100644 --- a/platform/linux-generic/include/odp_cpu_internal.h +++ b/platform/linux-generic/include/odp_cpu_internal.h @@ -19,7 +19,7 @@ uint64_t _odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) if (odp_likely(c2 >= c1)) return c2 - c1; - return c2 + (odp_cpu_cycles_max() - c1); + return c2 + (odp_cpu_cycles_max() - c1) + 1; } #ifdef __cplusplus -- 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 1/2] linux-generic: use cycles_diff for time API also
Currently, time API reuses cpu API to get ticks, but uses it's own function to count diff but it can differ from cpu diff function. So, better to use the same function in order to eliminate possible difference in counting. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/Makefile.am| 1 + platform/linux-generic/include/odp_cpu_internal.h | 29 +++ platform/linux-generic/odp_cpu.c | 6 ++--- platform/linux-generic/odp_time.c | 6 ++--- 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 platform/linux-generic/include/odp_cpu_internal.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 202ec6a..2b4a277 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -140,6 +140,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_schedule_internal.h \ ${srcdir}/include/odp_spin_internal.h \ ${srcdir}/include/odp_timer_internal.h \ + ${srcdir}/include/odp_cpu_internal.h \ ${srcdir}/Makefile.inc __LIB__libodp_la_SOURCES = \ diff --git a/platform/linux-generic/include/odp_cpu_internal.h b/platform/linux-generic/include/odp_cpu_internal.h new file mode 100644 index 000..28a0a84 --- /dev/null +++ b/platform/linux-generic/include/odp_cpu_internal.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_CPU_INTERNAL_H_ +#define ODP_CPU_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +static inline +uint64_t _odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) +{ + if (odp_likely(c2 >= c1)) + return c2 - c1; + + return c2 + (odp_cpu_cycles_max() - c1); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c index 45a79db..e5ec4f0 100644 --- a/platform/linux-generic/odp_cpu.c +++ b/platform/linux-generic/odp_cpu.c @@ -6,11 +6,9 @@ #include #include +#include uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) { - if (odp_likely(c2 >= c1)) - return c2 - c1; - - return c2 + (odp_cpu_cycles_max() - c1); + return _odp_cpu_cycles_diff(c1, c2); } diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index b378c35..74f802b 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -10,6 +10,7 @@ #include #include #include +#include #define GIGA 10 @@ -20,10 +21,7 @@ uint64_t odp_time_cycles(void) uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { - if (odp_likely(t2 >= t1)) - return t2 - t1; - - return t2 + (UINT64_MAX - t1); + return _odp_cpu_cycles_diff(t1, t2); } uint64_t odp_time_cycles_to_ns(uint64_t cycles) -- 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 0/2] linux-generic: cpu: fix cycle lost while cycle counter overflow
This series fixes cycle lost while counter overflow. First patch move diff function in one place. Second corrects diff function. Based on api-next as it corrects new cpu cycle api. Ivan Khoronzhuk (2): linux-generic: use cycles_diff for time API also linux-generic: cpu: fix cycle lost while cycle counter overflow platform/linux-generic/Makefile.am| 1 + platform/linux-generic/include/odp_cpu_internal.h | 29 +++ platform/linux-generic/odp_cpu.c | 6 ++--- platform/linux-generic/odp_time.c | 6 ++--- 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 platform/linux-generic/include/odp_cpu_internal.h -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [NEXT PATCHv3] api: define pktio statistics api
Hi, Maxim What about to extend API a little. Why API doesn't support work with statistic counter, I mean not only read. What if I want to reset a statistic counter and only one? In my case I have h/w support to reset concrete counter by writing 0x to it in runtime. Also there is possibility to subtract some value from counter by writing this value in counter in runtime. In case if statistic module is off these counters behave like usual registers for read/write. Also it be good to have API allowing to enable and disable statistic for pktio. The main reason for that the same statistic module can be used by different pktios, so if it's used for one of them it cannot be used by other, to allow it for first it should be disable for second. For instance 2 statistic modules are shared between 4 eth ports, etc. Also maybe it's redundancy, but what about to support some arithmetic operations for counters, like diff and sum for time API. If you want I can send the full list of counter that I can retrieve. On 07.09.15 05:43, Maxim Uvarov wrote: Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- v3: - reduce number of counters; v2: - add function to check supported cnts; - add optional functio to reset cnts; include/odp/api/packet_io_stats.h | 94 ++ platform/linux-generic/include/odp/packet_io.h | 1 + 2 files changed, 95 insertions(+) create mode 100644 include/odp/api/packet_io_stats.h diff --git a/include/odp/api/packet_io_stats.h b/include/odp/api/packet_io_stats.h new file mode 100644 index 000..0faf15b --- /dev/null +++ b/include/odp/api/packet_io_stats.h @@ -0,0 +1,94 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP Packet IO + */ + +#ifndef ODP_API_PACKET_IO_STATS_H_ +#define ODP_API_PACKET_IO_STATS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_packet_io ODP PACKET IO + * @{ + */ + +/** + * Packet IO statistics + * + */ +typedef struct odp_pktio_stats_t { + uint64_t collisions; /**< number of collisions */ + uint64_t multicast; /**< multicast packets received */ + + uint64_t rx_bytes;/**< total bytes received */ + uint64_t rx_crc_errors; /**< received packets with crc error */ + uint64_t rx_dropped; /**< no space in buffers */ + uint64_t rx_errors; /**< bad packets received */ + uint64_t rx_length_errors;/**< bad packets length */ + uint64_t rx_over_errors; /**< receiver buff overflow */ + uint64_t rx_packets; /**< total packets received*/ + + uint64_t tx_aborted_errors; /**< packets aborted during + transmission by a network device (e.g: + because of a medium collision) */ + uint64_t tx_bytes;/**< total bytes transmitted */ + uint64_t tx_carrier_errors; /**< not transmitted packets because of + carrier errors (e.g: physical link down) */ + uint64_t tx_dropped; /**< no resources to transmit packet*/ + uint64_t tx_errors; /**< packets transmit problems */ + uint64_t tx_fifo_errors; /**< packets transmit FIFO errors */ + uint64_t tx_packets; /**< total packets transmitted */ +} odp_pktio_stats_t; + +/** + * Get supported counters for pktio handle + * + * @param pktioPacket IO handle + * @param[out] *stats Output buffer + * For each stat field: + * 0 - counter not supported. + * !0 - counter is supported . + * @retval 0 on success + * @retval <0 on failure + */ +int odp_config_pktio_stats(odp_pktio_t pktio, odp_pktio_stats_t *stat); + +/** + * Get statistics for pktio handle + * + * @param pktioPacket IO handle + * @param[out] *stats Output buffer + * @retval 0 on success + * @retval <0 on failure + */ +int odp_pktio_stats(odp_pktio_t pktio, odp_pktio_stats_t *stats); + +/** + * Reset statistics for pktio handle + * + * @param pktioPacket IO handle + * @retval 0 on success + * @retval <0 on failure + * + * @note Optional. + */ +int odp_pktio_stats_reset(odp_pktio_t pktio); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/packet_io.h b/platform/linux-generic/include/odp/packet_io.h index 1d690f5..18f8e78 100644 --- a/platform/linux-generic/include/odp/packet_io.h +++ b/platform/linux-generic/include/odp/packet_io.h @@ -33,6 +33,7 @@ extern "C" { */ #include +#include #ifdef __cplusplus } -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3 4/5] performance: odp_pktio_perf: fix potential overflow for send_duration
The direct comparing of "cur_cycles" and "end_cycles" is not valid, as "end_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account cycles overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Reviewed-by: Stuart Haslam <stuart.has...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 185375e..61ff312 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -305,7 +305,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, end_cycles, cur_cycles; + uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -330,15 +330,14 @@ static void *run_thread_tx(void *arg) burst_gap_cycles = odp_time_ns_to_cycles( ODP_TIME_SEC / (targs->pps / targs->batch_len)); + send_duration = odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); odp_barrier_wait(>tx_barrier); cur_cycles = odp_time_cycles(); + start_cycles = cur_cycles; next_tx_cycles = cur_cycles; - end_cycles = cur_cycles + -odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); - - while (cur_cycles < end_cycles) { + while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; if (cur_cycles < next_tx_cycles) { -- 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/5] example: ipsec: avoid mixing of scheduler wait time and time API time
It's not correct to mix time API time and scheduler wait time, used timers can have different rates. As in this example scheduler is used only for polling till event, using wait time for scheduling can be avoided at all. This patch replaces callback function on function w/o wait time, and doesn't add any functional changes. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/ipsec/odp_ipsec.c | 57 +-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 96effe2..564d65e 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -221,8 +221,7 @@ void free_pkt_ctx(pkt_ctx_t *ctx) */ typedef odp_queue_t (*queue_create_func_t) (const char *, odp_queue_type_t, odp_queue_param_t *); -typedef odp_event_t (*schedule_func_t) -(odp_queue_t *, uint64_t); +typedef odp_event_t (*schedule_func_t) (odp_queue_t *); static queue_create_func_t queue_create; static schedule_func_t schedule; @@ -259,49 +258,33 @@ odp_queue_t polled_odp_queue_create(const char *name, return my_queue; } +static inline +odp_event_t odp_schedule_cb(odp_queue_t *from) +{ + return odp_schedule(from, ODP_SCHED_WAIT); +} + /** * odp_schedule replacement to poll queues versus using ODP scheduler */ static -odp_event_t polled_odp_schedule(odp_queue_t *from, uint64_t wait) +odp_event_t polled_odp_schedule_cb(odp_queue_t *from) { - uint64_t start_cycle; - uint64_t cycle; - uint64_t diff; - - start_cycle = 0; + int idx = 0; while (1) { - int idx; + if (idx >= num_polled_queues) + idx = 0; - for (idx = 0; idx < num_polled_queues; idx++) { - odp_queue_t queue = poll_queues[idx]; - odp_event_t buf; + odp_queue_t queue = poll_queues[idx++]; + odp_event_t buf; - buf = odp_queue_deq(queue); + buf = odp_queue_deq(queue); - if (ODP_EVENT_INVALID != buf) { - *from = queue; - return buf; - } + if (ODP_EVENT_INVALID != buf) { + *from = queue; + return buf; } - - if (ODP_SCHED_WAIT == wait) - continue; - - if (ODP_SCHED_NO_WAIT == wait) - break; - - if (0 == start_cycle) { - start_cycle = odp_time_cycles(); - continue; - } - - cycle = odp_time_cycles(); - diff = odp_time_diff_cycles(start_cycle, cycle); - - if (wait < diff) - break; } *from = ODP_QUEUE_INVALID; @@ -1095,7 +1078,7 @@ void *pktio_thread(void *arg EXAMPLE_UNUSED) odp_crypto_op_result_t result; /* Use schedule to get event from any input queue */ - ev = schedule(, ODP_SCHED_WAIT); + ev = schedule(); /* Determine new work versus completion or sequence number */ if (ODP_EVENT_PACKET == odp_event_type(ev)) { @@ -1246,12 +1229,12 @@ main(int argc, char *argv[]) /* create by default scheduled queues */ queue_create = odp_queue_create; - schedule = odp_schedule; + schedule = odp_schedule_cb; /* check for using poll queues */ if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) { queue_create = polled_odp_queue_create; - schedule = polled_odp_schedule; + schedule = polled_odp_schedule_cb; } /* Init ODP before calling anything else */ -- 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/5] linux-generic: odp_time: reutrn 0 if t2 = t1 for diff
When times are equal the difference should be 0. Currently it's equal to UINT64_MAX and doesn't allow to compare ranges beginning from start time. The validation test to check it will be added later. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 6e69e53..b378c35 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -20,7 +20,7 @@ uint64_t odp_time_cycles(void) uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { - if (odp_likely(t2 > t1)) + if (odp_likely(t2 >= t1)) return t2 - t1; return t2 + (UINT64_MAX - t1); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v3 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes into account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 61ff312..4dfeb6a 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -305,7 +305,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; + uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -336,11 +336,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; - next_tx_cycles = cur_cycles; + burst_start_cycles = odp_time_diff_cycles(burst_gap_cycles, cur_cycles); while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; - if (cur_cycles < next_tx_cycles) { + if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) + < burst_gap_cycles) { cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -353,7 +354,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } - next_tx_cycles += burst_gap_cycles; + burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 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 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 16.09.15 12:16, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Wednesday, September 16, 2015 11:19 AM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap Petri, On 16.09.15 10:02, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 5:07 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap Petri, On 15.09.15 16:01, Ivan Khoronzhuk wrote: On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng- o...@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. Yes, I forgot to swap burst_gap_cycles and cur_cycles. so odp_time_diff_cycles(cur_cycles, burst_gap_cycles) -> odp_time_diff_cycles(burst_gap_cycles, cur_cycles); Are you OK with this? I will update it after some review of other patches from this series. Seems, it's simplest way to not wait at first iteration and not use additional vars or comparison with start time. I think it works correctly only when cur_cycles > burst_gap_cycles (which is likely but there's no guarantees). In case of cur_cycles < burst_gap_cycles it should work. burst_start_cycles = MAX - gap + cur. For instance: gap = 100; cur = 5; burst_start_cycles = MAX - 100 + 5 = MAX - 95; After MAX it wraps to 0 + 5, so 95 + 5 = 100; That's correct. No matter
[lng-odp] [PATCH v3 0/5] preparation series before updating odp time API
This series contains corrections/fixes and is required before changing time API. V2: https://lists.linaro.org/pipermail/lng-odp/2015-September/015355.html Since v2: example: ipsec: avoid mixing of scheduler wait time and time API time - use time instead of wall time in commint msg linux-generic: odp_time: reutrn 0 if t2 = t1 for diff - corrected commit msg performance: odp_pktio_perf: fix potential overflow for burst_gap - swap burst_gap_cycles and cur_cycles in diff at init Since v1: "example: timer: print timer ticks/ns table instead of cycles/ns" - included as new patch Based on master. CC: stuart.has...@linaro.org ola.liljed...@linaro.org petri.savolai...@nokia.com Ivan Khoronzhuk (5): example: timer: print timer ticks/ns table instead of cycles/ns example: ipsec: avoid mixing of scheduler wait time and time API time linux-generic: odp_time: reutrn 0 if t2 = t1 for diff performance: odp_pktio_perf: fix potential overflow for send_duration performance: odp_pktio_perf: fix potential overflow for burst_gap example/ipsec/odp_ipsec.c | 57 ++- example/timer/odp_timer_test.c| 22 +++ platform/linux-generic/odp_time.c | 2 +- test/performance/odp_pktio_perf.c | 16 +-- 4 files changed, 40 insertions(+), 57 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/5] example: timer: print timer ticks/ns table instead of cycles/ns
The timer API can have nothing common with CPU cycles or time API. Thus timer test shouldn't print conversion cycles/ns table. More correct to print conversion table for timer ticks/ns. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/timer/odp_timer_test.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..3aa0f51 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -322,7 +322,7 @@ int main(int argc, char *argv[]) odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; + uint64_t tick, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -447,21 +447,21 @@ int main(int argc, char *argv[]) } printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); + printf("Timer ticks vs nanoseconds:\n"); ns = 0; - cycles = odp_time_ns_to_cycles(ns); + tick = odp_timer_ns_to_tick(gbls->tp, ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, tick); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, + odp_timer_tick_to_ns(gbls->tp, tick)); for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); + tick = odp_timer_ns_to_tick(gbls->tp, ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, + tick); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, + odp_timer_tick_to_ns(gbls->tp, tick)); } printf("\n"); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [API-NEXT PATCHv2] api: rename odp_cpumask_def to _default
On 14.09.15 16:35, Maxim Uvarov wrote: Use full default word in api to make function name more clear. https://bugs.linaro.org/show_bug.cgi?id=1745 Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- v2: - merge 1 (api update) and 2 (code fix) patches from v1. - remove patches 3 and 4 to not support NULL for mask. example/classifier/odp_classifier.c | 2 +- example/generator/odp_generator.c | 4 ++-- example/ipsec/odp_ipsec.c | 2 +- example/packet/odp_pktio.c| 2 +- example/timer/odp_timer_test.c| 2 +- helper/test/odp_process.c | 2 +- helper/test/odp_thread.c | 2 +- include/odp/api/cpumask.h | 4 ++-- platform/linux-generic/odp_cpumask_task.c | 4 ++-- test/api_test/odp_common.c| 2 +- test/performance/odp_atomic.c | 2 +- test/performance/odp_l2fwd.c | 2 +- test/performance/odp_pktio_perf.c | 5 +++-- test/performance/odp_scheduling.c | 2 +- test/validation/common/odp_cunit_common.c | 2 +- test/validation/cpumask/cpumask.c | 8 test/validation/scheduler/scheduler.c | 2 +- test/validation/synchronizers/synchronizers.c | 2 +- 18 files changed, 26 insertions(+), 25 deletions(-) diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 3123936..2d90ae7 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -431,7 +431,7 @@ int main(int argc, char *argv[]) num_workers = args->cpu_count; /* Get default worker cpumask */ - num_workers = odp_cpumask_def_worker(, num_workers); + num_workers = odp_cpumask_default_worker(, num_workers); (void)odp_cpumask_to_str(, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index f7aed76..3bb6c4f 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -692,7 +692,7 @@ int main(int argc, char *argv[]) if (args->appl.cpu_count) num_workers = args->appl.cpu_count; - num_workers = odp_cpumask_def_worker(, num_workers); + num_workers = odp_cpumask_default_worker(, num_workers); if (args->appl.mask) { odp_cpumask_from_str(, args->appl.mask); num_workers = odp_cpumask_count(); @@ -918,7 +918,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) case 'c': appl_args->mask = optarg; odp_cpumask_from_str(_args, args->appl.mask); - num_workers = odp_cpumask_def_worker(, 0); + num_workers = odp_cpumask_default_worker(, 0); odp_cpumask_and(_and, _args, ); if (odp_cpumask_count(_and) < odp_cpumask_count(_args)) { diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 96effe2..998e51d 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -1296,7 +1296,7 @@ main(int argc, char *argv[]) num_workers = args->appl.cpu_count; /* Get default worker cpumask */ - num_workers = odp_cpumask_def_worker(, num_workers); + num_workers = odp_cpumask_default_worker(, num_workers); (void)odp_cpumask_to_str(, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index df53ea2..ce53ee3 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -386,7 +386,7 @@ int main(int argc, char *argv[]) num_workers = args->appl.cpu_count; /* Get default worker cpumask */ - num_workers = odp_cpumask_def_worker(, num_workers); + num_workers = odp_cpumask_default_worker(, num_workers); (void)odp_cpumask_to_str(, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..ce9faf9 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -381,7 +381,7 @@ int main(int argc, char *argv[]) num_workers = gbls->args.cpu_count; /* Get default worker cpumask */ - num_workers = odp_cpumask_def_worker(, num_workers); + num_workers = odp_cpumask_default_worker(, num_workers); (void)odp_cpumask_to_str(, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); diff --git
Re: [lng-odp] [PATCH v2 0/2] Fix ODP_SCHED_NO_WAIT case for odp_schedule_wait_time
Maxim, On 16.09.15 11:05, Maxim Uvarov wrote: On 09/15/15 18:03, Ivan Khoronzhuk wrote: ping are you planning v3 with removed CU_ASSERT(wait_time > 0) ? Maxim. Not here. It will be removed along with ODP-190 implementation. On 10.09.15 19:18, Ivan Khoronzhuk wrote: These patches corrects ODP_SCHED_NO_WAIT corner case when scheduler time has resolution more then 1ns. Since v2: - linux-generic: odp_schedule: fix odp_schdule_wait_time Correct commit message - validation: schedule: don't check schedule time on 0 Don't remove check on wait_time = odp_schedule_wait_time(1); Ivan Khoronzhuk (2): linux-generic: odp_schedule: fix odp_schdule_wait_time validation: schedule: don't check schedule time on 0 platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- test/validation/scheduler/scheduler.c| 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) -- 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 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
Petri, On 16.09.15 10:02, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 5:07 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap Petri, On 15.09.15 16:01, Ivan Khoronzhuk wrote: On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. Yes, I forgot to swap burst_gap_cycles and cur_cycles. so odp_time_diff_cycles(cur_cycles, burst_gap_cycles) -> odp_time_diff_cycles(burst_gap_cycles, cur_cycles); Are you OK with this? I will update it after some review of other patches from this series. Seems, it's simplest way to not wait at first iteration and not use additional vars or comparison with start time. I think it works correctly only when cur_cycles > burst_gap_cycles (which is likely but there's no guarantees). In case of cur_cycles < burst_gap_cycles it should work. burst_start_cycles = MAX - gap + cur. For instance: gap = 100; cur = 5; burst_start_cycles = MAX - 100 + 5 = MAX - 95; After MAX it wraps to 0 + 5, so 95 + 5 = 100; That's correct. No matter we diff range or counter from cur_time, it will be correct, second argument cannot wrap. So, if you are OK, we can leave it as simplest fix. -Petri while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; -if (cur_cycles < next_tx_cycles) { +if (odp_time_diff_cycles(burst_start_cycles,
Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 16.09.15 10:02, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 5:07 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap Petri, On 15.09.15 16:01, Ivan Khoronzhuk wrote: On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. Yes, I forgot to swap burst_gap_cycles and cur_cycles. so odp_time_diff_cycles(cur_cycles, burst_gap_cycles) -> odp_time_diff_cycles(burst_gap_cycles, cur_cycles); Are you OK with this? I will update it after some review of other patches from this series. Seems, it's simplest way to not wait at first iteration and not use additional vars or comparison with start time. I think it works correctly only when cur_cycles > burst_gap_cycles (which is likely but there's no guarantees). Would it be more robust to init burst_start_cycles = cur_cycles, and thus wait also in the first iteration. Maybe iteration counting needs updating then, but the time calculation would be more robust. It's not very good to miss first iteration. It's supposed that during burst period we send some number of packets. In case of first dummy gap it will simply wait, w/o sending. The results of test can be used for comparison with some previous results and can create additional questions. We shouldn't add even such small diff (or not small in some cases?) What about to init to init burst_start_cycles = cur_cycles and add some start = 1; if (odp_time_di
Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 16.09.15 10:52, Ivan Khoronzhuk wrote: On 16.09.15 10:02, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 5:07 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap Petri, On 15.09.15 16:01, Ivan Khoronzhuk wrote: On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. Yes, I forgot to swap burst_gap_cycles and cur_cycles. so odp_time_diff_cycles(cur_cycles, burst_gap_cycles) -> odp_time_diff_cycles(burst_gap_cycles, cur_cycles); Are you OK with this? I will update it after some review of other patches from this series. Seems, it's simplest way to not wait at first iteration and not use additional vars or comparison with start time. I think it works correctly only when cur_cycles > burst_gap_cycles (which is likely but there's no guarantees). Would it be more robust to init burst_start_cycles = cur_cycles, and thus wait also in the first iteration. Maybe iteration counting needs updating then, but the time calculation would be more robust. It's not very good to miss first iteration. It's supposed that during burst period we send some number of packets. In case of first dummy gap it will simply wait, w/o sending. The results of test can be used for comparison with some previous results and can create additional questions. We shouldn't add even such small diff (or not small in some cases?) What about to init to init burst_start_cycles = cur_cycl
Re: [lng-odp] [PATCH v2 3/5] linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff
Petri, What about this fix? It's similar to to CPU API. On 11.09.15 13:04, Ivan Khoronzhuk wrote: It's better to describe by example: cur = 15; start = 15; diff = 2; while (odp_time_cycles_diff(start, cur) < diff) { cur = odp_time_cycles(); } This example has to work. It's possible only when t2 - t1 = 0 if t2 = t1. The validation test on it will be added later. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index a08833d..a007d69 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -14,7 +14,7 @@ uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { - if (odp_likely(t2 > t1)) + if (odp_likely(t2 >= t1)) return t2 - t1; return t2 + (UINT64_MAX - t1); But I have additional proposition. Maybe I'm wrong, but one cycle can be lost here (equal as in CPU api, I'm ready to fix it also) For instance: start = MAX - 2; cur = 1 res = MAX - MAX + 2 + 1 = 3; It's correct. But in real it will be: (MAX - 2) -> 1 cycle (MAX - 1) -> 2 cycle MAX -> 3 cycle 0 -> 4 cycle 1 The function returns 3 cycles difference, but due to 0, physically, timer counts 4 cycles. Not sure, but I should send +1 patch that corrects it to: return t2 + (UINT64_MAX - t1) + 1; due to counter in continuous mode is reset to 0, then continues counting. Can we apply this on cycle counter? (then I need correct CPU API implementation also) Is it reseted to zero or wraps to 1 for all arches? -- 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 3/5] linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff
On 16.09.15 14:39, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Wednesday, September 16, 2015 1:47 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo) Subject: Re: [lng-odp] [PATCH v2 3/5] linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff On 16.09.15 13:23, Ivan Khoronzhuk wrote: Petri, What about this fix? It's similar to to CPU API. On 11.09.15 13:04, Ivan Khoronzhuk wrote: It's better to describe by example: cur = 15; start = 15; diff = 2; while (odp_time_cycles_diff(start, cur) < diff) { cur = odp_time_cycles(); } This example has to work. It's possible only when t2 - t1 = 0 if t2 = t1. The validation test on it will be added later. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux- generic/odp_time.c index a08833d..a007d69 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -14,7 +14,7 @@ uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { -if (odp_likely(t2 > t1)) +if (odp_likely(t2 >= t1)) return t2 - t1; return t2 + (UINT64_MAX - t1); But I have additional proposition. Maybe I'm wrong, but one cycle can be lost here (equal as in CPU api, I'm ready to fix it also) For instance: start = MAX - 2; cur = 1 res = MAX - MAX + 2 + 1 = 3; It's correct. But in real it will be: (MAX - 2) -> 1 cycle (MAX - 1) -> 2 cycle MAX -> 3 cycle 0 -> 4 cycle 1 The function returns 3 cycles difference, but due to 0, physically, timer counts 4 cycles. Not sure, but I should send +1 patch that corrects it to: return t2 + (UINT64_MAX - t1) + 1; due to counter in continuous mode is reset to 0, then continues counting. Can we apply this on cycle counter? (then I need correct CPU API implementation also) Is it reseted to zero or wraps to 1 for all arches? For instance, from here http://download.intel.com/design/intelxscale/27347302.pdf, (Intel XScale(r) Core) CCNT behaves like: "When CCNT reaches its maximum value 0x,, the next clock cycle will cause it to roll over to zero" But I'm not sure about other arches hidden under linux-generic. I tend to believe that it's applicable for all cases. -- Regards, Ivan Khoronzhuk uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { if (odp_unlikely(t2 == t1)) return 0; if (odp_likely(t2 > t1)) return t2 - t1; Sorry, but why not if (odp_likely(t2 >= t1)) return t2 - t1; as in patch. return t2 + (UINT64_MAX - t1) + 1; } t1 = MAX t2 = MAX - 1, diff = MAX - 1 + MAX - MAX + 1 = MAX True, as we count +1 cycle in real. Ok. t2 = MAX, diff = 0 True. t2 = 0, diff = 0 + MAX - MAX + 1 = 1 Also true. As for count from MAX to 0 we need 1 cycle. Ok. t1 = MAX - 1 t2 = MAX - 2, diff = MAX - 2 + MAX - MAX + 1 + 1 = MAX True and OK. t2 = MAX - 1, diff = 0 True and OK. t2 = MAX, diff = MAX - MAX + 1 = 1 True and OK. t2 = 0, diff = 0 + MAX - MAX + 1 + 1 = 2 True, as we need 2 cycles to reach 0. Ok. t2 = 1, diff = 1 + MAX - MAX + 1 + 1 = 3 True, as we need 3 cycles to reach 1. Ok. It's very likely that when t1 == t2, the correct result is 0. Yep, I'm not proposing to change this patch. I propose to send additional patch later. It will be rather series, as I want to correct cpu API also. Let's catch that first. Wrap around case can have then the extra +1. Right, that is I worry about. But seems on current arches it's applicable. Also we can limit it to arches we are sure, as -1 cycle it's obvious error now and it adds additional error in accuracy +-2 cycles instead of 1. In case of bad cycle counter resolution, say 64, it can have valuable impact, especially if it's multiplied on some value. -Petri -- 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 3/5] linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff
On 16.09.15 13:23, Ivan Khoronzhuk wrote: Petri, What about this fix? It's similar to to CPU API. On 11.09.15 13:04, Ivan Khoronzhuk wrote: It's better to describe by example: cur = 15; start = 15; diff = 2; while (odp_time_cycles_diff(start, cur) < diff) { cur = odp_time_cycles(); } This example has to work. It's possible only when t2 - t1 = 0 if t2 = t1. The validation test on it will be added later. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index a08833d..a007d69 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -14,7 +14,7 @@ uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { -if (odp_likely(t2 > t1)) +if (odp_likely(t2 >= t1)) return t2 - t1; return t2 + (UINT64_MAX - t1); But I have additional proposition. Maybe I'm wrong, but one cycle can be lost here (equal as in CPU api, I'm ready to fix it also) For instance: start = MAX - 2; cur = 1 res = MAX - MAX + 2 + 1 = 3; It's correct. But in real it will be: (MAX - 2) -> 1 cycle (MAX - 1) -> 2 cycle MAX -> 3 cycle 0 -> 4 cycle 1 The function returns 3 cycles difference, but due to 0, physically, timer counts 4 cycles. Not sure, but I should send +1 patch that corrects it to: return t2 + (UINT64_MAX - t1) + 1; due to counter in continuous mode is reset to 0, then continues counting. Can we apply this on cycle counter? (then I need correct CPU API implementation also) Is it reseted to zero or wraps to 1 for all arches? For instance, from here http://download.intel.com/design/intelxscale/27347302.pdf, (Intel XScale® Core) CCNT behaves like: "When CCNT reaches its maximum value 0x,, the next clock cycle will cause it to roll over to zero" But I'm not sure about other arches hidden under linux-generic. I tend to believe that it's applicable for all cases. -- 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 2/5] example: ipsec: avoid mixing scheduler wait time and wall time
Petri, Could you please review this patch? This patch fixes bad ipsec example we were talked about some time ago. On 11.09.15 13:04, Ivan Khoronzhuk wrote: It's not correct to mix wall time and scheduler wait time, used timers can have different rates. As in this example scheduler is used only for poll purposes, using wait time for scheduling can be avoided at all. This patch replaces callback function on function w/o wait time, and doesn't add any functional changes. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/ipsec/odp_ipsec.c | 57 +-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 96effe2..564d65e 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -221,8 +221,7 @@ void free_pkt_ctx(pkt_ctx_t *ctx) */ typedef odp_queue_t (*queue_create_func_t) (const char *, odp_queue_type_t, odp_queue_param_t *); -typedef odp_event_t (*schedule_func_t) -(odp_queue_t *, uint64_t); +typedef odp_event_t (*schedule_func_t) (odp_queue_t *); static queue_create_func_t queue_create; static schedule_func_t schedule; @@ -259,49 +258,33 @@ odp_queue_t polled_odp_queue_create(const char *name, return my_queue; } +static inline +odp_event_t odp_schedule_cb(odp_queue_t *from) +{ + return odp_schedule(from, ODP_SCHED_WAIT); +} + /** * odp_schedule replacement to poll queues versus using ODP scheduler */ static -odp_event_t polled_odp_schedule(odp_queue_t *from, uint64_t wait) +odp_event_t polled_odp_schedule_cb(odp_queue_t *from) { - uint64_t start_cycle; - uint64_t cycle; - uint64_t diff; - - start_cycle = 0; + int idx = 0; while (1) { - int idx; + if (idx >= num_polled_queues) + idx = 0; - for (idx = 0; idx < num_polled_queues; idx++) { - odp_queue_t queue = poll_queues[idx]; - odp_event_t buf; + odp_queue_t queue = poll_queues[idx++]; + odp_event_t buf; - buf = odp_queue_deq(queue); + buf = odp_queue_deq(queue); - if (ODP_EVENT_INVALID != buf) { - *from = queue; - return buf; - } + if (ODP_EVENT_INVALID != buf) { + *from = queue; + return buf; } - - if (ODP_SCHED_WAIT == wait) - continue; - - if (ODP_SCHED_NO_WAIT == wait) - break; - - if (0 == start_cycle) { - start_cycle = odp_time_cycles(); - continue; - } - - cycle = odp_time_cycles(); - diff = odp_time_diff_cycles(start_cycle, cycle); - - if (wait < diff) - break; } *from = ODP_QUEUE_INVALID; @@ -1095,7 +1078,7 @@ void *pktio_thread(void *arg EXAMPLE_UNUSED) odp_crypto_op_result_t result; /* Use schedule to get event from any input queue */ - ev = schedule(, ODP_SCHED_WAIT); + ev = schedule(); /* Determine new work versus completion or sequence number */ if (ODP_EVENT_PACKET == odp_event_type(ev)) { @@ -1246,12 +1229,12 @@ main(int argc, char *argv[]) /* create by default scheduled queues */ queue_create = odp_queue_create; - schedule = odp_schedule; + schedule = odp_schedule_cb; /* check for using poll queues */ if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) { queue_create = polled_odp_queue_create; - schedule = polled_odp_schedule; + schedule = polled_odp_schedule_cb; } /* Init ODP before calling anything else */ -- 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 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; + uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; - next_tx_cycles = cur_cycles; + burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; - if (cur_cycles < next_tx_cycles) { + if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) + < burst_gap_cycles) { cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -351,7 +352,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } - next_tx_cycles += burst_gap_cycles; + burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 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] [PATCH v2 0/2] Fix ODP_SCHED_NO_WAIT case for odp_schedule_wait_time
ping On 10.09.15 19:18, Ivan Khoronzhuk wrote: These patches corrects ODP_SCHED_NO_WAIT corner case when scheduler time has resolution more then 1ns. Since v2: - linux-generic: odp_schedule: fix odp_schdule_wait_time Correct commit message - validation: schedule: don't check schedule time on 0 Don't remove check on wait_time = odp_schedule_wait_time(1); Ivan Khoronzhuk (2): linux-generic: odp_schedule: fix odp_schdule_wait_time validation: schedule: don't check schedule time on 0 platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- test/validation/scheduler/scheduler.c| 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) -- 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 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
Petri, On 15.09.15 16:01, Ivan Khoronzhuk wrote: On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. Yes, I forgot to swap burst_gap_cycles and cur_cycles. so odp_time_diff_cycles(cur_cycles, burst_gap_cycles) -> odp_time_diff_cycles(burst_gap_cycles, cur_cycles); Are you OK with this? I will update it after some review of other patches from this series. Seems, it's simplest way to not wait at first iteration and not use additional vars or comparison with start time. while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; -if (cur_cycles < next_tx_cycles) { +if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) +< burst_gap_cycles) { This spins back to the top of the while loop until 'cur_cycles' has passed 'burst_start_cycles' by ' burst_gap_cycles'. So, in the example the first packet is sent at cur_cycles == 9 002 000 cycles. -Petri cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -351,7 +352,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } -next_tx_cycles += burst_gap_cycles; +burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp -- Regards, Ivan Khoronzhuk -- Regards, Ivan Khoronzhu
Re: [lng-odp] [API NEXT PATCH v5 03/17] api: sysinfo: move CPU model API to cpu.h
Hi, Hongbo Can it be built after this change? Should it be build-able at least? On 15.09.15 16:55, hongbo.zh...@freescale.com wrote: From: Hongbo Zhang <hongbo.zh...@linaro.org> This patch moves odp_sys_cpu_model_str() to cpu.h, all the calling functions will be updated in later separate patch. Signed-off-by: Hongbo Zhang <hongbo.zh...@linaro.org> --- include/odp/api/cpu.h| 9 + include/odp/api/system_info.h| 7 --- platform/linux-generic/odp_system_info.c | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h index c389093..78c3ffc 100644 --- a/include/odp/api/cpu.h +++ b/include/odp/api/cpu.h @@ -44,6 +44,15 @@ int odp_cpu_id(void); int odp_cpu_count(void); /** + * CPU model name of this CPU + * + * Returns the CPU model name of this CPU. + * + * @return Pointer to CPU model name string + */ +const char *odp_cpu_model_str(void); + +/** * @} */ diff --git a/include/odp/api/system_info.h b/include/odp/api/system_info.h index e55ff6d..1cd883f 100644 --- a/include/odp/api/system_info.h +++ b/include/odp/api/system_info.h @@ -45,13 +45,6 @@ uint64_t odp_sys_huge_page_size(void); uint64_t odp_sys_page_size(void); /** - * CPU model name - * - * @return Pointer to CPU model name string - */ -const char *odp_sys_cpu_model_str(void); - -/** * Cache line size in bytes * * @return CPU cache line size in bytes diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 83226f8..ed6b515 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -389,7 +389,7 @@ uint64_t odp_sys_page_size(void) return odp_global_data.system_info.page_size; } -const char *odp_sys_cpu_model_str(void) +const char *odp_cpu_model_str(void) { return odp_global_data.system_info.model_str[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 v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; + uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; - next_tx_cycles = cur_cycles; + burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; - if (cur_cycles < next_tx_cycles) { + if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) + < burst_gap_cycles) { This spins back to the top of the while loop until 'cur_cycles' has passed 'burst_start_cycles' by ' burst_gap_cycles'. So, in the example the first packet is sent at cur_cycles == 9 002 000 cycles. -Petri cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -351,7 +352,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } - next_tx_cycles += burst_gap_cycles; + burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp -- 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 v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
On 15.09.15 15:54, Ivan Khoronzhuk wrote: On 15.09.15 15:45, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 15, 2015 3:08 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap On 15.09.15 14:42, 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, September 11, 2015 1:05 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; -uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; +uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; -next_tx_cycles = cur_cycles; +burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); Shouldn't this be: burst_start_cycles = cur_cycles + burst_gap_cycles; ,which works as long as cycle count wraps at UINT64_MAX. Maybe we need a cpu.h API for summing two values with correct wrapping. It's initialization for burst gap, which is changing while send_duration. Current algorithm don't wait "burst gap" at first iteration, my intention to not change it. So I've used diff, in another case it waits one init gap. In case of cur_cycles + burst_gap_cycles it waits 2 x burst_gap. So it's not correct. I suppose here shouldn't be functional changes. The cpu API doesn't have sum function and is not for this case, we need time here, that is Time API is indented for. The new Time API is going to be added after this series and will contain sum function which will replace "+" on odp_time_sum(). Current API supposes that "+" correctly handles UINT64_MAX wrap and doesn't contain sum function. For example: burst_gap_cycles = 1k; // e.g. 1msec cur_cycles = 1M; // wraps at 10M burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); burst_start_cycles = 10M - 1M + 1k = 9 001 000 I've checked it some time ago and it was working, I remember I corrected this, strange. Seems I forgot it to swap. Let me check it again. And maybe I will revise loop a little. I dislike this diff at init also. while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; -if (cur_cycles < next_tx_cycles) { +if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) +< burst_gap_cycles) { This spins back to the top of the while loop until 'cur_cycles' has passed 'burst_start_cycles' by ' burst_gap_cycles'. So, in the example the first packet is sent at cur_cycles == 9 002 000 cycles. -Petri cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -351,7 +352,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } -next_tx_cycles += burst_gap_cycles; +burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp -- 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 v2 4/5] performance: odp_pktio_perf: fix potential overflow for send_duration
Stuart, Could you please review this patch. It uses start_cycles as it was proposed. On 11.09.15 13:04, Ivan Khoronzhuk wrote: The direct comparing of "cur_cycles" and "end_cycles" is not valid, as "end_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account cycles overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 709becf..ac32b15 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, end_cycles, cur_cycles; + uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -328,15 +328,14 @@ static void *run_thread_tx(void *arg) burst_gap_cycles = odp_time_ns_to_cycles( ODP_TIME_SEC / (targs->pps / targs->batch_len)); + send_duration = odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); odp_barrier_wait(>tx_barrier); cur_cycles = odp_time_cycles(); + start_cycles = cur_cycles; next_tx_cycles = cur_cycles; - end_cycles = cur_cycles + -odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); - - while (cur_cycles < end_cycles) { + while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; if (cur_cycles < next_tx_cycles) { -- 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 v2 1/5] api: cpu: added cpu cycle count API
Petri, On 11.09.15 12:47, Savolainen, Petri (Nokia - FI/Espoo) wrote: Ping. It be good schedule some task to update/add validation test for cpu API. -Original Message- From: ext Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 08, 2015 1:04 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [API-NEXT PATCH v2 1/5] api: cpu: added cpu cycle count API On 08.09.15 11:31, Petri Savolainen wrote: Raw CPU cycle counts can be used to measure performance in CPU cycles. These functions will replace some usage of odp_time_cycles() of odp_time_diff_cycles(). Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> I'm only hesitate about 32bits, for sum & cmp, but it can be never required. And can be added any time. Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- include/odp/api/cpu.h | 52 +++ 1 file changed, 52 insertions(+) diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h index c389093..50a7e3d 100644 --- a/include/odp/api/cpu.h +++ b/include/odp/api/cpu.h @@ -18,6 +18,8 @@ extern "C" { #endif +#include + /** @defgroup odp_cpu ODP CPU * @{ */ @@ -44,6 +46,56 @@ int odp_cpu_id(void); int odp_cpu_count(void); /** + * Current CPU cycle count + * + * Return current CPU cycle count. Cycle count may not be reset at ODP init + * and thus may wrap back to zero between two calls. Use odp_cpu_cycles_max() + * to read the maximum count value after which it wraps. Cycle count frequency + * follows the CPU frequency and thus may change at any time. The count may + * advance in steps larger than one. Use odp_cpu_cycles_resolution() to read + * the step size. + * + * @note Do not use CPU count for time measurements since the frequency may + * vary. + * + * @return Current CPU cycle count + */ +uint64_t odp_cpu_cycles(void); + +/** + * CPU cycle count difference + * + * Calculate difference between cycle counts c1 and c2. Parameter c1 must be the + * first cycle count sample and c2 the second. The function handles correctly + * single cycle count wrap between c1 and c2. + * + * @param c1First cycle count + * @param c2Second cycle count + * + * @return CPU cycles from c1 to c2 + */ +uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2); + +/** + * Maximum CPU cycle count + * + * Maximum CPU cycle count value before it wraps back to zero. + * + * @return Maximum CPU cycle count value + */ +uint64_t odp_cpu_cycles_max(void); + +/** + * Resolution of CPU cycle count + * + * CPU cycle count may advance in steps larger than one. This function returns + * resolution of odp_cpu_cycles() in CPU cycles. + * + * @return CPU cycle count resolution in CPU cycles + */ +uint64_t odp_cpu_cycles_resolution(void); + +/** * @} */ -- Regards, Ivan Khoronzhuk ___ 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 v2 5/5] performance: odp_pktio_perf: fix potential overflow for burst_gap
The direct comparing of "cur_cycles" and "next_tx_cycles" is not valid, as "next_tx_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account ticks overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index ac32b15..85ef2bc 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; + uint64_t burst_start_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -334,11 +334,12 @@ static void *run_thread_tx(void *arg) cur_cycles = odp_time_cycles(); start_cycles = cur_cycles; - next_tx_cycles = cur_cycles; + burst_start_cycles = odp_time_diff_cycles(cur_cycles, burst_gap_cycles); while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; - if (cur_cycles < next_tx_cycles) { + if (odp_time_diff_cycles(burst_start_cycles, cur_cycles) + < burst_gap_cycles) { cur_cycles = odp_time_cycles(); if (idle_start == 0) idle_start = cur_cycles; @@ -351,7 +352,7 @@ static void *run_thread_tx(void *arg) idle_start = 0; } - next_tx_cycles += burst_gap_cycles; + burst_start_cycles += burst_gap_cycles; alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) -- 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 2/2] validation: schedule: don't check schedule time on 0
I don't want to delete check under odp_schedule_wait_time((uint64_t)-1LL); because at least for now it's only one test that check smth real. It will be deleted along with patches that add real wait_time test on odp_schedule(). In this concrete patch I'm not fixing it. So, please don't hesitate to review it. On 10.09.15 19:18, Ivan Khoronzhuk wrote: The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..39357e7 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -95,9 +95,7 @@ void scheduler_test_wait_time(void) uint64_t wait_time; wait_time = odp_schedule_wait_time(0); - wait_time = odp_schedule_wait_time(1); - CU_ASSERT(wait_time > 0); wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time > 0); -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 1/5] example: timer: print timer ticks/ns table instead of cycles/ns
The timer API can have nothing common with CPU cycles or time API. Thus timer test shouldn't print here conversion cycles/ns table. More correct to print here conversion table for timer ticks/ns. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/timer/odp_timer_test.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..3aa0f51 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -322,7 +322,7 @@ int main(int argc, char *argv[]) odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; + uint64_t tick, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -447,21 +447,21 @@ int main(int argc, char *argv[]) } printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); + printf("Timer ticks vs nanoseconds:\n"); ns = 0; - cycles = odp_time_ns_to_cycles(ns); + tick = odp_timer_ns_to_tick(gbls->tp, ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, tick); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, + odp_timer_tick_to_ns(gbls->tp, tick)); for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); + tick = odp_timer_ns_to_tick(gbls->tp, ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, + tick); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, + odp_timer_tick_to_ns(gbls->tp, tick)); } printf("\n"); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 3/5] linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff
It's better to describe by example: cur = 15; start = 15; diff = 2; while (odp_time_cycles_diff(start, cur) < diff) { cur = odp_time_cycles(); } This example has to work. It's possible only when t2 - t1 = 0 if t2 = t1. The validation test on it will be added later. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/odp_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index a08833d..a007d69 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -14,7 +14,7 @@ uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { - if (odp_likely(t2 > t1)) + if (odp_likely(t2 >= t1)) return t2 - t1; return t2 + (UINT64_MAX - t1); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 2/5] example: ipsec: avoid mixing scheduler wait time and wall time
It's not correct to mix wall time and scheduler wait time, used timers can have different rates. As in this example scheduler is used only for poll purposes, using wait time for scheduling can be avoided at all. This patch replaces callback function on function w/o wait time, and doesn't add any functional changes. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/ipsec/odp_ipsec.c | 57 +-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 96effe2..564d65e 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -221,8 +221,7 @@ void free_pkt_ctx(pkt_ctx_t *ctx) */ typedef odp_queue_t (*queue_create_func_t) (const char *, odp_queue_type_t, odp_queue_param_t *); -typedef odp_event_t (*schedule_func_t) -(odp_queue_t *, uint64_t); +typedef odp_event_t (*schedule_func_t) (odp_queue_t *); static queue_create_func_t queue_create; static schedule_func_t schedule; @@ -259,49 +258,33 @@ odp_queue_t polled_odp_queue_create(const char *name, return my_queue; } +static inline +odp_event_t odp_schedule_cb(odp_queue_t *from) +{ + return odp_schedule(from, ODP_SCHED_WAIT); +} + /** * odp_schedule replacement to poll queues versus using ODP scheduler */ static -odp_event_t polled_odp_schedule(odp_queue_t *from, uint64_t wait) +odp_event_t polled_odp_schedule_cb(odp_queue_t *from) { - uint64_t start_cycle; - uint64_t cycle; - uint64_t diff; - - start_cycle = 0; + int idx = 0; while (1) { - int idx; + if (idx >= num_polled_queues) + idx = 0; - for (idx = 0; idx < num_polled_queues; idx++) { - odp_queue_t queue = poll_queues[idx]; - odp_event_t buf; + odp_queue_t queue = poll_queues[idx++]; + odp_event_t buf; - buf = odp_queue_deq(queue); + buf = odp_queue_deq(queue); - if (ODP_EVENT_INVALID != buf) { - *from = queue; - return buf; - } + if (ODP_EVENT_INVALID != buf) { + *from = queue; + return buf; } - - if (ODP_SCHED_WAIT == wait) - continue; - - if (ODP_SCHED_NO_WAIT == wait) - break; - - if (0 == start_cycle) { - start_cycle = odp_time_cycles(); - continue; - } - - cycle = odp_time_cycles(); - diff = odp_time_diff_cycles(start_cycle, cycle); - - if (wait < diff) - break; } *from = ODP_QUEUE_INVALID; @@ -1095,7 +1078,7 @@ void *pktio_thread(void *arg EXAMPLE_UNUSED) odp_crypto_op_result_t result; /* Use schedule to get event from any input queue */ - ev = schedule(, ODP_SCHED_WAIT); + ev = schedule(); /* Determine new work versus completion or sequence number */ if (ODP_EVENT_PACKET == odp_event_type(ev)) { @@ -1246,12 +1229,12 @@ main(int argc, char *argv[]) /* create by default scheduled queues */ queue_create = odp_queue_create; - schedule = odp_schedule; + schedule = odp_schedule_cb; /* check for using poll queues */ if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) { queue_create = polled_odp_queue_create; - schedule = polled_odp_schedule; + schedule = polled_odp_schedule_cb; } /* Init ODP before calling anything else */ -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 4/5] performance: odp_pktio_perf: fix potential overflow for send_duration
The direct comparing of "cur_cycles" and "end_cycles" is not valid, as "end_cycles" can be overflowed and comparison will give wrong result. So use odp_time_diff_cycles() for that, as it takes in account cycles overflow. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/performance/odp_pktio_perf.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 709becf..ac32b15 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -303,7 +303,7 @@ static void *run_thread_tx(void *arg) int thr_id; odp_queue_t outq; pkt_tx_stats_t *stats; - uint64_t next_tx_cycles, end_cycles, cur_cycles; + uint64_t next_tx_cycles, start_cycles, cur_cycles, send_duration; uint64_t burst_gap_cycles; uint32_t batch_len; int unsent_pkts = 0; @@ -328,15 +328,14 @@ static void *run_thread_tx(void *arg) burst_gap_cycles = odp_time_ns_to_cycles( ODP_TIME_SEC / (targs->pps / targs->batch_len)); + send_duration = odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); odp_barrier_wait(>tx_barrier); cur_cycles = odp_time_cycles(); + start_cycles = cur_cycles; next_tx_cycles = cur_cycles; - end_cycles = cur_cycles + -odp_time_ns_to_cycles(targs->duration * ODP_TIME_SEC); - - while (cur_cycles < end_cycles) { + while (odp_time_diff_cycles(start_cycles, cur_cycles) < send_duration) { unsigned alloc_cnt = 0, tx_cnt; if (cur_cycles < next_tx_cycles) { -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 0/5] preparation series before updating odp time API
This series contains fixes and is required before changing time API. It has no conflicts with "[lng-odp] [API-NEXT PATCH v2 0/5] CPU cycle count API" series that is ready to be merged. V1: "[lng-odp] [odp-lng] [Patch 0/4] preparation series before updating odp time API" https://lists.linaro.org/pipermail/lng-odp/2015-August/014850.html Since v1: - included new patch "example: timer: print timer ticks/ns table instead of cycles/ns" Based on master. CC: stuart.haslam at linaro.org ola.liljed...@linaro.org petri.savolai...@nokia.com Ivan Khoronzhuk (5): example: timer: print timer ticks/ns table instead of cycles/ns example: ipsec: avoid mixing scheduler wait time and wall time linux-generic: odp_time: reutrn 0 if t2 = t1 instead of MAX for diff performance: odp_pktio_perf: fix potential overflow for send_duration performance: odp_pktio_perf: fix potential overflow for burst_gap example/ipsec/odp_ipsec.c | 57 ++- example/timer/odp_timer_test.c| 22 +++ platform/linux-generic/odp_time.c | 2 +- test/performance/odp_pktio_perf.c | 16 +-- 4 files changed, 40 insertions(+), 57 deletions(-) -- 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] example: timer: move cycles/ns table to validation tests
Ola, The patch with your corrections is included in the series that I sent recently: "[lng-odp] [PATCH v2 0/5] preparation series before updating odp time API" On 07.09.15 14:55, Ivan Khoronzhuk wrote: Ola, On 07.09.15 14:45, Ola Liljedahl wrote: On 7 September 2015 at 11:45, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: Petri, Maybe this peace of code should migrate to some other place, but on my opinion it has more common with time API then cpu API. The table to check time table mixes time/cycles with timer API example, and it is confusing a little. Here it doesn't bear any sense except time API has something common with timer API, but that's not true. I agree that the code shouldn't be in the timer example. If anything, we could print the conversion from ns to timer ticks in the example. Agree. I'll adopt it for timer. Maybe it can be deleted at all, just want to leave it somewhere. On 03.09.15 11:50, Ivan Khoronzhuk wrote: The linux-generic implements timers supposing that timers are based on CPU cycle counter. It's not always true and timer API can have nothing common with CPU cycles. Thus timer test shouldn't print here conversion cycles/ns table for time API. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> --- I'm not sure about moving the table to validation test, but it can be useful to visually see resolution impact. This patch should be included in "odp-lng] [Patch 0/4] preparation series before updating odp time API" https://lists.linaro.org/pipermail/lng-odp/2015-August/014850.html But before let's clarify it. example/timer/odp_timer_test.c | 21 - test/validation/time/time.c| 21 - 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..6248939 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -322,7 +322,6 @@ int main(int argc, char *argv[]) odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -446,26 +445,6 @@ int main(int argc, char *argv[]) return -1; } - printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); - ns = 0; - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - - for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - } - - printf("\n"); - gbls->num_workers = num_workers; /* Initialize number of timeouts to receive */ diff --git a/test/validation/time/time.c b/test/validation/time/time.c index 4b81c2c..ae5e77c 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -45,7 +45,7 @@ void time_test_odp_cycles_negative_diff(void) /* check that related conversions come back to the same value */ void time_test_odp_time_conversion(void) { - uint64_t ns1, ns2, cycles; + uint64_t ns, ns1, ns2, cycles; uint64_t upper_limit, lower_limit; ns1 = 100; @@ -59,6 +59,25 @@ void time_test_odp_time_conversion(void) upper_limit = ns1 + TOLERANCE; lower_limit = ns1 - TOLERANCE; CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + + printf("Cycles vs nanoseconds:\n"); + ns = 0; + cycles = odp_time_ns_to_cycles(ns); + + printf(" %12" PRIu64 "
Re: [lng-odp] [PATCH v2 2/5] example: ipsec: avoid mixing scheduler wait time and wall time
On 11.09.15 13:04, Ivan Khoronzhuk wrote: It's not correct to mix wall time and scheduler wait time, It's not wall time, rather time from time API. Should be corrected. used timers can have different rates. As in this example scheduler is used only for poll purposes, using wait time for scheduling can be avoided at all. This patch replaces callback function on function w/o wait time, and doesn't add any functional changes. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/ipsec/odp_ipsec.c | 57 +-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 96effe2..564d65e 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -221,8 +221,7 @@ void free_pkt_ctx(pkt_ctx_t *ctx) */ typedef odp_queue_t (*queue_create_func_t) (const char *, odp_queue_type_t, odp_queue_param_t *); -typedef odp_event_t (*schedule_func_t) -(odp_queue_t *, uint64_t); +typedef odp_event_t (*schedule_func_t) (odp_queue_t *); static queue_create_func_t queue_create; static schedule_func_t schedule; @@ -259,49 +258,33 @@ odp_queue_t polled_odp_queue_create(const char *name, return my_queue; } +static inline +odp_event_t odp_schedule_cb(odp_queue_t *from) +{ + return odp_schedule(from, ODP_SCHED_WAIT); +} + /** * odp_schedule replacement to poll queues versus using ODP scheduler */ static -odp_event_t polled_odp_schedule(odp_queue_t *from, uint64_t wait) +odp_event_t polled_odp_schedule_cb(odp_queue_t *from) { - uint64_t start_cycle; - uint64_t cycle; - uint64_t diff; - - start_cycle = 0; + int idx = 0; while (1) { - int idx; + if (idx >= num_polled_queues) + idx = 0; - for (idx = 0; idx < num_polled_queues; idx++) { - odp_queue_t queue = poll_queues[idx]; - odp_event_t buf; + odp_queue_t queue = poll_queues[idx++]; + odp_event_t buf; - buf = odp_queue_deq(queue); + buf = odp_queue_deq(queue); - if (ODP_EVENT_INVALID != buf) { - *from = queue; - return buf; - } + if (ODP_EVENT_INVALID != buf) { + *from = queue; + return buf; } - - if (ODP_SCHED_WAIT == wait) - continue; - - if (ODP_SCHED_NO_WAIT == wait) - break; - - if (0 == start_cycle) { - start_cycle = odp_time_cycles(); - continue; - } - - cycle = odp_time_cycles(); - diff = odp_time_diff_cycles(start_cycle, cycle); - - if (wait < diff) - break; } *from = ODP_QUEUE_INVALID; @@ -1095,7 +1078,7 @@ void *pktio_thread(void *arg EXAMPLE_UNUSED) odp_crypto_op_result_t result; /* Use schedule to get event from any input queue */ - ev = schedule(, ODP_SCHED_WAIT); + ev = schedule(); /* Determine new work versus completion or sequence number */ if (ODP_EVENT_PACKET == odp_event_type(ev)) { @@ -1246,12 +1229,12 @@ main(int argc, char *argv[]) /* create by default scheduled queues */ queue_create = odp_queue_create; - schedule = odp_schedule; + schedule = odp_schedule_cb; /* check for using poll queues */ if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) { queue_create = polled_odp_queue_create; - schedule = polled_odp_schedule; + schedule = polled_odp_schedule_cb; } /* Init ODP before calling anything else */ -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0
The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); - wait_time = odp_schedule_wait_time(1); - CU_ASSERT(wait_time > 0); - wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time > 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: odp_schedule: fix odp_schdule_wait_time
Nicolas, On 09.09.15 16:38, Ivan Khoronzhuk wrote: On 09.09.15 16:27, Ivan Khoronzhuk wrote: On 09.09.15 15:44, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Wednesday, September 09, 2015 3:35 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time On 09.09.15 15:00, 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: Monday, September 07, 2015 11:51 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { -if (ns <= ODP_SCHED_NO_WAIT) -ns = ODP_SCHED_NO_WAIT + 1; +uint64_t time; -return odp_time_ns_to_cycles(ns); +time = odp_time_ns_to_cycles(ns); +if (!time) +time = ODP_SCHED_NO_WAIT; + +return time; } I think it's better to change (implementation specific) WAIT/NO_WAIT values like this. plat/schedule_types.h #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 ... and avoid any conversion in the common case (WAIT/NO_WAIT). It will not matter, if 1 ns is rounded to 0 == NO_WAIT. uint64_t odp_schedule_wait_time(uint64_t ns) { if (ns == ODP_SCHED_WAIT || ns == ODP_SCHED_NO_WAIT) We shouldn't compare sched time and ns, even it's under implementation. And there is no direct mapping between ns and sched time. In case of maximum for ns, it doesn't mean pool forever for scheduler. Even if it has very low possibility. Assigning POOL forever it's rather an application responsibility then conversion function. If application asks for a timeout in 580 years (== UINT64_MAX in nsec), it's pretty much the same thing than asking for WAIT. It would see the difference after 580 years. Not a huge problem. It's not a huge problem, but why? And we can use the "conversion" function for some calculations, who knows, what can be in user mind. Bumc, we return him UINT64_MAX, instead of some UNIT64/10. (but the same we can say about 1 instead of 0 , but it has less impact) There is can be other things This function can be reused by implementations, mostly on transition stage. As you mentioned, WAIT/NO_WAIT it's implementation specific (define can be not from linux-generic, and function from linux-generic) and better to not rely on WAIT/NO_WAIT = 0. Currently it is implementation specified value. Linux-generic can use -1 and 0. Others can use other values. This as well as other #defines may need to be fixed for binary compatibility. Binary compatibility is fine. But why current values cannot be used for that? I didn't break them. Adding patch I bear in mind how to not break other implementations, applications... I like more small steps in patch then add two ideas in one, if possible. It allows save time in future. If we must have proposed values for defines in order to follow binary compatibility lets add it in separate patch, that can be easily reverted in case of issue. But I have no objection to add your proposition here, if you very insist on it, seems it removes problem with 1 cycle. But I think, better to rewrite it a little like this, no need to control ODP_SCHED_WAIT in this function, and better remove direct comparison ns and sched time. #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); What do you say? Even like this: #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 return odp_time_ns_to_cycles(ns); Is it OK for you? It's better to cleanly catch both values (WAIT/NO_WAIT) and use conversion only for the rest (real nsec values). -Petri My variant has no such drawback and is more clear in what's going on. And your example shou
[lng-odp] [Patch 0/2] Fix ODP_SCHED_NO_WAIT case for odp_schedule_wait_time
These patches corrects ODP_SCHED_NO_WAIT corner case when scheduler time has resolution more then 1ns. Patch 2 has ancestor and is included in series: "[lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time" https://lists.linaro.org/pipermail/lng-odp/2015-September/015093.html Ivan Khoronzhuk (2): linux-generic: odp_schedule: fix odp_schdule_wait_time validation: schedule: don't check schedule time on 0 platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- test/validation/scheduler/scheduler.c| 3 --- 3 files changed, 2 insertions(+), 8 deletions(-) -- 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: odp_schedule: fix odp_schdule_wait_time
The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can wait a little, when shced time has slower rate. It should correspond to schedule only once. So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h index c48b652..8cdc40b 100644 --- a/platform/linux-generic/include/odp/plat/schedule_types.h +++ b/platform/linux-generic/include/odp/plat/schedule_types.h @@ -22,8 +22,8 @@ extern "C" { * @{ */ -#define ODP_SCHED_WAIT 0 -#define ODP_SCHED_NO_WAIT 1 +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 typedef int odp_schedule_prio_t; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index c6619e5..827fcf0 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,9 +646,6 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; - return odp_time_ns_to_cycles(ns); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0
On 10.09.15 15:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); This test is OK. It's even not tested. But I don't touch it in my series. I can push it with separate patch. But I tend to add it in this patch like: CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); And rename patch on "correct wait time test" is it OK for you? - wait_time = odp_schedule_wait_time(1); This is OK. - CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. That's why it's deleted. - wait_time = odp_schedule_wait_time((uint64_t)-1LL); This is OK. CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. Probably better test it here like: CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); I'll add it along with proposed test improvements. Is it OK for you? So, both asserts should be removed. In addition, wait time should be tested with a schedule call ... but that's for another patch. Right. But not here. Probably with next test like "schedule_wait_time_check" and test it with time API? -- 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: odp_schedule: fix odp_schdule_wait_time
On 10.09.15 16:03, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 3:34 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time On 10.09.15 15:16, Savolainen, Petri (Nokia - FI/Espoo) wrote: Change is OK. The calculation can be changed to use cpu cycle API (with max CPU hz) later. Time measurement does not have to be accurate, so we can continue to use CPU cycles and max hz (to spin at least 'ns' nanosec). We can wait more than 4s, with my cpu cycle counter it's not possible. And don't forget about CPU freq and conversion to ns. This is not place to write about that, lets talk about later. With scheduler you can wait more than 4 sec, since your implementation does the spinning and it can be sure that counter is not wrapping (you'll check the counter every 30 cycles or so while waiting). Ok. When you know the max freq (e.g. 1GHz) and calculate how many CPU cycles you need to spin based on that, you'll always wait at least the time requested. CPU can run slower than max (e.g. 500MHz), which means that you may wait longer than 'ns' nanoseconds, but it's OK according the spec. You did wait "at least" 'ns' nsec (e.g. 2x ns). 2x can have much bigger delay error than time API produces. Especially when bigger delay is requested, say 50 ns, and you wait ~100ns. In most cases I suppose rate of counter ~ 3 time less than Fmax. Lets take 7ns time resolution, then 50ns + 7ns = 57ns. error: 7ns << 50ns. And for linux-generic cpu_cycles are only one source of counter. It's reused by time API, so here cpu cycles anyway. -Petri The patch needs to be labeled with "v2". And preferably PATCH, in capital letters. It differs in numbering 1/2. I prefer to hold the same numbering within series. But, next time I will bear it in mind. The log entry could be clarified a bit, see under. -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. In short: "Depending on resolution, a low nsec value could be converted to 0 cycles, which was specified as WAIT ..." Ok Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. "... and would instruct a schedule call to wait forever." Ok Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can wait a little, when shced time has slower rate. It should correspond to schedule only once. So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/linux- generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h index c48b652..8cdc40b 100644 --- a/platform/linux-generic/include/odp/plat/schedule_types.h +++ b/platform/linux-generic/include/odp/plat/schedule_types.h @@ -22,8 +22,8 @@ extern "C" { * @{ */ -#define ODP_SCHED_WAIT 0 -#define ODP_SCHED_NO_WAIT 1 +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 typedef int odp_schedule_prio_t; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..827fcf0 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,9 +646,6 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; - return odp_time_ns_to_cycles(ns); } -- 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 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time
Petri, Are you OK with this change? On 10.09.15 12:48, Ivan Khoronzhuk wrote: The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can wait a little, when shced time has slower rate. It should correspond to schedule only once. So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h index c48b652..8cdc40b 100644 --- a/platform/linux-generic/include/odp/plat/schedule_types.h +++ b/platform/linux-generic/include/odp/plat/schedule_types.h @@ -22,8 +22,8 @@ extern "C" { * @{ */ -#define ODP_SCHED_WAIT 0 -#define ODP_SCHED_NO_WAIT 1 +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 typedef int odp_schedule_prio_t; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index c6619e5..827fcf0 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,9 +646,6 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; - return odp_time_ns_to_cycles(ns); } -- 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] api: packet reference count support
t.c +++ b/platform/linux-generic/odp_packet.c @@ -28,27 +28,33 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) { pool_entry_t *pool = odp_pool_to_entry(pool_hdl); + odp_packet_t pkt = ODP_PACKET_INVALID; if (pool->s.params.type != ODP_POOL_PACKET) - return ODP_PACKET_INVALID; + return pkt; - /* Handle special case for zero-length packets */ - if (len == 0) { - odp_packet_t pkt = - (odp_packet_t)buffer_alloc(pool_hdl, - pool->s.params.buf.size); + if (!len) { + /* Handle special case for zero-length packets */ + pkt = (odp_packet_t)buffer_alloc(pool_hdl, + pool->s.params.buf.size); if (pkt != ODP_PACKET_INVALID) pull_tail(odp_packet_hdr(pkt), pool->s.params.buf.size); - - return pkt; + } else { + pkt = (odp_packet_t)buffer_alloc(pool_hdl, len); Are you allocating pkt twice here or is this a diff artifact? The patch is unclear as posted. } - return (odp_packet_t)buffer_alloc(pool_hdl, len); + if (pkt != ODP_PACKET_INVALID) + odp_packet_refcount_set(pkt, 1); + + return pkt; } void odp_packet_free(odp_packet_t pkt) { + if (odp_packet_refcount_dec(pkt, 1) > 1) Correct test is if (odp_packet_refcount_dec(pkt, 1)) That skips if the refcount > 0, not > 1. + return; + odp_buffer_free((odp_buffer_t)pkt); } @@ -85,6 +91,46 @@ odp_event_t odp_packet_to_event(odp_packet_t pkt) return (odp_event_t)pkt; } +uint32_t odp_packet_refcount(odp_packet_t pkt) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return odp_atomic_load_u32(>ref_count); +} + +int odp_packet_refcount_set(odp_packet_t pkt, uint32_t val) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + odp_atomic_store_u32(>ref_count, val); + return 0; +} + +uint32_t odp_packet_refcount_inc(odp_packet_t pkt, uint32_t val) +{ + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + return odp_atomic_fetch_add_u32(>ref_count, val) + val; +} + +uint32_t odp_packet_refcount_dec(odp_packet_t pkt, uint32_t val) +{ + uint32_t tmp; + odp_buffer_t buf = _odp_packet_to_buffer(pkt); + odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); + + tmp = odp_atomic_fetch_sub_u32(>ref_count, val); + if (tmp < val) { + odp_atomic_fetch_add_u32(>ref_count, val - tmp); + return 0; + } else { + return tmp - val; + } +} + /* * * Pointers and lengths -- 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 _______ 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 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time
On 10.09.15 15:16, Savolainen, Petri (Nokia - FI/Espoo) wrote: Change is OK. The calculation can be changed to use cpu cycle API (with max CPU hz) later. Time measurement does not have to be accurate, so we can continue to use CPU cycles and max hz (to spin at least 'ns' nanosec). We can wait more than 4s, with my cpu cycle counter it's not possible. And don't forget about CPU freq and conversion to ns. This is not place to write about that, lets talk about later. The patch needs to be labeled with "v2". And preferably PATCH, in capital letters. It differs in numbering 1/2. I prefer to hold the same numbering within series. But, next time I will bear it in mind. The log entry could be clarified a bit, see under. -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. In short: "Depending on resolution, a low nsec value could be converted to 0 cycles, which was specified as WAIT ..." Ok Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. "... and would instruct a schedule call to wait forever." Ok Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can wait a little, when shced time has slower rate. It should correspond to schedule only once. So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h index c48b652..8cdc40b 100644 --- a/platform/linux-generic/include/odp/plat/schedule_types.h +++ b/platform/linux-generic/include/odp/plat/schedule_types.h @@ -22,8 +22,8 @@ extern "C" { * @{ */ -#define ODP_SCHED_WAIT 0 -#define ODP_SCHED_NO_WAIT 1 +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 typedef int odp_schedule_prio_t; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..827fcf0 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,9 +646,6 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; - return odp_time_ns_to_cycles(ns); } -- 1.9.1 -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0
Petri, On 10.09.15 17:35, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 5:13 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 All, On 10.09.15 16:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 4:00 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 On 10.09.15 15:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); This test is OK. It's even not tested. But I don't touch it in my series. I can push it with separate patch. But I tend to add it in this patch like: CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); And rename patch on "correct wait time test" is it OK for you? - wait_time = odp_schedule_wait_time(1); This is OK. - CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. That's why it's deleted. - wait_time = odp_schedule_wait_time((uint64_t)-1LL); This is OK. CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. Probably better test it here like: CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); I'll add it along with proposed test improvements. Is it OK for you? So, both asserts should be removed. In addition, wait time should be tested with a schedule call ... but that's for another patch. Right. But not here. Probably with next test like "schedule_wait_time_check" and test it with time API? These are correct test cases: I don't think so. // calls don't crash odp_schedule_wait_time(0); odp_schedule_wait_time(1); Let it be. Don't forget, I'm not going to add it in this series. ... odp_schedule_wait_time(-1); Why do we need this at all? // waits odp_schedule(NULL, ODP_SCHED_WAIT); How long are you going to wait on it? Don't forget, I'm not going to add it in this series. My intention here fix simple bug, not more. // doesn't wait odp_schedule(NULL, ODP_SCHED_NO_WAIT); I dislike dependency on time API, but How are you going to test it here w/o time API? You can check that it was returned say within 5ns. Don't forget, I'm not going to add it in this series. // wait at least 'ns' nsec wait_time = odp_schedule_wait_time(ns); odp_schedule(NULL, wait_time); Same here, + time API, another case your conversion function can produce completely wrong result. And don't forget, I'm not going to add it in this series. Note that ODP_SCHED_WAIT and ODP_SCHED_NO_WAIT - are inputs to odp_schedule() right - are not inputs to odp_schedule_wait_time() rignt, that's why I deleted it in this patch (remember ns == ODP_SCHED_WAIT) - are not outputs from odp_schedule_wait_time() right and not. It must return ODP_SCHED_NO_WAIT if ns = 0. Seems we agreed on this. Also it shouldn't produce ODP_SCHED_WAIT, never. We don't need surprises in the code, especially wait forever. From application (API spec) point of view output from odp_schedule_wait_time() is a random value I started to scare this call at all. that may or may not match ODP_SCHED_WAIT or ODP_SCHED_NO_WAIT. Really? Seems we extract information from different specs. If you really see it, please, it should be corrected, even if it's obvious that it must to not return ODP_SCHED_WAIT. Application uses odp_schedule_wait_time() only when it needs to wait for a certain time. Ohh. Thanks. So, according to my view on that: In this concrete test, we should have: wait_time = odp_schedule_wait_time(0); CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); Other cha
Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0
All, On 10.09.15 16:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 4:00 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 On 10.09.15 15:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); This test is OK. It's even not tested. But I don't touch it in my series. I can push it with separate patch. But I tend to add it in this patch like: CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); And rename patch on "correct wait time test" is it OK for you? - wait_time = odp_schedule_wait_time(1); This is OK. - CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. That's why it's deleted. - wait_time = odp_schedule_wait_time((uint64_t)-1LL); This is OK. CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. Probably better test it here like: CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); I'll add it along with proposed test improvements. Is it OK for you? So, both asserts should be removed. In addition, wait time should be tested with a schedule call ... but that's for another patch. Right. But not here. Probably with next test like "schedule_wait_time_check" and test it with time API? These are correct test cases: I don't think so. // calls don't crash odp_schedule_wait_time(0); odp_schedule_wait_time(1); Let it be. Don't forget, I'm not going to add it in this series. ... odp_schedule_wait_time(-1); Why do we need this at all? // waits odp_schedule(NULL, ODP_SCHED_WAIT); How long are you going to wait on it? Don't forget, I'm not going to add it in this series. My intention here fix simple bug, not more. // doesn't wait odp_schedule(NULL, ODP_SCHED_NO_WAIT); I dislike dependency on time API, but How are you going to test it here w/o time API? You can check that it was returned say within 5ns. Don't forget, I'm not going to add it in this series. // wait at least 'ns' nsec wait_time = odp_schedule_wait_time(ns); odp_schedule(NULL, wait_time); Same here, + time API, another case your conversion function can produce completely wrong result. And don't forget, I'm not going to add it in this series. Note that ODP_SCHED_WAIT and ODP_SCHED_NO_WAIT - are inputs to odp_schedule() right - are not inputs to odp_schedule_wait_time() rignt, that's why I deleted it in this patch (remember ns == ODP_SCHED_WAIT) - are not outputs from odp_schedule_wait_time() right and not. It must return ODP_SCHED_NO_WAIT if ns = 0. Seems we agreed on this. Also it shouldn't produce ODP_SCHED_WAIT, never. We don't need surprises in the code, especially wait forever. From application (API spec) point of view output from odp_schedule_wait_time() is a random value I started to scare this call at all. that may or may not match ODP_SCHED_WAIT or ODP_SCHED_NO_WAIT. Really? Seems we extract information from different specs. If you really see it, please, it should be corrected, even if it's obvious that it must to not return ODP_SCHED_WAIT. Application uses odp_schedule_wait_time() only when it needs to wait for a certain time. Ohh. Thanks. So, according to my view on that: In this concrete test, we should have: wait_time = odp_schedule_wait_time(0); CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); Other changes can be added sometime later. If you disagree, I better won't add it here at all and limit this patch to simple fix, and remove simply CU_ASSERT(wait_time > 0) for wait_time = odp_schedule_wait_time(1); -Petri -- Regards, Ivan Khoronzhuk -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.
[lng-odp] [PATCH v2 0/2] Fix ODP_SCHED_NO_WAIT case for odp_schedule_wait_time
These patches corrects ODP_SCHED_NO_WAIT corner case when scheduler time has resolution more then 1ns. Since v2: - linux-generic: odp_schedule: fix odp_schdule_wait_time Correct commit message - validation: schedule: don't check schedule time on 0 Don't remove check on wait_time = odp_schedule_wait_time(1); Ivan Khoronzhuk (2): linux-generic: odp_schedule: fix odp_schdule_wait_time validation: schedule: don't check schedule time on 0 platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- test/validation/scheduler/scheduler.c| 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time
Depending on resolution, a low nsec value could be converted to 0 cycles, wich was specified as ODP_SCHED_WAIT and would instruct a schedule call to wait forever. Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can wait a little, when shced time has slower rate. It should correspond to schedule only once. So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++-- platform/linux-generic/odp_schedule.c| 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h index c48b652..8cdc40b 100644 --- a/platform/linux-generic/include/odp/plat/schedule_types.h +++ b/platform/linux-generic/include/odp/plat/schedule_types.h @@ -22,8 +22,8 @@ extern "C" { * @{ */ -#define ODP_SCHED_WAIT 0 -#define ODP_SCHED_NO_WAIT 1 +#define ODP_SCHED_WAIT UINT64_MAX +#define ODP_SCHED_NO_WAIT 0 typedef int odp_schedule_prio_t; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index c6619e5..827fcf0 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,9 +646,6 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; - return odp_time_ns_to_cycles(ns); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCH v2 2/2] validation: schedule: don't check schedule time on 0
The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..39357e7 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -95,9 +95,7 @@ void scheduler_test_wait_time(void) uint64_t wait_time; wait_time = odp_schedule_wait_time(0); - wait_time = odp_schedule_wait_time(1); - CU_ASSERT(wait_time > 0); wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time > 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 2/2] validation: schedule: don't check schedule time on 0
On 10.09.15 21:08, Ivan Khoronzhuk wrote: Petri, On 10.09.15 18:16, Ivan Khoronzhuk wrote: Petri, On 10.09.15 17:35, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 5:13 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 All, On 10.09.15 16:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 4:00 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 On 10.09.15 15:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); This test is OK. It's even not tested. But I don't touch it in my series. I can push it with separate patch. But I tend to add it in this patch like: CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); And rename patch on "correct wait time test" is it OK for you? -wait_time = odp_schedule_wait_time(1); This is OK. -CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. That's why it's deleted. - wait_time = odp_schedule_wait_time((uint64_t)-1LL); This is OK. CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. Probably better test it here like: CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); I'll add it along with proposed test improvements. Is it OK for you? So, both asserts should be removed. In addition, wait time should be tested with a schedule call ... but that's for another patch. Right. But not here. Probably with next test like "schedule_wait_time_check" and test it with time API? These are correct test cases: I don't think so. // calls don't crash odp_schedule_wait_time(0); odp_schedule_wait_time(1); Let it be. Don't forget, I'm not going to add it in this series. ... odp_schedule_wait_time(-1); Why do we need this at all? // waits odp_schedule(NULL, ODP_SCHED_WAIT); How long are you going to wait on it? Don't forget, I'm not going to add it in this series. My intention here fix simple bug, not more. // doesn't wait odp_schedule(NULL, ODP_SCHED_NO_WAIT); I dislike dependency on time API, but How are you going to test it here w/o time API? You can check that it was returned say within 5ns. Don't forget, I'm not going to add it in this series. // wait at least 'ns' nsec wait_time = odp_schedule_wait_time(ns); odp_schedule(NULL, wait_time); Same here, + time API, another case your conversion function can produce completely wrong result. And don't forget, I'm not going to add it in this series. Note that ODP_SCHED_WAIT and ODP_SCHED_NO_WAIT - are inputs to odp_schedule() right - are not inputs to odp_schedule_wait_time() rignt, that's why I deleted it in this patch (remember ns == ODP_SCHED_WAIT) - are not outputs from odp_schedule_wait_time() right and not. It must return ODP_SCHED_NO_WAIT if ns = 0. Seems we agreed on this. Also it shouldn't produce ODP_SCHED_WAIT, never. We don't need surprises in the code, especially wait forever. From application (API spec) point of view output from odp_schedule_wait_time() is a random value I started to scare this call at all. that may or may not match ODP_SCHED_WAIT or ODP_SCHED_NO_WAIT. Really? Seems we extract information from different specs. If you really see it, please, it should be corrected, even if it's obvious that it must to not return ODP_SCHED_WAIT. Application uses odp_schedule_wait_time() only when it needs to wait for a certain time. Ohh. Thanks. So, according to my view on that: In this concrete test, we should have: wait_time = odp_schedule_wait_time(0); CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); wait_time = odp_schedule_wait_time((uin
Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0
Petri, On 10.09.15 18:16, Ivan Khoronzhuk wrote: Petri, On 10.09.15 17:35, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 5:13 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 All, On 10.09.15 16:15, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 4:00 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org; nmo...@kalray.eu Subject: Re: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 On 10.09.15 15:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 10, 2015 12:49 PM To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo); nmo...@kalray.eu Cc: Ivan Khoronzhuk Subject: [lng-odp] [Patch 2/2] validation: schedule: don't check schedule time on 0 The ODP_SCHED_NO_WAIT now corresponds to 0, not 1. So no need to check it anymore. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- test/validation/scheduler/scheduler.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 1874889..94facea 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -96,9 +96,6 @@ void scheduler_test_wait_time(void) wait_time = odp_schedule_wait_time(0); This test is OK. It's even not tested. But I don't touch it in my series. I can push it with separate patch. But I tend to add it in this patch like: CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); And rename patch on "correct wait time test" is it OK for you? -wait_time = odp_schedule_wait_time(1); This is OK. -CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. That's why it's deleted. - wait_time = odp_schedule_wait_time((uint64_t)-1LL); This is OK. CU_ASSERT(wait_time > 0); This is not. The value returned is implementation specific. Probably better test it here like: CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_ASSERT(wait_time != ODP_SCHED_WAIT); I'll add it along with proposed test improvements. Is it OK for you? So, both asserts should be removed. In addition, wait time should be tested with a schedule call ... but that's for another patch. Right. But not here. Probably with next test like "schedule_wait_time_check" and test it with time API? These are correct test cases: I don't think so. // calls don't crash odp_schedule_wait_time(0); odp_schedule_wait_time(1); Let it be. Don't forget, I'm not going to add it in this series. ... odp_schedule_wait_time(-1); Why do we need this at all? // waits odp_schedule(NULL, ODP_SCHED_WAIT); How long are you going to wait on it? Don't forget, I'm not going to add it in this series. My intention here fix simple bug, not more. // doesn't wait odp_schedule(NULL, ODP_SCHED_NO_WAIT); I dislike dependency on time API, but How are you going to test it here w/o time API? You can check that it was returned say within 5ns. Don't forget, I'm not going to add it in this series. // wait at least 'ns' nsec wait_time = odp_schedule_wait_time(ns); odp_schedule(NULL, wait_time); Same here, + time API, another case your conversion function can produce completely wrong result. And don't forget, I'm not going to add it in this series. Note that ODP_SCHED_WAIT and ODP_SCHED_NO_WAIT - are inputs to odp_schedule() right - are not inputs to odp_schedule_wait_time() rignt, that's why I deleted it in this patch (remember ns == ODP_SCHED_WAIT) - are not outputs from odp_schedule_wait_time() right and not. It must return ODP_SCHED_NO_WAIT if ns = 0. Seems we agreed on this. Also it shouldn't produce ODP_SCHED_WAIT, never. We don't need surprises in the code, especially wait forever. From application (API spec) point of view output from odp_schedule_wait_time() is a random value I started to scare this call at all. that may or may not match ODP_SCHED_WAIT or ODP_SCHED_NO_WAIT. Really? Seems we extract information from different specs. If you really see it, please, it should be corrected, even if it's obvious that it must to not return ODP_SCHED_WAIT. Application uses odp_schedule_wait_time() only when it needs to wait for a certain time. Ohh. Thanks. So, according to my view on that: In this concrete test, we should have: wait_time = odp_schedule_wait_time(0); CU_ASSERT(wait_time == ODP_SCHED_NO_WAIT); wait_time = odp_schedule_wait_time((uint64_t)-1LL); CU_ASSERT(wait_time != ODP_SCHED_NO_WAIT); CU_AS
Re: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time
On 09.09.15 15:34, Ivan Khoronzhuk wrote: On 09.09.15 15:00, 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: Monday, September 07, 2015 11:51 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { -if (ns <= ODP_SCHED_NO_WAIT) -ns = ODP_SCHED_NO_WAIT + 1; +uint64_t time; -return odp_time_ns_to_cycles(ns); +time = odp_time_ns_to_cycles(ns); +if (!time) +time = ODP_SCHED_NO_WAIT; + +return time; } I think it's better to change (implementation specific) WAIT/NO_WAIT values like this. plat/schedule_types.h #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 ... and avoid any conversion in the common case (WAIT/NO_WAIT). It will not matter, if 1 ns is rounded to 0 == NO_WAIT. uint64_t odp_schedule_wait_time(uint64_t ns) { if (ns == ODP_SCHED_WAIT || ns == ODP_SCHED_NO_WAIT) We shouldn't compare sched time and ns, even it's under implementation. And there is no direct mapping between ns and sched time. In case of maximum for ns, it doesn't mean pool forever for scheduler. Even if it has very low possibility. Assigning POOL forever it's rather an *pool -> poll application responsibility then conversion function. This function can be reused by implementations, mostly on transition stage. As you mentioned, WAIT/NO_WAIT it's implementation specific (define can be not from linux-generic, and function from linux-generic) and better to not rely on WAIT/NO_WAIT = 0. My variant has no such drawback and is more clear in what's going on. And your example should be revritten like: if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); It doesn't differ a lot with proposed patch but still has mentioned drawback, even if it's very rarely case. return ns; return odp_time_ns_to_cycles(ns); } -Petri -- 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: odp_schedule: fix odp_schdule_wait_time
On 09.09.15 15:00, 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: Monday, September 07, 2015 11:51 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; + uint64_t time; - return odp_time_ns_to_cycles(ns); + time = odp_time_ns_to_cycles(ns); + if (!time) + time = ODP_SCHED_NO_WAIT; + + return time; } I think it's better to change (implementation specific) WAIT/NO_WAIT values like this. plat/schedule_types.h #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 ... and avoid any conversion in the common case (WAIT/NO_WAIT). It will not matter, if 1 ns is rounded to 0 == NO_WAIT. uint64_t odp_schedule_wait_time(uint64_t ns) { if (ns == ODP_SCHED_WAIT || ns == ODP_SCHED_NO_WAIT) We shouldn't compare sched time and ns, even it's under implementation. And there is no direct mapping between ns and sched time. In case of maximum for ns, it doesn't mean pool forever for scheduler. Even if it has very low possibility. Assigning POOL forever it's rather an application responsibility then conversion function. This function can be reused by implementations, mostly on transition stage. As you mentioned, WAIT/NO_WAIT it's implementation specific (define can be not from linux-generic, and function from linux-generic) and better to not rely on WAIT/NO_WAIT = 0. My variant has no such drawback and is more clear in what's going on. And your example should be revritten like: if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); It doesn't differ a lot with proposed patch but still has mentioned drawback, even if it's very rarely case. return ns; return odp_time_ns_to_cycles(ns); } -Petri -- 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 time check
The patch in question is transformed to new one: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time Please, review. On 07.09.15 17:19, Savolainen, Petri (Nokia - FI/Espoo) wrote: *From:*ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] *Sent:* Monday, September 07, 2015 4:51 PM *To:* Savolainen, Petri (Nokia - FI/Espoo) *Cc:* Bill Fischofer; LNG ODP Mailman List *Subject:* Re: [lng-odp] [Patch] validation: scheduler: increase time check On 7 September 2015 at 14:59, Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com <mailto:petri.savolai...@nokia.com>> wrote: Scheduler timeout (wait time) enables application to wait on a schedule call, for an finite time. Otherwise application would need to wait infinitely (SCHED_WAIT) or poll full scheduler on full CPU speed (SCHED_NO_WAIT). Periodic return from scheduler can be implemented also using a timer, but it would be waste when a HW scheduler has this finite wait time option build in. Also the “a la carte” principle fits here: user can use the scheduler API without the timer API, if he does not really need timers, just a way to break scheduler to from waiting for ever. Application may use this e.g. to poll some other (non-ODP) resource when it seems that ODP side (of the application) is lightly loaded (e.g. no single event in last 100ms). Yes there are probably use cases for a timeout from odp_schedule. But the examples given below (e.g. timeout receiving some packet) are not valid, such cases should be handled with timers. The timeout is an event itself that should be scheduled by the scheduler so that the proper synchronisation (e.g. accessing some state associated with the queue) can be achieved. If odp_schedule() timeouts and returns without an event, the application should *not* start doing packet processing. Scheduler timeouts are for other types of application background processing and maintenance. Yes, the scheduler timeout should not be used for driving bulk of the ODP event/packet processing. It enables integration of non-ODP SW (which don’t produce events), or driving back ground processing (started only when app is idling). -Petri ___ 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] linux-generic: odp_schedule: fix odp_schdule_wait_time
On 09.09.15 15:44, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Wednesday, September 09, 2015 3:35 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time On 09.09.15 15:00, 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: Monday, September 07, 2015 11:51 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; + uint64_t time; - return odp_time_ns_to_cycles(ns); + time = odp_time_ns_to_cycles(ns); + if (!time) + time = ODP_SCHED_NO_WAIT; + + return time; } I think it's better to change (implementation specific) WAIT/NO_WAIT values like this. plat/schedule_types.h #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 ... and avoid any conversion in the common case (WAIT/NO_WAIT). It will not matter, if 1 ns is rounded to 0 == NO_WAIT. uint64_t odp_schedule_wait_time(uint64_t ns) { if (ns == ODP_SCHED_WAIT || ns == ODP_SCHED_NO_WAIT) We shouldn't compare sched time and ns, even it's under implementation. And there is no direct mapping between ns and sched time. In case of maximum for ns, it doesn't mean pool forever for scheduler. Even if it has very low possibility. Assigning POOL forever it's rather an application responsibility then conversion function. If application asks for a timeout in 580 years (== UINT64_MAX in nsec), it's pretty much the same thing than asking for WAIT. It would see the difference after 580 years. Not a huge problem. It's not a huge problem, but why? And we can use the "conversion" function for some calculations, who knows, what can be in user mind. Bumc, we return him UINT64_MAX, instead of some UNIT64/10. (but the same we can say about 1 instead of 0 , but it has less impact) There is can be other things This function can be reused by implementations, mostly on transition stage. As you mentioned, WAIT/NO_WAIT it's implementation specific (define can be not from linux-generic, and function from linux-generic) and better to not rely on WAIT/NO_WAIT = 0. Currently it is implementation specified value. Linux-generic can use -1 and 0. Others can use other values. This as well as other #defines may need to be fixed for binary compatibility. Binary compatibility is fine. But why current values cannot be used for that? I didn't break them. Adding patch I bear in mind how to not break other implementations, applications... I like more small steps in patch then add two ideas in one, if possible. It allows save time in future. If we must have proposed values for defines in order to follow binary compatibility lets add it in separate patch, that can be easily reverted in case of issue. But I have no objection to add your proposition here, if you very insist on it, seems it removes problem with 1 cycle. But I think, better to rewrite it a little like this, no need to control ODP_SCHED_WAIT in this function, and better remove direct comparison ns and sched time. #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); What do you say? It's better to cleanly catch both values (WAIT/NO_WAIT) and use conversion only for the rest (real nsec values). -Petri My variant has no such drawback and is more clear in what's going on. And your example should be revritten like: if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); It doesn't differ a lot with proposed patch but still has mentioned drawback, even if it's very rarely case
Re: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time
On 09.09.15 16:27, Ivan Khoronzhuk wrote: On 09.09.15 15:44, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: EXT Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Wednesday, September 09, 2015 3:35 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time On 09.09.15 15:00, 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: Monday, September 07, 2015 11:51 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { -if (ns <= ODP_SCHED_NO_WAIT) -ns = ODP_SCHED_NO_WAIT + 1; +uint64_t time; -return odp_time_ns_to_cycles(ns); +time = odp_time_ns_to_cycles(ns); +if (!time) +time = ODP_SCHED_NO_WAIT; + +return time; } I think it's better to change (implementation specific) WAIT/NO_WAIT values like this. plat/schedule_types.h #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 ... and avoid any conversion in the common case (WAIT/NO_WAIT). It will not matter, if 1 ns is rounded to 0 == NO_WAIT. uint64_t odp_schedule_wait_time(uint64_t ns) { if (ns == ODP_SCHED_WAIT || ns == ODP_SCHED_NO_WAIT) We shouldn't compare sched time and ns, even it's under implementation. And there is no direct mapping between ns and sched time. In case of maximum for ns, it doesn't mean pool forever for scheduler. Even if it has very low possibility. Assigning POOL forever it's rather an application responsibility then conversion function. If application asks for a timeout in 580 years (== UINT64_MAX in nsec), it's pretty much the same thing than asking for WAIT. It would see the difference after 580 years. Not a huge problem. It's not a huge problem, but why? And we can use the "conversion" function for some calculations, who knows, what can be in user mind. Bumc, we return him UINT64_MAX, instead of some UNIT64/10. (but the same we can say about 1 instead of 0 , but it has less impact) There is can be other things This function can be reused by implementations, mostly on transition stage. As you mentioned, WAIT/NO_WAIT it's implementation specific (define can be not from linux-generic, and function from linux-generic) and better to not rely on WAIT/NO_WAIT = 0. Currently it is implementation specified value. Linux-generic can use -1 and 0. Others can use other values. This as well as other #defines may need to be fixed for binary compatibility. Binary compatibility is fine. But why current values cannot be used for that? I didn't break them. Adding patch I bear in mind how to not break other implementations, applications... I like more small steps in patch then add two ideas in one, if possible. It allows save time in future. If we must have proposed values for defines in order to follow binary compatibility lets add it in separate patch, that can be easily reverted in case of issue. But I have no objection to add your proposition here, if you very insist on it, seems it removes problem with 1 cycle. But I think, better to rewrite it a little like this, no need to control ODP_SCHED_WAIT in this function, and better remove direct comparison ns and sched time. #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_ns_to_cycles(ns); What do you say? Even like this: #define ODP_SCHED_WAIT UINT64_MAX #define ODP_SCHED_NO_WAIT 0 return odp_time_ns_to_cycles(ns); It's better to cleanly catch both values (WAIT/NO_WAIT) and use conversion only for the rest (real nsec values). -Petri My variant has no such drawback and is more clear in what's going on. And your example should be revritten like: if (!ns) return ODP_SCHED_NO_WAIT; return odp_time_
Re: [lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles
On 07.09.15 15:41, Petri Savolainen wrote: Implemented odp_cpu_cycles() be renaming odp_time_cycles() implementation. Time implementation uses odp_cpu_cycles temporarely. Right. You didn't add functional changes here. Currently It's not documented that odp_time_cycles returns global cycles ). But time API does. So question is, on what I should replace this function for linux generic. on clock_gettime ? Which impact it will have on applications/tests/examples? Do we have choice? Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- platform/linux-generic/arch/linux/odp_cpu_cycles.c | 4 ++-- platform/linux-generic/arch/mips64/odp_cpu_cycles.c | 4 ++-- platform/linux-generic/arch/x86/odp_cpu_cycles.c| 4 ++-- platform/linux-generic/odp_time.c | 6 ++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c b/platform/linux-generic/arch/linux/odp_cpu_cycles.c index 256ad7c..c312f3d 100644 --- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c @@ -9,14 +9,14 @@ #include #include -#include +#include #include #include #include #define GIGA 10 -uint64_t odp_time_cycles(void) +uint64_t odp_cpu_cycles(void) { struct timespec time; uint64_t sec, ns, hz, cycles; diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c index 4fb790b..acd7058 100644 --- a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c @@ -4,11 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include #include #include -uint64_t odp_time_cycles(void) +uint64_t odp_cpu_cycles(void) { #define CVMX_TMP_STR(x) CVMX_TMP_STR2(x) #define CVMX_TMP_STR2(x) #x diff --git a/platform/linux-generic/arch/x86/odp_cpu_cycles.c b/platform/linux-generic/arch/x86/odp_cpu_cycles.c index a111561..20ad44a 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/x86/odp_cpu_cycles.c @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include -uint64_t odp_time_cycles(void) +uint64_t odp_cpu_cycles(void) { union { uint64_t tsc_64; diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index a08833d..6e69e53 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -9,9 +9,15 @@ #include #include #include +#include #define GIGA 10 +uint64_t odp_time_cycles(void) +{ + return odp_cpu_cycles(); +} + uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) { if (odp_likely(t2 > t1)) -- 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 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles
On 08.09.15 12:37, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: ext Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 08, 2015 12:20 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles On 08.09.15 11:35, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: ext Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 08, 2015 10:26 AM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles On 07.09.15 15:41, Petri Savolainen wrote: Implemented odp_cpu_cycles() be renaming odp_time_cycles() implementation. Time implementation uses odp_cpu_cycles temporarely. Right. You didn't add functional changes here. Currently It's not documented that odp_time_cycles returns global cycles ). But time API does. So question is, on what I should replace this function for linux generic. on clock_gettime ? Which impact it will have on applications/tests/examples? Do we have choice? This series does not change time API or functionality of the implementation, just adds CPU cycles API. The new time API needs to specify global wall clock time and implement it so that it's globally synchronized (==> not use CPU cycles counter any more, if those counters are not kept in sync by the HW) +, or can be impacted by freq change. I'm afraid that it will be smth similar to timer API s/w counter. Which has not very good resolution for short time measurements. Do we have direct access to counters in linux-generic cases, like it's done for cycles? It depends on HW and default access rights (linux) on the platform - but, yes some platforms will provide direct read access to the global time counter. I think an arch/linux implementation is enough for linux-generic at the moment. Current implementation is for local counter only. For now maybe it's enough to use it as global? I agree to not touch it for now, and don't know correct substitution for that at this moment. HW specific (arch/xxx) implementations can be added later on. -Petri -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles
On 08.09.15 11:35, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: ext Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Tuesday, September 08, 2015 10:26 AM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles On 07.09.15 15:41, Petri Savolainen wrote: Implemented odp_cpu_cycles() be renaming odp_time_cycles() implementation. Time implementation uses odp_cpu_cycles temporarely. Right. You didn't add functional changes here. Currently It's not documented that odp_time_cycles returns global cycles ). But time API does. So question is, on what I should replace this function for linux generic. on clock_gettime ? Which impact it will have on applications/tests/examples? Do we have choice? This series does not change time API or functionality of the implementation, just adds CPU cycles API. The new time API needs to specify global wall clock time and implement it so that it's globally synchronized (==> not use CPU cycles counter any more, if those counters are not kept in sync by the HW) +, or can be impacted by freq change. I'm afraid that it will be smth similar to timer API s/w counter. Which has not very good resolution for short time measurements. Do we have direct access to counters in linux-generic cases, like it's done for cycles? -Petri -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [API-NEXT PATCH v2 4/5] linux-generic: cpu: implementation for cycle count API
On 08.09.15 11:31, Petri Savolainen wrote: Added implementation for CPU cycle diff, max and resolution. 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 | 10 ++ platform/linux-generic/arch/mips64/odp_cpu_cycles.c | 10 ++ platform/linux-generic/arch/x86/odp_cpu_cycles.c| 10 ++ platform/linux-generic/odp_cpu.c| 16 5 files changed, 47 insertions(+) create mode 100644 platform/linux-generic/odp_cpu.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index c2a4778..43f8de8 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -139,6 +139,7 @@ __LIB__libodp_la_SOURCES = \ odp_barrier.c \ odp_buffer.c \ odp_classification.c \ + odp_cpu.c \ odp_cpumask.c \ odp_cpumask_task.c \ odp_crypto.c \ diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c b/platform/linux-generic/arch/linux/odp_cpu_cycles.c index c312f3d..37a4d94 100644 --- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c @@ -36,3 +36,13 @@ uint64_t odp_cpu_cycles(void) return cycles; } + +uint64_t odp_cpu_cycles_max(void) +{ + return UINT64_MAX; +} + +uint64_t odp_cpu_cycles_resolution(void) +{ + return 1; +} diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c index acd7058..a20a313 100644 --- a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c @@ -19,3 +19,13 @@ uint64_t odp_cpu_cycles(void) return cycle; } + +uint64_t odp_cpu_cycles_max(void) +{ + return UINT64_MAX; +} + +uint64_t odp_cpu_cycles_resolution(void) +{ + return 1; +} diff --git a/platform/linux-generic/arch/x86/odp_cpu_cycles.c b/platform/linux-generic/arch/x86/odp_cpu_cycles.c index 20ad44a..1c5c0ec 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/x86/odp_cpu_cycles.c @@ -21,3 +21,13 @@ uint64_t odp_cpu_cycles(void) return tsc.tsc_64; } + +uint64_t odp_cpu_cycles_max(void) +{ + return UINT64_MAX; +} + +uint64_t odp_cpu_cycles_resolution(void) +{ + return 1; +} diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c new file mode 100644 index 000..45a79db --- /dev/null +++ b/platform/linux-generic/odp_cpu.c @@ -0,0 +1,16 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) +{ + if (odp_likely(c2 >= c1)) + return c2 - c1; + + return c2 + (odp_cpu_cycles_max() - c1); +} -- 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 1/4] api: rename odp_cpumask_def to _default
On 08.09.15 14:03, Maxim Uvarov wrote: On 09/08/15 13:55, Ivan Khoronzhuk wrote: Maxim, Could you please clarify. I expect that after patch adding some implementation should build. If you adding new API it doesn't have impact. But if API is modified, probably that project has build problem. This patch, can have examples/validations in one patch in order to allow every patch to build. linux-generic changes can exist separately as it's implementation specific. What do you say? On merge I'm going to concatenate patches 1/4 and 2/4 to one single patch. For review it might be easy to review separately api change and renames in implementation. I planned to write about that in cover latter. But can also send v2. Maxim. I just wanted to clarify if it has some other sense. It can require to be squashed for checking in some cases If it's going to be squashed it's OK. On 08.09.15 13:31, Maxim Uvarov wrote: Use full default word in api to make function name more clear. https://bugs.linaro.org/show_bug.cgi?id=1745 Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- include/odp/api/cpumask.h | 4 ++-- platform/linux-generic/odp_cpumask_task.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 2ad7fea..4835a6c 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -203,7 +203,7 @@ int odp_cpumask_next(const odp_cpumask_t *mask, int cpu); * @param num Number of worker threads, zero for all available CPUs * @return Actual number of CPUs used to create the mask */ -int odp_cpumask_def_worker(odp_cpumask_t *mask, int num); +int odp_cpumask_default_worker(odp_cpumask_t *mask, int num); /** * Default cpumask for control threads @@ -215,7 +215,7 @@ int odp_cpumask_def_worker(odp_cpumask_t *mask, int num); * @param num Number of control threads, zero for all available CPUs * @return Actual number of CPUs used to create the mask */ -int odp_cpumask_def_control(odp_cpumask_t *mask, int num); +int odp_cpumask_default_control(odp_cpumask_t *mask, int num); /** * @} diff --git a/platform/linux-generic/odp_cpumask_task.c b/platform/linux-generic/odp_cpumask_task.c index 665e82a..535891c 100644 --- a/platform/linux-generic/odp_cpumask_task.c +++ b/platform/linux-generic/odp_cpumask_task.c @@ -13,7 +13,7 @@ #include #include -int odp_cpumask_def_worker(odp_cpumask_t *mask, int num) +int odp_cpumask_default_worker(odp_cpumask_t *mask, int num) { int ret, cpu, i; cpu_set_t cpuset; @@ -43,7 +43,7 @@ int odp_cpumask_def_worker(odp_cpumask_t *mask, int num) return cpu; } -int odp_cpumask_def_control(odp_cpumask_t *mask, int num ODP_UNUSED) +int odp_cpumask_default_control(odp_cpumask_t *mask, int num ODP_UNUSED) { odp_cpumask_zero(mask); /* By default all control threads on CPU 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 PATCH 1/4] api: rename odp_cpumask_def to _default
Maxim, Could you please clarify. I expect that after patch adding some implementation should build. If you adding new API it doesn't have impact. But if API is modified, probably that project has build problem. This patch, can have examples/validations in one patch in order to allow every patch to build. linux-generic changes can exist separately as it's implementation specific. What do you say? On 08.09.15 13:31, Maxim Uvarov wrote: Use full default word in api to make function name more clear. https://bugs.linaro.org/show_bug.cgi?id=1745 Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- include/odp/api/cpumask.h | 4 ++-- platform/linux-generic/odp_cpumask_task.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 2ad7fea..4835a6c 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -203,7 +203,7 @@ int odp_cpumask_next(const odp_cpumask_t *mask, int cpu); * @param num Number of worker threads, zero for all available CPUs * @return Actual number of CPUs used to create the mask */ -int odp_cpumask_def_worker(odp_cpumask_t *mask, int num); +int odp_cpumask_default_worker(odp_cpumask_t *mask, int num); /** * Default cpumask for control threads @@ -215,7 +215,7 @@ int odp_cpumask_def_worker(odp_cpumask_t *mask, int num); * @param num Number of control threads, zero for all available CPUs * @return Actual number of CPUs used to create the mask */ -int odp_cpumask_def_control(odp_cpumask_t *mask, int num); +int odp_cpumask_default_control(odp_cpumask_t *mask, int num); /** * @} diff --git a/platform/linux-generic/odp_cpumask_task.c b/platform/linux-generic/odp_cpumask_task.c index 665e82a..535891c 100644 --- a/platform/linux-generic/odp_cpumask_task.c +++ b/platform/linux-generic/odp_cpumask_task.c @@ -13,7 +13,7 @@ #include #include -int odp_cpumask_def_worker(odp_cpumask_t *mask, int num) +int odp_cpumask_default_worker(odp_cpumask_t *mask, int num) { int ret, cpu, i; cpu_set_t cpuset; @@ -43,7 +43,7 @@ int odp_cpumask_def_worker(odp_cpumask_t *mask, int num) return cpu; } -int odp_cpumask_def_control(odp_cpumask_t *mask, int num ODP_UNUSED) +int odp_cpumask_default_control(odp_cpumask_t *mask, int num ODP_UNUSED) { odp_cpumask_zero(mask); /* By default all control threads on CPU 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 PATCH v2 2/5] linux-generic: cpu: created arch depedent cpu_cycles files
On 08.09.15 11:31, Petri Savolainen wrote: Renamed time_cycles files to cpu_cycles, since those files implement cpu cycle counter read needed by cpu API but not needed by new time API. Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/Makefile.am | 8 ++--- platform/linux-generic/arch/linux/odp_cpu_cycles.c | 38 ++ .../linux-generic/arch/linux/odp_time_cycles.c | 38 -- .../linux-generic/arch/mips64/odp_cpu_cycles.c | 21 .../linux-generic/arch/mips64/odp_time_cycles.c| 21 platform/linux-generic/arch/x86/odp_cpu_cycles.c | 23 + platform/linux-generic/arch/x86/odp_time_cycles.c | 23 - 7 files changed, 86 insertions(+), 86 deletions(-) create mode 100644 platform/linux-generic/arch/linux/odp_cpu_cycles.c delete mode 100644 platform/linux-generic/arch/linux/odp_time_cycles.c create mode 100644 platform/linux-generic/arch/mips64/odp_cpu_cycles.c delete mode 100644 platform/linux-generic/arch/mips64/odp_time_cycles.c create mode 100644 platform/linux-generic/arch/x86/odp_cpu_cycles.c delete mode 100644 platform/linux-generic/arch/x86/odp_time_cycles.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 4c79730..c2a4778 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -167,9 +167,9 @@ __LIB__libodp_la_SOURCES = \ odp_timer.c \ odp_version.c \ odp_weak.c \ - arch/@ARCH@/odp_time_cycles.c + arch/@ARCH@/odp_cpu_cycles.c EXTRA_DIST = \ -arch/linux/odp_time_cycles.c \ -arch/mips64/odp_time_cycles.c \ -arch/x86/odp_time_cycles.c +arch/linux/odp_cpu_cycles.c \ +arch/mips64/odp_cpu_cycles.c \ +arch/x86/odp_cpu_cycles.c diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c b/platform/linux-generic/arch/linux/odp_cpu_cycles.c new file mode 100644 index 000..256ad7c --- /dev/null +++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define _POSIX_C_SOURCE 199309L + +#include +#include + +#include +#include +#include +#include + +#define GIGA 10 + +uint64_t odp_time_cycles(void) +{ + struct timespec time; + uint64_t sec, ns, hz, cycles; + int ret; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, ); + + if (ret != 0) + ODP_ABORT("clock_gettime failed\n"); + + hz = odp_sys_cpu_hz(); + sec = (uint64_t)time.tv_sec; + ns = (uint64_t)time.tv_nsec; + + cycles = sec * hz; + cycles += (ns * hz) / GIGA; + + return cycles; +} diff --git a/platform/linux-generic/arch/linux/odp_time_cycles.c b/platform/linux-generic/arch/linux/odp_time_cycles.c deleted file mode 100644 index 4dc0764..000 --- a/platform/linux-generic/arch/linux/odp_time_cycles.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#define _POSIX_C_SOURCE 199309L - -#include -#include - -#include -#include -#include -#include - -#define GIGA 10 - -uint64_t odp_time_cycles(void) -{ - struct timespec time; - uint64_t sec, ns, hz, cycles; - int ret; - - ret = clock_gettime(CLOCK_MONOTONIC_RAW, ); - - if (ret != 0) - ODP_ABORT("clock_gettime failed\n"); - - hz = odp_sys_cpu_hz(); - sec = (uint64_t) time.tv_sec; - ns = (uint64_t) time.tv_nsec; - - cycles = sec * hz; - cycles += (ns * hz) / GIGA; - - return cycles; -} diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c new file mode 100644 index 000..4fb790b --- /dev/null +++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c @@ -0,0 +1,21 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +uint64_t odp_time_cycles(void) +{ + #define CVMX_TMP_STR(x) CVMX_TMP_STR2(x) + #define CVMX_TMP_STR2(x) #x + uint64_t cycle; + + __asm__ __volatile__ ("rdhwr %[rt],$" CVMX_TMP_STR(31) : + [rt] "=d" (cycle) : : "memory"); + + return cycle; +} diff --git a/platform/linux-generic/arch/mips64/odp_time_cycles.c b/platform/linux-generic/arch/mips64/odp_time_cycles.c deleted file mode 100644 index 4fb790b..000 --- a/platform/linux-generic/arch/mips64/odp_time_cycles.c
[lng-odp] [Patch] linux-generic: odp_schedule: fix odp_schdule_wait_time
The resolution of schedule time can be more than 1ns. As result can happen that 1ns corresponds 0 ticks of timer counter, but if passed 1ns it's obvious that user wanted to schedule at least once. Currently it can lead to wait forever, as 0 corresponds to ODP_SCHED_WAIT, it can block program flow at all. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Prerequisit for this patch was taken from: "[lng-odp] [Patch] validation: scheduler: increase time check" https://lists.linaro.org/pipermail/lng-odp/2015-August/014738.html platform/linux-generic/odp_schedule.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index c6619e5..05497de 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -646,10 +646,13 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - if (ns <= ODP_SCHED_NO_WAIT) - ns = ODP_SCHED_NO_WAIT + 1; + uint64_t time; - return odp_time_ns_to_cycles(ns); + time = odp_time_ns_to_cycles(ns); + if (!time) + time = ODP_SCHED_NO_WAIT; + + return time; } -- 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] example: timer: move cycles/ns table to validation tests
Petri, Maybe this peace of code should migrate to some other place, but on my opinion it has more common with time API then cpu API. The table to check time table mixes time/cycles with timer API example, and it is confusing a little. Here it doesn't bear any sense except time API has something common with timer API, but that's not true. Maybe it can be deleted at all, just want to leave it somewhere. On 03.09.15 11:50, Ivan Khoronzhuk wrote: The linux-generic implements timers supposing that timers are based on CPU cycle counter. It's not always true and timer API can have nothing common with CPU cycles. Thus timer test shouldn't print here conversion cycles/ns table for time API. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- I'm not sure about moving the table to validation test, but it can be useful to visually see resolution impact. This patch should be included in "odp-lng] [Patch 0/4] preparation series before updating odp time API" https://lists.linaro.org/pipermail/lng-odp/2015-August/014850.html But before let's clarify it. example/timer/odp_timer_test.c | 21 - test/validation/time/time.c| 21 - 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..6248939 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -322,7 +322,6 @@ int main(int argc, char *argv[]) odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -446,26 +445,6 @@ int main(int argc, char *argv[]) return -1; } - printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); - ns = 0; - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - - for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - } - - printf("\n"); - gbls->num_workers = num_workers; /* Initialize number of timeouts to receive */ diff --git a/test/validation/time/time.c b/test/validation/time/time.c index 4b81c2c..ae5e77c 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -45,7 +45,7 @@ void time_test_odp_cycles_negative_diff(void) /* check that related conversions come back to the same value */ void time_test_odp_time_conversion(void) { - uint64_t ns1, ns2, cycles; + uint64_t ns, ns1, ns2, cycles; uint64_t upper_limit, lower_limit; ns1 = 100; @@ -59,6 +59,25 @@ void time_test_odp_time_conversion(void) upper_limit = ns1 + TOLERANCE; lower_limit = ns1 - TOLERANCE; CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + + printf("Cycles vs nanoseconds:\n"); + ns = 0; + cycles = odp_time_ns_to_cycles(ns); + + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, cycles); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", cycles, + odp_time_cycles_to_ns(cycles)); + + for (ns = 1; ns <= 100 * ODP_TIME_SEC; ns *= 10) { + cycles = odp_time_ns_to_cycles(ns); + + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, + cycles); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", cycles, + odp_time_cycles_to_ns(cycles)); + } + + printf("\n"); } CU_TestInfo 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] [API-NEXT PATCH v4 05/10] linux-generic: sysinfo: clarify the API for max CPU frequency
On 07.09.15 14:08, Hongbo Zhang wrote: On 3 September 2015 at 22:47, Ivan Khoronzhuk <ivan.khoronz...@linaro.org> wrote: Hi, Hongbo On 11.08.15 10:33, hongbo.zh...@freescale.com wrote: From: Hongbo Zhang <hongbo.zh...@linaro.org> Currently the API to get CPU frequency is vague, it needs to be clarified whether max or current frequency is returned, and now most use cases want to get max capacity of CPU in fact, so this patch makes it clear that the cpu_hz stand for max CPU frequency. (there is no need to store current instant frequency) Also patch name linux-generic, but it's changing api/examples/tests and linux-generic in one patch What about to split it? I don't know how others, but I tend to miss linux-generic specific patches when I have no time enough and look only on common patches. In this case it's hidden. Some APIs are renamed due to: moving them to cpu.h and necessary re-implement. I choose to update all the calling functions in one patch, because it is easy to review although the patch seems long. If separated as you suggested, patch numbers will be too huge, because almost related APIs are renamed due to moving to cpu.h, and there are too many functions calling them. It's too huge already. It should be max 6 patches at series, it scares people to review it. Usually in such case I split them on several series, if possible. Also it simplier to revert in case of some error. Accordingly the API odp_cpu_hz() is renamed to odp_cpu_hz_max(). While there may still be some use case of acquiring the current CPU frequency, so the previous odp_cpu_hz() will be re-implemented for this purpose in the next patch. As to platforms other than x86, if their cpu_hz's don't stand for max CPU frequency, they should be changed following up this patch, and then max or current frequency of CPU should be clear. Signed-off-by: Hongbo Zhang <hongbo.zh...@linaro.org> --- example/classifier/odp_classifier.c | 2 +- example/generator/odp_generator.c| 2 +- example/ipsec/odp_ipsec.c| 2 +- example/packet/odp_pktio.c | 2 +- example/timer/odp_timer_test.c | 4 ++-- include/odp/api/cpu.h| 2 +- platform/linux-generic/arch/linux/odp_time.c | 2 +- platform/linux-generic/odp_system_info.c | 22 +++--- platform/linux-generic/odp_time.c| 4 ++-- test/api_test/odp_common.c | 2 +- test/performance/odp_atomic.c| 2 +- test/performance/odp_l2fwd.c | 2 +- test/performance/odp_scheduling.c| 2 +- test/validation/system/system.c | 6 +++--- test/validation/system/system.h | 2 +- 15 files changed, 25 insertions(+), 33 deletions(-) diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 8b68ce0..16e567d 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -733,7 +733,7 @@ static void print_info(char *progname, appl_args_t *appl_args) "CPU count: %i\n" "\n", odp_version_api_str(), odp_cpu_model_str(), - odp_cpu_hz(), odp_sys_cache_line_size(), + odp_cpu_hz_max(), odp_sys_cache_line_size(), odp_cpu_count()); printf("Running ODP appl: \"%s\"\n" diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 2ed4ea2..7982801 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -988,7 +988,7 @@ static void print_info(char *progname, appl_args_t *appl_args) "Cache line size: %i\n" "CPU count: %i\n" "\n", - odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz(), + odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz_max(), odp_sys_cache_line_size(), odp_cpu_count()); printf("Running ODP appl: \"%s\"\n" diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 32a91e4..b2bc501 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -1516,7 +1516,7 @@ static void print_info(char *progname, appl_args_t *appl_args) "Cache line size: %i\n" "CPU count: %i\n" "\n", - odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz(), + odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz_max(), odp_sys_cache_line_size(), odp_cpu_count()); printf("Running ODP appl: \"%s\"\n" diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index 75de6b8..f0bc
Re: [lng-odp] [API-NEXT PATCH 5/5] performance: sched: update scheduling test to use cycle counts
sorry one typo . -printf("\nTime accuracy test (%i sec)\n", TEST_SEC); +printf("\nCPU cycle count accuracy test (%i sec)\n", TEST_SEC); Maybe beter to put this line under clock_gettime? In order to not miss *under -> above t1 == t2? Maybe here it's not so important but if it's going to be replaced on odp_time, better to do it here, anyway printf is changed. do { if (clock_gettime(CLOCK_MONOTONIC, )) { @@ -738,7 +719,7 @@ static void test_time(void) } while (tp1.tv_sec == tp2.tv_sec); -t1 = odp_time_cycles(); +c1 = odp_cpu_cycles(); .... -- 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 5/5] performance: sched: update scheduling test to use cycle counts
p2.tv_nsec - tp1.tv_nsec; + nsec += tp2.tv_nsec - tp1.tv_nsec; else - ns1 -= tp1.tv_nsec - tp2.tv_nsec; + nsec -= tp1.tv_nsec - tp2.tv_nsec; - cycles = odp_time_diff_cycles(t1, t2); - ns2= odp_time_cycles_to_ns(cycles); + cycles = odp_cpu_cycles_diff(c1, c2); + max_cycles = (nsec * odp_sys_cpu_hz()) / 10.0; That case could be impacted by cpufreq change...I believe that it's static. - err = ((double)(ns2) - (double)ns1) / (double)ns1; + /* Compare measured CPU cycles to maximum theoretical CPU cycle count */ + diff_max_hz = ((double)(cycles) - max_cycles) / max_cycles; It's expected here to be -X%, but due to "time measurement" can have resolution impact, can happen that it will be +X%...that is confusing. Is it OK? - printf("clock_gettime %"PRIu64" ns\n",ns1); - printf("odp_time_cycles %"PRIu64" cycles\n", cycles); - printf("odp_time_cycles_to_ns %"PRIu64" ns\n",ns2); - printf("odp get cycle error %f%%\n", err*100.0); + printf("clock_gettime %" PRIu64 " ns\n", nsec); + printf("odp_cpu_cycles %" PRIu64 " CPU cycles\n", cycles); + printf("odp_sys_cpu_hz %" PRIu64 " hz\n", odp_sys_cpu_hz()); + printf("Diff from max CPU freq %f%%\n", diff_max_hz * 100.0); printf("\n"); } @@ -879,7 +861,7 @@ int main(int argc, char *argv[]) printf("---\n"); printf("ODP API version: %s\n",odp_version_api_str()); printf("CPU model: %s\n",odp_sys_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_sys_cpu_hz()); + printf("CPU freq (hz): %" PRIu64 "\n", odp_sys_cpu_hz()); printf("Cache line size: %i\n",odp_sys_cache_line_size()); printf("Max CPU count: %i\n",odp_cpu_count()); @@ -898,8 +880,8 @@ int main(int argc, char *argv[]) printf("first CPU: %i\n", odp_cpumask_first()); printf("cpu mask: %s\n", cpumaskstr); - /* Test cycle count accuracy */ - test_time(); + /* Test cycle count frequency */ + test_cpu_freq(); shm = odp_shm_reserve("test_globals", sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 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 PATCH 1/5] api: cpu: added cpu cycle count API
Petri, On 07.09.15 15:41, Petri Savolainen wrote: Raw CPU cycle counts can be used to measure performance in CPU cycles. These functions will replace some usage of odp_time_cycles() of odp_time_diff_cycles(). Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- Probably proposed API covers all existent cases. Also we agreed that it can be 32-bits counter like for ARMv7. Just imaged situation when we need to put some masg in N cycles. Or complete some job when we spend some amount of cpu cycles. In this case c1 + c2(range) should be avoided, as in 64-bits it approximately will never be overflowed and in comparison will be more then current cycle number forever. But don't bother, I think that if you use this API for such case, your program definitely is wrong and should be rewritten. + operation should be used only to integrate spent cycles, not more. include/odp/api/cpu.h | 52 +++ 1 file changed, 52 insertions(+) diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h index c389093..50a7e3d 100644 --- a/include/odp/api/cpu.h +++ b/include/odp/api/cpu.h @@ -18,6 +18,8 @@ extern "C" { #endif +#include + /** @defgroup odp_cpu ODP CPU * @{ */ @@ -44,6 +46,56 @@ int odp_cpu_id(void); int odp_cpu_count(void); /** + * Current CPU cycle count + * + * Return current CPU cycle count. Cycle count may not be reset at ODP init + * and thus may wrap back to zero between two calls. Use odp_cpu_cycles_max() + * to read the maximum count value after which it wraps. Cycle count frequency + * follows the CPU frequency and thus may change at any time. The count may + * advance in steps larger than one. Use odp_cpu_cycles_resolution() to read + * the step size. + * + * @note Do not use CPU count for time measurements since the frequency may + * vary. + * + * @return Current CPU cycle count + */ +uint64_t odp_cpu_cycles(void); + +/** + * CPU cycle count difference + * + * Calculate difference between cycle counts c1 and c2. Parameter c1 must be the + * first cycle count sample and c2 the second. The function handles correctly + * single cycle count wrap between c1 and c2. + * + * @param c1First cycle count + * @param c2Second cycle count + * + * @return CPU cycles from c1 to c2 + */ +uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2); + +/** + * Maximum CPU cycle count + * + * Maximum CPU cycle count value before it wraps back to zero. + * + * @return Maximum CPU cycle count value + */ +uint64_t odp_cpu_cycles_max(void); + +/** + * Resolution of CPU cycle count + * + * CPU cycle count may advance in steps larger than one. This function returns + * resolution of odp_cpu_cycles() in CPU cycles. + * + * @return CPU cycle count resolution in CPU cycles + */ +uint64_t odp_cpu_cycles_resolution(void); + +/** * @} */ -- 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 time check
Bill, On 04.09.15 05:46, Bill Fischofer wrote: The time waiting is of dubious value (and portability) in a system with dedicated worker threads. What else are they planning to do? Is that the best design for the application? There are valid common uses for ODP_SCHED_WAIT and ODP_SCHED_NO_WAIT. Everything else is questionable. Periodic processing should be done via timers that trigger events rather than by guesswork on the part of workers. I tend to leave it as proposed Nicolas to cover existent examples. It cannot touch cases where timers are used, I guess. if (ns && !cycle) cycle = 1; ODP_SCHED_NO_WAIT (1) like check once, so if we passed ~ 1ns we wanted to schedule at least once. Currently it can lead to wait forever ODP_SCHED_WAIT (0). On Thu, Sep 3, 2015 at 1:28 AM, Ivan Khoronzhuk <ivan.khoronz...@linaro.org <mailto:ivan.khoronz...@linaro.org>> wrote: On 03.09.15 09:20, Nicolas Morey-Chaisemartin wrote: On 09/02/2015 11:16 PM, Ivan Khoronzhuk wrote: On 02.09.15 12:42, Nicolas Morey-Chaisemartin wrote: On 08/26/2015 05:47 PM, Ivan Khoronzhuk wrote: On 26.08.15 18:22, Stuart Haslam wrote: On Wed, Aug 26, 2015 at 06:11:13PM +0300, Ivan Khoronzhuk wrote: It's needed because time resolution can be a little more than 1ns and in this case odp_schedule_wait_time(1) returns 0, and test generates warn w/o reason. So increase scheduler wait time check from 1ns to 100ns. It's hard to imagine time source with resolution more than 100ns, so every implementation can return positive value from odp_schedule_wait_time(). In case if resolution is more than 100ns it's normal to warn about it at validation stage, The wait parameter is documented as the *minimum* time to wait for an event so the existing check looks OK to me. Implementations with a lower resolution should round up. It defined as "minimum" time to wait for odp_schedule and others, for odp_schedule_wait_time() it's not defined as minimum, it's simple convert function. Not shure, but any of the functions I saw in linux-generic doesn't round ticks up. It seems that it was decided to allow application to do it, if needed. But if so, we have much more to change ). In case if you are right, linux-generic implementation should be corrected, as it doesn't round it up. Thanks. I ran into this issue with our port as our clock are < 1GHz. So 1 ns is < 1 cycle which tends to break a few things on the linux generic port. I fix this particular issue like this: uint64_t odp_schedule_wait_time(uint64_t ns) { uint64_t cycle = odp_time_ns_to_cycles(ns); if(cycle == 0) cycle = 1; return cycle; } Not the nicest patch but it works. The test should probably be changed to if(ns && !cycle) so ns=0 returns 0; Yes. As said Stuart it may cause collisions with ODP_SCHED_WAIT (0) and ODP_SCHED_NO_WAIT (1) I will correct it a little later. I don't think the collision with ODP_SCHED_NO_WAIT is too bad. We only fall into this case if a cycle is larger than 1 ns so waiting not waiting or waiting less thana cycle is close to the same thing. Maybe you are right. -- Regards, Ivan Khoronzhuk ___ 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
Re: [lng-odp] [odp-lng] [Patch v3 1/3] api: time: unbind CPU cycles from time API
Petri, On 04.09.15 12:14, Savolainen, Petri (Nokia - FI/Espoo) wrote: -Original Message- From: ext Ivan Khoronzhuk [mailto:ivan.khoronz...@linaro.org] Sent: Thursday, September 03, 2015 6:26 PM To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [odp-lng] [Patch v3 1/3] api: time: unbind CPU cycles from time API Petri, On 03.09.15 16:13, Ivan Khoronzhuk wrote: On 03.09.15 15:29, Savolainen, Petri (Nokia - FI/Espoo) wrote: There are many example apps that actually want to measure execution time in CPU cycles, not in nsec. Time API and CPU (cycle) API updates are linked together. Real CPU cycle cases must not converted to use time API, but to use a new odp_cpu_cycle() count API first. Then what is left should be actual time API use cases. Let me look at CPU API first. I hesitate to answer because of freq scaling. I have filling that there is not so very well. And yes, probably I should move part of this changes in preparation series. where did you see, odp_cycle_count? Even if you are going to add. Think once again. It seems it's better replace it here on odp_time. Imagine the system which has cpufreq governor that dependently on packet rate, and hence system load, regulate CPU frequency in order to reduce power consumption. In this case you CPU rate is changing very fast and frequently. When you get frequency with odp_cpu_hz() it doesn't mean that this freq was the same a 1ms ago or 1ms after. Or What if we have frequency spectrum: F1 F2 F3 Fmax Fmax can be switched on in rarely cases when traffic rate is extremely hi. This period is very short and most time (99%) CPU is working at F3, as processor can be damaged by temperature. In some point in time odp_cpu_hz() can return Fmax. But you want to count some number of cycles in period of time, mostly with freq = F3. But you got Fmax, your calculation will be wrong. In this regard current cpu frequency API looks very pure. And by a big account it should be calculated in combine with governor, which can be absent or even in operating system. Seems we don't have a choice, and should use odp_time for that. cpu cycles count can be evaluated only by odp_time()*odp_cpu_hz()/odp_time_hz(). But I'm worry about how we can count some cpu cycles if we are not sure in cpu frequency :-|? It's not informative for systems in question. So better to evaluate it with odp_time. No choice. CPU cycle measurement is different from time (latency) measurement. CPU cycle count tells you exact CPU overhead. These tests measure CPU overhead, which is many times more relevant for performance measurement than latency (nsec). User can choose the governor policy and interpret the measurement results accordingly. I'm going to add cpu cycle functions into cpu.h. No objection. It be good you add it in near future. And don't forget to mention that it's valid only in debug purposes. Also it can be 32-bit counter and it can wrap (4s), so it should be close to time api. And create maybe some ticket I can point that it blocks me to add time API. -Petri -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] RFC: New time API
leave it in non zero state - then possible glitches. But in this case lets assume. Also spec can guarantee, but real life can add surprises, like in most cases it's by default 0, but at some circumstances can happen that not, you will be catching very rarely glitches and don't know what's happening. => nsec time (that start from zero by the spec) will not wrap in the life time of this application yes. we can do this. but only for ns. in some odp_time_wall() in ns... When you converting odp_time_to_ns() in most cases you need to know some time distance in ns. If we convert odp_time_from_ns(), probably we are going to use it to get some range. Like odp_time_from_ns(9), and use it in some wait loop. And here shouldn't be any start time or else. What about to add separate functions to support wall time? Like: odp_time_wall();// here we always returns diff (that take into account wrap). // Can be compared, diff/sum directly w/o functions. odp_time_wall_ns(); // Also, obvious, can be compared, diff/sum directly w/o functions. Only these functions are global. And can be used to trace some packet times on threads. Mostly diff and sum for them are not needed, but they are simple C operations. Also odp_time_wall_rate() can be added to evaluate rate and thus resolution. => nsec time wrap is not possible => can use cmp(). Done. Only for case, counter = 0 at init, another case - glitches. And how are you going to explain this to an application? Use in one case, changed hardware - don't use. Check timer inited correctly? Check it's 32 bit or 64 in application? Check time wrap period? It's not very friendly on my opinion. Always use only for ranges is more correct variant. -Petri -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2 8/8] validation: schedule: add coverage for new scheduler APIs
return -1; + } + + rc = odp_queue_context_set(q, qctx); + + if (rc != 0) { + printf("Cannot set queue context\n"); + return -1; + } } } @@ -919,11 +1046,15 @@ int scheduler_suite_init(void) static int destroy_queue(const char *name) { odp_queue_t q; + queue_context *qctx; q = odp_queue_lookup(name); if (q == ODP_QUEUE_INVALID) return -1; + qctx = odp_queue_context(q); + if (qctx) + odp_buffer_free(qctx->ctx_handle); return odp_queue_destroy(q); } @@ -952,6 +1083,9 @@ static int destroy_queues(void) } } + if (odp_pool_destroy(queue_ctx_pool) != 0) + return -1; + return 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 PATCH v4 05/10] linux-generic: sysinfo: clarify the API for max CPU frequency
odp_version_api_str()); printf("CPU model: %s\n",odp_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz()); + printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); printf("Cache line size: %i\n",odp_sys_cache_line_size()); printf("CPU count: %i\n",odp_cpu_count()); printf("CPU mask:%s\n",str); diff --git a/test/performance/odp_atomic.c b/test/performance/odp_atomic.c index 74d4f3a..dea6210 100644 --- a/test/performance/odp_atomic.c +++ b/test/performance/odp_atomic.c @@ -338,7 +338,7 @@ void odp_print_system_info(void) printf("---\n"); printf("ODP API version: %s\n",odp_version_api_str()); printf("CPU model: %s\n",odp_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz()); + printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); printf("Cache line size: %i\n",odp_sys_cache_line_size()); printf("CPU count: %i\n",odp_cpu_count()); printf("CPU mask:%s\n",str); diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 6951837..37c62ca 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -641,7 +641,7 @@ static void print_info(char *progname, appl_args_t *appl_args) "Cache line size: %i\n" "CPU count: %i\n" "\n", - odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz(), + odp_version_api_str(), odp_cpu_model_str(), odp_cpu_hz_max(), odp_sys_cache_line_size(), odp_cpu_count()); printf("Running ODP appl: \"%s\"\n" diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c index a73f013..53f84a7 100644 --- a/test/performance/odp_scheduling.c +++ b/test/performance/odp_scheduling.c @@ -881,7 +881,7 @@ int main(int argc, char *argv[]) printf("---\n"); printf("ODP API version: %s\n",odp_version_api_str()); printf("CPU model: %s\n",odp_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz()); + printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); printf("Cache line size: %i\n",odp_sys_cache_line_size()); printf("Max CPU count: %i\n",odp_cpu_count()); diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 54cb7c5..9134161 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -75,11 +75,11 @@ void system_test_odp_sys_huge_page_size(void) CU_ASSERT(0 < page); } -void system_test_odp_cpu_hz(void) +void system_test_odp_cpu_hz_max(void) { uint64_t hz; - hz = odp_cpu_hz(); + hz = odp_cpu_hz_max(); CU_ASSERT(0 < hz); } @@ -90,7 +90,7 @@ CU_TestInfo system_suite[] = { {"odp_cpu_model_str", system_test_odp_cpu_model_str}, {"odp_sys_page_size", system_test_odp_sys_page_size}, {"odp_sys_huge_page_size", system_test_odp_sys_huge_page_size}, - {"odp_cpu_hz", system_test_odp_cpu_hz}, + {"odp_cpu_hz_max", system_test_odp_cpu_hz_max}, CU_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index d05f104..67ddb7a 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -16,7 +16,7 @@ void system_test_odp_sys_cache_line_size(void); void system_test_odp_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_cpu_hz(void); +void system_test_odp_cpu_hz_max(void); /* test arrays: */ extern CU_TestInfo system_suite[]; -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [odp-lng] [Patch v3 1/3] api: time: unbind CPU cycles from time API
Petri, On 03.09.15 16:13, Ivan Khoronzhuk wrote: On 03.09.15 15:29, Savolainen, Petri (Nokia - FI/Espoo) wrote: There are many example apps that actually want to measure execution time in CPU cycles, not in nsec. Time API and CPU (cycle) API updates are linked together. Real CPU cycle cases must not converted to use time API, but to use a new odp_cpu_cycle() count API first. Then what is left should be actual time API use cases. Let me look at CPU API first. I hesitate to answer because of freq scaling. I have filling that there is not so very well. And yes, probably I should move part of this changes in preparation series. where did you see, odp_cycle_count? Even if you are going to add. Think once again. It seems it's better replace it here on odp_time. Imagine the system which has cpufreq governor that dependently on packet rate, and hence system load, regulate CPU frequency in order to reduce power consumption. In this case you CPU rate is changing very fast and frequently. When you get frequency with odp_cpu_hz() it doesn't mean that this freq was the same a 1ms ago or 1ms after. Or What if we have frequency spectrum: F1 F2 F3 Fmax Fmax can be switched on in rarely cases when traffic rate is extremely hi. This period is very short and most time (99%) CPU is working at F3, as processor can be damaged by temperature. In some point in time odp_cpu_hz() can return Fmax. But you want to count some number of cycles in period of time, mostly with freq = F3. But you got Fmax, your calculation will be wrong. In this regard current cpu frequency API looks very pure. And by a big account it should be calculated in combine with governor, which can be absent or even in operating system. Seems we don't have a choice, and should use odp_time for that. cpu cycles count can be evaluated only by odp_time()*odp_cpu_hz()/odp_time_hz(). But I'm worry about how we can count some cpu cycles if we are not sure in cpu frequency :-|? It's not informative for systems in question. So better to evaluate it with odp_time. No choice. -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ivan Khoronzhuk Sent: Thursday, September 03, 2015 12:11 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [odp-lng] [Patch v3 1/3] api: time: unbind CPU cycles from time API Current time API supposes that frequency of counter is equal to CPU frequency. But that's not always true, for instance, in case if no access to CPU cycle counter, another hi-resolution timer can be used, and it`s rate can be different from CPU rate. There is no big difference in which cycles to measure time, the better hi-resolution timer the better measurements. So, unbind CPU cycle counter from time API by eliminating word "cycle" as it's believed to be used with CPU. Also add new opaque type for time odp_time_t, as it asks user to use API and abstracts time from units. New odp_time_t requires several additional API functions to be added: odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2); int odp_time_cmp(odp_time_t t1, odp_time_t t2); uint64_t odp_time_to_u64(odp_time_t hdl); Also added new definition that represents 0 ticks for time - ODP_TIME_NULL. It can be used instead of odp_time_from_ns(0) for comparison and initialization. This patch only changes used time API, it doesn't change used var names for simplicity. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- /* diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c index 2a7e531..5859460 100644 --- a/test/performance/odp_scheduling.c +++ b/test/performance/odp_scheduling.c @@ -183,9 +183,10 @@ static int test_alloc_single(int thr, odp_pool_t pool) { int i; odp_buffer_t temp_buf; -uint64_t t1, t2, cycles, ns; +odp_time_t t1, t2, cycles; +uint64_t ns; -t1 = odp_time_cycles(); +t1 = odp_time(); for (i = 0; i < ALLOC_ROUNDS; i++) { temp_buf = odp_buffer_alloc(pool); @@ -198,12 +199,12 @@ static int test_alloc_single(int thr, odp_pool_t pool) odp_buffer_free(temp_buf); } -t2 = odp_time_cycles(); -cycles = odp_time_diff_cycles(t1, t2); -ns = odp_time_cycles_to_ns(cycles); +t2 = odp_time(); +cycles = odp_time_diff(t1, t2); +ns = odp_time_to_ns(cycles); printf(" [%i] alloc_sng alloc+free %"PRIu64" cycles, %"PRIu64" ns\n", - thr, cycles/ALLOC_ROUNDS, ns/ALLOC_ROUNDS); + thr, odp_time_to_u64(cycles) / ALLOC_ROUNDS, ns / ALLOC_ROUNDS); return 0; For example, this is really measuring average CPU cycles (with or without freq scaling). The ns conversion can be removed. -Petri -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [API-NEXT PATCH v4 08/10] linux-generic: sysinfo: add API to get current CPU frequency
On 11.08.15 10:33, hongbo.zh...@freescale.com wrote: From: Hongbo Zhang <hongbo.zh...@linaro.org> Previous CPU frequency API is adapted to return max frequency, now new APIs are added for getting the current CPU frequency. odp_cpu_id_hz(int id) returns frequency of the CPU specified by parameter id, while odp_cpu_hz() returns frequency of the CPU on which the thread is running. Just trying to imagine system which has cpufreq governor that dependently on packet rate, and hence system load, regulate CPU frequency in order to reduce power consumption. In this case your CPU rate is changing very fast and frequently. When you get frequency with odp_cpu_hz() it doesn't mean that this freq was the same a 1ms ago or 1ms after. What the practical use-case for this call. I see only one variant - simply for some tracing tool, to get imagination how rate was changed in time for instance. Could you please explain, where it can be used else? And why we should rely on this call in proposed use-cases. Thanks. Signed-off-by: Hongbo Zhang <hongbo.zh...@linaro.org> --- include/odp/api/cpu.h| 20 ++ platform/linux-generic/odp_system_info.c | 63 2 files changed, 83 insertions(+) diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h index 36bc47f..02b3420 100644 --- a/include/odp/api/cpu.h +++ b/include/odp/api/cpu.h @@ -62,6 +62,26 @@ uint64_t odp_cpu_hz_max(void); uint64_t odp_cpu_id_hz_max(int id); /** + * Current CPU frequency in Hz + * + * Returns current frequency of this CPU + * + * @return CPU frequency in Hz + */ +uint64_t odp_cpu_hz(void); + +/** + * Current CPU frequency of a CPU (in Hz) + * + * Returns current frequency of the specified CPU + * + * @param idCPU ID + * + * @return CPU frequency in Hz + */ +uint64_t odp_cpu_id_hz(int id); + +/** * CPU model name * * @return Pointer to CPU model name string diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 55516d0..cb5e224 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -146,6 +146,42 @@ static int cpuinfo_x86(FILE *file, odp_system_info_t *sysinfo) return 0; } +static uint64_t arch_cpu_hz_current(int id) +{ + char str[1024]; + FILE *file; + int cpu; + char *pos; + double mhz = 0.0; + + file = fopen("/proc/cpuinfo", "rt"); + + /* find the correct processor instance */ + while (fgets(str, sizeof(str), file) != NULL) { + pos = strstr(str, "processor"); + if (pos) { + sscanf(pos, "processor : %d", ); + if (cpu == id) + break; + } + } + + /* extract the cpu current speed */ + while (fgets(str, sizeof(str), file) != NULL) { + pos = strstr(str, "cpu MHz"); + if (pos) { + sscanf(pos, "cpu MHz : %lf", ); + break; + } + } + + fclose(file); + if (mhz) + return (uint64_t)(mhz * 100.0); + + return -1; +} + #elif defined __arm__ || defined __aarch64__ static int cpuinfo_arm(FILE *file ODP_UNUSED, @@ -154,6 +190,11 @@ odp_system_info_t *sysinfo ODP_UNUSED) return 0; } +static uint64_t arch_cpu_hz_current(int id) +{ + return -1; +} + #elif defined __OCTEON__ static int cpuinfo_octeon(FILE *file, odp_system_info_t *sysinfo) @@ -196,6 +237,11 @@ static int cpuinfo_octeon(FILE *file, odp_system_info_t *sysinfo) return 0; } +static uint64_t arch_cpu_hz_current(int id) +{ + return -1; +} + #elif defined __powerpc__ static int cpuinfo_powerpc(FILE *file, odp_system_info_t *sysinfo) { @@ -237,6 +283,11 @@ static int cpuinfo_powerpc(FILE *file, odp_system_info_t *sysinfo) return 0; } +static uint64_t arch_cpu_hz_current(int id) +{ + return -1; +} + #else #error GCC target not found #endif @@ -380,6 +431,18 @@ uint64_t odp_cpu_id_hz_max(int id) return -1; } +uint64_t odp_cpu_hz(void) +{ + int id = sched_getcpu(); + + return arch_cpu_hz_current(id); +} + +uint64_t odp_cpu_id_hz(int id) +{ + return arch_cpu_hz_current(id); +} + uint64_t odp_sys_huge_page_size(void) { return odp_global_data.system_info.huge_page_size; -- 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 v4 10/10] validation: add test for new per_CPU system APIs
On 11.08.15 10:54, hongbo.zh...@freescale.com wrote: From: Hongbo Zhang <hongbo.zh...@linaro.org> This patch adds test for the newly introduced per-CPU system APIs: new per-CPU APIs: odp_cpu_id_hz_max(), odp_cpu_id_model_str() abd new crurrent frequency APIs: odp_cpu_hz(), odp_cpu_id_hz() abd? Signed-off-by: Hongbo Zhang <hongbo.zh...@linaro.org> --- test/validation/system/system.c | 62 + test/validation/system/system.h | 4 +++ 2 files changed, 66 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 9134161..5348469 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -6,6 +6,7 @@ #include #include +#include #include "odp_cunit_common.h" #include "test_debug.h" #include "system.h" @@ -58,6 +59,23 @@ void system_test_odp_cpu_model_str(void) CU_ASSERT(strlen(model) < 127); } +void system_test_odp_cpu_id_model_str(void) +{ + char model[128]; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + snprintf(model, 128, "%s", odp_cpu_id_model_str(cpu)); + CU_ASSERT(strlen(model) > 0); + CU_ASSERT(strlen(model) < 127); + cpu = odp_cpumask_next(, cpu); + } +} + void system_test_odp_sys_page_size(void) { uint64_t page; @@ -83,14 +101,58 @@ void system_test_odp_cpu_hz_max(void) CU_ASSERT(0 < hz); } +void system_test_odp_cpu_id_hz_max(void) +{ + uint64_t hz; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + hz = odp_cpu_id_hz_max(cpu); + CU_ASSERT(0 < hz); + cpu = odp_cpumask_next(, cpu); + } +} + +void system_test_odp_cpu_hz(void) +{ + uint64_t hz; + + hz = odp_cpu_hz(); + CU_ASSERT(0 < hz); +} + +void system_test_odp_cpu_id_hz(void) +{ + uint64_t hz; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + hz = odp_cpu_id_hz(cpu); + CU_ASSERT(0 < hz); + cpu = odp_cpumask_next(, cpu); + } +} + CU_TestInfo system_suite[] = { {"odp version", system_test_odp_version_numbers}, {"odp_cpu_count", system_test_odp_cpu_count}, {"odp_sys_cache_line_size", system_test_odp_sys_cache_line_size}, {"odp_cpu_model_str", system_test_odp_cpu_model_str}, + {"odp_cpu_id_model_str", system_test_odp_cpu_id_model_str}, {"odp_sys_page_size", system_test_odp_sys_page_size}, {"odp_sys_huge_page_size", system_test_odp_sys_huge_page_size}, {"odp_cpu_hz_max", system_test_odp_cpu_hz_max}, + {"odp_cpu_id_hz_max", system_test_odp_cpu_id_hz_max}, + {"odp_cpu_hz", system_test_odp_cpu_hz}, + {"odp_cpu_id_hz", system_test_odp_cpu_id_hz}, CU_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 67ddb7a..1bcc164 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -14,9 +14,13 @@ void system_test_odp_version_numbers(void); void system_test_odp_cpu_count(void); void system_test_odp_sys_cache_line_size(void); void system_test_odp_cpu_model_str(void); +void system_test_odp_cpu_id_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_cpu_hz_max(void); +void system_test_odp_cpu_id_hz_max(void); +void system_test_odp_cpu_hz(void); +void system_test_odp_cpu_id_hz(void); /* test arrays: */ extern CU_TestInfo system_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 PATCH v4 10/10] validation: add test for new per_CPU system APIs
On 11.08.15 10:54, hongbo.zh...@freescale.com wrote: From: Hongbo Zhang <hongbo.zh...@linaro.org> This patch adds test for the newly introduced per-CPU system APIs: new per-CPU APIs: odp_cpu_id_hz_max(), odp_cpu_id_model_str() abd new crurrent frequency APIs: odp_cpu_hz(), odp_cpu_id_hz() abd -> and. Signed-off-by: Hongbo Zhang <hongbo.zh...@linaro.org> --- test/validation/system/system.c | 62 + test/validation/system/system.h | 4 +++ 2 files changed, 66 insertions(+) diff --git a/test/validation/system/system.c b/test/validation/system/system.c index 9134161..5348469 100644 --- a/test/validation/system/system.c +++ b/test/validation/system/system.c @@ -6,6 +6,7 @@ #include #include +#include #include "odp_cunit_common.h" #include "test_debug.h" #include "system.h" @@ -58,6 +59,23 @@ void system_test_odp_cpu_model_str(void) CU_ASSERT(strlen(model) < 127); } +void system_test_odp_cpu_id_model_str(void) +{ + char model[128]; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + snprintf(model, 128, "%s", odp_cpu_id_model_str(cpu)); + CU_ASSERT(strlen(model) > 0); + CU_ASSERT(strlen(model) < 127); + cpu = odp_cpumask_next(, cpu); + } +} + void system_test_odp_sys_page_size(void) { uint64_t page; @@ -83,14 +101,58 @@ void system_test_odp_cpu_hz_max(void) CU_ASSERT(0 < hz); } +void system_test_odp_cpu_id_hz_max(void) +{ + uint64_t hz; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + hz = odp_cpu_id_hz_max(cpu); + CU_ASSERT(0 < hz); + cpu = odp_cpumask_next(, cpu); + } +} + +void system_test_odp_cpu_hz(void) +{ + uint64_t hz; + + hz = odp_cpu_hz(); + CU_ASSERT(0 < hz); +} + +void system_test_odp_cpu_id_hz(void) +{ + uint64_t hz; + odp_cpumask_t mask; + int i, num, cpu; + + num = odp_cpumask_available(); + cpu = odp_cpumask_first(); + + for (i = 0; i < num; i++) { + hz = odp_cpu_id_hz(cpu); + CU_ASSERT(0 < hz); + cpu = odp_cpumask_next(, cpu); + } +} + CU_TestInfo system_suite[] = { {"odp version", system_test_odp_version_numbers}, {"odp_cpu_count", system_test_odp_cpu_count}, {"odp_sys_cache_line_size", system_test_odp_sys_cache_line_size}, {"odp_cpu_model_str", system_test_odp_cpu_model_str}, + {"odp_cpu_id_model_str", system_test_odp_cpu_id_model_str}, {"odp_sys_page_size", system_test_odp_sys_page_size}, {"odp_sys_huge_page_size", system_test_odp_sys_huge_page_size}, {"odp_cpu_hz_max", system_test_odp_cpu_hz_max}, + {"odp_cpu_id_hz_max", system_test_odp_cpu_id_hz_max}, + {"odp_cpu_hz", system_test_odp_cpu_hz}, + {"odp_cpu_id_hz", system_test_odp_cpu_id_hz}, CU_TEST_INFO_NULL, }; diff --git a/test/validation/system/system.h b/test/validation/system/system.h index 67ddb7a..1bcc164 100644 --- a/test/validation/system/system.h +++ b/test/validation/system/system.h @@ -14,9 +14,13 @@ void system_test_odp_version_numbers(void); void system_test_odp_cpu_count(void); void system_test_odp_sys_cache_line_size(void); void system_test_odp_cpu_model_str(void); +void system_test_odp_cpu_id_model_str(void); void system_test_odp_sys_page_size(void); void system_test_odp_sys_huge_page_size(void); void system_test_odp_cpu_hz_max(void); +void system_test_odp_cpu_id_hz_max(void); +void system_test_odp_cpu_hz(void); +void system_test_odp_cpu_id_hz(void); /* test arrays: */ extern CU_TestInfo system_suite[]; -- 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 time check
On 03.09.15 09:20, Nicolas Morey-Chaisemartin wrote: On 09/02/2015 11:16 PM, Ivan Khoronzhuk wrote: On 02.09.15 12:42, Nicolas Morey-Chaisemartin wrote: On 08/26/2015 05:47 PM, Ivan Khoronzhuk wrote: On 26.08.15 18:22, Stuart Haslam wrote: On Wed, Aug 26, 2015 at 06:11:13PM +0300, Ivan Khoronzhuk wrote: It's needed because time resolution can be a little more than 1ns and in this case odp_schedule_wait_time(1) returns 0, and test generates warn w/o reason. So increase scheduler wait time check from 1ns to 100ns. It's hard to imagine time source with resolution more than 100ns, so every implementation can return positive value from odp_schedule_wait_time(). In case if resolution is more than 100ns it's normal to warn about it at validation stage, The wait parameter is documented as the *minimum* time to wait for an event so the existing check looks OK to me. Implementations with a lower resolution should round up. It defined as "minimum" time to wait for odp_schedule and others, for odp_schedule_wait_time() it's not defined as minimum, it's simple convert function. Not shure, but any of the functions I saw in linux-generic doesn't round ticks up. It seems that it was decided to allow application to do it, if needed. But if so, we have much more to change ). In case if you are right, linux-generic implementation should be corrected, as it doesn't round it up. Thanks. I ran into this issue with our port as our clock are < 1GHz. So 1 ns is < 1 cycle which tends to break a few things on the linux generic port. I fix this particular issue like this: uint64_t odp_schedule_wait_time(uint64_t ns) { uint64_t cycle = odp_time_ns_to_cycles(ns); if(cycle == 0) cycle = 1; return cycle; } Not the nicest patch but it works. The test should probably be changed to if(ns && !cycle) so ns=0 returns 0; Yes. As said Stuart it may cause collisions with ODP_SCHED_WAIT (0) and ODP_SCHED_NO_WAIT (1) I will correct it a little later. I don't think the collision with ODP_SCHED_NO_WAIT is too bad. We only fall into this case if a cycle is larger than 1 ns so waiting not waiting or waiting less thana cycle is close to the same thing. Maybe you are right. -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [RFC Patch] example: timer: move cycles/ns table to validation tests
The linux-generic implements timers supposing that timers are based on CPU cycle counter. It's not always true and timer API can have nothing common with CPU cycles. Thus timer test shouldn't print here conversion cycles/ns table for time API. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- I'm not sure about moving the table to validation test, but it can be useful to visually see resolution impact. This patch should be included in "odp-lng] [Patch 0/4] preparation series before updating odp time API" https://lists.linaro.org/pipermail/lng-odp/2015-August/014850.html But before let's clarify it. example/timer/odp_timer_test.c | 21 - test/validation/time/time.c| 21 - 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..6248939 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -322,7 +322,6 @@ int main(int argc, char *argv[]) odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -446,26 +445,6 @@ int main(int argc, char *argv[]) return -1; } - printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); - ns = 0; - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - - for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - } - - printf("\n"); - gbls->num_workers = num_workers; /* Initialize number of timeouts to receive */ diff --git a/test/validation/time/time.c b/test/validation/time/time.c index 4b81c2c..ae5e77c 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -45,7 +45,7 @@ void time_test_odp_cycles_negative_diff(void) /* check that related conversions come back to the same value */ void time_test_odp_time_conversion(void) { - uint64_t ns1, ns2, cycles; + uint64_t ns, ns1, ns2, cycles; uint64_t upper_limit, lower_limit; ns1 = 100; @@ -59,6 +59,25 @@ void time_test_odp_time_conversion(void) upper_limit = ns1 + TOLERANCE; lower_limit = ns1 - TOLERANCE; CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + + printf("Cycles vs nanoseconds:\n"); + ns = 0; + cycles = odp_time_ns_to_cycles(ns); + + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, cycles); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", cycles, + odp_time_cycles_to_ns(cycles)); + + for (ns = 1; ns <= 100 * ODP_TIME_SEC; ns *= 10) { + cycles = odp_time_ns_to_cycles(ns); + + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, + cycles); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", cycles, + odp_time_cycles_to_ns(cycles)); + } + + printf("\n"); } CU_TestInfo time_suite_time[] = { -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] RFC: New time API
One correction, that also makes me worry a little. On 03.09.15 01:29, Ivan Khoronzhuk wrote: Hi, Petri We have to look at it proceeding from performance, platform portability and simplicity If you want to split on hi-res time and low-res they must have separate functions and be not under one common opaque time in order to not break hi-res measurements. But in fact you split the same quality timers, farther below... On 02.09.15 18:21, Savolainen, Petri (Nokia - FI/Espoo) wrote: Hi, I think we need to restart the time API discussion and specify it only wall time in mind. Let's suppose. CPU cycle count APIs can be tuned as a next step. CPU cycle counters are affected by frequency scaling, which makes those difficult to use for counting linear, real time. The time API should specify an easy way to check and use the real, wall clock time. We need at least one time source that will not wrap in years - here it's the "global" time (e.g. in POSIX it's CLOCK_MONOTONIC). Don't mix it with this API. CLOCK_MONOTONIC is guaranteed by OS, that can handle wraps, OS can use interrupts for that, you cannot. Also it must be zero at platform init and begin count time when application starts. For each application that starts. Can you guarantee that it's inited to zero for each platform? I hesitate to answer on this question. But let's suppose that we can guarantee it. In this case time should be aligned for all executed applications to start from zero. Let's suppose some start_time = odp_time() at application init. As it was noted earlier, in some fast loop, init_count must be extracted in diff function. I'm not talking event about checking of time type, as you are going to put all of them under one type. Global time can be also compared between threads. Local time is defined for optimizing short interval time checks. In fact global has same quality as local. As noted earlier, global can be emulated with local. It's not always true. As we anyway will have some out of sync. It can require to periodically synchronize the counters. We also cannot guarantee it. That's why every multi-core board has to have common timer/counter on SoC. In my case it runs with the same rate as arch arm timer, that is local. I want to believe that for other platforms also, but I can't be sure. In another case it's hard to guarantee global time availability also. So we can have situation that local time API is only variant here. For wall time, common timer or RTC should be used, I no see another variant And it should be separate API, with not hard requirement. Why we need to split them in this case? It'll add load on user only. It's thread local, may wrap sooner than global time, but may be lower overhead to use. They are both 64-bit. You are going to use the same function for both, overhead the same. There could be actually four time bases defined in the API, if we'd want to optimize for each use case (global.hi_res, global.low_res, local.hi_res and local.low_res). I'd propose to have only two and give system specific way to configure those (rate and duration). What do you mean "giv system way...", do you mean add some API? If so, I disagree. It's not ODP responsibility and it's not every platform applicable. Typical config would be global.low_res and local.hi_res. User can check hz and max time value (wrap around time) with odp_time_info() and adapt (fall back to use global time) if e.g. local time wraps too quickly (e.g. in 4 sec). If this time wrap every 4s, it shouldn't be used at all...(any 32-bits) See the proposal under. -Petri // // Use cases // // high resolution low resolution // short interval long interval // low overheadhigh overhead // // // global timestamp packets or |timestamp log entries or // other global resources |other global resources // at high rate |at low rate //| // ---+-- //| // local timestamp and sort items |measure execution time over // in thread local work queue,|many iterations or over // measure execution time |a "long" function // of a "short" function, | // spin and wait for a short | // while // // No see reason to overload user with this stuff. In fact we always need one hi-resolution time with best quality, no matter what we measure. No matter how resolution it has, it should be the max that platform can provide for that. At this moment all counters are 64-bit and can not wrap for years. On my opinion,32-bit counter we shouldn't take into account. // time in nsec // renamed to leave room for sec or other unit
[lng-odp] [odp-lng] [Patch v3 1/3] api: time: unbind CPU cycles from time API
Current time API supposes that frequency of counter is equal to CPU frequency. But that's not always true, for instance, in case if no access to CPU cycle counter, another hi-resolution timer can be used, and it`s rate can be different from CPU rate. There is no big difference in which cycles to measure time, the better hi-resolution timer the better measurements. So, unbind CPU cycle counter from time API by eliminating word "cycle" as it's believed to be used with CPU. Also add new opaque type for time odp_time_t, as it asks user to use API and abstracts time from units. New odp_time_t requires several additional API functions to be added: odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2); int odp_time_cmp(odp_time_t t1, odp_time_t t2); uint64_t odp_time_to_u64(odp_time_t hdl); Also added new definition that represents 0 ticks for time - ODP_TIME_NULL. It can be used instead of odp_time_from_ns(0) for comparison and initialization. This patch only changes used time API, it doesn't change used var names for simplicity. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/timer/odp_timer_test.c| 22 +++ include/odp/api/time.h| 65 test/performance/odp_pktio_perf.c | 47 --- test/performance/odp_scheduling.c | 109 +- test/validation/pktio/pktio.c | 20 +++ test/validation/scheduler/scheduler.c | 5 +- test/validation/time/time.c | 27 + 7 files changed, 170 insertions(+), 125 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 49630b0..23c5a9a 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -320,9 +320,10 @@ static void parse_args(int argc, char *argv[], test_args_t *args) int main(int argc, char *argv[]) { odph_linux_pthread_t thread_tbl[MAX_WORKERS]; + uint64_t ns; int num_workers; odp_queue_t queue; - uint64_t cycles, ns; + odp_time_t cycles; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -449,19 +450,20 @@ int main(int argc, char *argv[]) printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); printf("Cycles vs nanoseconds:\n"); ns = 0; - cycles = odp_time_ns_to_cycles(ns); + cycles = odp_time_from_ns(ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, + odp_time_to_u64(cycles)); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", + odp_time_to_u64(cycles), odp_time_to_ns(cycles)); for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); + cycles = odp_time_from_ns(ns); - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, + odp_time_to_u64(cycles)); + printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", + odp_time_to_u64(cycles), odp_time_to_ns(cycles)); } printf("\n"); diff --git a/include/odp/api/time.h b/include/odp/api/time.h index b0072fc..60800ba 100644 --- a/include/odp/api/time.h +++ b/include/odp/api/time.h @@ -28,14 +28,22 @@ extern "C" { #define ODP_TIME_MSEC 100ULL/**< Millisecond in nsec */ #define ODP_TIME_SEC 10ULL /**< Second in nsec */ +/** + * @typedef odp_time_t + * ODP time stamp. Time stamp is global and can be shared between threads. + */ /** - * Current time in CPU cycles - * - * @return Current time in CPU cycles + * @def ODP_TIME_NULL + * Zero time stamp */ -uint64_t odp_time_cycles(void); +/** + * Current global time stamp. + * + * @return Time stamp. It should be hi-resolution time. + */ +odp_time_t odp_time(void); /** * Time difference @@ -43,29 +51,60 @@ uint64_t odp_time_cycles(void); * @param t1First time stamp * @param t2Second time stamp * - * @return Difference of time stamps in CPU cycles + * @return Difference of time stamps */ -uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2); +odp_time_t odp_time_diff(odp_time_t t1, odp_time_t t2)
[lng-odp] [odp-lng] [Patch v3 0/3] api: time: unbind CPU cycles from time API
This seres is intended to unbind time API names from CPU "cycles". Also remove usage of word "cycle" from appropriate places as it's no more valid. Based on "[odp-lng] [Patch 0/4] preparation series before updating odp time API" https://lists.linaro.org/pipermail/lng-odp/2015-August/014850.html v2: api: time: change API to use ticks instead of cycles https://lists.linaro.org/pipermail/lng-odp/2015-August/014198.html Since v1: - changed series name a little bit - added opaque type odp_time_t - added missed spaces in printf - removed legacy "count" words Ivan Khoronzhuk (3): api: time: unbind CPU cycles from time API test/example: avoid "cycle" word usage linux-generic: align implementation with new time API example/generator/odp_generator.c | 12 +- example/timer/odp_timer_test.c | 24 ++-- include/odp/api/time.h | 65 --- platform/linux-generic/Makefile.am | 1 + .../linux-generic/arch/linux/odp_time_cycles.c | 4 +- .../linux-generic/arch/mips64/odp_time_cycles.c| 4 +- platform/linux-generic/arch/x86/odp_time_cycles.c | 4 +- .../linux-generic/include/odp/plat/time_types.h| 36 ++ platform/linux-generic/include/odp/time.h | 1 + platform/linux-generic/odp_schedule.c | 16 +-- platform/linux-generic/odp_time.c | 65 +-- test/performance/odp_pktio_perf.c | 56 + test/performance/odp_scheduling.c | 127 ++--- test/validation/pktio/pktio.c | 20 ++-- test/validation/scheduler/scheduler.c | 4 +- test/validation/time/time.c| 47 test/validation/time/time.h| 6 +- 17 files changed, 309 insertions(+), 183 deletions(-) create mode 100644 platform/linux-generic/include/odp/plat/time_types.h -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [Patch] validation: scheduler: increase time check
On 02.09.15 12:42, Nicolas Morey-Chaisemartin wrote: On 08/26/2015 05:47 PM, Ivan Khoronzhuk wrote: On 26.08.15 18:22, Stuart Haslam wrote: On Wed, Aug 26, 2015 at 06:11:13PM +0300, Ivan Khoronzhuk wrote: It's needed because time resolution can be a little more than 1ns and in this case odp_schedule_wait_time(1) returns 0, and test generates warn w/o reason. So increase scheduler wait time check from 1ns to 100ns. It's hard to imagine time source with resolution more than 100ns, so every implementation can return positive value from odp_schedule_wait_time(). In case if resolution is more than 100ns it's normal to warn about it at validation stage, The wait parameter is documented as the *minimum* time to wait for an event so the existing check looks OK to me. Implementations with a lower resolution should round up. It defined as "minimum" time to wait for odp_schedule and others, for odp_schedule_wait_time() it's not defined as minimum, it's simple convert function. Not shure, but any of the functions I saw in linux-generic doesn't round ticks up. It seems that it was decided to allow application to do it, if needed. But if so, we have much more to change ). In case if you are right, linux-generic implementation should be corrected, as it doesn't round it up. Thanks. I ran into this issue with our port as our clock are < 1GHz. So 1 ns is < 1 cycle which tends to break a few things on the linux generic port. I fix this particular issue like this: uint64_t odp_schedule_wait_time(uint64_t ns) { uint64_t cycle = odp_time_ns_to_cycles(ns); if(cycle == 0) cycle = 1; return cycle; } Not the nicest patch but it works. The test should probably be changed to if(ns && !cycle) so ns=0 returns 0; Yes. As said Stuart it may cause collisions with ODP_SCHED_WAIT (0) and ODP_SCHED_NO_WAIT (1) I will correct it a little later. -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [odp-lng] [Patch v3 3/3] linux-generic: align implementation with new time API
The time API names were changed from odp_time_cycle* to odp_time*. Also new time API operates with new opaque type - odp_time_t, as result several new API calls were added. For odp_schdule.c avoid "cycle" word usage as it was left from old time API names. This patch is intended to align linux-generic implementation with new time API. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/Makefile.am | 1 + .../linux-generic/arch/linux/odp_time_cycles.c | 4 +- .../linux-generic/arch/mips64/odp_time_cycles.c| 4 +- platform/linux-generic/arch/x86/odp_time_cycles.c | 4 +- .../linux-generic/include/odp/plat/time_types.h| 36 platform/linux-generic/include/odp/time.h | 1 + platform/linux-generic/odp_schedule.c | 16 +++--- platform/linux-generic/odp_time.c | 65 ++ 8 files changed, 106 insertions(+), 25 deletions(-) create mode 100644 platform/linux-generic/include/odp/plat/time_types.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index f2c081a..a2da4ed 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -70,6 +70,7 @@ odpplatinclude_HEADERS = \ $(srcdir)/include/odp/plat/strong_types.h \ $(srcdir)/include/odp/plat/thrmask_types.h \ $(srcdir)/include/odp/plat/ticketlock_types.h \ + $(srcdir)/include/odp/plat/time_types.h \ $(srcdir)/include/odp/plat/timer_types.h \ $(srcdir)/include/odp/plat/version_types.h diff --git a/platform/linux-generic/arch/linux/odp_time_cycles.c b/platform/linux-generic/arch/linux/odp_time_cycles.c index 4dc0764..70d611d 100644 --- a/platform/linux-generic/arch/linux/odp_time_cycles.c +++ b/platform/linux-generic/arch/linux/odp_time_cycles.c @@ -16,7 +16,7 @@ #define GIGA 10 -uint64_t odp_time_cycles(void) +odp_time_t odp_time(void) { struct timespec time; uint64_t sec, ns, hz, cycles; @@ -34,5 +34,5 @@ uint64_t odp_time_cycles(void) cycles = sec * hz; cycles += (ns * hz) / GIGA; - return cycles; + return (odp_time_t)cycles; } diff --git a/platform/linux-generic/arch/mips64/odp_time_cycles.c b/platform/linux-generic/arch/mips64/odp_time_cycles.c index 4fb790b..0bbd18a 100644 --- a/platform/linux-generic/arch/mips64/odp_time_cycles.c +++ b/platform/linux-generic/arch/mips64/odp_time_cycles.c @@ -8,7 +8,7 @@ #include #include -uint64_t odp_time_cycles(void) +odp_time_t odp_time(void) { #define CVMX_TMP_STR(x) CVMX_TMP_STR2(x) #define CVMX_TMP_STR2(x) #x @@ -17,5 +17,5 @@ uint64_t odp_time_cycles(void) __asm__ __volatile__ ("rdhwr %[rt],$" CVMX_TMP_STR(31) : [rt] "=d" (cycle) : : "memory"); - return cycle; + return (odp_time_t)cycle; } diff --git a/platform/linux-generic/arch/x86/odp_time_cycles.c b/platform/linux-generic/arch/x86/odp_time_cycles.c index a111561..78651c4 100644 --- a/platform/linux-generic/arch/x86/odp_time_cycles.c +++ b/platform/linux-generic/arch/x86/odp_time_cycles.c @@ -5,7 +5,7 @@ */ #include -uint64_t odp_time_cycles(void) +odp_time_t odp_time(void) { union { uint64_t tsc_64; @@ -19,5 +19,5 @@ uint64_t odp_time_cycles(void) "=a" (tsc.lo_32), "=d" (tsc.hi_32) : : "memory"); - return tsc.tsc_64; + return (odp_time_t)tsc.tsc_64; } diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h new file mode 100644 index 000..9ba1508 --- /dev/null +++ b/platform/linux-generic/include/odp/plat/time_types.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP time service + */ + +#ifndef ODP_TIME_TYPES_H_ +#define ODP_TIME_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup odp_time + * @{ + **/ + +typedef uint64_t odp_time_t; + +#define ODP_TIME_NULL ((odp_time_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/time.h b/platform/linux-generic/include/odp/time.h index 3a3960b..44e0d0d 100644 --- a/platform/linux-generic/include/odp/time.h +++ b/platform/linux-generic/include/odp/time.h @@ -21,6 +21,7 @@ extern "C" { +#include #include #ifdef __cplusplus diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index 5d32c81..fd7c263 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -510,10 +510,10 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
Re: [lng-odp] [PATCH] validation: pktio: revert wait time to msec
On 02.09.15 12:12, Nicolas Morey-Chaisemartin wrote: When fixing the wait time passed to schedule by using odp_schedule_wait_time in patch: commit 0bd245638dd0 ("validation: pktio: don't mix scheduler wait time and ns") wait time was increased to 1 second instead of 1 msec which causes the test to take nearly 2 minutes. Signed-off-by: Nicolas Morey-Chaisemartin <nmo...@kalray.eu> Cc: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- Reviewed-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 b136419..b985e81 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -595,7 +595,7 @@ void pktio_test_inq_remdef(void) CU_ASSERT(inq != ODP_QUEUE_INVALID); CU_ASSERT(odp_pktio_inq_remdef(pktio) == 0); - wait = odp_schedule_wait_time(ODP_TIME_SEC); + wait = odp_schedule_wait_time(ODP_TIME_MSEC); for (i = 0; i < 100; i++) { ev = odp_schedule(NULL, wait); 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] validation: pktio: don't mix scheduler wait time and ns in start_stop test
On 02.09.15 12:35, Nicolas Morey-Chaisemartin wrote: The odp_scheduler() requires time value in its own ticks, so pass scheduler wait time instead of ns. Signed-off-by: Nicolas Morey-Chaisemartin <nmo...@kalray.eu> --- Reviewed-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> test/validation/pktio/pktio.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index b985e81..5c0799b 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -671,6 +671,7 @@ static void pktio_test_start_stop(void) odp_event_t ev; int i, pkts, ret, alloc = 0; odp_queue_t outq; + uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC); for (i = 0; i < num_ifaces; i++) { pktio[i] = create_pktio(iface_name[i], ODP_QUEUE_TYPE_SCHED, 0); @@ -709,7 +710,7 @@ static void pktio_test_start_stop(void) } /* check that packets did not arrive */ for (i = 0, pkts = 0; i < 1000; i++) { - ev = odp_schedule(NULL, ODP_TIME_MSEC); + ev = odp_schedule(NULL, wait); if (ev != ODP_EVENT_INVALID) { if (odp_event_type(ev) == ODP_EVENT_PACKET) { if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID) @@ -730,7 +731,7 @@ static void pktio_test_start_stop(void) /* flush packets with magic number in pipes */ for (i = 0; i < 1000; i++) { - ev = odp_schedule(NULL, ODP_TIME_MSEC); + ev = odp_schedule(NULL, wait); if (ev != ODP_EVENT_INVALID) odp_event_free(ev); } @@ -756,7 +757,7 @@ static void pktio_test_start_stop(void) /* get */ for (i = 0, pkts = 0; i < 1000; i++) { - ev = odp_schedule(NULL, ODP_TIME_MSEC); + ev = odp_schedule(NULL, wait); if (ev != ODP_EVENT_INVALID) { if (odp_event_type(ev) == ODP_EVENT_PACKET) { pkt = odp_packet_from_event(ev); -- Regards, Ivan Khoronzhuk ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [odp-lng] [Patch v3 2/3] test/example: avoid "cycle" word usage
The word "cycle" is left from old API time names. The "cycle" is ambiguous word, especially when it can be used for other purposes. So better to use "tick" or "time" word or just "t" symbol. Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- example/generator/odp_generator.c | 12 ++--- example/timer/odp_timer_test.c| 24 +- test/performance/odp_pktio_perf.c | 39 + test/performance/odp_scheduling.c | 82 +-- test/validation/scheduler/scheduler.c | 5 +-- test/validation/time/time.c | 42 +- test/validation/time/time.h | 6 +-- 7 files changed, 105 insertions(+), 105 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index f7aed76..46ddf11 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -585,7 +585,7 @@ static void *gen_recv_thread(void *arg) */ static void print_global_stats(int num_workers) { - uint64_t start, now, diff; + odp_time_t start, now, diff; uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0; int verbose_interval = 20; odp_thrmask_t thrd_mask; @@ -593,7 +593,7 @@ static void print_global_stats(int num_workers) while (odp_thrmask_worker(_mask) < num_workers) continue; - start = odp_time_cycles(); + start = odp_time(); while (odp_thrmask_worker(_mask) == num_workers) { if (args->appl.number != -1 && @@ -602,14 +602,14 @@ static void print_global_stats(int num_workers) break; } - now = odp_time_cycles(); - diff = odp_time_diff_cycles(start, now); - if (odp_time_cycles_to_ns(diff) < + now = odp_time(); + diff = odp_time_diff(start, now); + if (odp_time_to_ns(diff) < verbose_interval * ODP_TIME_SEC) { continue; } - start = odp_time_cycles(); + start = odp_time(); if (args->appl.mode == APPL_MODE_RCV) { pkts = odp_atomic_load_u64(); diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 23c5a9a..58c215e 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -323,7 +323,7 @@ int main(int argc, char *argv[]) uint64_t ns; int num_workers; odp_queue_t queue; - odp_time_t cycles; + odp_time_t ticks; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; @@ -448,22 +448,22 @@ int main(int argc, char *argv[]) } printf("CPU freq %"PRIu64" Hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); + printf("Ticks vs nanoseconds:\n"); ns = 0; - cycles = odp_time_from_ns(ns); + ticks = odp_time_from_ns(ns); - printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, - odp_time_to_u64(cycles)); - printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", - odp_time_to_u64(cycles), odp_time_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, + odp_time_to_u64(ticks)); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", + odp_time_to_u64(ticks), odp_time_to_ns(ticks)); for (ns = 1; ns <= 100*ODP_TIME_SEC; ns *= 10) { - cycles = odp_time_from_ns(ns); + ticks = odp_time_from_ns(ns); - printf(" %12" PRIu64 " ns -> %12" PRIu64 " cycles\n", ns, - odp_time_to_u64(cycles)); - printf(" %12" PRIu64 " cycles -> %12" PRIu64 " ns\n", - odp_time_to_u64(cycles), odp_time_to_ns(cycles)); + printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, + odp_time_to_u64(ticks)); + printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", + odp_time_to_u64(ticks), odp_time_to_ns(ticks)); } printf("\n"); diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index b27efc8..3ecd042 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -106,7 +106,7 @@ struct tx_stats_s { uint64_t tx_cnt;/* Packets transmitted */ uint64_t alloc_failures;/* Packet allocation fai