/** * functional test for rte_meter_trtcm_color_blind_check */ static inline int tm_test_trtcm_color_blind_check(void) { #define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check" uint64_t time; struct rte_meter_trtcm tm; uint64_t hz = rte_get_tsc_hz(); /* Test green */ if(rte_meter_trtcm_config(&tm, &tparams) != 0) melog(TRTCM_BLIND_CHECK_MSG); time = rte_get_tsc_cycles() + hz; if(rte_meter_trtcm_color_blind_check( &tm, time, TM_TEST_TRTCM_CBS_DF - 1) != e_RTE_METER_GREEN) melog(TRTCM_BLIND_CHECK_MSG" GREEN"); /* Test yellow */ if(rte_meter_trtcm_config(&tm, &tparams) != 0) melog(TRTCM_BLIND_CHECK_MSG); time = rte_get_tsc_cycles() + hz; if(rte_meter_trtcm_color_blind_check( &tm, time, TM_TEST_TRTCM_CBS_DF + 1) != e_RTE_METER_YELLOW) melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); if(rte_meter_trtcm_config(&tm, &tparams) != 0) melog(TRTCM_BLIND_CHECK_MSG); time = rte_get_tsc_cycles() + hz; if(rte_meter_trtcm_color_blind_check( &tm, time, TM_TEST_TRTCM_PBS_DF - 1) != e_RTE_METER_YELLOW) melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); /* Test red */ if(rte_meter_trtcm_config(&tm, &tparams) != 0) melog(TRTCM_BLIND_CHECK_MSG); time = rte_get_tsc_cycles() + hz; if(rte_meter_trtcm_color_blind_check( &tm, time, TM_TEST_TRTCM_PBS_DF + 1) != e_RTE_METER_RED) melog(TRTCM_BLIND_CHECK_MSG" RED"); return 0; }
/** * Dequeue mbufs from output queue and send to ethernet port. * This function is called from I/O (Output) thread. */ static inline void app_lcore_io_tx(struct app_lcore_params_io *lp, uint32_t n_workers, uint32_t bsz_rd, uint32_t bsz_wr) { uint32_t worker; for (worker = 0; worker < n_workers; worker ++) { uint32_t i; for (i = 0; i < lp->tx.n_nic_ports; i ++) { uint8_t port = lp->tx.nic_ports[i]; struct rte_ring *ring = lp->tx.rings[port][worker]; struct interface *ifp; uint32_t n_mbufs, n_pkts; int ret; n_mbufs = lp->tx.mbuf_out[port].n_mbufs; ret = rte_ring_sc_dequeue_burst(ring, (void **) &lp->tx.mbuf_out[port].array[n_mbufs], bsz_rd - n_mbufs); if (unlikely(ret == 0)) { continue; } n_mbufs += (uint32_t)ret; #if APP_IO_TX_DROP_ALL_PACKETS { uint32_t j; APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[0]); APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[1]); for (j = 0; j < n_mbufs; j ++) { if (likely(j < n_mbufs - 2)) { APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[j + 2]); } rte_pktmbuf_free(lp->tx.mbuf_out[port].array[j]); } lp->tx.mbuf_out[port].n_mbufs = 0; continue; } #endif if (unlikely(n_mbufs < bsz_wr)) { lp->tx.mbuf_out[port].n_mbufs = n_mbufs; lp->tx.mbuf_out_flush[port] = 1; continue; } ifp = dpdk_interface_lookup(port); if (ifp != NULL && ifp->sched_port != NULL) { struct lagopus_packet *pkt; struct rte_mbuf *m; int qidx, color; for (i = 0; i < n_mbufs; i++) { m = lp->tx.mbuf_out[port].array[i]; pkt = (struct lagopus_packet *) (m->buf_addr + APP_DEFAULT_MBUF_LOCALDATA_OFFSET); if (unlikely(pkt->queue_id != 0)) { qidx = dpdk_interface_queue_id_to_index(ifp, pkt->queue_id); color = rte_meter_trtcm_color_blind_check(&ifp->ifqueue.meters[qidx], rte_rdtsc(), OS_M_PKTLEN(m)); rte_sched_port_pkt_write(m, 0, 0, 0, qidx, color); } } n_mbufs = rte_sched_port_enqueue(ifp->sched_port, lp->tx.mbuf_out[port].array, n_mbufs); n_mbufs = rte_sched_port_dequeue(ifp->sched_port, lp->tx.mbuf_out[port].array, n_mbufs); } DPRINTF("send %d pkts\n", n_mbufs); n_pkts = rte_eth_tx_burst(port, 0, lp->tx.mbuf_out[port].array, (uint16_t) n_mbufs); DPRINTF("sent %d pkts\n", n_pkts); #if APP_STATS lp->tx.nic_ports_iters[port] ++; lp->tx.nic_ports_count[port] += n_pkts; if (unlikely(lp->tx.nic_ports_iters[port] == APP_STATS)) { unsigned lcore = rte_lcore_id(); printf("\t\t\tI/O TX %u out (port %u): avg burst size = %.2f\n", lcore, (unsigned) port, ((double) lp->tx.nic_ports_count[port]) / ((double) lp->tx.nic_ports_iters[port])); lp->tx.nic_ports_iters[port] = 0; lp->tx.nic_ports_count[port] = 0; } #endif if (unlikely(n_pkts < n_mbufs)) { uint32_t k; for (k = n_pkts; k < n_mbufs; k ++) { struct rte_mbuf *pkt_to_free = lp->tx.mbuf_out[port].array[k]; rte_pktmbuf_free(pkt_to_free); } } lp->tx.mbuf_out[port].n_mbufs = 0; lp->tx.mbuf_out_flush[port] = 0; } } }