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 62B9D42C5C;
	Thu,  8 Jun 2023 12:06:02 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id B905A42D5C;
	Thu,  8 Jun 2023 12:05:30 +0200 (CEST)
Received: from mga12.intel.com (mga12.intel.com [192.55.52.136])
 by mails.dpdk.org (Postfix) with ESMTP id A3164427F5
 for <dev@dpdk.org>; Thu,  8 Jun 2023 12:05:29 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1686218729; x=1717754729;
 h=from:to:cc:subject:date:message-id:in-reply-to:
 references:mime-version:content-transfer-encoding;
 bh=q8vmp3Ia6xkaWY2cNBAmIWUS+yPl+ie1Myk6K10yDn0=;
 b=eOoKtrAO55PrqBiscQPl1c+JlvY7Zpl6+6NuDPXIBsZdNX7Oj1kpNU91
 SmsDjxO6RwRWQDRXc7RaGFTkNuFIgx9KhkYNQSKueIuls8scKxk+oDnSI
 05u7KqHGeXB/FOygRVV1kf9l3Sk3YWgS6fCLabzZPV0UuPeRIaNx7zdj+
 dOHmOJRHH+j4IdpnJjVwcIC1oyN4f383Kd8cLmwNIjnoCB3HnoqR13Sdc
 9qj2juVKMlzC29rbO7Ws6era8LOWMxp8OItPyqTyV/uFFVmzlhNhImv1E
 t9zmW+y6OOI/S5ONWc903ip4Yp88UzsCNar/4n4MZB0yjv5QI4kL0LJDW Q==;
X-IronPort-AV: E=McAfee;i="6600,9927,10734"; a="336896237"
X-IronPort-AV: E=Sophos;i="6.00,226,1681196400"; d="scan'208";a="336896237"
Received: from orsmga001.jf.intel.com ([10.7.209.18])
 by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 08 Jun 2023 03:05:29 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=McAfee;i="6600,9927,10734"; a="743053744"
X-IronPort-AV: E=Sophos;i="6.00,226,1681196400"; d="scan'208";a="743053744"
Received: from dpdk-zhirun-lmm.sh.intel.com ([10.67.119.94])
 by orsmga001.jf.intel.com with ESMTP; 08 Jun 2023 03:05:26 -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
Cc: cunming.liang@intel.com, haiyue.wang@intel.com,
 mattias.ronnblom@ericsson.com, Zhirun Yan <zhirun.yan@intel.com>
Subject: [PATCH v10 08/16] graph: introduce graph clone API for other worker
 core
Date: Thu,  8 Jun 2023 17:57:51 +0800
Message-Id: <20230608095759.1800617-9-zhirun.yan@intel.com>
X-Mailer: git-send-email 2.37.2
In-Reply-To: <20230608095759.1800617-1-zhirun.yan@intel.com>
References: <20230607035144.1214492-1-zhirun.yan@intel.com>
 <20230608095759.1800617-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 5a6e13e62b..dbb3507687 100644
--- a/lib/graph/version.map
+++ b/lib/graph/version.map
@@ -7,6 +7,7 @@ EXPERIMENTAL {
 
 	rte_graph_create;
 	rte_graph_destroy;
+	rte_graph_clone;
 	rte_graph_dump;
 	rte_graph_export;
 	rte_graph_from_name;
-- 
2.37.2