@@ -34,6 +34,10 @@ SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+#ifeq ($(CONFIG_RTE_TEST_PMD_NOISY),y)
+#SRCS-y += fifo.c
+#endif
+
ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC)$(CONFIG_RTE_LIBRTE_SCHED),yy)
SRCS-y += tm.c
endif
new file mode 100644
@@ -0,0 +1,16 @@
+#ifdef RTE_TEST_PMD_NOISY
+//#include <rte_ring.h>
+#include "fifo.h"
+//#include "testpmd.h"
+
+
+struct rte_ring * fifo_init(uint32_t qi)
+{
+ struct noisy_config *n = &noisy_cfg[qi];
+
+ n->f = rte_ring_create("noisy ring", 1024, rte_socket_id(),
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+ return n->f;
+}
+
+#endif
@@ -36,6 +36,7 @@
#include <rte_flow.h>
#include "testpmd.h"
+#include "fifo.h"
/*
* Forwarding of packets in I/O mode.
@@ -48,7 +49,7 @@ pkt_burst_io_forward(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
uint16_t nb_rx;
- uint16_t nb_tx;
+ uint16_t nb_tx = 0;
uint32_t retry;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
@@ -56,6 +57,15 @@ pkt_burst_io_forward(struct fwd_stream *fs)
uint64_t end_tsc;
uint64_t core_cycles;
#endif
+#ifdef RTE_TEST_PMD_NOISY
+ const uint64_t freq_khz = rte_get_timer_hz() / 1000;
+ struct noisy_config *ncf = &noisy_cfg[fs->tx_queue];
+ struct rte_mbuf *tmp_pkts[MAX_PKT_BURST];
+ uint16_t nb_enqd;
+ uint16_t nb_deqd = 0;
+ uint64_t delta_ms;
+ uint64_t now;
+#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
@@ -73,8 +83,55 @@ pkt_burst_io_forward(struct fwd_stream *fs)
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
#endif
+#ifdef RTE_TEST_PMD_NOISY
+ if (bsize_before_send > 0) {
+ if (rte_ring_free_count(ncf->f) >= nb_rx) {
+ /* enqueue into fifo */
+ nb_enqd = fifo_put(ncf->f, pkts_burst, nb_rx);
+ if (nb_enqd < nb_rx)
+ nb_rx = nb_enqd;
+ } else {
+ /* fifo is full, dequeue first */
+ nb_deqd = fifo_get(ncf->f, tmp_pkts, nb_rx);
+ /* enqueue into fifo */
+ nb_enqd = fifo_put(ncf->f, pkts_burst, nb_deqd);
+ if (nb_enqd < nb_rx)
+ nb_rx = nb_enqd;
+ if (nb_deqd > 0)
+ nb_tx = rte_eth_tx_burst(fs->tx_port,
+ fs->tx_queue, tmp_pkts,
+ nb_deqd);
+ }
+ } else {
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
+ pkts_burst, nb_rx);
+ }
+
+ /*
+ * TX burst queue drain
+ */
+ if (ncf->prev_time == 0) {
+ now = ncf->prev_time = rte_get_timer_cycles();
+ } else {
+ now = rte_get_timer_cycles();
+ }
+ delta_ms = (now - ncf->prev_time) / freq_khz;
+ if (unlikely(delta_ms >= flush_timer) && flush_timer > 0 && (nb_tx == 0)) {
+ while (fifo_count(ncf->f) > 0) {
+ nb_deqd = fifo_get(ncf->f, tmp_pkts, nb_rx);
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
+ tmp_pkts, nb_deqd);
+ if(rte_ring_empty(ncf->f))
+ break;
+ }
+ ncf->prev_time = now;
+ }
+ if (nb_tx < nb_rx && fs->retry_enabled)
+ *pkts_burst = *tmp_pkts;
+#else
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
pkts_burst, nb_rx);
+#endif
/*
* Retry if necessary
*/
@@ -621,6 +621,8 @@ launch_args_parse(int argc, char** argv)
{ "print-event", 1, 0, 0 },
{ "mask-event", 1, 0, 0 },
{ "tx-offloads", 1, 0, 0 },
+ { "buffersize-before-sending", 1, 0, 0 },
+ { "flush-timer", 1, 0, 0 },
{ 0, 0, 0, 0 },
};
@@ -1102,7 +1104,24 @@ launch_args_parse(int argc, char** argv)
rte_exit(EXIT_FAILURE,
"invalid mask-event argument\n");
}
-
+#ifdef RTE_TEST_PMD_NOISY
+ if (!strcmp(lgopts[opt_idx].name, "buffersize-before-sending")) {
+ n = atoi(optarg);
+ if (n > 0)
+ bsize_before_send = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "buffersize-before-sending must be > 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "flush-timer")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ flush_timer = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "flush-timer must be > 0\n");
+ }
+#endif
break;
case 'h':
usage(argv[0]);
@@ -59,6 +59,9 @@
#ifdef RTE_LIBRTE_LATENCY_STATS
#include <rte_latencystats.h>
#endif
+#ifdef RTE_TEST_PMD_NOISY
+#include "fifo.h"
+#endif
#include "testpmd.h"
@@ -249,6 +252,18 @@ int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
*/
int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
+#ifdef RTE_TEST_PMD_NOISY
+/*
+ * Configurable value of buffered packed before sending.
+ */
+uint16_t bsize_before_send = 0;
+
+/*
+ * Configurable value of packet buffer timeout.
+ */
+uint16_t flush_timer = 0;
+#endif
+
/*
* Receive Side Scaling (RSS) configuration.
*/
@@ -401,6 +416,20 @@ static int all_ports_started(void);
struct gso_status gso_ports[RTE_MAX_ETHPORTS];
uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
+#ifdef RTE_TEST_PMD_NOISY
+#define STRSIZE 256
+#define NOISY_RING "noisy_ring_%d:%d\n"
+struct rte_ring * fifo_init(uint32_t qi, uint32_t pi)
+{
+ struct noisy_config *n = &noisy_cfg[qi];
+ char name[STRSIZE];
+
+ snprintf(name, STRSIZE, NOISY_RING, pi, qi);
+ n->f = rte_ring_create(name, bsize_before_send, rte_socket_id(), 0);
+ return n->f;
+}
+#endif
+
/*
* Helper function to check if socket is already discovered.
* If yes, return positive value. If not, return zero.
@@ -1584,6 +1613,16 @@ start_port(portid_t pid)
return -1;
}
}
+#ifdef RTE_TEST_PMD_NOISY
+ noisy_cfg = (struct noisy_config *) rte_zmalloc("testpmd noisy fifo and timers",
+ nb_txq * sizeof(struct noisy_config),
+ RTE_CACHE_LINE_SIZE);
+ if (noisy_cfg == NULL) {
+ rte_exit(EXIT_FAILURE,
+ "rte_zmalloc(%d struct noisy_config) failed\n",
+ (int)(nb_txq * sizeof(struct noisy_config)));
+ }
+#endif
if (port->need_reconfig_queues > 0) {
port->need_reconfig_queues = 0;
port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
@@ -1591,6 +1630,11 @@ start_port(portid_t pid)
port->tx_conf.offloads = port->dev_conf.txmode.offloads;
/* setup tx queues */
for (qi = 0; qi < nb_txq; qi++) {
+#ifdef RTE_TEST_PMD_NOISY
+ if (!fifo_init(qi, pi) && bsize_before_send > 0)
+ rte_exit(EXIT_FAILURE, "%s\n",
+ rte_strerror(rte_errno));
+#endif
if ((numa_support) &&
(txring_numa[pi] != NUMA_NO_CONFIG))
diag = rte_eth_tx_queue_setup(pi, qi,
@@ -1755,6 +1799,10 @@ stop_port(portid_t pid)
RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
printf("Port %d can not be set into stopped\n", pi);
need_check_link_status = 1;
+
+#ifdef RTE_TEST_PMD_NOISY
+ rte_free(noisy_cfg);
+#endif
}
if (need_check_link_status && !no_link_check)
check_all_ports_link_status(RTE_PORT_ALL);
@@ -9,6 +9,9 @@
#include <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#ifdef RTE_TEST_PMD_NOISY
+#include "fifo.h"
+#endif
#define RTE_PORT_ALL (~(portid_t)0x0)
@@ -109,6 +112,15 @@ struct fwd_stream {
#endif
};
+#ifdef RTE_TEST_PMD_NOISY
+struct noisy_config {
+ struct rte_ring *f;
+ uint64_t prev_time;
+};
+struct noisy_config *noisy_cfg;
+#endif
+
+
/** Descriptor for a single flow. */
struct port_flow {
size_t size; /**< Allocated space including data[]. */
@@ -382,6 +394,9 @@ extern int8_t rx_drop_en;
extern int16_t tx_free_thresh;
extern int16_t tx_rs_thresh;
+extern uint16_t bsize_before_send;
+extern uint16_t flush_timer;
+
extern uint8_t dcb_config;
extern uint8_t dcb_test;
@@ -808,6 +808,7 @@ CONFIG_RTE_PROC_INFO=n
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+CONFIG_RTE_TEST_PMD_NOISY=y
#
# Compile the bbdev test application