From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 435B042C71;
	Fri,  9 Jun 2023 21:20:52 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id BEB4042D3B;
	Fri,  9 Jun 2023 21:20:14 +0200 (CEST)
Received: from mga09.intel.com (mga09.intel.com [134.134.136.24])
 by mails.dpdk.org (Postfix) with ESMTP id CDB9942D3B
 for <dev@dpdk.org>; Fri,  9 Jun 2023 21:20:12 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1686338412; x=1717874412;
 h=from:to:cc:subject:date:message-id:in-reply-to:
 references:mime-version:content-transfer-encoding;
 bh=ugiSbSmNm/W3sfN8yPSwlWYf2h565KfAoikIH2mKWVY=;
 b=VB9tTV8fRurNZejDdXMWG0MrDJJhdpx1vEWFYlUNhDbt5aDmWzGQq9+w
 MPq7uz1mIrSgkNCf5njtcUmbeU4GD+gFMH2vH0qiY8P62moRKuuF9NfPL
 6wuWqmu75ndQBelhdR6Db2vm/MCxzUTE2F9et2NotxVmTGD2c54vHa7uC
 YktaDw656ObaDwEUbnfOQ5rr+pIBzDXQseKCTHEqXOeUGrbKZ98bNI3q9
 jZhGPJexdzpUSZX5vbJ+EzNnRsJwdcR26Lbbmm7SHH0yk3+UBPMIsLvUP
 kyHtyjixZKI+CI5XzTu5dPjbQh0Dze7hm0mkrsawEiM8H1Q+Efl6ARdEr Q==;
X-IronPort-AV: E=McAfee;i="6600,9927,10736"; a="360155048"
X-IronPort-AV: E=Sophos;i="6.00,230,1681196400"; d="scan'208";a="360155048"
Received: from fmsmga006.fm.intel.com ([10.253.24.20])
 by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 09 Jun 2023 12:20:12 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=McAfee;i="6600,9927,10736"; a="957254666"
X-IronPort-AV: E=Sophos;i="6.00,230,1681196400"; d="scan'208";a="957254666"
Received: from dpdk-zhirun-lmm.sh.intel.com ([10.67.119.94])
 by fmsmga006.fm.intel.com with ESMTP; 09 Jun 2023 12:20:09 -0700
From: Zhirun Yan <zhirun.yan@intel.com>
To: dev@dpdk.org, jerinj@marvell.com, kirankumark@marvell.com,
 ndabilpuram@marvell.com, stephen@networkplumber.org,
 pbhagavatula@marvell.com, jerinjacobk@gmail.com, david.marchand@redhat.com
Cc: cunming.liang@intel.com, haiyue.wang@intel.com,
 mattias.ronnblom@ericsson.com, Zhirun Yan <zhirun.yan@intel.com>
Subject: [PATCH v12 08/16] graph: introduce graph clone API for other worker
 core
Date: Sat, 10 Jun 2023 03:12:37 +0800
Message-Id: <20230609191245.252521-9-zhirun.yan@intel.com>
X-Mailer: git-send-email 2.37.2
In-Reply-To: <20230609191245.252521-1-zhirun.yan@intel.com>
References: <20230608151844.1823783-1-zhirun.yan@intel.com>
 <20230609191245.252521-1-zhirun.yan@intel.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

This patch adds graph API for supporting to clone the graph object for
a specified worker core. The new graph will also clone all nodes.

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
Signed-off-by: Cunming Liang <cunming.liang@intel.com>
Signed-off-by: Zhirun Yan <zhirun.yan@intel.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/graph/graph.c         | 89 +++++++++++++++++++++++++++++++++++++++
 lib/graph/graph_private.h |  2 +
 lib/graph/rte_graph.h     | 20 +++++++++
 lib/graph/version.map     |  1 +
 4 files changed, 112 insertions(+)

diff --git a/lib/graph/graph.c b/lib/graph/graph.c
index 8d5bd8b9ae..1b34f0e543 100644
--- a/lib/graph/graph.c
+++ b/lib/graph/graph.c
@@ -405,6 +405,7 @@ rte_graph_create(const char *name, struct rte_graph_param *prm)
 	graph->src_node_count = src_node_count;
 	graph->node_count = graph_nodes_count(graph);
 	graph->id = graph_id;
+	graph->parent_id = RTE_GRAPH_ID_INVALID;
 	graph->lcore_id = RTE_MAX_LCORE;
 	graph->num_pkt_to_capture = prm->num_pkt_to_capture;
 	if (prm->pcap_filename)
@@ -469,6 +470,94 @@ rte_graph_destroy(rte_graph_t id)
 	return rc;
 }
 
+static rte_graph_t
+graph_clone(struct graph *parent_graph, const char *name)
+{
+	struct graph_node *graph_node;
+	struct graph *graph;
+
+	graph_spinlock_lock();
+
+	/* Don't allow to clone a node from a cloned graph */
+	if (parent_graph->parent_id != RTE_GRAPH_ID_INVALID)
+		SET_ERR_JMP(EEXIST, fail, "A cloned graph is not allowed to be cloned");
+
+	/* Create graph object */
+	graph = calloc(1, sizeof(*graph));
+	if (graph == NULL)
+		SET_ERR_JMP(ENOMEM, fail, "Failed to calloc cloned graph object");
+
+	/* Naming ceremony of the new graph. name is node->name + "-" + name */
+	if (clone_name(graph->name, parent_graph->name, name))
+		goto free;
+
+	/* Check for existence of duplicate graph */
+	if (rte_graph_from_name(graph->name) != RTE_GRAPH_ID_INVALID)
+		SET_ERR_JMP(EEXIST, free, "Found duplicate graph %s",
+			    graph->name);
+
+	/* Clone nodes from parent graph firstly */
+	STAILQ_INIT(&graph->node_list);
+	STAILQ_FOREACH(graph_node, &parent_graph->node_list, next) {
+		if (graph_node_add(graph, graph_node->node))
+			goto graph_cleanup;
+	}
+
+	/* Just update adjacency list of all nodes in the graph */
+	if (graph_adjacency_list_update(graph))
+		goto graph_cleanup;
+
+	/* Initialize the graph object */
+	graph->src_node_count = parent_graph->src_node_count;
+	graph->node_count = parent_graph->node_count;
+	graph->parent_id = parent_graph->id;
+	graph->lcore_id = parent_graph->lcore_id;
+	graph->socket = parent_graph->socket;
+	graph->id = graph_id;
+
+	/* Allocate the Graph fast path memory and populate the data */
+	if (graph_fp_mem_create(graph))
+		goto graph_cleanup;
+
+	/* Clone the graph model */
+	graph->graph->model = parent_graph->graph->model;
+
+	/* Call init() of the all the nodes in the graph */
+	if (graph_node_init(graph))
+		goto graph_mem_destroy;
+
+	/* All good, Lets add the graph to the list */
+	graph_id++;
+	STAILQ_INSERT_TAIL(&graph_list, graph, next);
+
+	graph_spinlock_unlock();
+	return graph->id;
+
+graph_mem_destroy:
+	graph_fp_mem_destroy(graph);
+graph_cleanup:
+	graph_cleanup(graph);
+free:
+	free(graph);
+fail:
+	graph_spinlock_unlock();
+	return RTE_GRAPH_ID_INVALID;
+}
+
+rte_graph_t
+rte_graph_clone(rte_graph_t id, const char *name)
+{
+	struct graph *graph;
+
+	GRAPH_ID_CHECK(id);
+	STAILQ_FOREACH(graph, &graph_list, next)
+		if (graph->id == id)
+			return graph_clone(graph, name);
+
+fail:
+	return RTE_GRAPH_ID_INVALID;
+}
+
 rte_graph_t
 rte_graph_from_name(const char *name)
 {
diff --git a/lib/graph/graph_private.h b/lib/graph/graph_private.h
index a6d8c6e98b..354dc8ac0a 100644
--- a/lib/graph/graph_private.h
+++ b/lib/graph/graph_private.h
@@ -102,6 +102,8 @@ struct graph {
 	/**< Circular buffer mask for wrap around. */
 	rte_graph_t id;
 	/**< Graph identifier. */
+	rte_graph_t parent_id;
+	/**< Parent graph identifier. */
 	unsigned int lcore_id;
 	/**< Lcore identifier where the graph prefer to run on. Used for mcore dispatch model. */
 	size_t mem_sz;
diff --git a/lib/graph/rte_graph.h b/lib/graph/rte_graph.h
index f70c694e77..998cade200 100644
--- a/lib/graph/rte_graph.h
+++ b/lib/graph/rte_graph.h
@@ -247,6 +247,26 @@ rte_graph_t rte_graph_create(const char *name, struct rte_graph_param *prm);
 __rte_experimental
 int rte_graph_destroy(rte_graph_t id);
 
+/**
+ * Clone Graph.
+ *
+ * Clone a graph from static graph (graph created from rte_graph_create()). And
+ * all cloned graphs attached to the parent graph MUST be destroyed together
+ * for fast schedule design limitation (stop ALL graph walk firstly).
+ *
+ * @param id
+ *   Static graph id to clone from.
+ * @param name
+ *   Name of the new graph. The library prepends the parent graph name to the
+ * user-specified name. The final graph name will be,
+ * "parent graph name" + "-" + name.
+ *
+ * @return
+ *   Valid graph id on success, RTE_GRAPH_ID_INVALID otherwise.
+ */
+__rte_experimental
+rte_graph_t rte_graph_clone(rte_graph_t id, const char *name);
+
 /**
  * Get graph id from graph name.
  *
diff --git a/lib/graph/version.map b/lib/graph/version.map
index 9a20dba5e7..9e92b54ffa 100644
--- a/lib/graph/version.map
+++ b/lib/graph/version.map
@@ -5,6 +5,7 @@ EXPERIMENTAL {
 	__rte_node_stream_alloc;
 	__rte_node_stream_alloc_size;
 
+	rte_graph_clone;
 	rte_graph_create;
 	rte_graph_destroy;
 	rte_graph_dump;
-- 
2.37.2