mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] cpuset: Optimize the number of iterations in the scheduling domain construction process
@ 2024-05-31  2:48 Xavier
  2024-05-31 21:13 ` Waiman Long
  2024-06-03 12:31 ` [PATCH v3] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
  0 siblings, 2 replies; 52+ messages in thread
From: Xavier @ 2024-05-31  2:48 UTC (permalink / raw)
  To: longman, lizefan.x, tj, hannes; +Cc: cgroups, linux-kernel, Xavier

The process of constructing scheduling domains involves multiple loops
and repeated evaluations, leading to numerous redundant and ineffective
assessments that impact code efficiency.

Here, we use Union-Find to optimize the merging of cpumasks. By employing
path compression and union by rank, we effectively reduce the number of
lookups and merge comparisons.

Signed-off-by: Xavier <ghostxavier@sina.com>
---
 kernel/cgroup/cpuset.c | 117 +++++++++++++++++++++++------------------
 1 file changed, 66 insertions(+), 51 deletions(-)

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index c12b9fdb2..4bea1c2db 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -891,6 +891,44 @@ static inline int nr_cpusets(void)
 	return static_key_count(&cpusets_enabled_key.key) + 1;
 }
 
+/*define a union find node struct*/
+struct uf_node {
+	int parent;
+	int rank;
+};
+
+static int find_root(struct uf_node *nodes, int x)
+{
+	int root = x;
+	int parent;
+
+	/*Find the root node and perform path compression at the same time*/
+	while (nodes[root].parent != root) {
+		parent = nodes[root].parent;
+		nodes[root].parent = nodes[parent].parent;
+		root = parent;
+	}
+	return root;
+}
+
+/*Function to merge two sets, using union by rank*/
+static void union_sets(struct uf_node *nodes, int a, int b)
+{
+	int root_a = find_root(nodes, a);
+	int root_b = find_root(nodes, b);
+
+	if (root_a != root_b) {
+		if (nodes[root_a].rank < nodes[root_b].rank) {
+			nodes[root_a].parent = root_b;
+		} else if (nodes[root_a].rank > nodes[root_b].rank) {
+			nodes[root_b].parent = root_a;
+		} else {
+			nodes[root_b].parent = root_a;
+			nodes[root_a].rank++;
+		}
+	}
+}
+
 /*
  * generate_sched_domains()
  *
@@ -950,13 +988,14 @@ static int generate_sched_domains(cpumask_var_t **domains,
 	struct cpuset *cp;	/* top-down scan of cpusets */
 	struct cpuset **csa;	/* array of all cpuset ptrs */
 	int csn;		/* how many cpuset ptrs in csa so far */
-	int i, j, k;		/* indices for partition finding loops */
+	int i, j;		/* indices for partition finding loops */
 	cpumask_var_t *doms;	/* resulting partition; i.e. sched domains */
 	struct sched_domain_attr *dattr;  /* attributes for custom domains */
 	int ndoms = 0;		/* number of sched domains in result */
 	int nslot;		/* next empty doms[] struct cpumask slot */
 	struct cgroup_subsys_state *pos_css;
 	bool root_load_balance = is_sched_load_balance(&top_cpuset);
+	struct uf_node *nodes;
 
 	doms = NULL;
 	dattr = NULL;
@@ -1022,33 +1061,31 @@ static int generate_sched_domains(cpumask_var_t **domains,
 	}
 	rcu_read_unlock();
 
-	for (i = 0; i < csn; i++)
-		csa[i]->pn = i;
-	ndoms = csn;
-
-restart:
-	/* Find the best partition (set of sched domains) */
-	for (i = 0; i < csn; i++) {
-		struct cpuset *a = csa[i];
-		int apn = a->pn;
+	nodes = kmalloc_array(csn, sizeof(struct uf_node), GFP_KERNEL);
+	if (!nodes)
+		goto done;
 
-		for (j = 0; j < csn; j++) {
-			struct cpuset *b = csa[j];
-			int bpn = b->pn;
 
-			if (apn != bpn && cpusets_overlap(a, b)) {
-				for (k = 0; k < csn; k++) {
-					struct cpuset *c = csa[k];
+	/* Each node is initially its own parent */
+	for (i = 0; i < csn; i++) {
+		nodes[i].parent = i;
+		nodes[i].rank = 0;
+	}
 
-					if (c->pn == bpn)
-						c->pn = apn;
-				}
-				ndoms--;	/* one less element */
-				goto restart;
-			}
+	/* Merge overlapping cpusets */
+	for (i = 0; i < csn; i++) {
+		for (j = i + 1; j < csn; j++) {
+			if (cpusets_overlap(csa[i], csa[j]))
+				union_sets(nodes, i, j);
 		}
 	}
 
+	/* Calculate the number of domains after merging */
+	for (i = 0; i < csn; i++) {
+		if (nodes[i].parent == i)
+			ndoms++;
+	}
+
 	/*
 	 * Now we know how many domains to create.
 	 * Convert <csn, csa> to <ndoms, doms> and populate cpu masks.
@@ -1065,47 +1102,25 @@ static int generate_sched_domains(cpumask_var_t **domains,
 			      GFP_KERNEL);
 
 	for (nslot = 0, i = 0; i < csn; i++) {
-		struct cpuset *a = csa[i];
-		struct cpumask *dp;
-		int apn = a->pn;
-
-		if (apn < 0) {
-			/* Skip completed partitions */
-			continue;
-		}
-
-		dp = doms[nslot];
-
-		if (nslot == ndoms) {
-			static int warnings = 10;
-			if (warnings) {
-				pr_warn("rebuild_sched_domains confused: nslot %d, ndoms %d, csn %d, i %d, apn %d\n",
-					nslot, ndoms, csn, i, apn);
-				warnings--;
-			}
-			continue;
-		}
+		struct cpumask *dp = doms[nslot];
 
 		cpumask_clear(dp);
 		if (dattr)
 			*(dattr + nslot) = SD_ATTR_INIT;
 		for (j = i; j < csn; j++) {
-			struct cpuset *b = csa[j];
+			if (find_root(nodes, j) == i) {
+				if (i == j)
+					nslot++;
 
-			if (apn == b->pn) {
-				cpumask_or(dp, dp, b->effective_cpus);
+				cpumask_or(dp, dp, csa[j]->effective_cpus);
 				cpumask_and(dp, dp, housekeeping_cpumask(HK_TYPE_DOMAIN));
 				if (dattr)
-					update_domain_attr_tree(dattr + nslot, b);
-
-				/* Done with this partition */
-				b->pn = -1;
+					update_domain_attr_tree(dattr + nslot, csa[j]);
 			}
 		}
-		nslot++;
 	}
 	BUG_ON(nslot != ndoms);
-
+	kfree(nodes);
 done:
 	kfree(csa);
 
-- 
2.34.1


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

end of thread, other threads:[~2024-07-30 23:06 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-31  2:48 [PATCH v2] cpuset: Optimize the number of iterations in the scheduling domain construction process Xavier
2024-05-31 21:13 ` Waiman Long
2024-06-03 12:31 ` [PATCH v3] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-06-04 15:02   ` Waiman Long
2024-06-10 17:18   ` Michal Koutný
2024-06-20  8:52   ` [PATCH v4 v4 0/2] cpuset: use Union-Find to optimize Xavier
2024-06-20  8:52     ` [PATCH v4 v4 1/2] Union-Find: add a new module in kernel library Xavier
2024-06-20 14:54       ` Waiman Long
2024-06-21  8:49         ` [PATCH-cpuset v5 0/2] cpuset: use Union-Find to optimize Xavier
2024-06-21  8:49           ` [PATCH-cpuset v5 1/2] Union-Find: add a new module in kernel library Xavier
2024-06-21 21:10             ` Tejun Heo
2024-06-22  7:14               ` [PATCH-cpuset v6 0/2] Add Union-Find and use it to optimize cpuset Xavier
2024-06-22  7:14                 ` [PATCH-cpuset v6 1/2] Union-Find: add a new module in kernel library Xavier
2024-06-22  7:14                 ` [PATCH-cpuset v6 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-06-22 16:13                 ` [PATCH-cpuset v6 0/2] Add Union-Find and use it to optimize cpuset Tejun Heo
2024-06-23  2:38                   ` [PATCH-cpuset v7 " Xavier
2024-06-23  2:39                     ` [PATCH-cpuset v7 1/2] Union-Find: add a new module in kernel library Xavier
2024-06-23  2:39                     ` [PATCH-cpuset v7 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-06-27 21:06                     ` [PATCH-cpuset v7 0/2] Add Union-Find and use it to optimize cpuset Tejun Heo
2024-06-28 16:13                       ` [PATCH-cpuset v8 " Xavier
2024-06-28 16:13                         ` [PATCH-cpuset v8 1/2] Union-Find: add a new module in kernel library Xavier
2024-07-01 20:53                           ` Tejun Heo
2024-07-02 10:50                             ` [PATCH-cpuset v9 0/2] Add Union-Find and use it to optimize cpuset Xavier
2024-07-02 10:50                               ` [PATCH-cpuset v9 1/2] Union-Find: add a new module in kernel library Xavier
2024-07-02 10:50                               ` [PATCH-cpuset v9 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-07-03  3:05                                 ` Waiman Long
2024-07-02 19:22                               ` [PATCH-cpuset v9 0/2] Add Union-Find and use it to optimize cpuset Tejun Heo
2024-07-03  0:31                                 ` Andrew Morton
2024-07-03 17:34                                   ` Tejun Heo
2024-07-03  6:37                                 ` [PATCH-cpuset v10 " Xavier
2024-07-03  6:37                                   ` [PATCH-cpuset v10 1/2] Union-Find: add a new module in kernel library Xavier
2024-07-03  9:40                                     ` Michal Koutný
2024-07-03 11:20                                       ` Xavier
2024-07-04 12:12                                         ` Michal Koutný
2024-07-03  6:37                                   ` [PATCH-cpuset v10 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-07-03  9:40                                     ` Michal Koutný
2024-07-03 10:49                                       ` Xavier
2024-07-03 16:43                                         ` Waiman Long
2024-07-04  6:24                                           ` [PATCH-cpuset v11 0/2] Add Union-Find and use it to optimize cpuset Xavier
2024-07-04  6:24                                             ` [PATCH-cpuset v11 1/2] Union-Find: add a new module in kernel library Xavier
2024-07-30 23:05                                               ` Tejun Heo
2024-07-04  6:24                                             ` [PATCH-cpuset v11 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-07-30 23:05                                               ` Tejun Heo
2024-07-08  1:59                                             ` [PATCH-cpuset v11 0/2] Add Union-Find and use it to optimize cpuset Waiman Long
2024-07-08 18:38                                               ` Tejun Heo
2024-07-09  2:45                                                 ` Xavier
2024-07-29  2:44                                                 ` Xavier
2024-07-30 23:06                                                   ` Tejun Heo
2024-06-28 16:13                         ` [PATCH-cpuset v8 2/2] cpuset: use Union-Find to optimize the merging of cpumasks Xavier
2024-07-01 20:53                           ` Tejun Heo
2024-06-21  8:49           ` [PATCH-cpuset v5 " Xavier
2024-06-20  8:52     ` [PATCH v4 v4 " Xavier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®