Add several options to simulate route lookups (memory reads) in tables that can be quite large, as well as route hit statistics update. These options simulates the while stack traversal and will trash the cache. Memory access is random.
Options to simulate route lookups: --memory-footprint [size] Size of the VNF internal memory (MB), in which the random read/write will be done, allocated by rte_malloc (hugepages). --nb-rnd-write [num] Number of random writes in memory per packet should be performed, simulating hit-flags update. 64 bits per write, all write in different cache lines. --nb-rnd-read [num] Number of random reads in memory per packet should be performed, simulating FIB/table lookups. 64 bits per read, all write in different cache lines. --nb-rnd-read-write [num] Number of random reads and writes in memory per packet should be performed, simulating stats update. 64 bits per read-write, all reads and writes in different cache lines. Signed-off-by: Jens Freimann <jfreim...@redhat.com> --- app/test-pmd/iofwd.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/parameters.c | 36 ++++++++++++++++++++++++++++++++++ app/test-pmd/testpmd.c | 30 ++++++++++++++++++++++++++++ app/test-pmd/testpmd.h | 5 +++++ 4 files changed, 121 insertions(+) diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c index 85fa000f7..e69727e2c 100644 --- a/app/test-pmd/iofwd.c +++ b/app/test-pmd/iofwd.c @@ -34,10 +34,57 @@ #include <rte_ethdev.h> #include <rte_string_fns.h> #include <rte_flow.h> +#include <rte_malloc.h> #include "testpmd.h" #include "fifo.h" +static inline void +do_write(char *vnf_mem) +{ + uint64_t i = rte_rand(); + uint64_t w = rte_rand(); + + vnf_mem[i % ((vnf_memory_footprint * 1024 * 1024 ) / + RTE_CACHE_LINE_SIZE)] = w; +} + +static inline void +do_read(char *vnf_mem) +{ + uint64_t i = rte_rand(); + uint64_t r = 0; + + r = vnf_mem[i % ((vnf_memory_footprint * 1024 * 1024 ) / + RTE_CACHE_LINE_SIZE)]; + r++; +} + +static inline void +do_rw(char *vnf_mem) +{ + do_read(vnf_mem); + do_write(vnf_mem); +} + +/* + * Simulate route lookups as defined by commandline parameters + */ +static void +sim_memory_lookups(struct noisy_config *ncf, uint16_t nb_pkts) +{ + uint16_t i,j; + + for (i = 0; i < nb_pkts; i++) { + for (j = 0; j < nb_rnd_write; j++) + do_write(ncf->vnf_mem); + for (j = 0; j < nb_rnd_read; j++) + do_read(ncf->vnf_mem); + for (j = 0; j < nb_rnd_read_write; j++) + do_rw(ncf->vnf_mem); + } +} + /* * Forwarding of packets in I/O mode. * Forward packets "as-is". @@ -107,6 +154,9 @@ pkt_burst_io_forward(struct fwd_stream *fs) pkts_burst, nb_rx); } + /* simulate noisy vnf by trashing cache lines, simulate route lookups */ + sim_memory_lookups(ncf, nb_rx); + /* * TX burst queue drain */ diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index df0db933a..78e146164 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -623,6 +623,10 @@ launch_args_parse(int argc, char** argv) { "tx-offloads", 1, 0, 0 }, { "buffersize-before-sending", 1, 0, 0 }, { "flush-timer", 1, 0, 0 }, + { "memory-footprint", 1, 0, 0 }, + { "nb-rnd-write", 1, 0, 0 }, + { "nb-rnd-read", 1, 0, 0 }, + { "nb-rnd-read-write", 1, 0, 0 }, { 0, 0, 0, 0 }, }; @@ -1120,6 +1124,38 @@ launch_args_parse(int argc, char** argv) rte_exit(EXIT_FAILURE, "flush-timer must be > 0\n"); } + if (!strcmp(lgopts[opt_idx].name, "memory-footprint")) { + n = atoi(optarg); + if (n > 0) + vnf_memory_footprint = (uint16_t) n; + else + rte_exit(EXIT_FAILURE, + "memory-footprint must be > 0\n"); + } + if (!strcmp(lgopts[opt_idx].name, "nb-rnd-write")) { + n = atoi(optarg); + if (n > 0) + nb_rnd_write = (uint16_t) n; + else + rte_exit(EXIT_FAILURE, + "nb-rnd-write must be > 0\n"); + } + if (!strcmp(lgopts[opt_idx].name, "nb-rnd-read")) { + n = atoi(optarg); + if (n > 0) + nb_rnd_read = (uint16_t) n; + else + rte_exit(EXIT_FAILURE, + "nb-rnd-read must be > 0\n"); + } + if (!strcmp(lgopts[opt_idx].name, "nb-rnd-read-write")) { + n = atoi(optarg); + if (n > 0) + nb_rnd_read_write = (uint16_t) n; + else + rte_exit(EXIT_FAILURE, + "nb-rnd-read-write must be > 0\n"); + } #endif break; case 'h': diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 7b8ffdc9c..d33139a89 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -262,6 +262,30 @@ uint16_t bsize_before_send = 0; * Configurable value of packet buffer timeout. */ uint16_t flush_timer = 0; + +/* + * Configurable value for size of VNF internal memory area + * used for simulating noisy neighbour behaviour + */ +uint64_t vnf_memory_footprint = 0; + +/* + * Configurable value of number of random writes done in + * VNF simulation memory area. + */ +uint64_t nb_rnd_write = 0; + +/* + * Configurable value of number of random reads done in + * VNF simulation memory area. + */ +uint64_t nb_rnd_read = 0; + +/* + * Configurable value of number of random reads/wirtes done in + * VNF simulation memory area. + */ +uint64_t nb_rnd_read_write = 0; #endif /* @@ -426,6 +450,12 @@ struct rte_ring * fifo_init(uint32_t qi, uint32_t pi) snprintf(name, STRSIZE, NOISY_RING, pi, qi); n->f = rte_ring_create(name, bsize_before_send, rte_socket_id(), 0); + n->vnf_mem = (char *) rte_zmalloc("vnf sim memory", + vnf_memory_footprint * 1024 * 1024, + RTE_CACHE_LINE_SIZE); + if (n->vnf_mem == NULL) + printf("allocating vnf memory failed\n"); + return n->f; } #endif diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index a6c1a17bb..0411b5266 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -116,6 +116,7 @@ struct fwd_stream { struct noisy_config { struct rte_ring *f; uint64_t prev_time; + char *vnf_mem; }; struct noisy_config *noisy_cfg; #endif @@ -396,6 +397,10 @@ extern int16_t tx_rs_thresh; extern uint16_t bsize_before_send; extern uint16_t flush_timer; +extern uint64_t vnf_memory_footprint; +extern uint64_t nb_rnd_write; +extern uint64_t nb_rnd_read; +extern uint64_t nb_rnd_read_write; extern uint8_t dcb_config; extern uint8_t dcb_test; -- 2.14.3