diff options
Diffstat (limited to 'test')
30 files changed, 2200 insertions, 327 deletions
diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 481fb01d2..a85b8309b 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -208,8 +208,8 @@ static void *pktio_queue_thread(void *arg) stats->s.packets += pkts; } - /* Make sure that the last stats write is visible to readers */ - odp_sync_stores(); + /* Make sure that latest stat writes are visible to other threads */ + odp_mb_full(); return NULL; } @@ -326,8 +326,8 @@ static void *pktio_direct_recv_thread(void *arg) stats->s.packets += pkts; } - /* Make sure that the last stats write is visible to readers */ - odp_sync_stores(); + /* Make sure that latest stat writes are visible to other threads */ + odp_mb_full(); return NULL; } diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 82dcf19c1..4cc1affc3 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -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_time, cur_time, send_duration; - odp_time_t burst_start_time, burst_gap; + odp_time_t cur_time, send_time_end, send_duration; + odp_time_t burst_gap_end, burst_gap; uint32_t batch_len; int unsent_pkts = 0; odp_event_t tx_event[BATCH_LEN_MAX]; @@ -336,19 +336,19 @@ static void *run_thread_tx(void *arg) odp_barrier_wait(&globals->tx_barrier); cur_time = odp_time_local(); - start_time = cur_time; - burst_start_time = odp_time_diff(cur_time, burst_gap); - while (odp_time_diff(cur_time, start_time) < send_duration) { + send_time_end = odp_time_sum(cur_time, send_duration); + burst_gap_end = cur_time; + while (odp_time_cmp(send_time_end, cur_time) > 0) { unsigned alloc_cnt = 0, tx_cnt; - if (odp_time_diff(cur_time, burst_start_time) < burst_gap) { + if (odp_time_cmp(burst_gap_end, cur_time) > 0) { cur_time = odp_time_local(); if (!odp_time_cmp(idle_start, ODP_TIME_NULL)) idle_start = cur_time; continue; } - if (odp_time_cmp(idle_start, ODP_TIME_NULL)) { + if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) { odp_time_t diff = odp_time_diff(cur_time, idle_start); stats->s.idle_ticks = @@ -357,7 +357,7 @@ static void *run_thread_tx(void *arg) idle_start = ODP_TIME_NULL; } - burst_start_time += burst_gap; + burst_gap_end = odp_time_sum(burst_gap_end, burst_gap); alloc_cnt = alloc_packets(tx_event, batch_len - unsent_pkts); if (alloc_cnt != batch_len) @@ -591,20 +591,6 @@ static int setup_txrx_masks(odp_cpumask_t *thd_mask_tx, } /* - * Busy loop for specified length of time. - */ -static void busy_loop_ns(uint64_t wait_ns) -{ - odp_time_t diff; - odp_time_t start_time = odp_time_local(); - odp_time_t wait = odp_time_local_from_ns(wait_ns); - - do { - diff = odp_time_diff(odp_time_local(), start_time); - } while (odp_time_cmp(wait, diff) > 0); -} - -/* * Run a single instance of the throughput test. When attempting to determine * the maximum packet rate this will be invoked multiple times with the only * difference between runs being the target PPS rate. @@ -647,7 +633,7 @@ static int run_test_single(odp_cpumask_t *thd_mask_tx, num_tx_workers); /* delay to allow transmitted packets to reach the receivers */ - busy_loop_ns(SHUTDOWN_DELAY_NS); + odp_time_wait_ns(SHUTDOWN_DELAY_NS); /* indicate to the receivers to exit */ odp_atomic_store_u32(&shutdown, 1); diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c index 971d19b05..fc6ccdc2a 100644 --- a/test/performance/odp_scheduling.c +++ b/test/performance/odp_scheduling.c @@ -702,7 +702,7 @@ static void *run_thread(void *arg) */ static void test_cpu_freq(void) { - struct timespec tp1, tp2; + odp_time_t cur_time, test_time, start_time, end_time; uint64_t c1, c2, cycles; uint64_t nsec; double diff_max_hz, max_cycles; @@ -710,40 +710,21 @@ static void test_cpu_freq(void) printf("\nCPU cycle count frequency test (runs about %i sec)\n", TEST_SEC); - if (clock_gettime(CLOCK_MONOTONIC, &tp2)) { - LOG_ERR("clock_gettime failed.\n"); - return; - } - - /* Wait until clock moves to the next second. It enables easy comparison - * during the measurement. */ - do { - if (clock_gettime(CLOCK_MONOTONIC, &tp1)) { - LOG_ERR("clock_gettime failed.\n"); - return; - } - - } while (tp1.tv_sec == tp2.tv_sec); + test_time = odp_time_local_from_ns(TEST_SEC * ODP_TIME_SEC_IN_NS); + start_time = odp_time_local(); + end_time = odp_time_sum(start_time, test_time); /* Start the measurement */ c1 = odp_cpu_cycles(); do { - if (clock_gettime(CLOCK_MONOTONIC, &tp2)) { - LOG_ERR("clock_gettime failed.\n"); - return; - } - - } while ((tp2.tv_sec - tp1.tv_sec) < TEST_SEC); + cur_time = odp_time_local(); + } while (odp_time_cmp(end_time, cur_time) > 0); c2 = odp_cpu_cycles(); - nsec = (tp2.tv_sec - tp1.tv_sec) * 1000000000; - - if (tp2.tv_nsec > tp1.tv_nsec) - nsec += tp2.tv_nsec - tp1.tv_nsec; - else - nsec -= tp1.tv_nsec - tp2.tv_nsec; + test_time = odp_time_diff(cur_time, start_time); + nsec = odp_time_to_ns(test_time); cycles = odp_cpu_cycles_diff(c2, c1); max_cycles = (nsec * odp_sys_cpu_hz()) / 1000000000.0; @@ -751,7 +732,7 @@ static void test_cpu_freq(void) /* Compare measured CPU cycles to maximum theoretical CPU cycle count */ diff_max_hz = ((double)(cycles) - max_cycles) / max_cycles; - printf("clock_gettime %" PRIu64 " ns\n", nsec); + printf("odp_time %" 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); diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am index 4e364944a..1711b93e7 100644 --- a/test/validation/Makefile.am +++ b/test/validation/Makefile.am @@ -4,6 +4,7 @@ ODP_MODULES = buffer \ cpumask \ crypto \ errno \ + hash \ init \ queue \ packet \ @@ -11,6 +12,7 @@ ODP_MODULES = buffer \ pool \ random \ scheduler \ + std_clib \ synchronizers \ thread \ time \ diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h index 99dbd65cf..a186339ff 100644 --- a/test/validation/classification/classification.h +++ b/test/validation/classification/classification.h @@ -59,6 +59,7 @@ void classification_test_destroy_cos(void); void classification_test_create_pmr_match(void); void classification_test_destroy_pmr(void); void classification_test_cos_set_queue(void); +void classification_test_cos_set_pool(void); void classification_test_cos_set_drop(void); void classification_test_pmr_match_set_create(void); void classification_test_pmr_match_set_destroy(void); diff --git a/test/validation/classification/odp_classification_basic.c b/test/validation/classification/odp_classification_basic.c index 20c157f4e..f0b7a4243 100644 --- a/test/validation/classification/odp_classification_basic.c +++ b/test/validation/classification/odp_classification_basic.c @@ -13,26 +13,60 @@ void classification_test_create_cos(void) { odp_cos_t cos; - char name[ODP_COS_NAME_LEN]; - sprintf(name, "ClassOfService"); - cos = odp_cos_create(name); - CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + odp_cls_cos_param_t cls_param; + odp_pool_t pool; + odp_queue_t queue; + char cosname[ODP_COS_NAME_LEN]; + + pool = pool_create("cls_basic_pool"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + queue = queue_create("cls_basic_queue", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + sprintf(cosname, "ClassOfService"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT(odp_cos_to_u64(cos) != odp_cos_to_u64(ODP_COS_INVALID)); odp_cos_destroy(cos); + odp_pool_destroy(pool); + odp_queue_destroy(queue); } void classification_test_destroy_cos(void) { odp_cos_t cos; char name[ODP_COS_NAME_LEN]; + odp_pool_t pool; + odp_queue_t queue; + odp_cls_cos_param_t cls_param; int retval; + + pool = pool_create("cls_basic_pool"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + queue = queue_create("cls_basic_queue", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + sprintf(name, "ClassOfService"); - cos = odp_cos_create(name); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(name, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); retval = odp_cos_destroy(cos); CU_ASSERT(retval == 0); retval = odp_cos_destroy(ODP_COS_INVALID); CU_ASSERT(retval < 0); + + odp_pool_destroy(pool); + odp_queue_destroy(queue); } void classification_test_create_pmr_match(void) @@ -82,35 +116,101 @@ void classification_test_cos_set_queue(void) { int retval; char cosname[ODP_COS_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; - odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; + odp_pool_t pool; + odp_queue_t queue; odp_queue_t queue_cos; odp_cos_t cos_queue; + odp_queue_t recvqueue; + + pool = pool_create("cls_basic_pool"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + queue = queue_create("cls_basic_queue", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + sprintf(cosname, "CoSQueue"); - cos_queue = odp_cos_create(cosname); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_queue = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos_queue != ODP_COS_INVALID); - odp_queue_param_init(&qparam); - qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; - qparam.sched.sync = ODP_SCHED_SYNC_NONE; - qparam.sched.group = ODP_SCHED_GROUP_ALL; - sprintf(queuename, "%s", "QueueCoS"); + queue_cos = queue_create("QueueCoS", true); + CU_ASSERT_FATAL(queue_cos != ODP_QUEUE_INVALID); - queue_cos = odp_queue_create(queuename, - ODP_QUEUE_TYPE_SCHED, &qparam); retval = odp_cos_queue_set(cos_queue, queue_cos); CU_ASSERT(retval == 0); + recvqueue = odp_cos_queue(cos_queue); + CU_ASSERT(recvqueue == queue_cos); + odp_cos_destroy(cos_queue); odp_queue_destroy(queue_cos); + odp_queue_destroy(queue); + odp_pool_destroy(pool); +} + +void classification_test_cos_set_pool(void) +{ + int retval; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; + odp_pool_t pool; + odp_queue_t queue; + odp_pool_t cos_pool; + odp_cos_t cos; + odp_pool_t recvpool; + + pool = pool_create("cls_basic_pool"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + queue = queue_create("cls_basic_queue", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + sprintf(cosname, "CoSQueue"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + cos_pool = pool_create("PoolCoS"); + CU_ASSERT_FATAL(cos_pool != ODP_POOL_INVALID); + + retval = odp_cls_cos_pool_set(cos, cos_pool); + CU_ASSERT(retval == 0); + recvpool = odp_cls_cos_pool(cos); + CU_ASSERT(recvpool == cos_pool); + + odp_cos_destroy(cos); + odp_queue_destroy(queue); + odp_pool_destroy(pool); + odp_pool_destroy(cos_pool); } void classification_test_cos_set_drop(void) { int retval; char cosname[ODP_COS_NAME_LEN]; - sprintf(cosname, "CoSDrop"); odp_cos_t cos_drop; - cos_drop = odp_cos_create(cosname); + odp_queue_t queue; + odp_pool_t pool; + odp_cls_cos_param_t cls_param; + + pool = pool_create("cls_basic_pool"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + queue = queue_create("cls_basic_queue", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + sprintf(cosname, "CoSDrop"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_drop = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos_drop != ODP_COS_INVALID); retval = odp_cos_drop_set(cos_drop, ODP_COS_DROP_POOL); @@ -118,6 +218,8 @@ void classification_test_cos_set_drop(void) retval = odp_cos_drop_set(cos_drop, ODP_COS_DROP_NEVER); CU_ASSERT(retval == 0); odp_cos_destroy(cos_drop); + odp_pool_destroy(pool); + odp_queue_destroy(queue); } void classification_test_pmr_match_set_create(void) @@ -177,6 +279,7 @@ odp_testinfo_t classification_suite_basic[] = { ODP_TEST_INFO(classification_test_destroy_pmr), ODP_TEST_INFO(classification_test_cos_set_queue), ODP_TEST_INFO(classification_test_cos_set_drop), + ODP_TEST_INFO(classification_test_cos_set_pool), ODP_TEST_INFO(classification_test_pmr_match_set_create), ODP_TEST_INFO(classification_test_pmr_match_set_destroy), ODP_TEST_INFO_NULL, diff --git a/test/validation/classification/odp_classification_common.c b/test/validation/classification/odp_classification_common.c index a56c017fb..afcea4546 100644 --- a/test/validation/classification/odp_classification_common.c +++ b/test/validation/classification/odp_classification_common.c @@ -154,7 +154,7 @@ odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns) return odp_packet_from_event(ev); } -odp_queue_t queue_create(char *queuename, bool sched) +odp_queue_t queue_create(const char *queuename, bool sched) { odp_queue_t queue; odp_queue_param_t qparam; @@ -177,6 +177,19 @@ odp_queue_t queue_create(char *queuename, bool sched) return queue; } +odp_pool_t pool_create(const char *poolname) +{ + odp_pool_param_t param; + + odp_pool_param_init(¶m); + param.pkt.seg_len = SHM_PKT_BUF_SIZE; + param.pkt.len = SHM_PKT_BUF_SIZE; + param.pkt.num = SHM_PKT_NUM_BUFS; + param.type = ODP_POOL_PACKET; + + return odp_pool_create(poolname, ¶m); +} + odp_packet_t create_packet(odp_pool_t pool, bool vlan, odp_atomic_u32_t *seq, bool flag_udp) { diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c index 5a6272e8f..6644b53a4 100644 --- a/test/validation/classification/odp_classification_test_pmr.c +++ b/test/validation/classification/odp_classification_test_pmr.c @@ -12,23 +12,15 @@ #include <odp/helper/udp.h> #include <odp/helper/tcp.h> -static odp_pool_t pool_default; +static odp_pool_t pkt_pool; /** sequence number of IP packets */ odp_atomic_u32_t seq; int classification_suite_pmr_init(void) { - odp_pool_param_t param; - - odp_pool_param_init(¶m); - param.pkt.seg_len = SHM_PKT_BUF_SIZE; - param.pkt.len = SHM_PKT_BUF_SIZE; - param.pkt.num = SHM_PKT_NUM_BUFS; - param.type = ODP_POOL_PACKET; - - pool_default = odp_pool_create("classification_pmr_pool", ¶m); - if (ODP_POOL_INVALID == pool_default) { + pkt_pool = pool_create("classification_pmr_pool"); + if (ODP_POOL_INVALID == pkt_pool) { fprintf(stderr, "Packet pool creation failed.\n"); return -1; } @@ -43,7 +35,7 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) odp_pktio_param_t pktio_param; int ret; - if (pool_default == ODP_POOL_INVALID) + if (pkt_pool == ODP_POOL_INVALID) return ODP_PKTIO_INVALID; odp_pktio_param_init(&pktio_param); @@ -52,9 +44,9 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; - pktio = odp_pktio_open("loop", pool_default, &pktio_param); + pktio = odp_pktio_open("loop", pkt_pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) { - ret = odp_pool_destroy(pool_default); + ret = odp_pool_destroy(pkt_pool); if (ret) fprintf(stderr, "unable to destroy pool.\n"); return ODP_PKTIO_INVALID; @@ -63,7 +55,7 @@ odp_pktio_t create_pktio(odp_queue_type_t q_type) return pktio; } -odp_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype) +int create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype) { odp_queue_param_t qparam; odp_queue_t inq_def; @@ -86,22 +78,56 @@ odp_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype) CU_ASSERT_FATAL(inq_def != ODP_QUEUE_INVALID); if (0 > odp_pktio_inq_setdef(pktio, inq_def)) - return ODP_QUEUE_INVALID; + return -1; if (odp_pktio_start(pktio)) { fprintf(stderr, "unable to start loop\n"); - return ODP_QUEUE_INVALID; + return -1; } - return inq_def; + return 0; +} + +void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, + odp_queue_t *queue, odp_pool_t *pool) +{ + odp_cls_cos_param_t cls_param; + odp_pool_t default_pool; + odp_cos_t default_cos; + odp_queue_t default_queue; + int retval; + char cosname[ODP_COS_NAME_LEN]; + + default_pool = pool_create("DefaultPool"); + CU_ASSERT(default_pool != ODP_POOL_INVALID); + + default_queue = queue_create("DefaultQueue", true); + CU_ASSERT(default_queue != ODP_QUEUE_INVALID); + + sprintf(cosname, "DefaultCos"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = default_pool; + cls_param.queue = default_queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + default_cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT(default_cos != ODP_COS_INVALID); + + retval = odp_pktio_default_cos_set(pktio, default_cos); + CU_ASSERT(retval == 0); + + *cos = default_cos; + *queue = default_queue; + *pool = default_pool; + return; } int classification_suite_pmr_term(void) { int retcode = 0; - if (0 != odp_pool_destroy(pool_default)) { - fprintf(stderr, "pool_default destroy failed.\n"); + if (0 != odp_pool_destroy(pkt_pool)) { + fprintf(stderr, "pkt_pool destroy failed.\n"); retcode = -1; } @@ -119,11 +145,16 @@ void classification_test_pmr_term_tcp_dport(void) odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; - odp_queue_t defqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t recvpool; odp_pmr_t pmr; odp_cos_t cos; - char cosname[ODP_QUEUE_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; + odp_pool_t pool; + odp_pool_t pool_recv; odp_pmr_match_t match; val = CLS_DEFAULT_DPORT; @@ -132,8 +163,8 @@ void classification_test_pmr_term_tcp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(defqueue != ODP_QUEUE_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); match.term = ODP_PMR_TCP_DPORT; match.val = &val; @@ -143,22 +174,29 @@ void classification_test_pmr_term_tcp_dport(void) pmr = odp_pmr_create(&match); CU_ASSERT(pmr != ODP_PMR_INVAL); - sprintf(cosname, "tcp_dport"); - cos = odp_cos_create(cosname); - CU_ASSERT(cos != ODP_COS_INVALID); - sprintf(queuename, "%s", "tcp_dport1"); - - queue = queue_create(queuename, true); + queue = queue_create("tcp_dport1", true); CU_ASSERT(queue != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos, queue); - CU_ASSERT(retval == 0); + pool = pool_create("tcp_dport1"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "tcp_dport"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT(cos != ODP_COS_INVALID); retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pool_default, false, &seq, false); + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, false); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -168,14 +206,17 @@ void classification_test_pmr_term_tcp_dport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + pool_recv = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_recv); CU_ASSERT(retqueue == queue); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); /* Other packets are delivered to default queue */ - pkt = create_packet(pool_default, false, &seq, false); + pkt = create_packet(pkt_pool, false, &seq, false); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -185,15 +226,21 @@ void classification_test_pmr_term_tcp_dport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - CU_ASSERT(retqueue == defqueue); + CU_ASSERT(retqueue == default_queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == default_pool); odp_packet_free(pkt); odp_cos_destroy(cos); + odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); destroy_inq(pktio); odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pool_destroy(pool); + odp_pool_destroy(default_pool); odp_pktio_close(pktio); } @@ -208,11 +255,15 @@ void classification_test_pmr_term_tcp_sport(void) odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; - odp_queue_t defqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t pool; + odp_pool_t recvpool; odp_pmr_t pmr; odp_cos_t cos; - char cosname[ODP_QUEUE_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; odp_pmr_match_t match; val = CLS_DEFAULT_SPORT; @@ -221,8 +272,8 @@ void classification_test_pmr_term_tcp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(defqueue != ODP_QUEUE_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); match.term = ODP_PMR_TCP_SPORT; match.val = &val; @@ -232,22 +283,28 @@ void classification_test_pmr_term_tcp_sport(void) pmr = odp_pmr_create(&match); CU_ASSERT(pmr != ODP_PMR_INVAL); - sprintf(cosname, "tcp_sport"); - cos = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + queue = queue_create("tcp_sport", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); - sprintf(queuename, "%s", "tcp_sport"); + pool = pool_create("tcp_sport"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); - queue = queue_create(queuename, true); - CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + sprintf(cosname, "tcp_sport"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; - retval = odp_cos_queue_set(cos, queue); - CU_ASSERT(retval == 0); + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pool_default, false, &seq, false); + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, false); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -257,12 +314,15 @@ void classification_test_pmr_term_tcp_sport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); CU_ASSERT(retqueue == queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool); odp_packet_free(pkt); - pkt = create_packet(pool_default, false, &seq, false); + pkt = create_packet(pkt_pool, false, &seq, false); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -272,15 +332,21 @@ void classification_test_pmr_term_tcp_sport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - CU_ASSERT(retqueue == defqueue); + CU_ASSERT(retqueue == default_queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == default_pool); odp_packet_free(pkt); odp_cos_destroy(cos); + odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); destroy_inq(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); odp_queue_destroy(queue); + odp_queue_destroy(default_queue); odp_pktio_close(pktio); } @@ -293,14 +359,18 @@ void classification_test_pmr_term_udp_dport(void) uint16_t mask; int retval; odp_pktio_t pktio; + odp_pool_t pool; + odp_pool_t recvpool; odp_queue_t queue; odp_queue_t retqueue; - odp_queue_t defqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; odp_pmr_t pmr; odp_cos_t cos; - char cosname[ODP_QUEUE_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; odp_pmr_match_t match; + odp_cls_cos_param_t cls_param; val = CLS_DEFAULT_DPORT; mask = 0xffff; @@ -308,8 +378,8 @@ void classification_test_pmr_term_udp_dport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(defqueue != ODP_QUEUE_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); match.term = ODP_PMR_UDP_DPORT; match.val = &val; @@ -319,22 +389,28 @@ void classification_test_pmr_term_udp_dport(void) pmr = odp_pmr_create(&match); CU_ASSERT(pmr != ODP_PMR_INVAL); - sprintf(cosname, "udp_dport"); - cos = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + queue = queue_create("udp_dport", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); - sprintf(queuename, "%s", "udp_dport"); + pool = pool_create("udp_dport"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); - queue = queue_create(queuename, true); - CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + sprintf(cosname, "udp_dport"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; - retval = odp_cos_queue_set(cos, queue); - CU_ASSERT(retval == 0); + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pool_default, false, &seq, true); + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -344,13 +420,16 @@ void classification_test_pmr_term_udp_dport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); CU_ASSERT(retqueue == queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool); odp_packet_free(pkt); /* Other packets received in default queue */ - pkt = create_packet(pool_default, false, &seq, true); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -360,15 +439,21 @@ void classification_test_pmr_term_udp_dport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - CU_ASSERT(retqueue == defqueue); + CU_ASSERT(retqueue == default_queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == default_pool); odp_packet_free(pkt); odp_cos_destroy(cos); + odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); destroy_inq(pktio); odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); odp_pktio_close(pktio); } @@ -383,12 +468,16 @@ void classification_test_pmr_term_udp_sport(void) odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; - odp_queue_t defqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t pool; + odp_pool_t recvpool; odp_pmr_t pmr; odp_cos_t cos; - char cosname[ODP_QUEUE_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; odp_pmr_match_t match; + odp_cls_cos_param_t cls_param; val = CLS_DEFAULT_SPORT; mask = 0xffff; @@ -396,8 +485,8 @@ void classification_test_pmr_term_udp_sport(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(defqueue != ODP_QUEUE_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); match.term = ODP_PMR_UDP_SPORT; match.val = &val; @@ -407,22 +496,28 @@ void classification_test_pmr_term_udp_sport(void) pmr = odp_pmr_create(&match); CU_ASSERT(pmr != ODP_PMR_INVAL); - sprintf(cosname, "udp_sport"); - cos = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + queue = queue_create("udp_sport", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); - sprintf(queuename, "%s", "udp_sport"); + pool = pool_create("udp_sport"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); - queue = queue_create(queuename, true); - CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + sprintf(cosname, "udp_sport"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; - retval = odp_cos_queue_set(cos, queue); - CU_ASSERT(retval == 0); + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pool_default, false, &seq, true); + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -432,12 +527,15 @@ void classification_test_pmr_term_udp_sport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); CU_ASSERT(retqueue == queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool); odp_packet_free(pkt); - pkt = create_packet(pool_default, false, &seq, true); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -447,15 +545,21 @@ void classification_test_pmr_term_udp_sport(void) enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - CU_ASSERT(retqueue == defqueue); + CU_ASSERT(retqueue == default_queue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == default_pool); odp_packet_free(pkt); odp_cos_destroy(cos); + odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); destroy_inq(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); odp_queue_destroy(queue); + odp_queue_destroy(default_queue); odp_pktio_close(pktio); } @@ -469,11 +573,15 @@ void classification_test_pmr_term_ipproto(void) odp_pktio_t pktio; odp_queue_t queue; odp_queue_t retqueue; - odp_queue_t defqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t pool; + odp_pool_t recvpool; odp_pmr_t pmr; odp_cos_t cos; - char cosname[ODP_QUEUE_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; odp_pmr_match_t match; val = ODPH_IPPROTO_UDP; @@ -482,8 +590,8 @@ void classification_test_pmr_term_ipproto(void) pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); - defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); - CU_ASSERT_FATAL(defqueue != ODP_QUEUE_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); match.term = ODP_PMR_IPPROTO; match.val = &val; @@ -493,50 +601,253 @@ void classification_test_pmr_term_ipproto(void) pmr = odp_pmr_create(&match); CU_ASSERT(pmr != ODP_PMR_INVAL); + queue = queue_create("ipproto", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + pool = pool_create("ipproto"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + sprintf(cosname, "ipproto"); - cos = odp_cos_create(cosname); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); - sprintf(queuename, "%s", "ipproto"); + retval = odp_pktio_pmr_cos(pmr, pktio, cos); + CU_ASSERT(retval == 0); + + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool); + CU_ASSERT(retqueue == queue); + odp_packet_free(pkt); + + /* Other packets delivered to default queue */ + pkt = create_packet(pkt_pool, false, &seq, false); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == default_pool); + CU_ASSERT(retqueue == default_queue); + + odp_cos_destroy(cos); + odp_cos_destroy(default_cos); + odp_pmr_destroy(pmr); + odp_packet_free(pkt); + destroy_inq(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pktio_close(pktio); +} + +static void classification_test_pmr_pool_set(void) +{ + odp_packet_t pkt; + uint32_t seqno; + uint8_t val; + uint8_t mask; + int retval; + odp_pktio_t pktio; + odp_queue_t queue; + odp_queue_t retqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t pool; + odp_pool_t pool_new; + odp_pool_t recvpool; + odp_pmr_t pmr; + odp_cos_t cos; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; + odp_pmr_match_t match; + + val = ODPH_IPPROTO_UDP; + mask = 0xff; + seqno = 0; + + pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); + CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); + + match.term = ODP_PMR_IPPROTO; + match.val = &val; + match.mask = &mask; + match.val_sz = sizeof(val); - queue = queue_create(queuename, true); + pmr = odp_pmr_create(&match); + CU_ASSERT(pmr != ODP_PMR_INVAL); + + queue = queue_create("ipproto1", true); CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos, queue); + pool = pool_create("ipproto1"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "ipproto1"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + pool_new = pool_create("ipproto2"); + CU_ASSERT_FATAL(pool_new != ODP_POOL_INVALID); + + /* new pool is set on CoS */ + retval = odp_cls_cos_pool_set(cos, pool_new); CU_ASSERT(retval == 0); retval = odp_pktio_pmr_cos(pmr, pktio, cos); CU_ASSERT(retval == 0); - pkt = create_packet(pool_default, false, &seq, true); + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool_new); CU_ASSERT(retqueue == queue); odp_packet_free(pkt); - /* Other packets delivered to default queue */ - pkt = create_packet(pool_default, false, &seq, false); + odp_cos_destroy(cos); + odp_cos_destroy(default_cos); + odp_pmr_destroy(pmr); + odp_packet_free(pkt); + destroy_inq(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_pool_destroy(pool_new); + odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pktio_close(pktio); +} + +static void classification_test_pmr_queue_set(void) +{ + odp_packet_t pkt; + uint32_t seqno; + uint8_t val; + uint8_t mask; + int retval; + odp_pktio_t pktio; + odp_queue_t queue; + odp_queue_t retqueue; + odp_queue_t default_queue; + odp_cos_t default_cos; + odp_pool_t default_pool; + odp_pool_t pool; + odp_queue_t queue_new; + odp_pool_t recvpool; + odp_pmr_t pmr; + odp_cos_t cos; + char cosname[ODP_COS_NAME_LEN]; + odp_cls_cos_param_t cls_param; + odp_pmr_match_t match; + + val = ODPH_IPPROTO_UDP; + mask = 0xff; + seqno = 0; + + pktio = create_pktio(ODP_QUEUE_TYPE_SCHED); + CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); + retval = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED); + CU_ASSERT(retval == 0); + + match.term = ODP_PMR_IPPROTO; + match.val = &val; + match.mask = &mask; + match.val_sz = sizeof(val); + + pmr = odp_pmr_create(&match); + CU_ASSERT(pmr != ODP_PMR_INVAL); + + queue = queue_create("ipproto1", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + pool = pool_create("ipproto1"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "ipproto1"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + queue_new = queue_create("ipproto2", true); + CU_ASSERT_FATAL(queue_new != ODP_QUEUE_INVALID); + + /* new queue is set on CoS */ + retval = odp_cos_queue_set(cos, queue_new); + CU_ASSERT(retval == 0); + + retval = odp_pktio_pmr_cos(pmr, pktio, cos); + CU_ASSERT(retval == 0); + + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + pkt = create_packet(pkt_pool, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); enqueue_pktio_interface(pkt, pktio); pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - CU_ASSERT(retqueue == defqueue); + recvpool = odp_packet_pool(pkt); + CU_ASSERT(recvpool == pool); + CU_ASSERT(retqueue == queue_new); + odp_packet_free(pkt); odp_cos_destroy(cos); + odp_cos_destroy(default_cos); odp_pmr_destroy(pmr); odp_packet_free(pkt); destroy_inq(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_queue_destroy(queue_new); odp_queue_destroy(queue); + odp_queue_destroy(default_queue); odp_pktio_close(pktio); } @@ -546,5 +857,7 @@ odp_testinfo_t classification_suite_pmr[] = { ODP_TEST_INFO(classification_test_pmr_term_udp_dport), ODP_TEST_INFO(classification_test_pmr_term_udp_sport), ODP_TEST_INFO(classification_test_pmr_term_ipproto), + ODP_TEST_INFO(classification_test_pmr_pool_set), + ODP_TEST_INFO(classification_test_pmr_queue_set), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index 3944d9456..e11c3d8b6 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -14,6 +14,7 @@ static odp_cos_t cos_list[CLS_ENTRIES]; static odp_pmr_t pmr_list[CLS_ENTRIES]; static odp_queue_t queue_list[CLS_ENTRIES]; +static odp_pool_t pool_list[CLS_ENTRIES]; static odp_pmr_set_t pmr_set; static odp_pool_t pool_default; @@ -24,7 +25,6 @@ odp_atomic_u32_t seq; int classification_suite_init(void) { - odp_pool_param_t param; odp_queue_t inq_def; odp_queue_param_t qparam; char queuename[ODP_QUEUE_NAME_LEN]; @@ -32,13 +32,7 @@ int classification_suite_init(void) int ret; odp_pktio_param_t pktio_param; - odp_pool_param_init(¶m); - param.pkt.seg_len = SHM_PKT_BUF_SIZE; - param.pkt.len = SHM_PKT_BUF_SIZE; - param.pkt.num = SHM_PKT_NUM_BUFS; - param.type = ODP_POOL_PACKET; - - pool_default = odp_pool_create("classification_pool", ¶m); + pool_default = pool_create("classification_pool"); if (ODP_POOL_INVALID == pool_default) { fprintf(stderr, "Packet pool creation failed.\n"); return -1; @@ -54,6 +48,7 @@ int classification_suite_init(void) fprintf(stderr, "unable to destroy pool.\n"); return -1; } + odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; @@ -73,6 +68,9 @@ int classification_suite_init(void) for (i = 0; i < CLS_ENTRIES; i++) queue_list[i] = ODP_QUEUE_INVALID; + for (i = 0; i < CLS_ENTRIES; i++) + pool_list[i] = ODP_POOL_INVALID; + odp_atomic_init_u32(&seq, 0); ret = odp_pktio_start(pktio_loop); @@ -113,6 +111,9 @@ int classification_suite_term(void) for (i = 0; i < CLS_ENTRIES; i++) odp_queue_destroy(queue_list[i]); + for (i = 0; i < CLS_ENTRIES; i++) + odp_pool_destroy(pool_list[i]); + return retcode; } @@ -129,14 +130,13 @@ void configure_cls_pmr_chain(void) int retval; char cosname[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; char queuename[ODP_QUEUE_NAME_LEN]; + char poolname[ODP_POOL_NAME_LEN]; uint32_t addr; uint32_t mask; odp_pmr_match_t match; - sprintf(cosname, "SrcCos"); - cos_list[CLS_PMR_CHAIN_SRC] = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_SRC] != ODP_COS_INVALID); odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; @@ -150,13 +150,19 @@ void configure_cls_pmr_chain(void) &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_SRC] != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_PMR_CHAIN_SRC], - queue_list[CLS_PMR_CHAIN_SRC]); - CU_ASSERT(retval == 0); - sprintf(cosname, "DstCos"); - cos_list[CLS_PMR_CHAIN_DST] = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_DST] != ODP_COS_INVALID); + sprintf(poolname, "%s", "SrcPool"); + pool_list[CLS_PMR_CHAIN_SRC] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_PMR_CHAIN_SRC] != ODP_POOL_INVALID); + + sprintf(cosname, "SrcCos"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_PMR_CHAIN_SRC]; + cls_param.queue = queue_list[CLS_PMR_CHAIN_SRC]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_PMR_CHAIN_SRC] = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_SRC] != ODP_COS_INVALID); + odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; @@ -169,9 +175,17 @@ void configure_cls_pmr_chain(void) &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_DST] != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_PMR_CHAIN_DST], - queue_list[CLS_PMR_CHAIN_DST]); - CU_ASSERT(retval == 0); + sprintf(poolname, "%s", "DstPool"); + pool_list[CLS_PMR_CHAIN_DST] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_PMR_CHAIN_DST] != ODP_POOL_INVALID); + + sprintf(cosname, "DstCos"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_PMR_CHAIN_DST]; + cls_param.queue = queue_list[CLS_PMR_CHAIN_DST]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_PMR_CHAIN_DST] = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_DST] != ODP_COS_INVALID); parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask); match.term = ODP_PMR_SIP_ADDR; @@ -206,11 +220,13 @@ void test_cls_pmr_chain(void) odph_ipv4hdr_t *ip; odph_udphdr_t *udp; odp_queue_t queue; + odp_pool_t pool; uint32_t addr = 0; uint32_t mask; uint32_t seqno = 0; pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -226,12 +242,15 @@ void test_cls_pmr_chain(void) enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_DST]); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_PMR_CHAIN_DST]); odp_packet_free(pkt); pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -243,9 +262,11 @@ void test_cls_pmr_chain(void) enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_SRC]); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_PMR_CHAIN_SRC]); odp_packet_free(pkt); } @@ -253,12 +274,10 @@ void configure_pktio_default_cos(void) { int retval; odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; char cosname[ODP_COS_NAME_LEN]; char queuename[ODP_QUEUE_NAME_LEN]; - - sprintf(cosname, "DefaultCoS"); - cos_list[CLS_DEFAULT] = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos_list[CLS_DEFAULT] != ODP_COS_INVALID); + char poolname[ODP_POOL_NAME_LEN]; odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; @@ -269,9 +288,17 @@ void configure_pktio_default_cos(void) ODP_QUEUE_TYPE_SCHED, &qparam); CU_ASSERT_FATAL(queue_list[CLS_DEFAULT] != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_DEFAULT], - queue_list[CLS_DEFAULT]); - CU_ASSERT(retval == 0); + sprintf(poolname, "DefaultPool"); + pool_list[CLS_DEFAULT] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_DEFAULT] != ODP_POOL_INVALID); + + sprintf(cosname, "DefaultCoS"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_DEFAULT]; + cls_param.queue = queue_list[CLS_DEFAULT]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_DEFAULT] = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos_list[CLS_DEFAULT] != ODP_COS_INVALID); retval = odp_pktio_default_cos_set(pktio_loop, cos_list[CLS_DEFAULT]); CU_ASSERT(retval == 0); @@ -282,18 +309,22 @@ void test_pktio_default_cos(void) odp_packet_t pkt; odp_queue_t queue; uint32_t seqno = 0; + odp_pool_t pool; /* create a default packet */ pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); /* Default packet should be received in default queue */ CU_ASSERT(queue == queue_list[CLS_DEFAULT]); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_DEFAULT]); odp_packet_free(pkt); } @@ -302,8 +333,10 @@ void configure_pktio_error_cos(void) { int retval; odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; char queuename[ODP_QUEUE_NAME_LEN]; char cosname[ODP_COS_NAME_LEN]; + char poolname[ODP_POOL_NAME_LEN]; odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_LOWEST; @@ -316,13 +349,18 @@ void configure_pktio_error_cos(void) &qparam); CU_ASSERT_FATAL(queue_list[CLS_ERROR] != ODP_QUEUE_INVALID); + sprintf(poolname, "ErrorPool"); + pool_list[CLS_ERROR] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_ERROR] != ODP_POOL_INVALID); + sprintf(cosname, "%s", "ErrorCos"); - cos_list[CLS_ERROR] = odp_cos_create(cosname); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_ERROR]; + cls_param.queue = queue_list[CLS_ERROR]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_ERROR] = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos_list[CLS_ERROR] != ODP_COS_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_ERROR], queue_list[CLS_ERROR]); - CU_ASSERT(retval == 0); - retval = odp_pktio_error_cos_set(pktio_loop, cos_list[CLS_ERROR]); CU_ASSERT(retval == 0); } @@ -331,9 +369,11 @@ void test_pktio_error_cos(void) { odp_queue_t queue; odp_packet_t pkt; + odp_pool_t pool; /*Create an error packet */ pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); /* Incorrect IpV4 version */ @@ -342,9 +382,11 @@ void test_pktio_error_cos(void) enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); /* Error packet should be received in error queue */ CU_ASSERT(queue == queue_list[CLS_ERROR]); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_ERROR]); odp_packet_free(pkt); } @@ -382,12 +424,15 @@ void configure_cos_with_l2_priority(void) uint8_t num_qos = CLS_L2_QOS_MAX; odp_cos_t cos_tbl[CLS_L2_QOS_MAX]; odp_queue_t queue_tbl[CLS_L2_QOS_MAX]; + odp_pool_t pool; uint8_t qos_tbl[CLS_L2_QOS_MAX]; char cosname[ODP_COS_NAME_LEN]; char queuename[ODP_QUEUE_NAME_LEN]; + char poolname[ODP_POOL_NAME_LEN]; int retval; int i; odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; /** Initialize scalar variable qos_tbl **/ for (i = 0; i < CLS_L2_QOS_MAX; i++) @@ -398,23 +443,31 @@ void configure_cos_with_l2_priority(void) qparam.sched.group = ODP_SCHED_GROUP_ALL; for (i = 0; i < num_qos; i++) { qparam.sched.prio = ODP_SCHED_PRIO_LOWEST - i; - sprintf(cosname, "%s_%d", "L2_Cos", i); - cos_tbl[i] = odp_cos_create(cosname); - if (cos_tbl[i] == ODP_COS_INVALID) - break; - - cos_list[CLS_L2_QOS_0 + i] = cos_tbl[i]; sprintf(queuename, "%s_%d", "L2_Queue", i); queue_tbl[i] = odp_queue_create(queuename, ODP_QUEUE_TYPE_SCHED, &qparam); CU_ASSERT_FATAL(queue_tbl[i] != ODP_QUEUE_INVALID); queue_list[CLS_L2_QOS_0 + i] = queue_tbl[i]; - retval = odp_cos_queue_set(cos_tbl[i], queue_tbl[i]); - CU_ASSERT(retval == 0); + + sprintf(poolname, "%s_%d", "L2_Pool", i); + pool = pool_create(poolname); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + pool_list[CLS_L2_QOS_0 + i] = pool; + + sprintf(cosname, "%s_%d", "L2_Cos", i); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue_tbl[i]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_tbl[i] = odp_cls_cos_create(cosname, &cls_param); + if (cos_tbl[i] == ODP_COS_INVALID) + break; + + cos_list[CLS_L2_QOS_0 + i] = cos_tbl[i]; qos_tbl[i] = i; } /* count 'i' is passed instead of num_qos to handle the rare scenario - if the odp_cos_create() failed in the middle*/ + if the odp_cls_cos_create() failed in the middle*/ retval = odp_cos_with_l2_priority(pktio_loop, i, qos_tbl, cos_tbl); CU_ASSERT(retval == 0); } @@ -425,11 +478,13 @@ void test_cos_with_l2_priority(void) odph_ethhdr_t *ethhdr; odph_vlanhdr_t *vlan; odp_queue_t queue; + odp_pool_t pool; uint32_t seqno = 0; uint8_t i; for (i = 0; i < CLS_L2_QOS_MAX; i++) { pkt = create_packet(pool_default, true, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); @@ -437,8 +492,10 @@ void test_cos_with_l2_priority(void) vlan->tci = odp_cpu_to_be_16(i << 13); enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_L2_QOS_0 + i]); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_L2_QOS_0 + i]); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); } @@ -451,8 +508,10 @@ void configure_pmr_cos(void) int retval; odp_pmr_match_t match; odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; char cosname[ODP_COS_NAME_LEN]; char queuename[ODP_QUEUE_NAME_LEN]; + char poolname[ODP_POOL_NAME_LEN]; val = CLS_PMR_SPORT; mask = 0xffff; @@ -462,11 +521,7 @@ void configure_pmr_cos(void) match.val_sz = sizeof(val); pmr_list[CLS_PMR] = odp_pmr_create(&match); - CU_ASSERT(pmr_list[CLS_PMR] != ODP_PMR_INVAL); - - sprintf(cosname, "PMR_CoS"); - cos_list[CLS_PMR] = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos_list[CLS_PMR] != ODP_COS_INVALID); + CU_ASSERT_FATAL(pmr_list[CLS_PMR] != ODP_PMR_INVAL); odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; @@ -479,9 +534,17 @@ void configure_pmr_cos(void) &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR] != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_PMR], - queue_list[CLS_PMR]); - CU_ASSERT(retval == 0); + sprintf(poolname, "PMR_Pool"); + pool_list[CLS_PMR] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_PMR] != ODP_POOL_INVALID); + + sprintf(cosname, "PMR_CoS"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_PMR]; + cls_param.queue = queue_list[CLS_PMR]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_PMR] = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos_list[CLS_PMR] != ODP_COS_INVALID); retval = odp_pktio_pmr_cos(pmr_list[CLS_PMR], pktio_loop, cos_list[CLS_PMR]); @@ -493,17 +556,21 @@ void test_pmr_cos(void) odp_packet_t pkt; odph_udphdr_t *udp; odp_queue_t queue; + odp_pool_t pool; uint32_t seqno = 0; pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); 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_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR]); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_PMR]); CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); } @@ -516,8 +583,10 @@ void configure_pktio_pmr_match_set_cos(void) uint16_t maskport; int num_terms = 2; /* one pmr for each L3 and L4 */ odp_queue_param_t qparam; + odp_cls_cos_param_t cls_param; char cosname[ODP_COS_NAME_LEN]; char queuename[ODP_QUEUE_NAME_LEN]; + char poolname[ODP_POOL_NAME_LEN]; uint32_t addr = 0; uint32_t mask; @@ -538,10 +607,6 @@ void configure_pktio_pmr_match_set_cos(void) retval = odp_pmr_match_set_create(num_terms, pmr_terms, &pmr_set); CU_ASSERT(retval > 0); - sprintf(cosname, "cos_pmr_set"); - cos_list[CLS_PMR_SET] = odp_cos_create(cosname); - CU_ASSERT_FATAL(cos_list[CLS_PMR_SET] != ODP_COS_INVALID); - odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; qparam.sched.sync = ODP_SCHED_SYNC_NONE; @@ -553,9 +618,17 @@ void configure_pktio_pmr_match_set_cos(void) &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_SET] != ODP_QUEUE_INVALID); - retval = odp_cos_queue_set(cos_list[CLS_PMR_SET], - queue_list[CLS_PMR_SET]); - CU_ASSERT(retval == 0); + sprintf(poolname, "cos_pmr_set_pool"); + pool_list[CLS_PMR_SET] = pool_create(poolname); + CU_ASSERT_FATAL(pool_list[CLS_PMR_SET] != ODP_POOL_INVALID); + + sprintf(cosname, "cos_pmr_set"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool_list[CLS_PMR_SET]; + cls_param.queue = queue_list[CLS_PMR_SET]; + cls_param.drop_policy = ODP_COS_DROP_POOL; + cos_list[CLS_PMR_SET] = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos_list[CLS_PMR_SET] != ODP_COS_INVALID); retval = odp_pktio_pmr_match_set_cos(pmr_set, pktio_loop, cos_list[CLS_PMR_SET]); @@ -569,10 +642,12 @@ void test_pktio_pmr_match_set_cos(void) odph_ipv4hdr_t *ip; odph_udphdr_t *udp; odp_packet_t pkt; + odp_pool_t pool; odp_queue_t queue; uint32_t seqno = 0; pkt = create_packet(pool_default, false, &seq, true); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -586,8 +661,10 @@ void test_pktio_pmr_match_set_cos(void) udp->src_port = odp_cpu_to_be_16(CLS_PMR_SET_SPORT); enqueue_pktio_interface(pkt, pktio_loop); pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS); - CU_ASSERT(pkt != ODP_PACKET_INVALID); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(queue == queue_list[CLS_PMR_SET]); + pool = odp_packet_pool(pkt); + CU_ASSERT(pool == pool_list[CLS_PMR_SET]); 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 7d27d95b5..02828e125 100644 --- a/test/validation/classification/odp_classification_testsuites.h +++ b/test/validation/classification/odp_classification_testsuites.h @@ -25,11 +25,14 @@ odp_packet_t create_packet(odp_pool_t pool, bool vlan, 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 create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype); +void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, + odp_queue_t *queue, odp_pool_t *pool); 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); +odp_pool_t pool_create(const char *poolname); +odp_queue_t queue_create(const char *queuename, bool sched); void configure_pktio_default_cos(void); void test_pktio_default_cos(void); void configure_pktio_error_cos(void); diff --git a/test/validation/crypto/crypto.h b/test/validation/crypto/crypto.h index 4769fad1f..5224e4763 100644 --- a/test/validation/crypto/crypto.h +++ b/test/validation/crypto/crypto.h @@ -18,6 +18,10 @@ void crypto_test_enc_alg_aes128_cbc(void); void crypto_test_enc_alg_aes128_cbc_ovr_iv(void); void crypto_test_dec_alg_aes128_cbc(void); void crypto_test_dec_alg_aes128_cbc_ovr_iv(void); +void crypto_test_enc_alg_aes128_gcm(void); +void crypto_test_enc_alg_aes128_gcm_ovr_iv(void); +void crypto_test_dec_alg_aes128_gcm(void); +void crypto_test_dec_alg_aes128_gcm_ovr_iv(void); void crypto_test_alg_hmac_md5(void); void crypto_test_alg_hmac_sha256(void); diff --git a/test/validation/crypto/odp_crypto_test_inp.c b/test/validation/crypto/odp_crypto_test_inp.c index 5295c6329..b6fcb1272 100644 --- a/test/validation/crypto/odp_crypto_test_inp.c +++ b/test/validation/crypto/odp_crypto_test_inp.c @@ -35,10 +35,15 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_key_t cipher_key, odp_auth_alg_t auth_alg, odp_crypto_key_t auth_key, - uint8_t *input_vec, - unsigned int input_vec_len, - uint8_t *output_vec, - unsigned int output_vec_len) + odp_crypto_data_range_t *cipher_range, + odp_crypto_data_range_t *auth_range, + const uint8_t *plaintext, + unsigned int plaintext_len, + const uint8_t *ciphertext, + unsigned int ciphertext_len, + const uint8_t *digest, + unsigned int digest_len + ) { odp_crypto_session_t session; int rc; @@ -69,11 +74,12 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); /* Prepare input data */ - odp_packet_t pkt = odp_packet_alloc(suite_context.pool, input_vec_len); + odp_packet_t pkt = odp_packet_alloc(suite_context.pool, + plaintext_len + digest_len); CU_ASSERT(pkt != ODP_PACKET_INVALID); uint8_t *data_addr = odp_packet_data(pkt); - memcpy(data_addr, input_vec, input_vec_len); - const int data_off = 0; + memcpy(data_addr, plaintext, plaintext_len); + int data_off = 0; /* Prepare input/output params */ odp_crypto_op_params_t op_params; @@ -82,20 +88,24 @@ static void alg_test(odp_crypto_op_t op, op_params.pkt = pkt; op_params.out_pkt = pkt; op_params.ctx = (void *)0xdeadbeef; - if (cipher_alg != ODP_CIPHER_ALG_NULL && - auth_alg == ODP_AUTH_ALG_NULL) { + + if (cipher_range) { + op_params.cipher_range = *cipher_range; + data_off = cipher_range->offset; + } else { op_params.cipher_range.offset = data_off; - op_params.cipher_range.length = input_vec_len; - if (op_iv_ptr) - op_params.override_iv_ptr = op_iv_ptr; - } else if (cipher_alg == ODP_CIPHER_ALG_NULL && - auth_alg != ODP_AUTH_ALG_NULL) { - op_params.auth_range.offset = data_off; - op_params.auth_range.length = input_vec_len; - op_params.hash_result_offset = data_off; + op_params.cipher_range.length = plaintext_len; + } + if (auth_range) { + op_params.auth_range = *auth_range; } else { - CU_FAIL("%s : not implemented for combined alg mode\n"); + op_params.auth_range.offset = data_off; + op_params.auth_range.length = plaintext_len; } + if (op_iv_ptr) + op_params.override_iv_ptr = op_iv_ptr; + + op_params.hash_result_offset = plaintext_len; rc = odp_crypto_operation(&op_params, &posted, &result); if (rc < 0) { @@ -119,7 +129,12 @@ static void alg_test(odp_crypto_op_t op, CU_ASSERT(result.ok); CU_ASSERT(result.pkt == pkt); - CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len)); + if (cipher_alg != ODP_CIPHER_ALG_NULL) + CU_ASSERT(!memcmp(data_addr, ciphertext, ciphertext_len)); + + if (op == ODP_CRYPTO_OP_ENCODE && auth_alg != ODP_AUTH_ALG_NULL) + CU_ASSERT(!memcmp(data_addr + op_params.hash_result_offset, + digest, digest_len)); CU_ASSERT(result.ctx == (void *)0xdeadbeef); cleanup: @@ -155,10 +170,11 @@ void crypto_test_enc_alg_3des_cbc(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, tdes_cbc_reference_plaintext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_ciphertext[i], - tdes_cbc_reference_length[i]); + tdes_cbc_reference_length[i], NULL, 0); } } @@ -185,10 +201,11 @@ void crypto_test_enc_alg_3des_cbc_ovr_iv(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, tdes_cbc_reference_plaintext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_ciphertext[i], - tdes_cbc_reference_length[i]); + tdes_cbc_reference_length[i], NULL, 0); } } @@ -220,10 +237,11 @@ void crypto_test_dec_alg_3des_cbc(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, tdes_cbc_reference_ciphertext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_plaintext[i], - tdes_cbc_reference_length[i]); + tdes_cbc_reference_length[i], NULL, 0); } } @@ -252,10 +270,161 @@ void crypto_test_dec_alg_3des_cbc_ovr_iv(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, tdes_cbc_reference_ciphertext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_plaintext[i], - tdes_cbc_reference_length[i]); + tdes_cbc_reference_length[i], NULL, 0); + } +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_GCM algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +void crypto_test_enc_alg_aes128_gcm(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / + sizeof(aes128_gcm_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + cipher_key.data = aes128_gcm_reference_key[i]; + cipher_key.length = sizeof(aes128_gcm_reference_key[i]); + iv.data = aes128_gcm_reference_iv[i]; + iv.length = sizeof(aes128_gcm_reference_iv[i]); + + alg_test(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES128_GCM, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_AES128_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i] + + aes128_gcm_reference_length[i], + AES128_GCM_CHECK_LEN); + } +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_GCM algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +void crypto_test_enc_alg_aes128_gcm_ovr_iv(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / + sizeof(aes128_gcm_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + cipher_key.data = aes128_gcm_reference_key[i]; + cipher_key.length = sizeof(aes128_gcm_reference_key[i]); + + alg_test(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES128_GCM, + iv, + aes128_gcm_reference_iv[i], + cipher_key, + ODP_AUTH_ALG_AES128_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i] + + aes128_gcm_reference_length[i], + AES128_GCM_CHECK_LEN); + } +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +void crypto_test_dec_alg_aes128_gcm(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / + sizeof(aes128_gcm_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + cipher_key.data = aes128_gcm_reference_key[i]; + cipher_key.length = sizeof(aes128_gcm_reference_key[i]); + iv.data = aes128_gcm_reference_iv[i]; + iv.length = sizeof(aes128_gcm_reference_iv[i]); + + alg_test(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES128_GCM, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_AES128_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i] + + aes128_gcm_reference_length[i], + AES128_GCM_CHECK_LEN); + } +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / + sizeof(aes128_gcm_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + cipher_key.data = aes128_gcm_reference_key[i]; + cipher_key.length = sizeof(aes128_gcm_reference_key[i]); + + alg_test(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES128_GCM, + iv, + aes128_gcm_reference_iv[i], + cipher_key, + ODP_AUTH_ALG_AES128_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + aes128_gcm_reference_ciphertext[i] + + aes128_gcm_reference_length[i], + AES128_GCM_CHECK_LEN); } } @@ -285,10 +454,11 @@ void crypto_test_enc_alg_aes128_cbc(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, aes128_cbc_reference_plaintext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_ciphertext[i], - aes128_cbc_reference_length[i]); + aes128_cbc_reference_length[i], NULL, 0); } } @@ -315,10 +485,11 @@ void crypto_test_enc_alg_aes128_cbc_ovr_iv(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, aes128_cbc_reference_plaintext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_ciphertext[i], - aes128_cbc_reference_length[i]); + aes128_cbc_reference_length[i], NULL, 0); } } @@ -349,10 +520,11 @@ void crypto_test_dec_alg_aes128_cbc(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, aes128_cbc_reference_ciphertext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_plaintext[i], - aes128_cbc_reference_length[i]); + aes128_cbc_reference_length[i], NULL, 0); } } @@ -381,10 +553,11 @@ void crypto_test_dec_alg_aes128_cbc_ovr_iv(void) cipher_key, ODP_AUTH_ALG_NULL, auth_key, + NULL, NULL, aes128_cbc_reference_ciphertext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_plaintext[i], - aes128_cbc_reference_length[i]); + aes128_cbc_reference_length[i], NULL, 0); } } @@ -417,8 +590,10 @@ void crypto_test_alg_hmac_md5(void) cipher_key, ODP_AUTH_ALG_MD5_96, auth_key, + NULL, NULL, hmac_md5_reference_plaintext[i], hmac_md5_reference_length[i], + NULL, 0, hmac_md5_reference_digest[i], HMAC_MD5_96_CHECK_LEN); } @@ -453,8 +628,10 @@ void crypto_test_alg_hmac_sha256(void) cipher_key, ODP_AUTH_ALG_SHA256_128, auth_key, + NULL, NULL, hmac_sha256_reference_plaintext[i], hmac_sha256_reference_length[i], + NULL, 0, hmac_sha256_reference_digest[i], HMAC_SHA256_128_CHECK_LEN); } @@ -493,6 +670,10 @@ odp_testinfo_t crypto_suite[] = { ODP_TEST_INFO(crypto_test_dec_alg_aes128_cbc), ODP_TEST_INFO(crypto_test_enc_alg_aes128_cbc_ovr_iv), ODP_TEST_INFO(crypto_test_dec_alg_aes128_cbc_ovr_iv), + ODP_TEST_INFO(crypto_test_enc_alg_aes128_gcm), + ODP_TEST_INFO(crypto_test_enc_alg_aes128_gcm_ovr_iv), + ODP_TEST_INFO(crypto_test_dec_alg_aes128_gcm), + ODP_TEST_INFO(crypto_test_dec_alg_aes128_gcm_ovr_iv), ODP_TEST_INFO(crypto_test_alg_hmac_md5), ODP_TEST_INFO(crypto_test_alg_hmac_sha256), ODP_TEST_INFO_NULL, diff --git a/test/validation/crypto/test_vectors.h b/test/validation/crypto/test_vectors.h index 73f54b5b3..1b760a24e 100644 --- a/test/validation/crypto/test_vectors.h +++ b/test/validation/crypto/test_vectors.h @@ -112,6 +112,158 @@ aes128_cbc_reference_ciphertext[][AES128_CBC_MAX_DATA_LEN] = { 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55 } }; +/* AES-GCM test vectors extracted from + * https://tools.ietf.org/html/draft-mcgrew-gcm-test-01#section-2 + */ +static uint8_t aes128_gcm_reference_key[][AES128_GCM_KEY_LEN] = { + { 0x4c, 0x80, 0xcd, 0xef, 0xbb, 0x5d, 0x10, 0xda, + 0x90, 0x6a, 0xc7, 0x3c, 0x36, 0x13, 0xa6, 0x34 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x3d, 0xe0, 0x98, 0x74, 0xb3, 0x88, 0xe6, 0x49, + 0x19, 0x88, 0xd0, 0xc3, 0x60, 0x7e, 0xae, 0x1f } +}; + +static uint8_t aes128_gcm_reference_iv[][AES128_GCM_IV_LEN] = { + { 0x2e, 0x44, 0x3b, 0x68, 0x49, 0x56, 0xed, 0x7e, + 0x3b, 0x24, 0x4c, 0xfe }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x57, 0x69, 0x0e, 0x43, 0x4e, 0x28, 0x00, 0x00, + 0xa2, 0xfc, 0xa1, 0xa3 } +}; + +static uint32_t aes128_gcm_reference_length[] = { 84, 72, 72, 40}; + +static odp_crypto_data_range_t aes128_gcm_cipher_range[] = { + { .offset = 12, .length = 72 }, + { .offset = 8, .length = 64 }, + { .offset = 8, .length = 64 }, + { .offset = 12, .length = 28 }, +}; + +static odp_crypto_data_range_t aes128_gcm_auth_range[] = { + { .offset = 0, .length = 84 }, + { .offset = 0, .length = 72 }, + { .offset = 0, .length = 72 }, + { .offset = 0, .length = 40 }, +}; + +static uint8_t +aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { + { /* Aad */ + 0x00, 0x00, 0x43, 0x21, 0x87, 0x65, 0x43, 0x21, + 0x00, 0x00, 0x00, 0x00, + /* Plain */ + 0x45, 0x00, 0x00, 0x48, 0x69, 0x9a, 0x00, 0x00, + 0x80, 0x11, 0x4d, 0xb7, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, 0x0a, 0x9b, 0xf1, 0x56, + 0x38, 0xd3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, 0x73, 0x69, + 0x70, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x73, + 0x69, 0x70, 0x09, 0x63, 0x79, 0x62, 0x65, 0x72, + 0x63, 0x69, 0x74, 0x79, 0x02, 0x64, 0x6b, 0x00, + 0x00, 0x21, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01 }, + + { /* Aad */ + 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, + /* Plain */ + 0x45, 0x00, 0x00, 0x3e, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x11, 0x4d, 0xcc, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, 0x0a, 0x98, 0x00, 0x35, + 0x00, 0x2a, 0x23, 0x43, 0xb2, 0xd0, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x73, 0x69, 0x70, 0x09, 0x63, 0x79, 0x62, + 0x65, 0x72, 0x63, 0x69, 0x74, 0x79, 0x02, 0x64, + 0x6b, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 }, + + { /* Aad */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* Plain */ + 0x45, 0x00, 0x00, 0x3c, 0x99, 0xc5, 0x00, 0x00, + 0x80, 0x01, 0xcb, 0x7a, 0x40, 0x67, 0x93, 0x18, + 0x01, 0x01, 0x01, 0x01, 0x08, 0x00, 0x07, 0x5c, + 0x02, 0x00, 0x44, 0x00, 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x01, 0x02, 0x02, 0x01 }, + + { /* Aad */ + 0x42, 0xf6, 0x7e, 0x3f, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, + /* Plain */ + 0x45, 0x00, 0x00, 0x1c, 0x42, 0xa2, 0x00, 0x00, + 0x80, 0x01, 0x44, 0x1f, 0x40, 0x67, 0x93, 0xb6, + 0xe0, 0x00, 0x00, 0x02, 0x0a, 0x00, 0xf5, 0xff, + 0x01, 0x02, 0x02, 0x01 } +}; + +static uint8_t +aes128_gcm_reference_ciphertext[][AES128_GCM_MAX_DATA_LEN] = { + { /* Aad */ + 0x00, 0x00, 0x43, 0x21, 0x87, 0x65, 0x43, 0x21, + 0x00, 0x00, 0x00, 0x00, + /* Plain */ + 0xfe, 0xcf, 0x53, 0x7e, 0x72, 0x9d, 0x5b, 0x07, + 0xdc, 0x30, 0xdf, 0x52, 0x8d, 0xd2, 0x2b, 0x76, + 0x8d, 0x1b, 0x98, 0x73, 0x66, 0x96, 0xa6, 0xfd, + 0x34, 0x85, 0x09, 0xfa, 0x13, 0xce, 0xac, 0x34, + 0xcf, 0xa2, 0x43, 0x6f, 0x14, 0xa3, 0xf3, 0xcf, + 0x65, 0x92, 0x5b, 0xf1, 0xf4, 0xa1, 0x3c, 0x5d, + 0x15, 0xb2, 0x1e, 0x18, 0x84, 0xf5, 0xff, 0x62, + 0x47, 0xae, 0xab, 0xb7, 0x86, 0xb9, 0x3b, 0xce, + 0x61, 0xbc, 0x17, 0xd7, 0x68, 0xfd, 0x97, 0x32, + /* Digest */ + 0x45, 0x90, 0x18, 0x14, 0x8f, 0x6c, 0xbe, 0x72, + 0x2f, 0xd0, 0x47, 0x96, 0x56, 0x2d, 0xfd, 0xb4 }, + + { /* Aad */ + 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, + /* Plain */ + 0xde, 0xb2, 0x2c, 0xd9, 0xb0, 0x7c, 0x72, 0xc1, + 0x6e, 0x3a, 0x65, 0xbe, 0xeb, 0x8d, 0xf3, 0x04, + 0xa5, 0xa5, 0x89, 0x7d, 0x33, 0xae, 0x53, 0x0f, + 0x1b, 0xa7, 0x6d, 0x5d, 0x11, 0x4d, 0x2a, 0x5c, + 0x3d, 0xe8, 0x18, 0x27, 0xc1, 0x0e, 0x9a, 0x4f, + 0x51, 0x33, 0x0d, 0x0e, 0xec, 0x41, 0x66, 0x42, + 0xcf, 0xbb, 0x85, 0xa5, 0xb4, 0x7e, 0x48, 0xa4, + 0xec, 0x3b, 0x9b, 0xa9, 0x5d, 0x91, 0x8b, 0xd1, + /* Digest */ + 0x83, 0xb7, 0x0d, 0x3a, 0xa8, 0xbc, 0x6e, 0xe4, + 0xc3, 0x09, 0xe9, 0xd8, 0x5a, 0x41, 0xad, 0x4a }, + { /* Aad */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* Plain */ + 0x46, 0x88, 0xda, 0xf2, 0xf9, 0x73, 0xa3, 0x92, + 0x73, 0x29, 0x09, 0xc3, 0x31, 0xd5, 0x6d, 0x60, + 0xf6, 0x94, 0xab, 0xaa, 0x41, 0x4b, 0x5e, 0x7f, + 0xf5, 0xfd, 0xcd, 0xff, 0xf5, 0xe9, 0xa2, 0x84, + 0x45, 0x64, 0x76, 0x49, 0x27, 0x19, 0xff, 0xb6, + 0x4d, 0xe7, 0xd9, 0xdc, 0xa1, 0xe1, 0xd8, 0x94, + 0xbc, 0x3b, 0xd5, 0x78, 0x73, 0xed, 0x4d, 0x18, + 0x1d, 0x19, 0xd4, 0xd5, 0xc8, 0xc1, 0x8a, 0xf3, + /* Digest */ + 0xf8, 0x21, 0xd4, 0x96, 0xee, 0xb0, 0x96, 0xe9, + 0x8a, 0xd2, 0xb6, 0x9e, 0x47, 0x99, 0xc7, 0x1d }, + + { /* Aad */ + 0x42, 0xf6, 0x7e, 0x3f, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, + /* Plain */ + 0xfb, 0xa2, 0xca, 0x84, 0x5e, 0x5d, 0xf9, 0xf0, + 0xf2, 0x2c, 0x3e, 0x6e, 0x86, 0xdd, 0x83, 0x1e, + 0x1f, 0xc6, 0x57, 0x92, 0xcd, 0x1a, 0xf9, 0x13, + 0x0e, 0x13, 0x79, 0xed, + /* Digest */ + 0x36, 0x9f, 0x07, 0x1f, 0x35, 0xe0, 0x34, 0xbe, + 0x95, 0xf1, 0x12, 0xe4, 0xe7, 0xd0, 0x5d, 0x35 } +}; + static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = { { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } , diff --git a/test/validation/crypto/test_vectors_len.h b/test/validation/crypto/test_vectors_len.h index 5bc6f4b50..4fbb5cd70 100644 --- a/test/validation/crypto/test_vectors_len.h +++ b/test/validation/crypto/test_vectors_len.h @@ -16,6 +16,13 @@ #define AES128_CBC_IV_LEN 16 #define AES128_CBC_MAX_DATA_LEN 64 +/* AES128-CBC */ +#define AES128_GCM_KEY_LEN 16 +#define AES128_GCM_IV_LEN 12 +#define AES128_GCM_MAX_DATA_LEN 106 +#define AES128_GCM_DIGEST_LEN 16 +#define AES128_GCM_CHECK_LEN 16 + /* HMAC-MD5 */ #define HMAC_MD5_KEY_LEN 16 #define HMAC_MD5_MAX_DATA_LEN 128 diff --git a/test/validation/hash/.gitignore b/test/validation/hash/.gitignore new file mode 100644 index 000000000..6d0bc9314 --- /dev/null +++ b/test/validation/hash/.gitignore @@ -0,0 +1 @@ +hash_main diff --git a/test/validation/hash/Makefile.am b/test/validation/hash/Makefile.am new file mode 100644 index 000000000..b899b8bd3 --- /dev/null +++ b/test/validation/hash/Makefile.am @@ -0,0 +1,10 @@ +include ../Makefile.inc + +noinst_LTLIBRARIES = libtesthash.la +libtesthash_la_SOURCES = hash.c + +test_PROGRAMS = hash_main$(EXEEXT) +dist_hash_main_SOURCES = hash_main.c +hash_main_LDADD = libtesthash.la $(LIBCUNIT_COMMON) $(LIBODP) + +EXTRA_DIST = hash.h diff --git a/test/validation/hash/hash.c b/test/validation/hash/hash.c new file mode 100644 index 000000000..11b331e28 --- /dev/null +++ b/test/validation/hash/hash.c @@ -0,0 +1,49 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp.h> +#include <odp_cunit_common.h> +#include "hash.h" + +void hash_test_crc32c(void) +{ + uint32_t test_value = 0x12345678; + uint32_t ret = odp_hash_crc32c(&test_value, 4, 0); + + CU_ASSERT(ret == 0xfa745634); + + test_value = 0x87654321; + ret = odp_hash_crc32c(&test_value, 4, 0); + + CU_ASSERT(ret == 0xaca37da7); + + uint32_t test_values[] = {0x12345678, 0x87654321}; + + ret = odp_hash_crc32c(test_values, 8, 0); + + CU_ASSERT(ret == 0xe6e910b0); +} + +odp_testinfo_t hash_suite[] = { + ODP_TEST_INFO(hash_test_crc32c), + ODP_TEST_INFO_NULL, +}; + +odp_suiteinfo_t hash_suites[] = { + {"Hash", NULL, NULL, hash_suite}, + ODP_SUITE_INFO_NULL +}; + +int hash_main(void) +{ + int ret = odp_cunit_register(hash_suites); + + if (ret == 0) + ret = odp_cunit_run(); + + return ret; + +} diff --git a/test/validation/hash/hash.h b/test/validation/hash/hash.h new file mode 100644 index 000000000..46c74660d --- /dev/null +++ b/test/validation/hash/hash.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_HASH_H_ +#define _ODP_TEST_HASH_H_ + +#include <odp_cunit_common.h> + +/* test functions: */ +void hash_test_crc32c(void); + +/* test arrays: */ +extern odp_testinfo_t hash_suite[]; + +/* test registry: */ +extern odp_suiteinfo_t hash_suites[]; + +/* main test program: */ +int hash_main(void); + +#endif diff --git a/test/validation/hash/hash_main.c b/test/validation/hash/hash_main.c new file mode 100644 index 000000000..4f7765ca2 --- /dev/null +++ b/test/validation/hash/hash_main.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "hash.h" + +int main(void) +{ + return hash_main(); +} diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c index c85bce78d..e473a1d1c 100644 --- a/test/validation/pktio/pktio.c +++ b/test/validation/pktio/pktio.c @@ -288,6 +288,10 @@ static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_to_u64(pktio) != odp_pktio_to_u64(ODP_PKTIO_INVALID)); + /* Print pktio debug info and test that the odp_pktio_print() function + * is implemented. */ + if (pktio != ODP_PKTIO_INVALID) + odp_pktio_print(pktio); if (wait_for_network) spin_wait(ODP_TIME_SEC_IN_NS / 4); @@ -355,18 +359,16 @@ static int destroy_inq(odp_pktio_t pktio) static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns) { - odp_time_t start, now, diff; + odp_time_t wait, end; odp_event_t ev; - start = odp_time_local(); - + wait = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait); do { ev = odp_queue_deq(queue); if (ev != ODP_EVENT_INVALID) return ev; - now = odp_time_local(); - diff = odp_time_diff(now, start); - } while (odp_time_to_ns(diff) < ns); + } while (odp_time_cmp(end, odp_time_local()) > 0); return ODP_EVENT_INVALID; } @@ -374,14 +376,14 @@ static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns) static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx, uint32_t seq, uint64_t ns) { - odp_time_t start, now, diff; + odp_time_t wait_time, end; odp_event_t ev; odp_packet_t pkt; uint64_t wait; - start = odp_time_local(); wait = odp_schedule_wait_time(ns); - + wait_time = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait_time); do { pkt = ODP_PACKET_INVALID; @@ -407,10 +409,7 @@ static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx, odp_packet_free(pkt); } - - now = odp_time_local(); - diff = odp_time_diff(now, start); - } while (odp_time_to_ns(diff) < ns); + } while (odp_time_cmp(end, odp_time_local()) > 0); CU_FAIL("failed to receive transmitted packet"); diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c index 2e157a520..7ba6a0693 100644 --- a/test/validation/scheduler/scheduler.c +++ b/test/validation/scheduler/scheduler.c @@ -48,6 +48,8 @@ #define CHAOS_NDX_TO_PTR(n) ((void *)(uintptr_t)n) #define CHAOS_WAIT_FAIL (5 * ODP_TIME_SEC_IN_NS) +#define ODP_WAIT_TOLERANCE (20 * ODP_TIME_MSEC_IN_NS) + /* Test global variables */ typedef struct { int num_workers; @@ -114,13 +116,52 @@ static int exit_schedule_loop(void) void scheduler_test_wait_time(void) { + int i; + odp_queue_t queue; uint64_t wait_time; + odp_queue_param_t qp; + odp_time_t lower_limit, upper_limit; + odp_time_t start_time, end_time, diff; + /* check on read */ wait_time = odp_schedule_wait_time(0); wait_time = odp_schedule_wait_time(1); - wait_time = odp_schedule_wait_time((uint64_t)-1LL); - CU_ASSERT(wait_time > 0); + /* check ODP_SCHED_NO_WAIT */ + odp_queue_param_init(&qp); + queue = odp_queue_create("dummy_queue", ODP_QUEUE_TYPE_SCHED, &qp); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS); + start_time = odp_time_local(); + odp_schedule(&queue, ODP_SCHED_NO_WAIT); + end_time = odp_time_local(); + + diff = odp_time_diff(end_time, start_time); + lower_limit = ODP_TIME_NULL; + upper_limit = odp_time_local_from_ns(ODP_WAIT_TOLERANCE); + + CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); + CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); + + /* check time correctness */ + start_time = odp_time_local(); + for (i = 1; i < 6; i++) { + odp_schedule(&queue, wait_time); + printf("%d..", i); + } + end_time = odp_time_local(); + + diff = odp_time_diff(end_time, start_time); + lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS - + ODP_WAIT_TOLERANCE); + upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + + ODP_WAIT_TOLERANCE); + + CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); + CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); + + CU_ASSERT_FATAL(odp_queue_destroy(queue) == 0); } void scheduler_test_num_prio(void) diff --git a/test/validation/std_clib/.gitignore b/test/validation/std_clib/.gitignore new file mode 100644 index 000000000..37828330a --- /dev/null +++ b/test/validation/std_clib/.gitignore @@ -0,0 +1 @@ +std_clib_main diff --git a/test/validation/std_clib/Makefile.am b/test/validation/std_clib/Makefile.am new file mode 100644 index 000000000..e2fc0ccf3 --- /dev/null +++ b/test/validation/std_clib/Makefile.am @@ -0,0 +1,10 @@ +include ../Makefile.inc + +noinst_LTLIBRARIES = libteststd_clib.la +libteststd_clib_la_SOURCES = std_clib.c + +test_PROGRAMS = std_clib_main$(EXEEXT) +dist_std_clib_main_SOURCES = std_clib_main.c +std_clib_main_LDADD = libteststd_clib.la $(LIBCUNIT_COMMON) $(LIBODP) + +EXTRA_DIST = std_clib.h diff --git a/test/validation/std_clib/std_clib.c b/test/validation/std_clib/std_clib.c new file mode 100644 index 000000000..e53ad3946 --- /dev/null +++ b/test/validation/std_clib/std_clib.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp.h> +#include <odp_cunit_common.h> +#include "std_clib.h" + +#include <string.h> + +#define PATTERN 0x5e + +static void std_clib_test_memcpy(void) +{ + uint8_t src[] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15}; + uint8_t dst[16]; + int ret; + + memset(dst, 0, sizeof(dst)); + + odp_memcpy(dst, src, sizeof(dst)); + + ret = memcmp(dst, src, sizeof(dst)); + + CU_ASSERT(ret == 0); +} + +static void std_clib_test_memset(void) +{ + uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15}; + uint8_t ref[16]; + int ret; + + odp_memset(data, PATTERN, sizeof(data)); + + memset(ref, PATTERN, sizeof(ref)); + + ret = memcmp(data, ref, sizeof(data)); + + CU_ASSERT(ret == 0); +} + +odp_testinfo_t std_clib_suite[] = { + ODP_TEST_INFO(std_clib_test_memcpy), + ODP_TEST_INFO(std_clib_test_memset), + ODP_TEST_INFO_NULL, +}; + +odp_suiteinfo_t std_clib_suites[] = { + {"Std C library", NULL, NULL, std_clib_suite}, + ODP_SUITE_INFO_NULL +}; + +int std_clib_main(void) +{ + int ret = odp_cunit_register(std_clib_suites); + + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/validation/std_clib/std_clib.h b/test/validation/std_clib/std_clib.h new file mode 100644 index 000000000..eab6872f1 --- /dev/null +++ b/test/validation/std_clib/std_clib.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_STD_CLIB_H_ +#define _ODP_TEST_STD_CLIB_H_ + +#include <odp_cunit_common.h> + +/* test arrays: */ +extern odp_testinfo_t std_clib_suite[]; + +/* test registry: */ +extern odp_suiteinfo_t std_clib_suites[]; + +/* main test program: */ +int std_clib_main(void); + +#endif diff --git a/test/validation/std_clib/std_clib_main.c b/test/validation/std_clib/std_clib_main.c new file mode 100644 index 000000000..010c1c6f4 --- /dev/null +++ b/test/validation/std_clib/std_clib_main.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "std_clib.h" + +int main(void) +{ + return std_clib_main(); +} diff --git a/test/validation/synchronizers/synchronizers.c b/test/validation/synchronizers/synchronizers.c index 2406c7706..0302069b8 100644 --- a/test/validation/synchronizers/synchronizers.c +++ b/test/validation/synchronizers/synchronizers.c @@ -36,6 +36,8 @@ static odp_atomic_u32_t a32u; static odp_atomic_u64_t a64u; +static volatile int temp_result; + typedef __volatile uint32_t volatile_u32_t; typedef __volatile uint64_t volatile_u64_t; @@ -63,8 +65,10 @@ typedef struct { /* Locks */ odp_spinlock_t global_spinlock; + odp_spinlock_recursive_t global_recursive_spinlock; odp_ticketlock_t global_ticketlock; odp_rwlock_t global_rwlock; + odp_rwlock_recursive_t global_recursive_rwlock; volatile_u32_t global_lock_owner; } global_shared_mem_t; @@ -77,8 +81,10 @@ typedef struct { int thread_core; odp_spinlock_t per_thread_spinlock; + odp_spinlock_recursive_t per_thread_recursive_spinlock; odp_ticketlock_t per_thread_ticketlock; odp_rwlock_t per_thread_rwlock; + odp_rwlock_recursive_t per_thread_recursive_rwlock; volatile_u64_t delay_counter; } per_thread_mem_t; @@ -220,12 +226,12 @@ static uint32_t barrier_test(per_thread_mem_t *per_thread_mem, odp_barrier_wait(&global_mem->test_barriers[cnt]); global_mem->barrier_cnt1 = cnt + 1; - odp_sync_stores(); + odp_mb_full(); if (i_am_slow_thread) { global_mem->slow_thread_num = next_slow_thread; global_mem->barrier_cnt2 = cnt + 1; - odp_sync_stores(); + odp_mb_full(); } else { while (global_mem->barrier_cnt2 != (cnt + 1)) thread_delay(per_thread_mem, BASE_DELAY); @@ -314,6 +320,56 @@ static void *spinlock_api_tests(void *arg UNUSED) return NULL; } +static void spinlock_recursive_api_test(odp_spinlock_recursive_t *spinlock) +{ + odp_spinlock_recursive_init(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 0); + + odp_spinlock_recursive_lock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + odp_spinlock_recursive_lock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + odp_spinlock_recursive_unlock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + odp_spinlock_recursive_unlock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 0); + + CU_ASSERT(odp_spinlock_recursive_trylock(spinlock) == 1); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + CU_ASSERT(odp_spinlock_recursive_trylock(spinlock) == 1); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + odp_spinlock_recursive_unlock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 1); + + odp_spinlock_recursive_unlock(spinlock); + CU_ASSERT(odp_spinlock_recursive_is_locked(spinlock) == 0); +} + +static void *spinlock_recursive_api_tests(void *arg UNUSED) +{ + global_shared_mem_t *global_mem; + per_thread_mem_t *per_thread_mem; + odp_spinlock_recursive_t local_recursive_spin_lock; + + per_thread_mem = thread_init(); + global_mem = per_thread_mem->global_mem; + + odp_barrier_wait(&global_mem->global_barrier); + + spinlock_recursive_api_test(&local_recursive_spin_lock); + spinlock_recursive_api_test( + &per_thread_mem->per_thread_recursive_spinlock); + + thread_finalize(per_thread_mem); + + return NULL; +} + static void ticketlock_api_test(odp_ticketlock_t *ticketlock) { odp_ticketlock_init(ticketlock); @@ -386,6 +442,45 @@ static void *rwlock_api_tests(void *arg UNUSED) return NULL; } +static void rwlock_recursive_api_test(odp_rwlock_recursive_t *rw_lock) +{ + odp_rwlock_recursive_init(rw_lock); + /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 0); */ + + odp_rwlock_recursive_read_lock(rw_lock); + odp_rwlock_recursive_read_lock(rw_lock); + + odp_rwlock_recursive_read_unlock(rw_lock); + odp_rwlock_recursive_read_unlock(rw_lock); + + odp_rwlock_recursive_write_lock(rw_lock); + odp_rwlock_recursive_write_lock(rw_lock); + /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 1); */ + + odp_rwlock_recursive_write_unlock(rw_lock); + odp_rwlock_recursive_write_unlock(rw_lock); + /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 0); */ +} + +static void *rwlock_recursive_api_tests(void *arg UNUSED) +{ + global_shared_mem_t *global_mem; + per_thread_mem_t *per_thread_mem; + odp_rwlock_recursive_t local_recursive_rwlock; + + per_thread_mem = thread_init(); + global_mem = per_thread_mem->global_mem; + + odp_barrier_wait(&global_mem->global_barrier); + + rwlock_recursive_api_test(&local_recursive_rwlock); + rwlock_recursive_api_test(&per_thread_mem->per_thread_recursive_rwlock); + + thread_finalize(per_thread_mem); + + return NULL; +} + static void *no_lock_functional_test(void *arg UNUSED) { global_shared_mem_t *global_mem; @@ -408,7 +503,7 @@ static void *no_lock_functional_test(void *arg UNUSED) for (cnt = 1; cnt <= iterations; cnt++) { global_mem->global_lock_owner = thread_num; - odp_sync_stores(); + odp_mb_full(); thread_delay(per_thread_mem, lock_owner_delay); if (global_mem->global_lock_owner != thread_num) { @@ -417,7 +512,7 @@ static void *no_lock_functional_test(void *arg UNUSED) } global_mem->global_lock_owner = 0; - odp_sync_stores(); + odp_mb_full(); thread_delay(per_thread_mem, MIN_DELAY); if (global_mem->global_lock_owner == thread_num) { @@ -498,7 +593,7 @@ static void *spinlock_functional_test(void *arg UNUSED) * global_lock_owner to be themselves */ global_mem->global_lock_owner = thread_num; - odp_sync_stores(); + odp_mb_full(); thread_delay(per_thread_mem, lock_owner_delay); if (global_mem->global_lock_owner != thread_num) { current_errs++; @@ -507,7 +602,7 @@ static void *spinlock_functional_test(void *arg UNUSED) /* Release shared lock, and make sure we no longer have it */ global_mem->global_lock_owner = 0; - odp_sync_stores(); + odp_mb_full(); odp_spinlock_unlock(&global_mem->global_spinlock); if (global_mem->global_lock_owner == thread_num) { current_errs++; @@ -543,6 +638,115 @@ static void *spinlock_functional_test(void *arg UNUSED) return NULL; } +static void *spinlock_recursive_functional_test(void *arg UNUSED) +{ + global_shared_mem_t *global_mem; + per_thread_mem_t *per_thread_mem; + uint32_t thread_num, resync_cnt, rs_idx, iterations, cnt; + uint32_t sync_failures, recursive_errs, is_locked_errs, current_errs; + uint32_t lock_owner_delay; + + thread_num = odp_cpu_id() + 1; + per_thread_mem = thread_init(); + global_mem = per_thread_mem->global_mem; + iterations = global_mem->g_iterations; + + odp_barrier_wait(&global_mem->global_barrier); + + sync_failures = 0; + recursive_errs = 0; + is_locked_errs = 0; + current_errs = 0; + rs_idx = 0; + resync_cnt = iterations / NUM_RESYNC_BARRIERS; + lock_owner_delay = BASE_DELAY; + + for (cnt = 1; cnt <= iterations; cnt++) { + /* Acquire the shared global lock */ + odp_spinlock_recursive_lock( + &global_mem->global_recursive_spinlock); + + /* Make sure we have the lock AND didn't previously own it */ + if (odp_spinlock_recursive_is_locked( + &global_mem->global_recursive_spinlock) != 1) + is_locked_errs++; + + if (global_mem->global_lock_owner != 0) { + current_errs++; + sync_failures++; + } + + /* Now set the global_lock_owner to be us, wait a while, and + * then we see if anyone else has snuck in and changed the + * global_lock_owner to be themselves + */ + global_mem->global_lock_owner = thread_num; + odp_mb_full(); + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + sync_failures++; + } + + /* Verify that we can acquire the lock recursively */ + odp_spinlock_recursive_lock( + &global_mem->global_recursive_spinlock); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + recursive_errs++; + } + + /* Release the lock and verify that we still have it*/ + odp_spinlock_recursive_unlock( + &global_mem->global_recursive_spinlock); + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + recursive_errs++; + } + + /* Release shared lock, and make sure we no longer have it */ + global_mem->global_lock_owner = 0; + odp_mb_full(); + odp_spinlock_recursive_unlock( + &global_mem->global_recursive_spinlock); + if (global_mem->global_lock_owner == thread_num) { + current_errs++; + sync_failures++; + } + + if (current_errs == 0) + lock_owner_delay++; + + /* Wait a small amount of time and rerun the test */ + thread_delay(per_thread_mem, BASE_DELAY); + + /* Try to resync all of the threads to increase contention */ + if ((rs_idx < NUM_RESYNC_BARRIERS) && + ((cnt % resync_cnt) == (resync_cnt - 1))) + odp_barrier_wait(&global_mem->barrier_array[rs_idx++]); + } + + if ((global_mem->g_verbose) && + (sync_failures != 0 || recursive_errs != 0 || is_locked_errs != 0)) + printf("\nThread %" PRIu32 " (id=%d core=%d) had %" PRIu32 + " sync_failures and %" PRIu32 + " recursive_errs and %" PRIu32 + " is_locked_errs in %" PRIu32 + " iterations\n", thread_num, + per_thread_mem->thread_id, per_thread_mem->thread_core, + sync_failures, recursive_errs, is_locked_errs, + iterations); + + CU_ASSERT(sync_failures == 0); + CU_ASSERT(recursive_errs == 0); + CU_ASSERT(is_locked_errs == 0); + + thread_finalize(per_thread_mem); + + return NULL; +} + static void *ticketlock_functional_test(void *arg UNUSED) { global_shared_mem_t *global_mem; @@ -585,7 +789,7 @@ static void *ticketlock_functional_test(void *arg UNUSED) * global_lock_owner to be themselves */ global_mem->global_lock_owner = thread_num; - odp_sync_stores(); + odp_mb_full(); thread_delay(per_thread_mem, lock_owner_delay); if (global_mem->global_lock_owner != thread_num) { current_errs++; @@ -594,7 +798,7 @@ static void *ticketlock_functional_test(void *arg UNUSED) /* Release shared lock, and make sure we no longer have it */ global_mem->global_lock_owner = 0; - odp_sync_stores(); + odp_mb_full(); odp_ticketlock_unlock(&global_mem->global_ticketlock); if (global_mem->global_lock_owner == thread_num) { current_errs++; @@ -652,6 +856,19 @@ static void *rwlock_functional_test(void *arg UNUSED) lock_owner_delay = BASE_DELAY; for (cnt = 1; cnt <= iterations; cnt++) { + /* Verify that we can obtain a read lock */ + odp_rwlock_read_lock(&global_mem->global_rwlock); + + /* Verify lock is unowned (no writer holds it) */ + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != 0) { + current_errs++; + sync_failures++; + } + + /* Release the read lock */ + odp_rwlock_read_unlock(&global_mem->global_rwlock); + /* Acquire the shared global lock */ odp_rwlock_write_lock(&global_mem->global_rwlock); @@ -666,7 +883,7 @@ static void *rwlock_functional_test(void *arg UNUSED) * global_lock_owner to be themselves */ global_mem->global_lock_owner = thread_num; - odp_sync_stores(); + odp_mb_full(); thread_delay(per_thread_mem, lock_owner_delay); if (global_mem->global_lock_owner != thread_num) { current_errs++; @@ -675,7 +892,7 @@ static void *rwlock_functional_test(void *arg UNUSED) /* Release shared lock, and make sure we no longer have it */ global_mem->global_lock_owner = 0; - odp_sync_stores(); + odp_mb_full(); odp_rwlock_write_unlock(&global_mem->global_rwlock); if (global_mem->global_lock_owner == thread_num) { current_errs++; @@ -708,6 +925,136 @@ static void *rwlock_functional_test(void *arg UNUSED) return NULL; } +static void *rwlock_recursive_functional_test(void *arg UNUSED) +{ + global_shared_mem_t *global_mem; + per_thread_mem_t *per_thread_mem; + uint32_t thread_num, resync_cnt, rs_idx, iterations, cnt; + uint32_t sync_failures, recursive_errs, current_errs, lock_owner_delay; + + thread_num = odp_cpu_id() + 1; + per_thread_mem = thread_init(); + global_mem = per_thread_mem->global_mem; + iterations = global_mem->g_iterations; + + /* Wait here until all of the threads have also reached this point */ + odp_barrier_wait(&global_mem->global_barrier); + + sync_failures = 0; + recursive_errs = 0; + current_errs = 0; + rs_idx = 0; + resync_cnt = iterations / NUM_RESYNC_BARRIERS; + lock_owner_delay = BASE_DELAY; + + for (cnt = 1; cnt <= iterations; cnt++) { + /* Verify that we can obtain a read lock */ + odp_rwlock_recursive_read_lock( + &global_mem->global_recursive_rwlock); + + /* Verify lock is unowned (no writer holds it) */ + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != 0) { + current_errs++; + sync_failures++; + } + + /* Verify we can get read lock recursively */ + odp_rwlock_recursive_read_lock( + &global_mem->global_recursive_rwlock); + + /* Verify lock is unowned (no writer holds it) */ + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != 0) { + current_errs++; + sync_failures++; + } + + /* Release the read lock */ + odp_rwlock_recursive_read_unlock( + &global_mem->global_recursive_rwlock); + odp_rwlock_recursive_read_unlock( + &global_mem->global_recursive_rwlock); + + /* Acquire the shared global lock */ + odp_rwlock_recursive_write_lock( + &global_mem->global_recursive_rwlock); + + /* Make sure we have lock now AND didn't previously own it */ + if (global_mem->global_lock_owner != 0) { + current_errs++; + sync_failures++; + } + + /* Now set the global_lock_owner to be us, wait a while, and + * then we see if anyone else has snuck in and changed the + * global_lock_owner to be themselves + */ + global_mem->global_lock_owner = thread_num; + odp_mb_full(); + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + sync_failures++; + } + + /* Acquire it again and verify we still own it */ + odp_rwlock_recursive_write_lock( + &global_mem->global_recursive_rwlock); + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + recursive_errs++; + } + + /* Release the recursive lock and make sure we still own it */ + odp_rwlock_recursive_write_unlock( + &global_mem->global_recursive_rwlock); + thread_delay(per_thread_mem, lock_owner_delay); + if (global_mem->global_lock_owner != thread_num) { + current_errs++; + recursive_errs++; + } + + /* Release shared lock, and make sure we no longer have it */ + global_mem->global_lock_owner = 0; + odp_mb_full(); + odp_rwlock_recursive_write_unlock( + &global_mem->global_recursive_rwlock); + if (global_mem->global_lock_owner == thread_num) { + current_errs++; + sync_failures++; + } + + if (current_errs == 0) + lock_owner_delay++; + + /* Wait a small amount of time and then rerun the test */ + thread_delay(per_thread_mem, BASE_DELAY); + + /* Try to resync all of the threads to increase contention */ + if ((rs_idx < NUM_RESYNC_BARRIERS) && + ((cnt % resync_cnt) == (resync_cnt - 1))) + odp_barrier_wait(&global_mem->barrier_array[rs_idx++]); + } + + if ((global_mem->g_verbose) && (sync_failures != 0)) + printf("\nThread %" PRIu32 " (id=%d core=%d) had %" PRIu32 + " sync_failures and %" PRIu32 + " recursive_errs in %" PRIu32 + " iterations\n", thread_num, + per_thread_mem->thread_id, + per_thread_mem->thread_core, + sync_failures, recursive_errs, iterations); + + CU_ASSERT(sync_failures == 0); + CU_ASSERT(recursive_errs == 0); + + thread_finalize(per_thread_mem); + + return NULL; +} + static void barrier_test_init(void) { uint32_t num_threads, idx; @@ -922,6 +1269,26 @@ static void test_atomic_validate(void) } /* Barrier tests */ +void synchronizers_test_memory_barrier(void) +{ + volatile int a = 0; + volatile int b = 0; + volatile int c = 0; + volatile int d = 0; + + /* Call all memory barriers to verify that those are implemented */ + a = 1; + odp_mb_release(); + b = 1; + odp_mb_acquire(); + c = 1; + odp_mb_full(); + d = 1; + + /* Avoid "variable set but not used" warning */ + temp_result = a + b + c + d; +} + void synchronizers_test_no_barrier_functional(void) { pthrd_arg arg; @@ -943,6 +1310,7 @@ void synchronizers_test_barrier_functional(void) } odp_testinfo_t synchronizers_suite_barrier[] = { + ODP_TEST_INFO(synchronizers_test_memory_barrier), ODP_TEST_INFO(synchronizers_test_no_barrier_functional), ODP_TEST_INFO(synchronizers_test_barrier_functional), ODP_TEST_INFO_NULL @@ -983,12 +1351,37 @@ void synchronizers_test_spinlock_functional(void) odp_cunit_thread_exit(&arg); } +void synchronizers_test_spinlock_recursive_api(void) +{ + pthrd_arg arg; + + arg.numthrds = global_mem->g_num_threads; + odp_cunit_thread_create(spinlock_recursive_api_tests, &arg); + odp_cunit_thread_exit(&arg); +} + +void synchronizers_test_spinlock_recursive_functional(void) +{ + pthrd_arg arg; + + arg.numthrds = global_mem->g_num_threads; + odp_spinlock_recursive_init(&global_mem->global_recursive_spinlock); + odp_cunit_thread_create(spinlock_recursive_functional_test, &arg); + odp_cunit_thread_exit(&arg); +} + odp_testinfo_t synchronizers_suite_spinlock[] = { ODP_TEST_INFO(synchronizers_test_spinlock_api), ODP_TEST_INFO(synchronizers_test_spinlock_functional), ODP_TEST_INFO_NULL }; +odp_testinfo_t synchronizers_suite_spinlock_recursive[] = { + ODP_TEST_INFO(synchronizers_test_spinlock_recursive_api), + ODP_TEST_INFO(synchronizers_test_spinlock_recursive_functional), + ODP_TEST_INFO_NULL +}; + /* Ticket lock tests */ void synchronizers_test_ticketlock_api(void) { @@ -1042,6 +1435,31 @@ odp_testinfo_t synchronizers_suite_rwlock[] = { ODP_TEST_INFO_NULL }; +void synchronizers_test_rwlock_recursive_api(void) +{ + pthrd_arg arg; + + arg.numthrds = global_mem->g_num_threads; + odp_cunit_thread_create(rwlock_recursive_api_tests, &arg); + odp_cunit_thread_exit(&arg); +} + +void synchronizers_test_rwlock_recursive_functional(void) +{ + pthrd_arg arg; + + arg.numthrds = global_mem->g_num_threads; + odp_rwlock_recursive_init(&global_mem->global_recursive_rwlock); + odp_cunit_thread_create(rwlock_recursive_functional_test, &arg); + odp_cunit_thread_exit(&arg); +} + +odp_testinfo_t synchronizers_suite_rwlock_recursive[] = { + ODP_TEST_INFO(synchronizers_test_rwlock_recursive_api), + ODP_TEST_INFO(synchronizers_test_rwlock_recursive_functional), + ODP_TEST_INFO_NULL +}; + int synchronizers_suite_init(void) { uint32_t num_threads, idx; @@ -1203,10 +1621,14 @@ odp_suiteinfo_t synchronizers_suites[] = { synchronizers_suite_no_locking}, {"spinlock", synchronizers_suite_init, NULL, synchronizers_suite_spinlock}, + {"spinlock_recursive", synchronizers_suite_init, NULL, + synchronizers_suite_spinlock_recursive}, {"ticketlock", synchronizers_suite_init, NULL, synchronizers_suite_ticketlock}, {"rwlock", synchronizers_suite_init, NULL, synchronizers_suite_rwlock}, + {"rwlock_recursive", synchronizers_suite_init, NULL, + synchronizers_suite_rwlock_recursive}, {"atomic", NULL, NULL, synchronizers_suite_atomic}, ODP_SUITE_INFO_NULL diff --git a/test/validation/synchronizers/synchronizers.h b/test/validation/synchronizers/synchronizers.h index f16477cb9..ad8db0b2e 100644 --- a/test/validation/synchronizers/synchronizers.h +++ b/test/validation/synchronizers/synchronizers.h @@ -10,15 +10,20 @@ #include <odp_cunit_common.h> /* test functions: */ +void synchronizers_test_memory_barrier(void); void synchronizers_test_no_barrier_functional(void); void synchronizers_test_barrier_functional(void); void synchronizers_test_no_lock_functional(void); void synchronizers_test_spinlock_api(void); void synchronizers_test_spinlock_functional(void); +void synchronizers_test_spinlock_recursive_api(void); +void synchronizers_test_spinlock_recursive_functional(void); void synchronizers_test_ticketlock_api(void); void synchronizers_test_ticketlock_functional(void); void synchronizers_test_rwlock_api(void); void synchronizers_test_rwlock_functional(void); +void synchronizers_test_rwlock_recursive_api(void); +void synchronizers_test_rwlock_recursive_functional(void); void synchronizers_test_atomic_inc_dec(void); void synchronizers_test_atomic_add_sub(void); void synchronizers_test_atomic_fetch_inc_dec(void); @@ -28,8 +33,10 @@ void synchronizers_test_atomic_fetch_add_sub(void); extern odp_testinfo_t synchronizers_suite_barrier[]; extern odp_testinfo_t synchronizers_suite_no_locking[]; extern odp_testinfo_t synchronizers_suite_spinlock[]; +extern odp_testinfo_t synchronizers_suite_spinlock_recursive[]; extern odp_testinfo_t synchronizers_suite_ticketlock[]; extern odp_testinfo_t synchronizers_suite_rwlock[]; +extern odp_testinfo_t synchronizers_suite_rwlock_recursive[]; extern odp_testinfo_t synchronizers_suite_atomic[]; /* test array init/term functions: */ diff --git a/test/validation/time/time.c b/test/validation/time/time.c index f70c7768a..8b469b02c 100644 --- a/test/validation/time/time.c +++ b/test/validation/time/time.c @@ -8,64 +8,424 @@ #include "odp_cunit_common.h" #include "time.h" -#define TOLERANCE 1 -#define BUSY_LOOP_CNT 100 +#define BUSY_LOOP_CNT 30000000 /* used for t > min resolution */ +#define BUSY_LOOP_CNT_LONG 12000000000 /* used for t > 4 sec */ +#define MIN_TIME_RATE 32000 +#define MAX_TIME_RATE 15000000000 +#define DELAY_TOLERANCE 20000000 /* deviation for delay */ + +static uint64_t local_res; +static uint64_t global_res; + +typedef odp_time_t time_cb(void); +typedef uint64_t time_res_cb(void); +typedef odp_time_t time_from_ns_cb(uint64_t ns); + +void time_test_constants(void) +{ + uint64_t ns; + + ns = ODP_TIME_SEC_IN_NS / 1000; + CU_ASSERT(ns == ODP_TIME_MSEC_IN_NS); + ns /= 1000; + CU_ASSERT(ns == ODP_TIME_USEC_IN_NS); +} + +static void time_test_res(time_res_cb time_res, uint64_t res) +{ + uint64_t rate; + + rate = time_res(); + CU_ASSERT(rate > MIN_TIME_RATE); + CU_ASSERT(rate < MAX_TIME_RATE); + + res = ODP_TIME_SEC_IN_NS / rate; + res = res ? res : 1; +} + +void time_test_local_res(void) +{ + time_test_res(odp_time_local_res, local_res); +} + +void time_test_global_res(void) +{ + time_test_res(odp_time_global_res, global_res); +} + +/* check that related conversions come back to the same value */ +static void time_test_conversion(time_from_ns_cb time_from_ns, uint64_t res) +{ + uint64_t ns1, ns2; + odp_time_t time; + uint64_t upper_limit, lower_limit; + + ns1 = 100; + time = time_from_ns(ns1); + + ns2 = odp_time_to_ns(time); + + /* need to check within arithmetic tolerance that the same + * value in ns is returned after conversions */ + upper_limit = ns1 + res; + lower_limit = ns1 - res; + CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + + ns1 = 60 * 11 * ODP_TIME_SEC_IN_NS; + time = time_from_ns(ns1); + + ns2 = odp_time_to_ns(time); + + /* need to check within arithmetic tolerance that the same + * value in ns is returned after conversions */ + upper_limit = ns1 + res; + lower_limit = ns1 - res; + CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + + /* test on 0 */ + ns1 = odp_time_to_ns(ODP_TIME_NULL); + CU_ASSERT(ns1 == 0); +} + +void time_test_local_conversion(void) +{ + time_test_conversion(odp_time_local_from_ns, local_res); +} + +void time_test_global_conversion(void) +{ + time_test_conversion(odp_time_global_from_ns, global_res); +} + +static void time_test_monotony(time_cb time) +{ + volatile uint64_t count = 0; + odp_time_t t1, t2, t3; + uint64_t ns1, ns2, ns3; + + t1 = time(); + + while (count < BUSY_LOOP_CNT) { + count++; + }; + + t2 = time(); + + while (count < BUSY_LOOP_CNT_LONG) { + count++; + }; + + t3 = time(); + + ns1 = odp_time_to_ns(t1); + ns2 = odp_time_to_ns(t2); + ns3 = odp_time_to_ns(t3); + + CU_ASSERT(ns2 > ns1); + CU_ASSERT(ns3 > ns2); +} + +void time_test_local_monotony(void) +{ + time_test_monotony(odp_time_local); +} + +void time_test_global_monotony(void) +{ + time_test_monotony(odp_time_global); +} + +static void time_test_cmp(time_cb time, time_from_ns_cb time_from_ns) +{ + /* volatile to stop optimization of busy loop */ + volatile int count = 0; + odp_time_t t1, t2, t3; + + t1 = time(); + + while (count < BUSY_LOOP_CNT) { + count++; + }; + + t2 = time(); + + while (count < BUSY_LOOP_CNT * 2) { + count++; + }; + + t3 = time(); + + CU_ASSERT(odp_time_cmp(t2, t1) > 0); + CU_ASSERT(odp_time_cmp(t3, t2) > 0); + CU_ASSERT(odp_time_cmp(t3, t1) > 0); + CU_ASSERT(odp_time_cmp(t1, t2) < 0); + CU_ASSERT(odp_time_cmp(t2, t3) < 0); + CU_ASSERT(odp_time_cmp(t1, t3) < 0); + CU_ASSERT(odp_time_cmp(t1, t1) == 0); + CU_ASSERT(odp_time_cmp(t2, t2) == 0); + CU_ASSERT(odp_time_cmp(t3, t3) == 0); + + t2 = time_from_ns(60 * 10 * ODP_TIME_SEC_IN_NS); + t1 = time_from_ns(3); + + CU_ASSERT(odp_time_cmp(t2, t1) > 0); + CU_ASSERT(odp_time_cmp(t1, t2) < 0); + + t1 = time_from_ns(0); + CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0); +} + +void time_test_local_cmp(void) +{ + time_test_cmp(odp_time_local, odp_time_local_from_ns); +} + +void time_test_global_cmp(void) +{ + time_test_cmp(odp_time_global, odp_time_global_from_ns); +} /* check that a time difference gives a reasonable result */ -void time_test_odp_diff(void) +static void time_test_diff(time_cb time, + time_from_ns_cb time_from_ns, + uint64_t res) { /* volatile to stop optimization of busy loop */ volatile int count = 0; odp_time_t diff, t1, t2; + uint64_t nsdiff, ns1, ns2, ns; + uint64_t upper_limit, lower_limit; - t1 = odp_time_local(); + /* test timestamp diff */ + t1 = time(); while (count < BUSY_LOOP_CNT) { count++; }; - t2 = odp_time_local(); + t2 = time(); CU_ASSERT(odp_time_cmp(t2, t1) > 0); diff = odp_time_diff(t2, t1); CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0); -} -/* check that a negative time difference gives a reasonable result */ -void time_test_odp_negative_diff(void) -{ - odp_time_t diff, t1, t2; + ns1 = odp_time_to_ns(t1); + ns2 = odp_time_to_ns(t2); + ns = ns2 - ns1; + nsdiff = odp_time_to_ns(diff); + + upper_limit = ns + res; + lower_limit = ns - res; + CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); + + /* test timestamp and interval diff */ + ns1 = 54; + t1 = time_from_ns(ns1); + ns = ns2 - ns1; - t1 = 10; - t2 = 5; diff = odp_time_diff(t2, t1); CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0); + nsdiff = odp_time_to_ns(diff); + + upper_limit = ns + res; + lower_limit = ns - res; + CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); + + /* test interval diff */ + ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS; + ns = ns2 - ns1; + + t2 = time_from_ns(ns2); + diff = odp_time_diff(t2, t1); + CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0); + nsdiff = odp_time_to_ns(diff); + + upper_limit = ns + res; + lower_limit = ns - res; + CU_ASSERT((nsdiff <= upper_limit) && (nsdiff >= lower_limit)); + + /* same time has to diff to 0 */ + diff = odp_time_diff(t2, t2); + CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0); + + diff = odp_time_diff(t2, ODP_TIME_NULL); + CU_ASSERT(odp_time_cmp(t2, diff) == 0); } -/* check that related conversions come back to the same value */ -void time_test_odp_conversion(void) +void time_test_local_diff(void) { - uint64_t ns1, ns2; - odp_time_t time; + time_test_diff(odp_time_local, odp_time_local_from_ns, local_res); +} + +void time_test_global_diff(void) +{ + time_test_diff(odp_time_global, odp_time_global_from_ns, global_res); +} + +/* check that a time sum gives a reasonable result */ +static void time_test_sum(time_cb time, + time_from_ns_cb time_from_ns, + uint64_t res) +{ + odp_time_t sum, t1, t2; + uint64_t nssum, ns1, ns2, ns; uint64_t upper_limit, lower_limit; - ns1 = 100; - time = odp_time_local_from_ns(ns1); - CU_ASSERT(odp_time_cmp(time, ODP_TIME_NULL) > 0); + /* sum timestamp and interval */ + t1 = time(); + ns2 = 103; + t2 = time_from_ns(ns2); + ns1 = odp_time_to_ns(t1); + ns = ns1 + ns2; - ns2 = odp_time_to_ns(time); + sum = odp_time_sum(t2, t1); + CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0); + nssum = odp_time_to_ns(sum); - /* need to check within arithmetic tolerance that the same - * value in ns is returned after conversions */ - upper_limit = ns1 + TOLERANCE; - lower_limit = ns1 - TOLERANCE; - CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit)); + upper_limit = ns + res; + lower_limit = ns - res; + CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit)); + + /* sum intervals */ + ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS; + t1 = time_from_ns(ns1); + ns = ns1 + ns2; + + sum = odp_time_sum(t2, t1); + CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0); + nssum = odp_time_to_ns(sum); + + upper_limit = ns + res; + lower_limit = ns - res; + CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit)); + + /* test on 0 */ + sum = odp_time_sum(t2, ODP_TIME_NULL); + CU_ASSERT(odp_time_cmp(t2, sum) == 0); +} + +void time_test_local_sum(void) +{ + time_test_sum(odp_time_local, odp_time_local_from_ns, local_res); +} + +void time_test_global_sum(void) +{ + time_test_sum(odp_time_global, odp_time_global_from_ns, global_res); +} + +static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) +{ + int i; + odp_time_t lower_limit, upper_limit; + odp_time_t start_time, end_time, wait; + odp_time_t second = time_from_ns(ODP_TIME_SEC_IN_NS); + + start_time = time(); + wait = start_time; + for (i = 1; i < 6; i++) { + wait = odp_time_sum(wait, second); + odp_time_wait_until(wait); + printf("%d..", i); + } + end_time = time(); + + wait = odp_time_diff(end_time, start_time); + lower_limit = time_from_ns(5 * ODP_TIME_SEC_IN_NS - DELAY_TOLERANCE); + upper_limit = time_from_ns(5 * ODP_TIME_SEC_IN_NS + DELAY_TOLERANCE); + + CU_ASSERT(odp_time_cmp(wait, lower_limit) >= 0); + CU_ASSERT(odp_time_cmp(wait, upper_limit) <= 0); +} + +void time_test_local_wait_until(void) +{ + time_test_wait_until(odp_time_local, odp_time_local_from_ns); +} + +void time_test_global_wait_until(void) +{ + time_test_wait_until(odp_time_global, odp_time_global_from_ns); +} + +void time_test_wait_ns(void) +{ + int i; + odp_time_t lower_limit, upper_limit; + odp_time_t start_time, end_time, diff; + + start_time = odp_time_local(); + for (i = 1; i < 6; i++) { + odp_time_wait_ns(ODP_TIME_SEC_IN_NS); + printf("%d..", i); + } + end_time = odp_time_local(); + + diff = odp_time_diff(end_time, start_time); + + lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS - + DELAY_TOLERANCE); + upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS + + DELAY_TOLERANCE); + + CU_ASSERT(odp_time_cmp(diff, lower_limit) >= 0); + CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0); +} + +static void time_test_to_u64(time_cb time) +{ + volatile int count = 0; + uint64_t val1, val2; + odp_time_t t1, t2; + + t1 = time(); + + val1 = odp_time_to_u64(t1); + CU_ASSERT(val1 > 0); + + while (count < BUSY_LOOP_CNT) { + count++; + }; + + t2 = time(); + val2 = odp_time_to_u64(t2); + CU_ASSERT(val2 > 0); + + CU_ASSERT(val2 > val1); + + val1 = odp_time_to_u64(ODP_TIME_NULL); + CU_ASSERT(val1 == 0); +} + +void time_test_local_to_u64(void) +{ + time_test_to_u64(odp_time_local); +} + +void time_test_global_to_u64(void) +{ + time_test_to_u64(odp_time_global); } odp_testinfo_t time_suite_time[] = { - ODP_TEST_INFO(time_test_odp_diff), - ODP_TEST_INFO(time_test_odp_negative_diff), - ODP_TEST_INFO(time_test_odp_conversion), + ODP_TEST_INFO(time_test_constants), + ODP_TEST_INFO(time_test_local_res), + ODP_TEST_INFO(time_test_local_conversion), + ODP_TEST_INFO(time_test_local_monotony), + ODP_TEST_INFO(time_test_local_cmp), + ODP_TEST_INFO(time_test_local_diff), + ODP_TEST_INFO(time_test_local_sum), + ODP_TEST_INFO(time_test_local_wait_until), + ODP_TEST_INFO(time_test_wait_ns), + ODP_TEST_INFO(time_test_local_to_u64), + ODP_TEST_INFO(time_test_global_res), + ODP_TEST_INFO(time_test_global_conversion), + ODP_TEST_INFO(time_test_global_monotony), + ODP_TEST_INFO(time_test_global_cmp), + ODP_TEST_INFO(time_test_global_diff), + ODP_TEST_INFO(time_test_global_sum), + ODP_TEST_INFO(time_test_global_wait_until), + ODP_TEST_INFO(time_test_global_to_u64), ODP_TEST_INFO_NULL }; diff --git a/test/validation/time/time.h b/test/validation/time/time.h index b4e613c0b..d75b0f58d 100644 --- a/test/validation/time/time.h +++ b/test/validation/time/time.h @@ -10,9 +10,24 @@ #include <odp_cunit_common.h> /* test functions: */ -void time_test_odp_diff(void); -void time_test_odp_conversion(void); -void time_test_odp_negative_diff(void); +void time_test_constants(void); +void time_test_local_res(void); +void time_test_global_res(void); +void time_test_local_conversion(void); +void time_test_global_conversion(void); +void time_test_local_monotony(void); +void time_test_global_monotony(void); +void time_test_local_cmp(void); +void time_test_global_cmp(void); +void time_test_local_diff(void); +void time_test_global_diff(void); +void time_test_local_sum(void); +void time_test_global_sum(void); +void time_test_local_wait_until(void); +void time_test_global_wait_until(void); +void time_test_wait_ns(void); +void time_test_local_to_u64(void); +void time_test_global_to_u64(void); /* test arrays: */ extern odp_testinfo_t time_suite_time[]; |