Example #1
0
/*
 * Should receive timeouts only
 */
static void *event_dispatcher(void *arg)
{
	odp_event_t ev;

	(void)arg;

	ofp_init_local();

	while (1) {
		ev = odp_schedule(NULL, ODP_SCHED_WAIT);

		if (ev == ODP_EVENT_INVALID)
			continue;

		if (odp_event_type(ev) == ODP_EVENT_TIMEOUT) {
			ofp_timer_handle(ev);
			continue;
		}

		OFP_ERR("Error: unexpected event type: %u\n",
			  odp_event_type(ev));

		odp_buffer_free(odp_buffer_from_event(ev));
	}

	/* Never reached */
	return NULL;
}
Example #2
0
File: timer.c Project: nmorey/odp
/* @private Handle a received (timeout) event */
static void handle_tmo(odp_event_t ev, bool stale, uint64_t prev_tick)
{
	CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID); /* Internal error */
	if (odp_event_type(ev) != ODP_EVENT_TIMEOUT) {
		/* Not a timeout event */
		CU_FAIL("Unexpected event type received");
		return;
	}
	/* Read the metadata from the timeout */
	odp_timeout_t tmo = odp_timeout_from_event(ev);
	odp_timer_t tim = odp_timeout_timer(tmo);
	uint64_t tick = odp_timeout_tick(tmo);
	struct test_timer *ttp = odp_timeout_user_ptr(tmo);

	if (tim == ODP_TIMER_INVALID)
		CU_FAIL("odp_timeout_timer() invalid timer");
	if (!ttp)
		CU_FAIL("odp_timeout_user_ptr() null user ptr");

	if (ttp && ttp->ev2 != ev)
		CU_FAIL("odp_timeout_user_ptr() wrong user ptr");
	if (ttp && ttp->tim != tim)
		CU_FAIL("odp_timeout_timer() wrong timer");
	if (stale) {
		if (odp_timeout_fresh(tmo))
			CU_FAIL("Wrong status (fresh) for stale timeout");
		/* Stale timeout => local timer must have invalid tick */
		if (ttp && ttp->tick != TICK_INVALID)
			CU_FAIL("Stale timeout for active timer");
	} else {
		if (!odp_timeout_fresh(tmo))
			CU_FAIL("Wrong status (stale) for fresh timeout");
		/* Fresh timeout => local timer must have matching tick */
		if (ttp && ttp->tick != tick) {
			LOG_DBG("Wrong tick: expected %" PRIu64
				" actual %" PRIu64 "\n",
				ttp->tick, tick);
			CU_FAIL("odp_timeout_tick() wrong tick");
		}
		/* Check that timeout was delivered 'timely' */
		if (tick > odp_timer_current_tick(tp))
			CU_FAIL("Timeout delivered early");
		if (tick < prev_tick) {
			LOG_DBG("Too late tick: %" PRIu64
				" prev_tick %" PRIu64"\n",
				tick, prev_tick);
			/* We don't report late timeouts using CU_FAIL */
			odp_atomic_inc_u32(&ndelivtoolate);
		}
	}

	if (ttp) {
		/* Internal error */
		CU_ASSERT_FATAL(ttp->ev == ODP_EVENT_INVALID);
		ttp->ev = ev;
	}
}
Example #3
0
void odp_event_free(odp_event_t event)
{
	switch (odp_event_type(event)) {
	case ODP_EVENT_BUFFER:
		odp_buffer_free(odp_buffer_from_event(event));
		break;
	case ODP_EVENT_PACKET:
		odp_packet_free(odp_packet_from_event(event));
		break;
	case ODP_EVENT_TIMEOUT:
		odp_timeout_free(odp_timeout_from_event(event));
		break;
	case ODP_EVENT_CRYPTO_COMPL:
		odp_crypto_compl_free(odp_crypto_compl_from_event(event));
		break;
	default:
		ODP_ABORT("Invalid event type: %d\n", odp_event_type(event));
	}
}
Example #4
0
void *pp_thread(void *arg)
{
	ALLOW_UNUSED_LOCAL(arg);
	if (ofp_init_local()) {
		OFP_ERR("ofp_init_local failed");
		return NULL;
	}

	while (odp_atomic_load_u32(&still_running)) {
		odp_event_t event;
		odp_queue_t source_queue;

		event = odp_schedule(&source_queue, ODP_SCHED_WAIT);

		if (odp_event_type(event) != ODP_EVENT_TIMEOUT) {
			OFP_ERR("Unexpected event type %d",
				odp_event_type(event));
			continue;
		}

		ofp_timer_handle(event);
	}
	return NULL;
}
Example #5
0
static void *run_thread_rx(void *arg)
{
	test_globals_t *globals;
	int thr_id, batch_len;
	odp_queue_t pollq = ODP_QUEUE_INVALID;

	thread_args_t *targs = arg;

	batch_len = targs->batch_len;

	if (batch_len > BATCH_LEN_MAX)
		batch_len = BATCH_LEN_MAX;

	thr_id = odp_thread_id();

	globals = odp_shm_addr(odp_shm_lookup("test_globals"));

	pkt_rx_stats_t *stats = &globals->rx_stats[thr_id];

	if (gbl_args->args.schedule == 0) {
		pollq = odp_pktio_inq_getdef(globals->pktio_rx);
		if (pollq == ODP_QUEUE_INVALID)
			LOG_ABORT("Invalid input queue.\n");
	}

	odp_barrier_wait(&globals->rx_barrier);
	while (1) {
		odp_event_t ev[BATCH_LEN_MAX];
		int i, n_ev;

		n_ev = receive_packets(pollq, ev, batch_len);

		for (i = 0; i < n_ev; ++i) {
			if (odp_event_type(ev[i]) == ODP_EVENT_PACKET) {
				odp_packet_t pkt = odp_packet_from_event(ev[i]);
				if (pktio_pkt_has_magic(pkt))
					stats->s.rx_cnt++;
				else
					stats->s.rx_ignore++;
			}
			odp_buffer_free(odp_buffer_from_event(ev[i]));
		}
		if (n_ev == 0 && odp_atomic_load_u32(&shutdown))
			break;
	}

	return NULL;
}
Example #6
0
File: timer.c Project: nmorey/odp
void timer_test_timeout_pool_alloc(void)
{
	odp_pool_t pool;
	const int num = 3;
	odp_timeout_t tmo[num];
	odp_event_t ev;
	int index;
	char wrong_type = 0;
	odp_pool_param_t params;

	odp_pool_param_init(&params);
	params.type    = ODP_POOL_TIMEOUT;
	params.tmo.num = num;

	pool = odp_pool_create("timeout_pool_alloc", &params);
	CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);

	odp_pool_print(pool);

	/* Try to allocate num items from the pool */
	for (index = 0; index < num; index++) {
		tmo[index] = odp_timeout_alloc(pool);

		if (tmo[index] == ODP_TIMEOUT_INVALID)
			break;

		ev = odp_timeout_to_event(tmo[index]);
		if (odp_event_type(ev) != ODP_EVENT_TIMEOUT)
			wrong_type = 1;
	}

	/* Check that the pool had at least num items */
	CU_ASSERT(index == num);
	/* index points out of buffer[] or it point to an invalid buffer */
	index--;

	/* Check that the pool had correct buffers */
	CU_ASSERT(wrong_type == 0);

	for (; index >= 0; index--)
		odp_timeout_free(tmo[index]);

	CU_ASSERT(odp_pool_destroy(pool) == 0);
}
Example #7
0
static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
				    uint32_t seq, uint64_t ns)
{
	odp_time_t wait_time, end;
	odp_event_t ev;
	odp_packet_t pkt;
	uint64_t wait;

	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;

		if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV) {
			odp_pktio_recv(pktio_rx->id, &pkt, 1);
		} else {
			if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
				ev = queue_deq_wait_time(pktio_rx->inq, ns);
			else
				ev = odp_schedule(NULL, wait);

			if (ev != ODP_EVENT_INVALID) {
				if (odp_event_type(ev) == ODP_EVENT_PACKET)
					pkt = odp_packet_from_event(ev);
				else
					odp_event_free(ev);
			}
		}

		if (pkt != ODP_PACKET_INVALID) {
			if (pktio_pkt_seq(pkt) == seq)
				return pkt;

			odp_packet_free(pkt);
		}
	} while (odp_time_cmp(end, odp_time_local()) > 0);

	CU_FAIL("failed to receive transmitted packet");

	return ODP_PACKET_INVALID;
}
Example #8
0
static void schedule_shutdown(void)
{
	odp_event_t evt;
	odp_queue_t from;

	while (1) {
		evt = odp_schedule(&from, ODP_SCHED_NO_WAIT);
		if (evt == ODP_EVENT_INVALID)
			break;
		switch (odp_event_type(evt)) {
		case ODP_EVENT_TIMEOUT:
			{
				ofp_timer_evt_cleanup(evt);
				break;
			}
		case ODP_EVENT_PACKET:
			{
				odp_packet_free(odp_packet_from_event(evt));
				break;
			}
		case ODP_EVENT_BUFFER:
			{
				odp_buffer_free(odp_buffer_from_event(evt));
				break;
			}
		case ODP_EVENT_CRYPTO_COMPL:
			{
				odp_crypto_compl_free(
					odp_crypto_compl_from_event(evt));
				break;
			}
		}
	}

	odp_schedule_pause();
}
Example #9
0
int default_event_dispatcher(void *arg)
{
	odp_event_t ev;
	odp_packet_t pkt;
	odp_queue_t in_queue;
	int event_idx = 0;
	int event_cnt = 0;
	ofp_pkt_processing_func pkt_func = (ofp_pkt_processing_func)arg;
	odp_bool_t *is_running = NULL;

	if (ofp_init_local()) {
		OFP_ERR("ofp_init_local failed");
		return -1;
	}

	int rx_burst = global_param->evt_rx_burst_size;
	odp_event_t events[rx_burst];

	is_running = ofp_get_processing_state();
	if (is_running == NULL) {
		OFP_ERR("ofp_get_processing_state failed");
		ofp_term_local();
		return -1;
	}

	/* PER CORE DISPATCHER */
	while (*is_running) {
		event_cnt = odp_schedule_multi(&in_queue, ODP_SCHED_WAIT,
					 events, rx_burst);
		for (event_idx = 0; event_idx < event_cnt; event_idx++) {
			odp_event_type_t ev_type;

			ev = events[event_idx];

			if (ev == ODP_EVENT_INVALID)
				continue;
			ev_type = odp_event_type(ev);

			if (odp_likely(ev_type == ODP_EVENT_PACKET)) {
				pkt = odp_packet_from_event(ev);
#if 0
				if (odp_unlikely(odp_packet_has_error(pkt))) {
					OFP_DBG("Dropping packet with error");
					odp_packet_free(pkt);
					continue;
				}
#endif
				ofp_packet_input(pkt, in_queue, pkt_func);
				continue;
			}
			if (ev_type == ODP_EVENT_TIMEOUT) {
				ofp_timer_handle(ev);
				continue;
			}

			OFP_ERR("Unexpected event type: %u", ev_type);
			odp_event_free(ev);
		}
		ofp_send_pending_pkt();
	}

	if (ofp_term_local())
		OFP_ERR("ofp_term_local failed");

	return 0;
}
Example #10
0
/** @private test timeout */
static void test_abs_timeouts(int thr, test_globals_t *gbls)
{
	uint64_t period;
	uint64_t period_ns;
	odp_queue_t queue;
	uint64_t tick;
	struct test_timer *ttp;
	odp_timeout_t tmo;

	EXAMPLE_DBG("  [%i] test_timeouts\n", thr);

	queue = odp_queue_lookup("timer_queue");

	period_ns = gbls->args.period_us*ODP_TIME_USEC;
	period    = odp_timer_ns_to_tick(gbls->tp, period_ns);

	EXAMPLE_DBG("  [%i] period %"PRIu64" ticks,  %"PRIu64" ns\n", thr,
		    period, period_ns);

	EXAMPLE_DBG("  [%i] current tick %"PRIu64"\n", thr,
		    odp_timer_current_tick(gbls->tp));

	ttp = &gbls->tt[thr];
	ttp->tim = odp_timer_alloc(gbls->tp, queue, ttp);
	if (ttp->tim == ODP_TIMER_INVALID) {
		EXAMPLE_ERR("Failed to allocate timer\n");
		return;
	}
	tmo = odp_timeout_alloc(gbls->pool);
	if (tmo == ODP_TIMEOUT_INVALID) {
		EXAMPLE_ERR("Failed to allocate timeout\n");
		return;
	}
	ttp->ev = odp_timeout_to_event(tmo);
	tick = odp_timer_current_tick(gbls->tp);

	while ((int)odp_atomic_load_u32(&gbls->remain) > 0) {
		odp_event_t ev;
		odp_timer_set_t rc;

		tick += period;
		rc = odp_timer_set_abs(ttp->tim, tick, &ttp->ev);
		if (odp_unlikely(rc != ODP_TIMER_SUCCESS)) {
			/* Too early or too late timeout requested */
			EXAMPLE_ABORT("odp_timer_set_abs() failed: %s\n",
				      timerset2str(rc));
		}

		/* Get the next expired timeout.
		 * We invoke the scheduler in a loop with a timeout because
		 * we are not guaranteed to receive any more timeouts. The
		 * scheduler isn't guaranteeing fairness when scheduling
		 * buffers to threads.
		 * Use 1.5 second timeout for scheduler */
		uint64_t sched_tmo =
			odp_schedule_wait_time(1500000000ULL);
		do {
			ev = odp_schedule(&queue, sched_tmo);
			/* Check if odp_schedule() timed out, possibly there
			 * are no remaining timeouts to receive */
		} while (ev == ODP_EVENT_INVALID &&
			 (int)odp_atomic_load_u32(&gbls->remain) > 0);

		if (ev == ODP_EVENT_INVALID)
			break; /* No more timeouts */
		if (odp_event_type(ev) != ODP_EVENT_TIMEOUT) {
			/* Not a default timeout event */
			EXAMPLE_ABORT("Unexpected event type (%u) received\n",
				      odp_event_type(ev));
		}
		odp_timeout_t tmo = odp_timeout_from_event(ev);
		tick = odp_timeout_tick(tmo);
		ttp = odp_timeout_user_ptr(tmo);
		ttp->ev = ev;
		if (!odp_timeout_fresh(tmo)) {
			/* Not the expected expiration tick, timer has
			 * been reset or cancelled or freed */
			EXAMPLE_ABORT("Unexpected timeout received (timer %" PRIx32 ", tick %" PRIu64 ")\n",
				      ttp->tim, tick);
		}
		EXAMPLE_DBG("  [%i] timeout, tick %"PRIu64"\n", thr, tick);

		odp_atomic_dec_u32(&gbls->remain);
	}

	/* Cancel and free last timer used */
	(void)odp_timer_cancel(ttp->tim, &ttp->ev);
	if (ttp->ev != ODP_EVENT_INVALID)
		odp_timeout_free(odp_timeout_from_event(ttp->ev));
	else
		EXAMPLE_ERR("Lost timeout event at timer cancel\n");
	/* Since we have cancelled the timer, there is no timeout event to
	 * return from odp_timer_free() */
	(void)odp_timer_free(ttp->tim);

	/* Remove any prescheduled events */
	remove_prescheduled_events();
}
Example #11
0
void *pp_thread(void *arg)
{
	ALLOW_UNUSED_LOCAL(arg);

#if ODP_VERSION >= 102
	if (odp_init_local(ODP_THREAD_WORKER)) {
#else
	if (odp_init_local()) {
#endif
		OFP_ERR("odp_init_local failed");
		return NULL;
	}
	if (ofp_init_local()) {
		OFP_ERR("ofp_init_local failed");
		return NULL;
	}

	while (odp_atomic_load_u32(&still_running)) {
		odp_event_t event;
		odp_queue_t source_queue;

		event = odp_schedule(&source_queue, ODP_SCHED_WAIT);

		if (odp_event_type(event) != ODP_EVENT_TIMEOUT) {
			OFP_ERR("Unexpected event type %d",
				odp_event_type(event));
			continue;
		}

		ofp_timer_handle(event);
	}
	return NULL;
}

static void test_arp(void)
{
	struct ofp_ifnet mock_ifnet;
	struct in_addr ip;
	uint8_t mac[OFP_ETHER_ADDR_LEN] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, };

	/* The buffer passed into ofp_ipv4_lookup_mac() must be 8 bytes since
	 * a 64-bit operation is currently being used to copy a MAC address.
	 */
	uint8_t mac_result[OFP_ETHER_ADDR_LEN + 2];

	CU_ASSERT(0 == ofp_init_local());

	memset(&mock_ifnet, 0, sizeof(mock_ifnet));
	CU_ASSERT(0 != inet_aton("1.1.1.1", &ip));

	/* Test entry insert, lookup, and remove. */
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));

	memset(mac_result, 0xFF, OFP_ETHER_ADDR_LEN);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	CU_ASSERT(0 == memcmp(mac, mac_result, OFP_ETHER_ADDR_LEN));

	CU_ASSERT(0 == ofp_arp_ipv4_remove(ip.s_addr, &mock_ifnet));
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out after a few hits. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
}

int main(void)
{
	CU_pSuite ptr_suite = NULL;
	int nr_of_failed_tests = 0;
	int nr_of_failed_suites = 0;

	/* Initialize the CUnit test registry */
	if (CUE_SUCCESS != CU_initialize_registry())
		return CU_get_error();

	/* add a suite to the registry */
	ptr_suite = CU_add_suite("ofp errno", init_suite, end_suite);
	if (NULL == ptr_suite) {
		CU_cleanup_registry();
		return CU_get_error();
	}
	if (NULL == CU_ADD_TEST(ptr_suite, test_arp)) {
		CU_cleanup_registry();
		return CU_get_error();
	}

#if defined(OFP_TESTMODE_AUTO)
	CU_set_output_filename("CUnit-Util");
	CU_automated_run_tests();
#else
	/* Run all tests using the CUnit Basic interface */
	CU_basic_set_mode(CU_BRM_VERBOSE);
	CU_basic_run_tests();
#endif

	nr_of_failed_tests = CU_get_number_of_tests_failed();
	nr_of_failed_suites = CU_get_number_of_suites_failed();
	CU_cleanup_registry();

	return (nr_of_failed_suites > 0 ?
		nr_of_failed_suites : nr_of_failed_tests);
}
/** @private test timeout */
static void test_abs_timeouts(int thr, test_globals_t *gbls)
{
    uint64_t    period;
    uint64_t    period_ns;
    odp_queue_t queue;
    uint64_t    tick;
    struct test_timer *ttp;
    odp_timeout_t tmo;
    uint32_t num_workers = gbls->num_workers;

    EXAMPLE_DBG("  [%i] test_timeouts\n", thr);

    queue      = odp_queue_lookup("timer_queue");

    period_ns  = gbls->args.period_us * ODP_TIME_USEC;
    period     = odp_timer_ns_to_tick(gbls->tp, period_ns);

    EXAMPLE_DBG("  [%i] period %d ticks,  %d ns\n", thr,
                period, period_ns);

    EXAMPLE_DBG("  [%i] current tick %d\n", thr,
                odp_timer_current_tick(gbls->tp));

    ttp = &gbls->tt[thr];
    ttp->tim = odp_timer_alloc(gbls->tp, queue, ttp);
    if (ttp->tim == ODP_TIMER_INVALID) {
        EXAMPLE_ERR("Failed to allocate timer\n");
        return;
    }

    tmo = odp_timeout_alloc(gbls->pool);
    if (tmo == ODP_TIMEOUT_INVALID) {
        EXAMPLE_ERR("Failed to allocate timeout\n");
        return;
    }

    ttp->ev    = odp_timeout_to_event(tmo);
    tick       = odp_timer_current_tick(gbls->tp);

    while (1) {
        int wait = 0;
        odp_event_t ev;
        odp_timer_set_t rc;

        if (ttp) {
            tick  += period;
            rc     = odp_timer_set_abs(ttp->tim, tick, &ttp->ev);
            if (odp_unlikely(rc != ODP_TIMER_SUCCESS))
                /* Too early or too late timeout requested */
                EXAMPLE_ABORT("odp_timer_set_abs() failed: %s\n",
                              timerset2str(rc));
        }

        /* Get the next expired timeout.
         * We invoke the scheduler in a loop with a timeout because
         * we are not guaranteed to receive any more timeouts. The
         * scheduler isn't guaranteeing fairness when scheduling
         * buffers to threads.
         * Use 1.5 second timeout for scheduler */
        uint64_t sched_tmo =
            odp_schedule_wait_time(1500000000ULL);
        do {
            ev = odp_schedule(&queue, sched_tmo);

            /* Check if odp_schedule() timed out, possibly there
             * are no remaining timeouts to receive */
            if ((++wait > WAIT_NUM)
                    && (odp_atomic_load_u32(&gbls->remain) < num_workers))
                EXAMPLE_ABORT("At least one TMO was lost\n");
        } while (ev == ODP_EVENT_INVALID
                 && (int)odp_atomic_load_u32(&gbls->remain) > 0);

        if (ev == ODP_EVENT_INVALID)
            break;  /* No more timeouts */

        if (odp_event_type(ev) != ODP_EVENT_TIMEOUT)
            /* Not a default timeout event */
            EXAMPLE_ABORT("Unexpected event type (%u) received\n",
                          odp_event_type(ev));

        odp_timeout_t tmo = odp_timeout_from_event(ev);
        tick       = odp_timeout_tick(tmo);
        ttp        = odp_timeout_user_ptr(tmo);
        ttp->ev    = ev;
        if (!odp_timeout_fresh(tmo))
            /* Not the expected expiration tick, timer has
             * been reset or cancelled or freed */
            EXAMPLE_ABORT("Unexpected timeout received (timer %x, tick %d)\n",
                          ttp->tim, tick);

        EXAMPLE_DBG("  [%i] timeout, tick %d\n", thr, tick);

        uint32_t rx_num = odp_atomic_fetch_dec_u32(&gbls->remain);

        if (!rx_num)
            EXAMPLE_ABORT("Unexpected timeout received (timer %x, tick %d)\n",
                          ttp->tim, tick);
        else if (rx_num > num_workers)
            continue;

        odp_timeout_free(odp_timeout_from_event(ttp->ev));
        odp_timer_free(ttp->tim);
        ttp = NULL;
    }

    /* Remove any prescheduled events */
    remove_prescheduled_events();
}
static ngx_int_t
ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
    ngx_uint_t flags)
{
	odp_packet_t pkts[OFP_PKT_RX_BURST_SIZE];
        odp_packet_t odp_pkt;
        int pkt_cnt = 0;
        int pkt_idx = 0;

	pkt_cnt = odp_pktin_recv(in_queue, pkts, OFP_PKT_RX_BURST_SIZE);

        for (pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) {
                odp_pkt = pkts[pkt_idx];
                ofp_packet_input(odp_pkt, ODP_QUEUE_INVALID, ofp_eth_vlan_processing);
        }

	if (pkt_cnt < 1) ofp_send_pending_pkt();

	static uint32_t count = 0;
	/*odp_queue_deq has a lock that impacts performance*/
	if (count ++ > 50) {
		count = 0;

		odp_queue_t timer_queue = ofp_timer_queue_cpu(-1);
		odp_event_t event = odp_queue_deq(timer_queue);

		if (event != ODP_EVENT_INVALID) {
			if (odp_event_type(event) == ODP_EVENT_TIMEOUT) {
				ofp_timer_handle(event);
			} else {
				odp_buffer_free(odp_buffer_from_event(event));
			}
		}
	}

#if OFP_NOTIFY
    return NGX_OK;
#endif
    int                ready, nready;
    ngx_err_t          err;
    ngx_uint_t         i, found;
    ngx_event_t       *ev;
    ngx_queue_t       *queue;
    struct timeval     tv, *tp;
    ngx_connection_t  *c;

    if (max_fd == -1) {
        for (i = 0; i < nevents; i++) {
            c = event_index[i]->data;
        ngx_log_debug(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "change max_fd: %i, c->fd : %d", max_fd, c->fd);
            if (max_fd < c->fd) {
                max_fd = c->fd;
            }
        }

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "change max_fd: %i", max_fd);
    }

#if (NGX_DEBUG)
    if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
        for (i = 0; i < nevents; i++) {
            ev = event_index[i];
            c = ev->data;
            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "select event: fd:%d wr:%d", c->fd, ev->write);
        }

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "max_fd: %i", max_fd);
    }
#endif

    if (timer == NGX_TIMER_INFINITE) {
        tp = NULL;

    } else {
        tv.tv_sec = (long) (timer / 1000);
        tv.tv_usec = (long) ((timer % 1000) * 1000);
        tp = &tv;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "select timer: %M", timer);

    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "select max_fd %d, tp %p ", max_fd, tp);
    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   " master %p : work %p", (ofp_fd_set *)&master_read_fd_set,
		   (ofp_fd_set *)&work_read_fd_set);
    ready = select(max_fd + 1, &master_read_fd_set, &master_write_fd_set, NULL, tp);

    err = (ready == -1) ? ngx_errno : 0;

    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
        ngx_time_update();
    }

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "select ready %d", ready);

    if (err) {
        ngx_uint_t  level;

        if (err == NGX_EINTR) {

            if (ngx_event_timer_alarm) {
                ngx_event_timer_alarm = 0;
                return NGX_OK;
            }

            level = NGX_LOG_INFO;

        } else {
            level = NGX_LOG_ALERT;
        }

        ngx_log_error(level, cycle->log, err, "select() failed");

        if (err == NGX_EBADF) {
            /*ngx_select_repair_fd_sets(cycle);*/
        }

        return NGX_ERROR;
    }

    if (ready == 0) {
return NGX_OK;
        if (timer != NGX_TIMER_INFINITE) {
            return NGX_OK;
        }

        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                      "select() returned no events without timeout");
        return NGX_ERROR;
    }

    nready = 0;

    for (i = 0; i < nevents; i++) {
        ev = event_index[i];
        c = ev->data;
        found = 0;

        if (ev->write) {
            if (FD_ISSET(c->fd, &master_write_fd_set)) {
                found = 1;
                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                               "select write %d", c->fd);
            }

        } else {
            if (FD_ISSET(c->fd, &master_read_fd_set)) {
                found = 1;
                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                               "select read %d", c->fd);
            }
        }

        if (found) {
            ev->ready = 1;

            queue = ev->accept ? &ngx_posted_accept_events
                               : &ngx_posted_events;

            ngx_post_event(ev, queue);

            nready++;
        }
    }

    if (ready != nready) {
        /*ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                      "select ready != events: %d:%d", ready, nready);

        ngx_select_repair_fd_sets(cycle);*/
    }

    return NGX_OK;
}
Example #14
0
void pktio_test_start_stop(void)
{
	odp_pktio_t pktio[MAX_NUM_IFACES];
	odp_packet_t pkt;
	odp_event_t tx_ev[100];
	odp_event_t ev;
	int i, pkts, ret, alloc = 0;
	odp_queue_t outq;
	uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS);

	for (i = 0; i < num_ifaces; i++) {
		pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED,
					ODP_PKTOUT_MODE_SEND);
		CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID);
		create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
	}

	outq = odp_pktio_outq_getdef(pktio[0]);

	/* Interfaces are stopped by default,
	 * Check that stop when stopped generates an error */
	ret = odp_pktio_stop(pktio[0]);
	CU_ASSERT(ret <= 0);

	/* start first */
	ret = odp_pktio_start(pktio[0]);
	CU_ASSERT(ret == 0);
	/* Check that start when started generates an error */
	ret = odp_pktio_start(pktio[0]);
	CU_ASSERT(ret < 0);

	/* Test Rx on a stopped interface. Only works if there are 2 */
	if (num_ifaces > 1) {
		for (alloc = 0; alloc < 100; alloc++) {
			pkt = odp_packet_alloc(default_pkt_pool, packet_len);
			if (pkt == ODP_PACKET_INVALID)
				break;
			pktio_init_packet(pkt);

			pktio_pkt_set_macs(pkt, pktio[0], pktio[1]);
			if (pktio_fixup_checksums(pkt) != 0) {
				odp_packet_free(pkt);
				break;
			}

			tx_ev[alloc] = odp_packet_to_event(pkt);
		}

		for (pkts = 0; pkts != alloc; ) {
			ret = odp_queue_enq_multi(outq, &tx_ev[pkts],
						  alloc - pkts);
			if (ret < 0) {
				CU_FAIL("unable to enqueue packet\n");
				break;
			}
			pkts += ret;
		}
		/* check that packets did not arrive */
		for (i = 0, pkts = 0; i < 1000; i++) {
			ev = odp_schedule(NULL, wait);
			if (ev == ODP_EVENT_INVALID)
				continue;

			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
				pkt = odp_packet_from_event(ev);
				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
					pkts++;
			}
			odp_event_free(ev);
		}
		if (pkts)
			CU_FAIL("pktio stopped, received unexpected events");

		/* start both, send and get packets */
		/* 0 already started */
		ret = odp_pktio_start(pktio[1]);
		CU_ASSERT(ret == 0);

		/* flush packets with magic number in pipes */
		for (i = 0; i < 1000; i++) {
			ev = odp_schedule(NULL, wait);
			if (ev != ODP_EVENT_INVALID)
				odp_event_free(ev);
		}
	}

	/* alloc */
	for (alloc = 0; alloc < 100; alloc++) {
		pkt = odp_packet_alloc(default_pkt_pool, packet_len);
		if (pkt == ODP_PACKET_INVALID)
			break;
		pktio_init_packet(pkt);
		if (num_ifaces > 1) {
			pktio_pkt_set_macs(pkt, pktio[0], pktio[1]);
			if (pktio_fixup_checksums(pkt) != 0) {
				odp_packet_free(pkt);
				break;
			}
		}
		tx_ev[alloc] = odp_packet_to_event(pkt);
	}

	/* send */
	for (pkts = 0; pkts != alloc; ) {
		ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts);
		if (ret < 0) {
			CU_FAIL("unable to enqueue packet\n");
			break;
		}
		pkts += ret;
	}

	/* get */
	for (i = 0, pkts = 0; i < 100; i++) {
		ev = odp_schedule(NULL, wait);
		if (ev != ODP_EVENT_INVALID) {
			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
				pkt = odp_packet_from_event(ev);
				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
					pkts++;
			}
			odp_event_free(ev);
		}
	}
	CU_ASSERT(pkts == alloc);

	for (i = 0; i < num_ifaces; i++) {
		CU_ASSERT(odp_pktio_stop(pktio[i]) == 0);
		destroy_inq(pktio[i]);
		CU_ASSERT(odp_pktio_close(pktio[i]) == 0);
	}
}
Example #15
0
void *default_event_dispatcher(void *arg)
{
	odp_event_t ev;
	odp_packet_t pkt;
	odp_queue_t in_queue;
	odp_event_t events[OFP_EVT_RX_BURST_SIZE];
	int event_idx = 0;
	int event_cnt = 0;
	ofp_pkt_processing_func pkt_func = (ofp_pkt_processing_func)arg;
	odp_bool_t *is_running = NULL;

#if ODP_VERSION < 106
	if (odp_init_local(ODP_THREAD_WORKER)) {
		OFP_ERR("odp_init_local failed");
		return NULL;
	}
#endif

	if (ofp_init_local()) {
		OFP_ERR("ofp_init_local failed");
		return NULL;
	}

	is_running = ofp_get_processing_state();
	if (is_running == NULL) {
		OFP_ERR("ofp_get_processing_state failed");
		ofp_term_local();
		return NULL;
	}

	/* PER CORE DISPATCHER */
	while (*is_running) {
		event_cnt = odp_schedule_multi(&in_queue, ODP_SCHED_WAIT,
					 events, OFP_EVT_RX_BURST_SIZE);
		for (event_idx = 0; event_idx < event_cnt; event_idx++) {
			ev = events[event_idx];

			if (ev == ODP_EVENT_INVALID)
				continue;

			if (odp_event_type(ev) == ODP_EVENT_TIMEOUT) {
				ofp_timer_handle(ev);
				continue;
			}

			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
				pkt = odp_packet_from_event(ev);
#if 0
				if (odp_unlikely(odp_packet_has_error(pkt))) {
					OFP_DBG("Dropping packet with error");
					odp_packet_free(pkt);
					continue;
				}
#endif
				ofp_packet_input(pkt, in_queue, pkt_func);
				continue;
			}

			OFP_ERR("Unexpected event type: %u", odp_event_type(ev));

			/* Free events by type */
			if (odp_event_type(ev) == ODP_EVENT_BUFFER) {
				odp_buffer_free(odp_buffer_from_event(ev));
				continue;
			}

			if (odp_event_type(ev) == ODP_EVENT_CRYPTO_COMPL) {
				odp_crypto_compl_free(
					odp_crypto_compl_from_event(ev));
				continue;
			}

		}
		ofp_send_pending_pkt();
	}

	if (ofp_term_local())
		OFP_ERR("ofp_term_local failed");

	return NULL;
}