DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
From: <jerinj@marvell.com>
Cc: <dev@dpdk.org>, <thomas@monjalon.net>,
	<david.marchand@redhat.com>, <mdr@ashroe.eu>,
	<mattias.ronnblom@ericsson.com>, <kirankumark@marvell.com>,
	<pbhagavatula@marvell.com>, <ndabilpuram@marvell.com>
Subject: [dpdk-dev]  [PATCH v2 13/28] graph: add unit test case
Date: Thu, 26 Mar 2020 22:26:29 +0530
Message-ID: <20200326165644.866053-14-jerinj@marvell.com> (raw)
In-Reply-To: <20200326165644.866053-1-jerinj@marvell.com>

From: Kiran Kumar K <kirankumark@marvell.com>

Adding the unit test to test the functionality of node and graph APIs.
Testing includes registering a node, cloning a node, creating a graph,
perform graph walk, collecting stats and all node and graph debug APIs.

example command to test:
echo "graph_autotest" | sudo ./build/app/test/dpdk-test -c 0x30

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
---
 app/test/Makefile     |   6 +
 app/test/meson.build  |  11 +-
 app/test/test_graph.c | 819 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 834 insertions(+), 2 deletions(-)
 create mode 100644 app/test/test_graph.c

diff --git a/app/test/Makefile b/app/test/Makefile
index 1f080d162..ce2e08e12 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -221,6 +221,10 @@ SRCS-y += test_event_timer_adapter.c
 SRCS-y += test_event_crypto_adapter.c
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_GRAPH), y)
+SRCS-y += test_graph.c
+endif
+
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 SRCS-y += test_rawdev.c
 endif
@@ -240,6 +244,8 @@ endif
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 CFLAGS += -O3
+# Strict-aliasing rules are violated by uint8_t[] to context size casts.
+CFLAGS += -fno-strict-aliasing
 CFLAGS += $(WERROR_FLAGS)
 
 LDLIBS += -lm
diff --git a/app/test/meson.build b/app/test/meson.build
index 351d29cb6..0de16290e 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -51,6 +51,7 @@ test_sources = files('commands.c',
 	'test_fib6_perf.c',
 	'test_func_reentrancy.c',
 	'test_flow_classify.c',
+	'test_graph.c',
 	'test_hash.c',
 	'test_hash_functions.c',
 	'test_hash_multiwriter.c',
@@ -151,7 +152,9 @@ test_deps = ['acl',
 	'rib',
 	'ring',
 	'stack',
-	'timer'
+	'timer',
+	'graph',
+	'node'
 ]
 
 # Each test is marked with flag true/false
@@ -362,6 +365,8 @@ endif
 
 # specify -D_GNU_SOURCE unconditionally
 cflags += '-D_GNU_SOURCE'
+# Strict-aliasing rules are violated by uint8_t[] to context size casts.
+cflags += '-fno-strict-aliasing'
 
 test_dep_objs = []
 if dpdk_conf.has('RTE_LIBRTE_COMPRESSDEV')
@@ -385,13 +390,15 @@ endforeach
 test_dep_objs += cc.find_library('execinfo', required: false)
 
 link_libs = []
+link_nodes = []
 if get_option('default_library') == 'static'
 	link_libs = dpdk_drivers
+	link_nodes = dpdk_graph_nodes
 endif
 
 dpdk_test = executable('dpdk-test',
 	test_sources,
-	link_whole: link_libs,
+	link_whole: link_libs + link_nodes,
 	dependencies: test_dep_objs,
 	c_args: [cflags, '-DALLOW_EXPERIMENTAL_API'],
 	install_rpath: driver_install_path,
diff --git a/app/test/test_graph.c b/app/test/test_graph.c
new file mode 100644
index 000000000..a90dc8f30
--- /dev/null
+++ b/app/test/test_graph.c
@@ -0,0 +1,819 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+#include <assert.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rte_errno.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_mbuf.h>
+
+#include "test.h"
+
+static uint16_t test_node_worker_source(struct rte_graph *graph,
+					struct rte_node *node, void **objs,
+					uint16_t nb_objs);
+
+static uint16_t test_node0_worker(struct rte_graph *graph,
+				  struct rte_node *node, void **objs,
+				  uint16_t nb_objs);
+
+static uint16_t test_node1_worker(struct rte_graph *graph,
+				  struct rte_node *node, void **objs,
+				  uint16_t nb_objs);
+
+static uint16_t test_node2_worker(struct rte_graph *graph,
+				  struct rte_node *node, void **objs,
+				  uint16_t nb_objs);
+
+static uint16_t test_node3_worker(struct rte_graph *graph,
+				  struct rte_node *node, void **objs,
+				  uint16_t nb_objs);
+
+#define MBUFF_SIZE 512
+#define MAX_NODES  4
+
+static struct rte_mbuf mbuf[MAX_NODES + 1][MBUFF_SIZE];
+static void *mbuf_p[MAX_NODES + 1][MBUFF_SIZE];
+static rte_graph_t graph_id;
+static uint64_t obj_stats[MAX_NODES + 1];
+static uint64_t fn_calls[MAX_NODES + 1];
+
+const char *node_patterns[] = {
+	"test_node_source1",	   "test_node00",
+	"test_node00-test_node11", "test_node00-test_node22",
+	"test_node00-test_node33",
+};
+
+const char *node_names[] = {
+	"test_node00",
+	"test_node00-test_node11",
+	"test_node00-test_node22",
+	"test_node00-test_node33",
+};
+
+struct test_node_register {
+	char name[RTE_NODE_NAMESIZE];
+	rte_node_process_t process;
+	uint16_t nb_edges;
+	const char *next_nodes[MAX_NODES];
+};
+
+typedef struct {
+	uint32_t idx;
+	struct test_node_register node;
+} test_node_t;
+
+typedef struct {
+	test_node_t test_node[MAX_NODES];
+} test_main_t;
+
+static test_main_t test_main = {
+	.test_node = {
+		{
+			.node = {
+					.name = "test_node00",
+					.process = test_node0_worker,
+					.nb_edges = 2,
+					.next_nodes = {"test_node00-"
+						       "test_node11",
+						       "test_node00-"
+						       "test_node22"},
+				},
+		},
+		{
+			.node = {
+					.name = "test_node11",
+					.process = test_node1_worker,
+					.nb_edges = 1,
+					.next_nodes = {"test_node00-"
+						       "test_node22"},
+				},
+		},
+		{
+			.node = {
+					.name = "test_node22",
+					.process = test_node2_worker,
+					.nb_edges = 1,
+					.next_nodes = {"test_node00-"
+						       "test_node33"},
+				},
+		},
+		{
+			.node = {
+					.name = "test_node33",
+					.process = test_node3_worker,
+					.nb_edges = 1,
+					.next_nodes = {"test_node00"},
+				},
+		},
+	},
+};
+
+static int
+node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	RTE_SET_USED(graph);
+	*(uint32_t *)node->ctx = node->id;
+
+	return 0;
+}
+
+static struct rte_node_register test_node_source = {
+	.name = "test_node_source1",
+	.process = test_node_worker_source,
+	.flags = RTE_NODE_SOURCE_F,
+	.nb_edges = 2,
+	.init = node_init,
+	.next_nodes = {"test_node00", "test_node00-test_node11"},
+};
+RTE_NODE_REGISTER(test_node_source);
+
+static struct rte_node_register test_node0 = {
+	.name = "test_node00",
+	.process = test_node0_worker,
+	.init = node_init,
+};
+RTE_NODE_REGISTER(test_node0);
+
+uint16_t
+test_node_worker_source(struct rte_graph *graph, struct rte_node *node,
+			void **objs, uint16_t nb_objs)
+{
+	uint32_t obj_node0 = rand() % 100, obj_node1;
+	test_main_t *tm = &test_main;
+	struct rte_mbuf *data;
+	void **next_stream;
+	rte_node_t next;
+	uint32_t i;
+
+	RTE_SET_USED(objs);
+	nb_objs = RTE_GRAPH_BURST_SIZE;
+
+	/* Prepare stream for next node 0 */
+	obj_node0 = nb_objs * obj_node0 * 0.01;
+	next = 0;
+	next_stream = rte_node_next_stream_get(graph, node, next, obj_node0);
+	for (i = 0; i < obj_node0; i++) {
+		data = &mbuf[0][i];
+		data->udata64 = ((uint64_t)tm->test_node[0].idx << 32) | i;
+		if ((i + 1) == obj_node0)
+			data->udata64 |= (1 << 16);
+		next_stream[i] = &mbuf[0][i];
+	}
+	rte_node_next_stream_put(graph, node, next, obj_node0);
+
+	/* Prepare stream for next node 1 */
+	obj_node1 = nb_objs - obj_node0;
+	next = 1;
+	next_stream = rte_node_next_stream_get(graph, node, next, obj_node1);
+	for (i = 0; i < obj_node1; i++) {
+		data = &mbuf[0][obj_node0 + i];
+		data->udata64 = ((uint64_t)tm->test_node[1].idx << 32) | i;
+		if ((i + 1) == obj_node1)
+			data->udata64 |= (1 << 16);
+		next_stream[i] = &mbuf[0][obj_node0 + i];
+	}
+
+	rte_node_next_stream_put(graph, node, next, obj_node1);
+	obj_stats[0] += nb_objs;
+	fn_calls[0] += 1;
+	return nb_objs;
+}
+
+uint16_t
+test_node0_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
+		  uint16_t nb_objs)
+{
+	test_main_t *tm = &test_main;
+
+	if (*(uint32_t *)node->ctx == test_node0.id) {
+		uint32_t obj_node0 = rand() % 100, obj_node1;
+		struct rte_mbuf *data;
+		uint8_t second_pass = 0;
+		uint32_t count = 0;
+		uint32_t i;
+
+		obj_stats[1] += nb_objs;
+		fn_calls[1] += 1;
+
+		for (i = 0; i < nb_objs; i++) {
+			data = (struct rte_mbuf *)objs[i];
+			if ((data->udata64 >> 32) != tm->test_node[0].idx) {
+				printf("Data idx miss match at node 0, expected"
+				       " = %u got = %u\n",
+				       tm->test_node[0].idx,
+				       (uint32_t)(data->udata64 >> 32));
+				goto end;
+			}
+
+			if ((data->udata64 & 0xffff) != (i - count)) {
+				printf("Expected buff count miss match at "
+				       "node 0\n");
+				goto end;
+			}
+
+			if (data->udata64 & (0x1 << 16))
+				count = i + 1;
+			if (data->udata64 & (0x1 << 17))
+				second_pass = 1;
+		}
+
+		if (count != i) {
+			printf("Count mismatch at node 0\n");
+			goto end;
+		}
+
+		obj_node0 = nb_objs * obj_node0 * 0.01;
+		for (i = 0; i < obj_node0; i++) {
+			data = &mbuf[1][i];
+			data->udata64 =
+				((uint64_t)tm->test_node[1].idx << 32) | i;
+			if ((i + 1) == obj_node0)
+				data->udata64 |= (1 << 16);
+			if (second_pass)
+				data->udata64 |= (1 << 17);
+		}
+		rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[1][0],
+				 obj_node0);
+
+		obj_node1 = nb_objs - obj_node0;
+		for (i = 0; i < obj_node1; i++) {
+			data = &mbuf[1][obj_node0 + i];
+			data->udata64 =
+				((uint64_t)tm->test_node[2].idx << 32) | i;
+			if ((i + 1) == obj_node1)
+				data->udata64 |= (1 << 16);
+			if (second_pass)
+				data->udata64 |= (1 << 17);
+		}
+		rte_node_enqueue(graph, node, 1, (void **)&mbuf_p[1][obj_node0],
+				 obj_node1);
+
+	} else if (*(uint32_t *)node->ctx == tm->test_node[1].idx) {
+		test_node1_worker(graph, node, objs, nb_objs);
+	} else if (*(uint32_t *)node->ctx == tm->test_node[2].idx) {
+		test_node2_worker(graph, node, objs, nb_objs);
+	} else if (*(uint32_t *)node->ctx == tm->test_node[3].idx) {
+		test_node3_worker(graph, node, objs, nb_objs);
+	} else {
+		printf("Unexpected node context\n");
+	}
+
+end:
+	return nb_objs;
+}
+
+uint16_t
+test_node1_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
+		  uint16_t nb_objs)
+{
+	test_main_t *tm = &test_main;
+	uint8_t second_pass = 0;
+	uint32_t obj_node0 = 0;
+	struct rte_mbuf *data;
+	uint32_t count = 0;
+	uint32_t i;
+
+	obj_stats[2] += nb_objs;
+	fn_calls[2] += 1;
+	for (i = 0; i < nb_objs; i++) {
+		data = (struct rte_mbuf *)objs[i];
+		if ((data->udata64 >> 32) != tm->test_node[1].idx) {
+			printf("Data idx miss match at node 1, expected = %u"
+			       " got = %u\n",
+			       tm->test_node[1].idx,
+			       (uint32_t)(data->udata64 >> 32));
+			goto end;
+		}
+
+		if ((data->udata64 & 0xffff) != (i - count)) {
+			printf("Expected buff count miss match at node 1\n");
+			goto end;
+		}
+
+		if (data->udata64 & (0x1 << 16))
+			count = i + 1;
+		if (data->udata64 & (0x1 << 17))
+			second_pass = 1;
+	}
+
+	if (count != i) {
+		printf("Count mismatch at node 1\n");
+		goto end;
+	}
+
+	obj_node0 = nb_objs;
+	for (i = 0; i < obj_node0; i++) {
+		data = &mbuf[2][i];
+		data->udata64 = ((uint64_t)tm->test_node[2].idx << 32) | i;
+		if ((i + 1) == obj_node0)
+			data->udata64 |= (1 << 16);
+		if (second_pass)
+			data->udata64 |= (1 << 17);
+	}
+	rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[2][0], obj_node0);
+
+end:
+	return nb_objs;
+}
+
+uint16_t
+test_node2_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
+		  uint16_t nb_objs)
+{
+	test_main_t *tm = &test_main;
+	uint8_t second_pass = 0;
+	struct rte_mbuf *data;
+	uint32_t count = 0;
+	uint32_t obj_node0;
+	uint32_t i;
+
+	obj_stats[3] += nb_objs;
+	fn_calls[3] += 1;
+	for (i = 0; i < nb_objs; i++) {
+		data = (struct rte_mbuf *)objs[i];
+		if ((data->udata64 >> 32) != tm->test_node[2].idx) {
+			printf("Data idx miss match at node 2, expected = %u"
+			       " got = %u\n",
+			       tm->test_node[2].idx,
+			       (uint32_t)(data->udata64 >> 32));
+			goto end;
+		}
+
+		if ((data->udata64 & 0xffff) != (i - count)) {
+			printf("Expected buff count miss match at node 2\n");
+			goto end;
+		}
+
+		if (data->udata64 & (0x1 << 16))
+			count = i + 1;
+		if (data->udata64 & (0x1 << 17))
+			second_pass = 1;
+	}
+
+	if (count != i) {
+		printf("Count mismatch at node 2\n");
+		goto end;
+	}
+
+	if (!second_pass) {
+		obj_node0 = nb_objs;
+		for (i = 0; i < obj_node0; i++) {
+			data = &mbuf[3][i];
+			data->udata64 =
+				((uint64_t)tm->test_node[3].idx << 32) | i;
+			if ((i + 1) == obj_node0)
+				data->udata64 |= (1 << 16);
+		}
+		rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[3][0],
+				 obj_node0);
+	}
+
+end:
+	return nb_objs;
+}
+
+uint16_t
+test_node3_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
+		  uint16_t nb_objs)
+{
+	test_main_t *tm = &test_main;
+	uint8_t second_pass = 0;
+	struct rte_mbuf *data;
+	uint32_t count = 0;
+	uint32_t obj_node0;
+	uint32_t i;
+
+	obj_stats[4] += nb_objs;
+	fn_calls[4] += 1;
+	for (i = 0; i < nb_objs; i++) {
+		data = (struct rte_mbuf *)objs[i];
+		if ((data->udata64 >> 32) != tm->test_node[3].idx) {
+			printf("Data idx miss match at node 3, expected = %u"
+			       " got = %u\n",
+			       tm->test_node[3].idx,
+			       (uint32_t)(data->udata64 >> 32));
+			goto end;
+		}
+
+		if ((data->udata64 & 0xffff) != (i - count)) {
+			printf("Expected buff count miss match at node 3\n");
+			goto end;
+		}
+
+		if (data->udata64 & (0x1 << 16))
+			count = i + 1;
+		if (data->udata64 & (0x1 << 17))
+			second_pass = 1;
+	}
+
+	if (count != i) {
+		printf("Count mismatch at node 3\n");
+		goto end;
+	}
+
+	if (second_pass) {
+		printf("Unexpected buffers are at node 3\n");
+		goto end;
+	} else {
+		obj_node0 = nb_objs * 2;
+		for (i = 0; i < obj_node0; i++) {
+			data = &mbuf[4][i];
+			data->udata64 =
+				((uint64_t)tm->test_node[0].idx << 32) | i;
+			data->udata64 |= (1 << 17);
+			if ((i + 1) == obj_node0)
+				data->udata64 |= (1 << 16);
+		}
+		rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[4][0],
+				 obj_node0);
+	}
+
+end:
+	return nb_objs;
+}
+
+static int
+test_lookup_functions(void)
+{
+	test_main_t *tm = &test_main;
+	int i;
+
+	/* Verify the name with ID */
+	for (i = 1; i < MAX_NODES; i++) {
+		char *name = rte_node_id_to_name(tm->test_node[i].idx);
+		if (strcmp(name, node_names[i]) != 0) {
+			printf("Test node name verify by ID = %d failed "
+			       "Expected = %s, got %s\n",
+			       i, node_names[i], name);
+			return -1;
+		}
+	}
+
+	/* Verify by name */
+	for (i = 1; i < MAX_NODES; i++) {
+		uint32_t idx = rte_node_from_name(node_names[i]);
+		if (idx != tm->test_node[i].idx) {
+			printf("Test node ID verify by name = %s failed "
+			       "Expected = %d, got %d\n",
+			       node_names[i], tm->test_node[i].idx, idx);
+			return -1;
+		}
+	}
+
+	/* Verify edge count */
+	for (i = 1; i < MAX_NODES; i++) {
+		uint32_t count = rte_node_edge_count(tm->test_node[i].idx);
+		if (count != tm->test_node[i].node.nb_edges) {
+			printf("Test number of edges for node = %s failed Expected = %d, got = %d\n",
+			       tm->test_node[i].node.name,
+			       tm->test_node[i].node.nb_edges, count);
+			return -1;
+		}
+	}
+
+	/* Verify edge names */
+	for (i = 1; i < MAX_NODES; i++) {
+		uint32_t j, count;
+		char **next_edges;
+
+		count = rte_node_edge_get(tm->test_node[i].idx, NULL);
+		if (count != tm->test_node[i].node.nb_edges * sizeof(char *)) {
+			printf("Test number of edge count for node = %s failed Expected = %d, got = %d\n",
+			       tm->test_node[i].node.name,
+			       tm->test_node[i].node.nb_edges, count);
+			return -1;
+		}
+		next_edges = malloc(count);
+		count = rte_node_edge_get(tm->test_node[i].idx, next_edges);
+		if (count != tm->test_node[i].node.nb_edges) {
+			printf("Test number of edges for node = %s failed Expected = %d, got %d\n",
+			       tm->test_node[i].node.name,
+			       tm->test_node[i].node.nb_edges, count);
+			return -1;
+		}
+
+		for (j = 0; j < count; j++) {
+			if (strcmp(next_edges[j],
+				   tm->test_node[i].node.next_nodes[j]) != 0) {
+				printf("Edge name miss match, expected = %s got = %s\n",
+				       tm->test_node[i].node.next_nodes[j],
+				       next_edges[j]);
+				return -1;
+			}
+		}
+		free(next_edges);
+	}
+
+	return 0;
+}
+
+static int
+test_node_clone(void)
+{
+	test_main_t *tm = &test_main;
+	uint32_t node_id, dummy_id;
+	int i;
+
+	node_id = rte_node_from_name("test_node00");
+	tm->test_node[0].idx = node_id;
+
+	/* Clone with same name, should fail */
+	dummy_id = rte_node_clone(node_id, "test_node00");
+	if (!rte_node_is_invalid(dummy_id)) {
+		printf("Got valid id when clone with same name, Expecting fail\n");
+		return -1;
+	}
+
+	for (i = 1; i < MAX_NODES; i++) {
+		tm->test_node[i].idx =
+			rte_node_clone(node_id, tm->test_node[i].node.name);
+		if (rte_node_is_invalid(tm->test_node[i].idx)) {
+			printf("Got invalid node id\n");
+			return -1;
+		}
+	}
+
+	/* Clone from cloned node should fail */
+	dummy_id = rte_node_clone(tm->test_node[1].idx, "dummy_node");
+	if (!rte_node_is_invalid(dummy_id)) {
+		printf("Got valid node id when cloning from cloned node, expected fail\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+test_update_edges(void)
+{
+	test_main_t *tm = &test_main;
+	uint32_t node_id;
+	uint16_t count;
+	int i;
+
+	node_id = rte_node_from_name("test_node00");
+	count = rte_node_edge_update(node_id, 0,
+				     tm->test_node[0].node.next_nodes,
+				     tm->test_node[0].node.nb_edges);
+	if (count != tm->test_node[0].node.nb_edges) {
+		printf("Update edges failed expected: %d got = %d\n",
+		       tm->test_node[0].node.nb_edges, count);
+		return -1;
+	}
+
+	for (i = 1; i < MAX_NODES; i++) {
+		count = rte_node_edge_update(tm->test_node[i].idx, 0,
+					     tm->test_node[i].node.next_nodes,
+					     tm->test_node[i].node.nb_edges);
+		if (count != tm->test_node[i].node.nb_edges) {
+			printf("Update edges failed expected: %d got = %d\n",
+			       tm->test_node[i].node.nb_edges, count);
+			return -1;
+		}
+
+		count = rte_node_edge_shrink(tm->test_node[i].idx,
+					     tm->test_node[i].node.nb_edges);
+		if (count != tm->test_node[i].node.nb_edges) {
+			printf("Shrink edges failed\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+test_create_graph(void)
+{
+	static const char *node_patterns_dummy[] = {
+		"test_node_source1",	   "test_node00",
+		"test_node00-test_node11", "test_node00-test_node22",
+		"test_node00-test_node33", "test_node00-dummy_node",
+	};
+	struct rte_graph_param gconf = {
+		.socket_id = SOCKET_ID_ANY,
+		.nb_node_patterns = 6,
+		.node_patterns = node_patterns_dummy,
+	};
+	uint32_t dummy_node_id;
+	uint32_t node_id;
+
+	node_id = rte_node_from_name("test_node00");
+	dummy_node_id = rte_node_clone(node_id, "dummy_node");
+	if (rte_node_is_invalid(dummy_node_id)) {
+		printf("Got invalid node id\n");
+		return -1;
+	}
+
+	graph_id = rte_graph_create("worker0", &gconf);
+	if (graph_id != RTE_GRAPH_ID_INVALID) {
+		printf("Graph creation success with isolated node, expected graph creation fail\n");
+		return -1;
+	}
+
+	gconf.nb_node_patterns = 5;
+	gconf.node_patterns = node_patterns;
+	graph_id = rte_graph_create("worker0", &gconf);
+	if (graph_id == RTE_GRAPH_ID_INVALID) {
+		printf("Graph creation failed with error = %d\n", rte_errno);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+test_graph_walk(void)
+{
+	struct rte_graph *graph = rte_graph_lookup("worker0");
+	int i;
+
+	if (!graph) {
+		printf("Graph lookup failed\n");
+		return -1;
+	}
+
+	for (i = 0; i < 5; i++)
+		rte_graph_walk(graph);
+	return 0;
+}
+
+static int
+test_graph_lookup_functions(void)
+{
+	test_main_t *tm = &test_main;
+	struct rte_node *node;
+	int i;
+
+	for (i = 0; i < MAX_NODES; i++) {
+		node = rte_graph_node_get(graph_id, tm->test_node[i].idx);
+		if (!node) {
+			printf("rte_graph_node_get, failed for node = %d\n",
+			       tm->test_node[i].idx);
+			return -1;
+		}
+
+		if (tm->test_node[i].idx != node->id) {
+			printf("Node id didn't match, expected = %d got = %d\n",
+			       tm->test_node[i].idx, node->id);
+			return 0;
+		}
+
+		if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) {
+			printf("Node name didn't match, expected = %s got %s\n",
+			       node_names[i], node->name);
+			return -1;
+		}
+	}
+
+	for (i = 0; i < MAX_NODES; i++) {
+		node = rte_graph_node_get_by_name("worker0", node_names[i]);
+		if (!node) {
+			printf("rte_graph_node_get, failed for node = %d\n",
+			       tm->test_node[i].idx);
+			return -1;
+		}
+
+		if (tm->test_node[i].idx != node->id) {
+			printf("Node id didn't match, expected = %d got = %d\n",
+			       tm->test_node[i].idx, node->id);
+			return 0;
+		}
+
+		if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) {
+			printf("Node name didn't match, expected = %s got %s\n",
+			       node_names[i], node->name);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+graph_cluster_stats_cb_t(bool is_first, bool is_last, void *cookie,
+			 const struct rte_graph_cluster_node_stats *st)
+{
+	int i;
+
+	RTE_SET_USED(is_first);
+	RTE_SET_USED(is_last);
+	RTE_SET_USED(cookie);
+
+	for (i = 0; i < MAX_NODES + 1; i++) {
+		rte_node_t id = rte_node_from_name(node_patterns[i]);
+		if (id == st->id) {
+			if (obj_stats[i] != st->objs) {
+				printf("Obj count miss match for node = %s expected = %"PRId64", got=%"PRId64"\n",
+				       node_patterns[i], obj_stats[i],
+				       st->objs);
+				return -1;
+			}
+
+			if (fn_calls[i] != st->calls) {
+				printf("Func call miss match for node = %s expected = %"PRId64", got = %"PRId64"\n",
+				       node_patterns[i], fn_calls[i],
+				       st->calls);
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+static int
+test_print_stats(void)
+{
+	struct rte_graph_cluster_stats_param s_param;
+	struct rte_graph_cluster_stats *stats;
+	const char *pattern = "worker0";
+
+	if (!rte_graph_has_stats_feature())
+		return 0;
+
+	/* Prepare stats object */
+	memset(&s_param, 0, sizeof(s_param));
+	s_param.f = stdout;
+	s_param.socket_id = SOCKET_ID_ANY;
+	s_param.graph_patterns = &pattern;
+	s_param.nb_graph_patterns = 1;
+	s_param.fn = graph_cluster_stats_cb_t;
+
+	stats = rte_graph_cluster_stats_create(&s_param);
+	if (stats == NULL) {
+		printf("Unable to get stats\n");
+		return -1;
+	}
+	/* Clear screen and move to top left */
+	rte_graph_cluster_stats_get(stats, 0);
+	rte_graph_cluster_stats_destroy(stats);
+
+	return 0;
+}
+
+static int
+graph_setup(void)
+{
+	int i, j;
+
+	for (i = 0; i <= MAX_NODES; i++) {
+		for (j = 0; j < MBUFF_SIZE; j++)
+			mbuf_p[i][j] = &mbuf[i][j];
+	}
+	if (test_node_clone()) {
+		printf("test_node_clone: fail\n");
+		return -1;
+	}
+	printf("test_node_clone: pass\n");
+
+	return 0;
+}
+
+static void
+graph_teardown(void)
+{
+	rte_graph_t id;
+
+	id = rte_graph_destroy("worker0");
+	if (id == RTE_GRAPH_ID_INVALID)
+		printf("Graph Destroy failed\n");
+}
+
+static struct unit_test_suite graph_testsuite = {
+	.suite_name = "Graph library test suite",
+	.setup = graph_setup,
+	.teardown = graph_teardown,
+	.unit_test_cases = {
+		TEST_CASE(test_update_edges),
+		TEST_CASE(test_lookup_functions),
+		TEST_CASE(test_create_graph),
+		TEST_CASE(test_graph_lookup_functions),
+		TEST_CASE(test_graph_walk),
+		TEST_CASE(test_print_stats),
+		TEST_CASES_END(), /**< NULL terminate unit test array */
+	},
+};
+
+static int
+graph_autotest_fn(void)
+{
+	return unit_test_suite_runner(&graph_testsuite);
+}
+
+REGISTER_TEST_COMMAND(graph_autotest, graph_autotest_fn);
+
+static int
+test_node_list_dump(void)
+{
+	rte_node_list_dump(stdout);
+
+	return TEST_SUCCESS;
+}
+REGISTER_TEST_COMMAND(node_list_dump, test_node_list_dump);
+
-- 
2.25.1


  parent reply index

Thread overview: 219+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-18 21:35 [dpdk-dev] [PATCH v1 00/26] graph: introduce graph subsystem jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 01/26] graph: define the public API for graph support jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 02/26] graph: implement node registration jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 03/26] graph: implement node operations jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 04/26] graph: implement node debug routines jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 05/26] graph: implement internal graph operation helpers jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 06/26] graph: populate fastpath memory for graph reel jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 07/26] graph: implement create and destroy APIs jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 08/26] graph: implement graph operation APIs jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 09/26] graph: implement Graphviz export jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 10/26] graph: implement debug routines jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 11/26] graph: implement stats support jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 12/26] graph: implement fastpath API routines jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 13/26] graph: add unit test case jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 14/26] graph: add performance testcase jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 15/26] node: add log infra and null node jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 16/26] node: add ethdev Rx node jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 17/26] node: add ethdev Tx node jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 18/26] node: add ethdev Rx and Tx node ctrl API jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 19/26] node: ipv4 lookup for arm64 jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 20/26] node: ipv4 lookup for x86 jerinj
2020-03-19 12:25   ` Ray Kinsella
2020-03-19 14:22     ` [dpdk-dev] [EXT] " Pavan Nikhilesh Bhagavatula
2020-03-19 15:50       ` Ray Kinsella
2020-03-19 16:13         ` Pavan Nikhilesh Bhagavatula
2020-03-20  9:14           ` Ray Kinsella
2020-03-24  9:40             ` Pavan Nikhilesh Bhagavatula
2020-03-24 14:38               ` Ray Kinsella
2020-03-26  9:56                 ` Pavan Nikhilesh Bhagavatula
2020-03-26 16:54                   ` Ray Kinsella
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 21/26] node: add ipv4 rewrite node jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 22/26] node: add ipv4 rewrite and lookup ctrl API jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 23/26] node: add pkt drop node jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 24/26] l3fwd-graph: add graph based l3fwd skeleton jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 25/26] l3fwd-graph: add ethdev configuration changes jerinj
2020-03-18 21:35 ` [dpdk-dev] [PATCH v1 26/26] l3fwd-graph: add graph config and main loop jerinj
2020-03-26 16:56 ` [dpdk-dev] [PATCH v2 00/28] graph: introduce graph subsystem jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 01/28] graph: define the public API for graph support jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 02/28] graph: implement node registration jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 03/28] graph: implement node operations jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 04/28] graph: implement node debug routines jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 05/28] graph: implement internal graph operation helpers jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 06/28] graph: populate fastpath memory for graph reel jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 07/28] graph: implement create and destroy APIs jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 08/28] graph: implement graph operation APIs jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 09/28] graph: implement Graphviz export jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 10/28] graph: implement debug routines jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 11/28] graph: implement stats support jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 12/28] graph: implement fastpath API routines jerinj
2020-03-26 16:56   ` jerinj [this message]
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 14/28] graph: add performance testcase jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 15/28] node: add log infra and null node jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 16/28] node: add ethdev Rx node jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 17/28] node: add ethdev Tx node jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 18/28] node: add ethdev Rx and Tx node ctrl API jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 19/28] node: ipv4 lookup for arm64 jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 20/28] node: ipv4 lookup for x86 jerinj
2020-03-27  8:40     ` Jerin Jacob
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 21/28] node: add ipv4 rewrite node jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 22/28] node: add ipv4 rewrite and lookup ctrl API jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 23/28] node: add pkt drop node jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 24/28] l3fwd-graph: add graph based l3fwd skeleton jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 25/28] l3fwd-graph: add ethdev configuration changes jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 26/28] l3fwd-graph: add graph config and main loop jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 27/28] doc: add graph library programmer's guide guide jerinj
2020-03-26 16:56   ` [dpdk-dev] [PATCH v2 28/28] doc: add l3fwd graph application user guide jerinj
2020-03-27  6:49   ` [dpdk-dev] [PATCH v2 00/28] graph: introduce graph subsystem Jerin Jacob
2020-03-27 10:42     ` Thomas Monjalon
2020-03-31 19:29   ` [dpdk-dev] [PATCH v3 00/29] " jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 01/29] graph: define the public API for graph support jerinj
2020-04-03  9:26       ` Wang, Xiao W
2020-04-04 12:15         ` Jerin Jacob
2020-04-06 12:36       ` Andrzej Ostruszka
2020-04-06 14:59         ` Jerin Jacob
2020-04-06 16:09           ` Andrzej Ostruszka
2020-04-07 10:27             ` Jerin Jacob
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 02/29] graph: implement node registration jerinj
2020-04-03 10:44       ` Wang, Xiao W
2020-04-04 12:29         ` Jerin Jacob
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 03/29] graph: implement node operations jerinj
2020-04-03 10:54       ` Wang, Xiao W
2020-04-04 13:07         ` Jerin Jacob
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 04/29] graph: implement node debug routines jerinj
2020-04-04  7:57       ` Wang, Xiao W
2020-04-04 13:12         ` Jerin Jacob
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 05/29] graph: implement internal graph operation helpers jerinj
2020-04-06 13:47       ` Wang, Xiao W
2020-04-06 14:08         ` Jerin Jacob
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 06/29] graph: populate fastpath memory for graph reel jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 07/29] graph: implement create and destroy APIs jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 08/29] graph: implement graph operation APIs jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 09/29] graph: implement Graphviz export jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 10/29] graph: implement debug routines jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 11/29] graph: implement stats support jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 12/29] graph: implement fastpath API routines jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 13/29] graph: add unit test case jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 14/29] graph: add performance testcase jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 15/29] node: add log infra and null node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 16/29] node: add ethdev Rx node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 17/29] node: add ethdev Tx node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 18/29] node: add ethdev Rx and Tx node ctrl API jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 19/29] node: add generic ipv4 lookup node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 20/29] node: ipv4 lookup for arm64 jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 21/29] node: ipv4 lookup for x86 jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 22/29] node: add ipv4 rewrite node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 23/29] node: add ipv4 rewrite and lookup ctrl API jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 24/29] node: add packet drop node jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 25/29] l3fwd-graph: add graph based l3fwd skeleton jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 26/29] l3fwd-graph: add ethdev configuration changes jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 27/29] l3fwd-graph: add graph config and main loop jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 28/29] doc: add graph library programmer's guide guide jerinj
2020-03-31 19:29     ` [dpdk-dev] [PATCH v3 29/29] doc: add l3fwd graph application user guide jerinj
2020-04-05  8:55     ` [dpdk-dev] [PATCH v4 00/29] graph: introduce graph subsystem jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 01/29] graph: define the public API for graph support jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 02/29] graph: implement node registration jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 03/29] graph: implement node operations jerinj
2020-04-06 17:57         ` Andrzej Ostruszka
2020-04-07  2:43           ` [dpdk-dev] [EXT] " Kiran Kumar Kokkilagadda
2020-04-07  8:47             ` Andrzej Ostruszka
2020-04-07 10:20             ` Jerin Jacob
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 04/29] graph: implement node debug routines jerinj
2020-04-06 18:17         ` Andrzej Ostruszka
2020-04-07 10:22           ` Jerin Jacob
2020-04-07 11:50             ` Andrzej Ostruszka
2020-04-07 12:09               ` Jerin Jacob
2020-04-07 12:50                 ` Andrzej Ostruszka
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 05/29] graph: implement internal graph operation helpers jerinj
2020-04-07 12:16         ` Andrzej Ostruszka
2020-04-07 12:27           ` Jerin Jacob
2020-04-07 12:54             ` Andrzej Ostruszka
2020-04-07 13:31               ` Jerin Jacob
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 06/29] graph: populate fastpath memory for graph reel jerinj
2020-04-08 17:30         ` Andrzej Ostruszka
2020-04-09  2:44           ` Kiran Kumar Kokkilagadda
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 07/29] graph: implement create and destroy APIs jerinj
2020-04-08 16:57         ` Andrzej Ostruszka
2020-04-08 17:23           ` Jerin Jacob
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 08/29] graph: implement graph operation APIs jerinj
2020-04-08 17:49         ` Andrzej Ostruszka
2020-04-08 19:18           ` Jerin Jacob
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 09/29] graph: implement Graphviz export jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 10/29] graph: implement debug routines jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 11/29] graph: implement stats support jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 12/29] graph: implement fastpath API routines jerinj
2020-04-09 23:07         ` Andrzej Ostruszka
2020-04-10  9:18           ` Jerin Jacob
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 13/29] graph: add unit test case jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 14/29] graph: add performance testcase jerinj
2020-04-05  8:55       ` [dpdk-dev] [PATCH v4 15/29] node: add log infra and null node jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 16/29] node: add ethdev Rx node jerinj
2020-04-09 23:05         ` Andrzej Ostruszka
2020-04-10  7:00           ` Nithin Dabilpuram
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 17/29] node: add ethdev Tx node jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 18/29] node: add ethdev Rx and Tx node ctrl API jerinj
2020-04-09 23:07         ` Andrzej Ostruszka
2020-04-10  5:09           ` Nithin Dabilpuram
2020-04-10  8:22             ` Nithin Dabilpuram
2020-04-10 12:52             ` Andrzej Ostruszka
2020-04-10 14:54               ` [dpdk-dev] [EXT] " Nithin Dabilpuram
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 19/29] node: add generic ipv4 lookup node jerinj
2020-04-09 23:07         ` Andrzej Ostruszka
2020-04-10 10:20           ` Nithin Dabilpuram
2020-04-10 14:41             ` Nithin Dabilpuram
2020-04-10 15:17               ` Andrzej Ostruszka
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 20/29] node: ipv4 lookup for arm64 jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 21/29] node: ipv4 lookup for x86 jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 22/29] node: add ipv4 rewrite node jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 23/29] node: add ipv4 rewrite and lookup ctrl API jerinj
2020-04-09 23:04         ` Andrzej Ostruszka
2020-04-10  7:24           ` Nithin Dabilpuram
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 24/29] node: add packet drop node jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 25/29] l3fwd-graph: add graph based l3fwd skeleton jerinj
2020-04-09 23:04         ` Andrzej Ostruszka
2020-04-10  8:23           ` Nithin Dabilpuram
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 26/29] l3fwd-graph: add ethdev configuration changes jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 27/29] l3fwd-graph: add graph config and main loop jerinj
2020-04-09 23:04         ` Andrzej Ostruszka
2020-04-10  9:29           ` Nithin Dabilpuram
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 28/29] doc: add graph library programmer's guide guide jerinj
2020-04-05  8:56       ` [dpdk-dev] [PATCH v4 29/29] doc: add l3fwd graph application user guide jerinj
2020-04-09 23:13       ` [dpdk-dev] [PATCH v4 00/29] graph: introduce graph subsystem Andrzej Ostruszka
2020-04-10  9:07         ` Jerin Jacob
2020-04-11 14:13       ` [dpdk-dev] [PATCH v5 " jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 01/29] graph: define the public API for graph support jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 02/29] graph: implement node registration jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 03/29] graph: implement node operations jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 04/29] graph: implement node debug routines jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 05/29] graph: implement internal graph operation helpers jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 06/29] graph: populate fastpath memory for graph reel jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 07/29] graph: implement create and destroy APIs jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 08/29] graph: implement graph operation APIs jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 09/29] graph: implement Graphviz export jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 10/29] graph: implement debug routines jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 11/29] graph: implement stats support jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 12/29] graph: implement fastpath API routines jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 13/29] graph: add unit test case jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 14/29] graph: add performance testcase jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 15/29] node: add log infra and null node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 16/29] node: add ethdev Rx node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 17/29] node: add ethdev Tx node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 18/29] node: add ethdev Rx and Tx node ctrl API jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 19/29] node: add generic ipv4 lookup node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 20/29] node: ipv4 lookup for arm64 jerinj
2020-05-12  9:31           ` David Marchand
2020-05-12  9:50             ` [dpdk-dev] [EXT] " Nithin Dabilpuram
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 21/29] node: ipv4 lookup for x86 jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 22/29] node: add ipv4 rewrite node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 23/29] node: add ipv4 rewrite and lookup ctrl API jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 24/29] node: add packet drop node jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 25/29] l3fwd-graph: add graph based l3fwd skeleton jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 26/29] l3fwd-graph: add ethdev configuration changes jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 27/29] l3fwd-graph: add graph config and main loop jerinj
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 28/29] doc: add graph library programmer's guide guide jerinj
2020-05-11  9:27           ` David Marchand
2020-05-11  9:30             ` Jerin Jacob
2020-04-11 14:14         ` [dpdk-dev] [PATCH v5 29/29] doc: add l3fwd graph application user guide jerinj
2020-04-30  8:07         ` [dpdk-dev] [PATCH v5 00/29] graph: introduce graph subsystem Tom Barbette
2020-04-30  8:42           ` Jerin Jacob
2020-05-05 21:44         ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200326165644.866053-14-jerinj@marvell.com \
    --to=jerinj@marvell.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=kirankumark@marvell.com \
    --cc=mattias.ronnblom@ericsson.com \
    --cc=mdr@ashroe.eu \
    --cc=ndabilpuram@marvell.com \
    --cc=pbhagavatula@marvell.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

DPDK-dev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dpdk-dev/0 dpdk-dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dpdk-dev dpdk-dev/ https://lore.kernel.org/dpdk-dev \
		dev@dpdk.org
	public-inbox-index dpdk-dev

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git