DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC 0/1] testpmd: simulating noisy host environment
@ 2018-03-23 15:35 Jens Freimann
  2018-03-23 15:35 ` [dpdk-dev] [PATCH 1/1] testpmd: add parameters buffersize-before-send and flush-timeout Jens Freimann
  0 siblings, 1 reply; 2+ messages in thread
From: Jens Freimann @ 2018-03-23 15:35 UTC (permalink / raw)
  To: dev; +Cc: ailan, jan.scheurich, vkaplans, bruce.richardson, thomas

This is an addition to testpmd that will allow to simulate a noisy
neighbour VNF.  It was previously discussed here:
http://dpdk.org/ml/archives/dev/2017-October/080763.html

It was not thoroughly tested and doesn't implement all features yet. I'm
sending this only for early feedback about how to approach this. 

Currently I've implmented the logic to buffer incoming packets and flush
the queue after a timeout has expired. The logic resides in the iofwd
code as an example. I think it needs to be in the forwarding mode logic
as packets are send and received from there. To avoid code duplication
some of it could be extracted into new helpers and changes to the
individual forward mode code kept minimal.

What is missing is actual functionality to simulate route lookups (by
doing random r/w memory accesses) and to simulate packet processing.
I'm working on this, but would like to get feedback on what I have so
far.  


regards, Jens 


Jens Freimann (1):
  testpmd: add parameters buffersize-before-send and flush-timeout

 app/test-pmd/Makefile     |  4 ++++
 app/test-pmd/fifo.c       | 16 +++++++++++++
 app/test-pmd/iofwd.c      | 59 ++++++++++++++++++++++++++++++++++++++++++++++-
 app/test-pmd/parameters.c | 21 ++++++++++++++++-
 app/test-pmd/testpmd.c    | 48 ++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h    | 15 ++++++++++++
 config/common_base        |  1 +
 7 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 app/test-pmd/fifo.c

-- 
2.14.3

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [dpdk-dev] [PATCH 1/1] testpmd: add parameters buffersize-before-send and flush-timeout
  2018-03-23 15:35 [dpdk-dev] [RFC 0/1] testpmd: simulating noisy host environment Jens Freimann
@ 2018-03-23 15:35 ` Jens Freimann
  0 siblings, 0 replies; 2+ messages in thread
From: Jens Freimann @ 2018-03-23 15:35 UTC (permalink / raw)
  To: dev; +Cc: ailan, jan.scheurich, vkaplans, bruce.richardson, thomas

Create a fifo to buffer received packets. Once it flows over put
those packets into the actual tx queue. The fifo is created per tx
queue and its size can be set with the --buffersize-before-sending
commandline parameter.

A second commandline parameter is used to set a timeout in
milliseconds after which the fifo is flushed.


Signed-off-by: Jens Freimann <jfreimann@redhat.com>
---
 app/test-pmd/Makefile     |  4 ++++
 app/test-pmd/fifo.c       | 16 +++++++++++++
 app/test-pmd/iofwd.c      | 59 ++++++++++++++++++++++++++++++++++++++++++++++-
 app/test-pmd/parameters.c | 21 ++++++++++++++++-
 app/test-pmd/testpmd.c    | 48 ++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h    | 15 ++++++++++++
 config/common_base        |  1 +
 7 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 app/test-pmd/fifo.c

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 60ae9b9c1..9254a9440 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -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
diff --git a/app/test-pmd/fifo.c b/app/test-pmd/fifo.c
new file mode 100644
index 000000000..2271215e8
--- /dev/null
+++ b/app/test-pmd/fifo.c
@@ -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
diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c
index 9dce76efe..85fa000f7 100644
--- a/app/test-pmd/iofwd.c
+++ b/app/test-pmd/iofwd.c
@@ -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
 	 */
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 97d22b860..8e64055a0 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -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]);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c0e2586c..7b8ffdc9c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -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);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 153abea05..a6c1a17bb 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -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;
 
diff --git a/config/common_base b/config/common_base
index ad03cf433..194e5901f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -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
-- 
2.14.3

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-03-23 15:35 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-23 15:35 [dpdk-dev] [RFC 0/1] testpmd: simulating noisy host environment Jens Freimann
2018-03-23 15:35 ` [dpdk-dev] [PATCH 1/1] testpmd: add parameters buffersize-before-send and flush-timeout Jens Freimann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).