Exemple #1
0
/**
 * test main entrance for library sched
 */
static int
test_sched(void)
{
	struct rte_mempool *mp = NULL;
	struct rte_sched_port *port = NULL;
	uint32_t pipe;
	struct rte_mbuf *in_mbufs[10];
	struct rte_mbuf *out_mbufs[10];
	int i;

	int err;

	mp = create_mempool();

	port_param.socket = 0;
	port_param.rate = (uint64_t) 10000 * 1000 * 1000 / 8;

	port = rte_sched_port_config(&port_param);
	VERIFY(port != NULL, "Error config sched port\n");


	err = rte_sched_subport_config(port, SUBPORT, subport_param);
	VERIFY(err == 0, "Error config sched, err=%d\n", err);

	for (pipe = 0; pipe < port_param.n_pipes_per_subport; pipe ++) {
		err = rte_sched_pipe_config(port, SUBPORT, pipe, 0);
		VERIFY(err == 0, "Error config sched pipe %u, err=%d\n", pipe, err);
	}

	for (i = 0; i < 10; i++) {
		in_mbufs[i] = rte_pktmbuf_alloc(mp);
		prepare_pkt(in_mbufs[i]);
	}


	err = rte_sched_port_enqueue(port, in_mbufs, 10);
	VERIFY(err == 10, "Wrong enqueue, err=%d\n", err);

	err = rte_sched_port_dequeue(port, out_mbufs, 10);
	VERIFY(err == 10, "Wrong dequeue, err=%d\n", err);

	for (i = 0; i < 10; i++) {
		enum rte_meter_color color;
		uint32_t subport, traffic_class, queue;

		color = rte_sched_port_pkt_read_color(out_mbufs[i]);
		VERIFY(color == e_RTE_METER_YELLOW, "Wrong color\n");

		rte_sched_port_pkt_read_tree_path(out_mbufs[i],
				&subport, &pipe, &traffic_class, &queue);

		VERIFY(subport == SUBPORT, "Wrong subport\n");
		VERIFY(pipe == PIPE, "Wrong pipe\n");
		VERIFY(traffic_class == TC, "Wrong traffic_class\n");
		VERIFY(queue == QUEUE, "Wrong queue\n");

	}


	struct rte_sched_subport_stats subport_stats;
	uint32_t tc_ov;
	rte_sched_subport_read_stats(port, SUBPORT, &subport_stats, &tc_ov);
	//VERIFY(subport_stats.n_pkts_tc[TC-1] == 10, "Wrong subport stats\n");

	struct rte_sched_queue_stats queue_stats;
	uint16_t qlen;
	rte_sched_queue_read_stats(port, QUEUE, &queue_stats, &qlen);
	//VERIFY(queue_stats.n_pkts == 10, "Wrong queue stats\n");

	rte_sched_port_free(port);

	return 0;
}
Exemple #2
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;
    }
  }
}