static void *pkt_io_recv(void *arg) { odp_pktio_t pktio; odp_packet_t pkt, pkt_tbl[OFP_PKT_BURST_SIZE]; int pkt_idx, pkt_cnt; struct pktio_thr_arg *thr_args; ofp_pkt_processing_func pkt_func; thr_args = arg; pkt_func = thr_args->pkt_func; if (odp_init_local(ODP_THREAD_WORKER)) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } pktio = ofp_port_pktio_get(thr_args->port); OFP_DBG("PKT-IO receive starting on port: %d, pktio-id: %"PRIX64"\n", thr_args->port, odp_pktio_to_u64(pktio)); while (1) { pkt_cnt = odp_pktio_recv(pktio, pkt_tbl, OFP_PKT_BURST_SIZE); for (pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) { pkt = pkt_tbl[pkt_idx]; if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Packet with error dropped.\n"); odp_packet_free(pkt); continue; } ofp_packet_input(pkt, ODP_QUEUE_INVALID, pkt_func); } #ifdef OFP_SEND_PKT_BURST ofp_send_pending_pkt_burst(); #endif /*OFP_SEND_PKT_BURST*/ } /* Never reached */ return NULL; }
/** * Main receive function * * @param arg thread arguments of type 'thread_args_t *' */ static void *gen_recv_thread(void *arg) { int thr; odp_pktio_t pktio; thread_args_t *thr_args; odp_packet_t pkt; odp_event_t ev; thr = odp_thread_id(); thr_args = arg; pktio = odp_pktio_lookup(thr_args->pktio_dev); if (pktio == ODP_PKTIO_INVALID) { EXAMPLE_ERR(" [%02i] Error: lookup of pktio %s failed\n", thr, thr_args->pktio_dev); return NULL; } printf(" [%02i] created mode: RECEIVE\n", thr); for (;;) { if (args->appl.number != -1 && odp_atomic_load_u64(&counters.icmp) >= (unsigned int)args->appl.number) { break; } /* Use schedule to get buf from any input queue */ ev = odp_schedule(NULL, ODP_SCHED_WAIT); pkt = odp_packet_from_event(ev); /* Drop packets with errors */ if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); continue; } print_pkts(thr, &pkt, 1); odp_packet_free(pkt); } return arg; }
/** * Drop packets which input parsing marked as containing errors. * * Frees packets with error and modifies pkt_tbl[] to only contain packets with * no detected errors. * * @param pkt_tbl Array of packet * @param len Length of pkt_tbl[] * * @return Number of packets with no detected error */ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) { odp_packet_t pkt; unsigned pkt_cnt = len; unsigned i, j; for (i = 0, j = 0; i < len; ++i) { pkt = pkt_tbl[i]; if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); /* Drop */ pkt_cnt--; } else if (odp_unlikely(i != j++)) { pkt_tbl[j-1] = pkt; } } return pkt_cnt; }
/** * Drop packets which input parsing marked as containing errors. * * Frees packets with error and modifies pkt_tbl[] to only contain packets with * no detected errors. * * @param pkt_tbl Array of packets * @param num Number of packets in pkt_tbl[] * * @return Number of packets dropped */ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned num) { odp_packet_t pkt; unsigned dropped = 0; unsigned i, j; for (i = 0, j = 0; i < num; ++i) { pkt = pkt_tbl[i]; if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); /* Drop */ dropped++; } else if (odp_unlikely(i != j++)) { pkt_tbl[j-1] = pkt; } } return dropped; }
static void *pkt_io_recv(void *arg) { odp_pktin_queue_t pktin; odp_packet_t pkt, pkt_tbl[PKT_BURST_SIZE]; int pkt_idx, pkt_cnt; struct pktio_thr_arg *thr_args; ofp_pkt_processing_func pkt_func; thr_args = arg; pkt_func = thr_args->pkt_func; pktin = thr_args->pktin; if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } OFP_DBG("PKT-IO receive starting on cpu: %d", odp_cpu_id()); while (1) { pkt_cnt = odp_pktin_recv(pktin, pkt_tbl, PKT_BURST_SIZE); for (pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) { pkt = pkt_tbl[pkt_idx]; if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Packet with error dropped.\n"); odp_packet_free(pkt); continue; } ofp_packet_input(pkt, ODP_QUEUE_INVALID, pkt_func); } ofp_send_pending_pkt(); } /* Never reached */ return NULL; }
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; }
static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b, int num_pkts) { odp_packet_t tx_pkt[num_pkts]; odp_event_t tx_ev[num_pkts]; odp_packet_t rx_pkt; uint32_t tx_seq[num_pkts]; int i, ret; /* generate test packets to send */ for (i = 0; i < num_pkts; ++i) { tx_pkt[i] = odp_packet_alloc(default_pkt_pool, packet_len); if (tx_pkt[i] == ODP_PACKET_INVALID) break; tx_seq[i] = pktio_init_packet(tx_pkt[i]); if (tx_seq[i] == TEST_SEQ_INVALID) { odp_packet_free(tx_pkt[i]); break; } pktio_pkt_set_macs(tx_pkt[i], pktio_a->id, pktio_b->id); if (pktio_fixup_checksums(tx_pkt[i]) != 0) { odp_packet_free(tx_pkt[i]); break; } tx_ev[i] = odp_packet_to_event(tx_pkt[i]); } if (i != num_pkts) { CU_FAIL("failed to generate test packets"); return; } /* send packet(s) out */ if (num_pkts == 1) { ret = odp_queue_enq(pktio_a->outq, tx_ev[0]); if (ret != 0) { CU_FAIL("failed to enqueue test packet"); odp_packet_free(tx_pkt[0]); return; } } else { ret = odp_queue_enq_multi(pktio_a->outq, tx_ev, num_pkts); if (ret != num_pkts) { CU_FAIL("failed to enqueue test packets"); i = ret < 0 ? 0 : ret; for ( ; i < num_pkts; i++) odp_packet_free(tx_pkt[i]); return; } } /* and wait for them to arrive back */ for (i = 0; i < num_pkts; ++i) { rx_pkt = wait_for_packet(pktio_b, tx_seq[i], ODP_TIME_SEC_IN_NS); if (rx_pkt == ODP_PACKET_INVALID) break; CU_ASSERT(odp_packet_input(rx_pkt) == pktio_b->id); CU_ASSERT(odp_packet_has_error(rx_pkt) == 0); odp_packet_free(rx_pkt); } CU_ASSERT(i == num_pkts); }
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; }