void queue_test_sunnydays(void) { odp_queue_t queue_creat_id, queue_id; odp_event_t enev[MAX_BUFFER_QUEUE]; odp_event_t deev[MAX_BUFFER_QUEUE]; odp_buffer_t buf; odp_event_t ev; odp_pool_t msg_pool; odp_event_t *pev_tmp; int i, deq_ret, ret; int nr_deq_entries = 0; int max_iteration = CONFIG_MAX_ITERATION; void *prtn = NULL; odp_queue_param_t qparams; odp_queue_param_init(&qparams); qparams.type = ODP_QUEUE_TYPE_SCHED; qparams.sched.prio = ODP_SCHED_PRIO_LOWEST; qparams.sched.sync = ODP_SCHED_SYNC_PARALLEL; qparams.sched.group = ODP_SCHED_GROUP_WORKER; queue_creat_id = odp_queue_create("test_queue", &qparams); CU_ASSERT(ODP_QUEUE_INVALID != queue_creat_id); CU_ASSERT(odp_queue_to_u64(queue_creat_id) != odp_queue_to_u64(ODP_QUEUE_INVALID)); CU_ASSERT_EQUAL(ODP_QUEUE_TYPE_SCHED, odp_queue_type(queue_creat_id)); queue_id = odp_queue_lookup("test_queue"); CU_ASSERT_EQUAL(queue_creat_id, queue_id); CU_ASSERT_EQUAL(ODP_SCHED_GROUP_WORKER, odp_queue_sched_group(queue_id)); CU_ASSERT_EQUAL(ODP_SCHED_PRIO_LOWEST, odp_queue_sched_prio(queue_id)); CU_ASSERT_EQUAL(ODP_SCHED_SYNC_PARALLEL, odp_queue_sched_type(queue_id)); CU_ASSERT(0 == odp_queue_context_set(queue_id, &queue_contest)); prtn = odp_queue_context(queue_id); CU_ASSERT(&queue_contest == (int *)prtn); msg_pool = odp_pool_lookup("msg_pool"); buf = odp_buffer_alloc(msg_pool); CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID); ev = odp_buffer_to_event(buf); if (!(CU_ASSERT(odp_queue_enq(queue_id, ev) == 0))) { odp_buffer_free(buf); } else { CU_ASSERT_EQUAL(ev, odp_queue_deq(queue_id)); odp_buffer_free(buf); } for (i = 0; i < MAX_BUFFER_QUEUE; i++) { odp_buffer_t buf = odp_buffer_alloc(msg_pool); enev[i] = odp_buffer_to_event(buf); } /* * odp_queue_enq_multi may return 0..n buffers due to the resource * constraints in the implementation at that given point of time. * But here we assume that we succeed in enqueuing all buffers. */ ret = odp_queue_enq_multi(queue_id, enev, MAX_BUFFER_QUEUE); CU_ASSERT(MAX_BUFFER_QUEUE == ret); i = ret < 0 ? 0 : ret; for ( ; i < MAX_BUFFER_QUEUE; i++) odp_event_free(enev[i]); pev_tmp = deev; do { deq_ret = odp_queue_deq_multi(queue_id, pev_tmp, MAX_BUFFER_QUEUE); nr_deq_entries += deq_ret; max_iteration--; pev_tmp += deq_ret; CU_ASSERT(max_iteration >= 0); } while (nr_deq_entries < MAX_BUFFER_QUEUE); for (i = 0; i < MAX_BUFFER_QUEUE; i++) { odp_buffer_t enbuf = odp_buffer_from_event(enev[i]); CU_ASSERT_EQUAL(enev[i], deev[i]); odp_buffer_free(enbuf); } CU_ASSERT(odp_queue_destroy(queue_id) == 0); }
static void fill_queues(thread_args_t *args) { odp_schedule_sync_t sync; int num_queues, num_prio; odp_pool_t pool; int i, j, k; int buf_count = 0; test_globals_t *globals; char name[32]; globals = args->globals; sync = args->sync; num_queues = args->num_queues; num_prio = args->num_prio; pool = odp_pool_lookup(MSG_POOL_NAME); CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); for (i = 0; i < num_prio; i++) { for (j = 0; j < num_queues; j++) { odp_queue_t queue; switch (sync) { case ODP_SCHED_SYNC_NONE: snprintf(name, sizeof(name), "sched_%d_%d_n", i, j); break; case ODP_SCHED_SYNC_ATOMIC: snprintf(name, sizeof(name), "sched_%d_%d_a", i, j); break; case ODP_SCHED_SYNC_ORDERED: snprintf(name, sizeof(name), "sched_%d_%d_o", i, j); break; default: CU_ASSERT(0); break; } queue = odp_queue_lookup(name); CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); for (k = 0; k < args->num_bufs; k++) { odp_buffer_t buf; odp_event_t ev; buf = odp_buffer_alloc(pool); CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID); ev = odp_buffer_to_event(buf); if (sync == ODP_SCHED_SYNC_ORDERED) { queue_context *qctx = odp_queue_context(queue); buf_contents *bctx = odp_buffer_addr(buf); bctx->sequence = qctx->sequence++; } if (!(CU_ASSERT(odp_queue_enq(queue, ev) == 0))) odp_buffer_free(buf); else buf_count++; } } } globals->buf_count = buf_count; globals->buf_count_cpy = buf_count; }
int ofp_term_post_global(const char *pool_name) { odp_pool_t pool; int rc = 0; if (ofp_inet_term()) { OFP_ERR("Failed to cleanup inet/inet6 domains.\n"); rc = -1; } /* Cleanup sockets */ CHECK_ERROR(ofp_socket_term_global(), rc); /* Cleanup of TCP content */ CHECK_ERROR(ofp_tcp_var_term_global(), rc); /* Cleanup vxlan */ CHECK_ERROR(ofp_vxlan_term_global(), rc); /* Cleanup interface related objects */ CHECK_ERROR(ofp_portconf_term_global(), rc); /* Cleanup routes */ CHECK_ERROR(ofp_route_term_global(), rc); /* Cleanup ARP*/ CHECK_ERROR(ofp_arp_term_global(), rc); /* Cleanup hooks */ CHECK_ERROR(ofp_hook_term_global(), rc); /* Cleanup stats */ CHECK_ERROR(ofp_stat_term_global(), rc); /* Cleanup packet capture */ CHECK_ERROR(ofp_pcap_term_global(), rc); /* Cleanup reassembly queues*/ CHECK_ERROR(ofp_reassembly_term_global(), rc); /* Cleanup avl trees*/ CHECK_ERROR(ofp_avl_term_global(), rc); /* Cleanup timers - phase 1*/ CHECK_ERROR(ofp_timer_stop_global(), rc); /* Cleanup pending events */ schedule_shutdown(); /* Cleanup timers - phase 2*/ CHECK_ERROR(ofp_timer_term_global(), rc); /* Cleanup packet pool */ pool = odp_pool_lookup(pool_name); if (pool == ODP_POOL_INVALID) { OFP_ERR("Failed to locate pool %s\n", pool_name); rc = -1; } else if (odp_pool_destroy(pool) < 0) { OFP_ERR("Failed to destroy pool %s.\n", pool_name); rc = -1; pool = ODP_POOL_INVALID; } CHECK_ERROR(ofp_global_config_free_shared_memory(), rc); CHECK_ERROR(ofp_unregister_sysctls(), rc); return rc; }
static void *schedule_common_(void *arg) { thread_args_t *args = (thread_args_t *)arg; odp_schedule_sync_t sync; test_globals_t *globals; queue_context *qctx; buf_contents *bctx, *bctx_cpy; odp_pool_t pool; int locked; globals = args->globals; sync = args->sync; pool = odp_pool_lookup(MSG_POOL_NAME); CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); if (args->num_workers > 1) odp_barrier_wait(&globals->barrier); while (1) { odp_event_t ev; odp_buffer_t buf, buf_cpy; odp_queue_t from = ODP_QUEUE_INVALID; int num = 0; odp_ticketlock_lock(&globals->lock); INVALIDATE(globals); if (globals->buf_count == 0) { odp_ticketlock_unlock(&globals->lock); break; } odp_ticketlock_unlock(&globals->lock); if (args->enable_schd_multi) { odp_event_t events[BURST_BUF_SIZE], ev_cpy[BURST_BUF_SIZE]; odp_buffer_t buf_cpy[BURST_BUF_SIZE]; int j; num = odp_schedule_multi(&from, ODP_SCHED_NO_WAIT, events, BURST_BUF_SIZE); CU_ASSERT(num >= 0); CU_ASSERT(num <= BURST_BUF_SIZE); if (num == 0) continue; if (sync == ODP_SCHED_SYNC_ORDERED) { int ndx; int ndx_max; int rc; ndx_max = odp_queue_lock_count(from); CU_ASSERT_FATAL(ndx_max >= 0); qctx = odp_queue_context(from); for (j = 0; j < num; j++) { bctx = odp_buffer_addr( odp_buffer_from_event (events[j])); buf_cpy[j] = odp_buffer_alloc(pool); CU_ASSERT_FATAL(buf_cpy[j] != ODP_BUFFER_INVALID); bctx_cpy = odp_buffer_addr(buf_cpy[j]); memcpy(bctx_cpy, bctx, sizeof(buf_contents)); bctx_cpy->output_sequence = bctx_cpy->sequence; ev_cpy[j] = odp_buffer_to_event(buf_cpy[j]); } rc = odp_queue_enq_multi(qctx->pq_handle, ev_cpy, num); CU_ASSERT(rc == num); bctx = odp_buffer_addr( odp_buffer_from_event(events[0])); for (ndx = 0; ndx < ndx_max; ndx++) { odp_schedule_order_lock(ndx); INVALIDATE(qctx); INVALIDATE(bctx); CU_ASSERT(bctx->sequence == qctx->lock_sequence[ndx]); qctx->lock_sequence[ndx] += num; odp_schedule_order_unlock(ndx); } } for (j = 0; j < num; j++) odp_event_free(events[j]); } else { ev = odp_schedule(&from, ODP_SCHED_NO_WAIT); buf = odp_buffer_from_event(ev); if (buf == ODP_BUFFER_INVALID) continue; num = 1; if (sync == ODP_SCHED_SYNC_ORDERED) { int ndx; int ndx_max; int rc; ndx_max = odp_queue_lock_count(from); CU_ASSERT_FATAL(ndx_max >= 0); qctx = odp_queue_context(from); bctx = odp_buffer_addr(buf); buf_cpy = odp_buffer_alloc(pool); CU_ASSERT_FATAL(buf_cpy != ODP_BUFFER_INVALID); bctx_cpy = odp_buffer_addr(buf_cpy); memcpy(bctx_cpy, bctx, sizeof(buf_contents)); bctx_cpy->output_sequence = bctx_cpy->sequence; rc = odp_queue_enq(qctx->pq_handle, odp_buffer_to_event (buf_cpy)); CU_ASSERT(rc == 0); for (ndx = 0; ndx < ndx_max; ndx++) { odp_schedule_order_lock(ndx); INVALIDATE(qctx); INVALIDATE(bctx); CU_ASSERT(bctx->sequence == qctx->lock_sequence[ndx]); qctx->lock_sequence[ndx] += num; odp_schedule_order_unlock(ndx); } } odp_buffer_free(buf); } if (args->enable_excl_atomic) { locked = odp_spinlock_trylock(&globals->atomic_lock); CU_ASSERT(locked == 1); CU_ASSERT(from != ODP_QUEUE_INVALID); if (locked) { int cnt; odp_time_t time = ODP_TIME_NULL; /* Do some work here to keep the thread busy */ for (cnt = 0; cnt < 1000; cnt++) time = odp_time_sum(time, odp_time_local()); odp_spinlock_unlock(&globals->atomic_lock); } } if (sync == ODP_SCHED_SYNC_ATOMIC) odp_schedule_release_atomic(); if (sync == ODP_SCHED_SYNC_ORDERED) odp_schedule_release_ordered(); odp_ticketlock_lock(&globals->lock); INVALIDATE(globals); globals->buf_count -= num; if (globals->buf_count < 0) { odp_ticketlock_unlock(&globals->lock); CU_FAIL_FATAL("Buffer counting failed"); } odp_ticketlock_unlock(&globals->lock); } if (args->num_workers > 1) odp_barrier_wait(&globals->barrier); if (sync == ODP_SCHED_SYNC_ORDERED) locked = odp_ticketlock_trylock(&globals->lock); else locked = 0; if (locked && globals->buf_count_cpy > 0) { odp_event_t ev; odp_queue_t pq; uint64_t seq; uint64_t bcount = 0; int i, j; char name[32]; uint64_t num_bufs = args->num_bufs; uint64_t buf_count = globals->buf_count_cpy; for (i = 0; i < args->num_prio; i++) { for (j = 0; j < args->num_queues; j++) { snprintf(name, sizeof(name), "poll_%d_%d_o", i, j); pq = odp_queue_lookup(name); CU_ASSERT_FATAL(pq != ODP_QUEUE_INVALID); seq = 0; while (1) { ev = odp_queue_deq(pq); if (ev == ODP_EVENT_INVALID) { CU_ASSERT(seq == num_bufs); break; } bctx = odp_buffer_addr( odp_buffer_from_event(ev)); CU_ASSERT(bctx->sequence == seq); seq++; bcount++; odp_event_free(ev); } } } CU_ASSERT(bcount == buf_count); globals->buf_count_cpy = 0; } if (locked) odp_ticketlock_unlock(&globals->lock); return NULL; }
static int create_odp_packet_ip4(odp_packet_t *opkt, uint8_t *pkt_data, int plen, uint32_t dst_addr) { odp_pool_t pool; uint8_t *buf; odp_packet_t pkt = ODP_PACKET_INVALID; struct ofp_ether_header *eth; struct ofp_ip *iphdr; uint32_t eth_len; memset(orig_pkt_data, 0x0, sizeof(orig_pkt_data)); pool = odp_pool_lookup("packet_pool"); if (pool == ODP_POOL_INVALID) { fail_with_odp("ODP packet_pool not found\n"); return -1; } pkt = odp_packet_alloc(pool, plen); if (pkt == ODP_PACKET_INVALID) { fail_with_odp("ODP packet alloc failed"); return -1; } buf = odp_packet_data(pkt); if (odp_packet_copy_from_mem(pkt, 0, plen, pkt_data) < 0) { fail_with_odp("Packet data copy failed\n"); return -1; }; iphdr = (struct ofp_ip *)&buf[OFP_ETHER_HDR_LEN]; /* changes to the default packet. Recalculate ip checksum */ if (dst_addr) { iphdr->ip_dst.s_addr = dst_addr; iphdr->ip_sum = 0; iphdr->ip_sum = ofp_cksum_buffer((uint16_t *)iphdr, iphdr->ip_hl<<2); } /* END OF changes to the default packet */ eth = (struct ofp_ether_header *)buf; if (eth->ether_type == odp_cpu_to_be_16(OFP_ETHERTYPE_VLAN)) eth_len = OFP_ETHER_HDR_LEN + OFP_ETHER_VLAN_ENCAP_LEN; else eth_len = OFP_ETHER_HDR_LEN; odp_packet_has_eth_set(pkt, 1); odp_packet_has_l2_set(pkt, 1); odp_packet_has_ipv4_set(pkt, 1); odp_packet_l2_offset_set(pkt, 0); odp_packet_l3_offset_set(pkt, eth_len); odp_packet_l4_offset_set(pkt, eth_len + (iphdr->ip_hl<<2)); *opkt = pkt; odp_packet_copy_to_mem(pkt, 0, plen, orig_pkt_data); return 0; }