1 // SPDX-License-Identifier: GPL-2.0
3 * NUMA support for s390
5 * A tree structure used for machine topology mangling
7 * Copyright IBM Corp. 2015
10 #include <linux/kernel.h>
11 #include <linux/memblock.h>
12 #include <linux/cpumask.h>
13 #include <linux/list.h>
14 #include <linux/list_sort.h>
15 #include <linux/slab.h>
21 * toptree_alloc - Allocate and initialize a new tree node.
22 * @level: The node's vertical level; level 0 contains the leaves.
23 * @id: ID number, explicitly not unique beyond scope of node's siblings
25 * Allocate a new tree node and initialize it.
28 * Pointer to the new tree node or NULL on error
30 struct toptree __ref
*toptree_alloc(int level
, int id
)
34 if (slab_is_available())
35 res
= kzalloc(sizeof(*res
), GFP_KERNEL
);
37 res
= memblock_alloc(sizeof(*res
), 8);
41 INIT_LIST_HEAD(&res
->children
);
42 INIT_LIST_HEAD(&res
->sibling
);
43 cpumask_clear(&res
->mask
);
50 * toptree_remove - Remove a tree node from a tree
51 * @cand: Pointer to the node to remove
53 * The node is detached from its parent node. The parent node's
54 * masks will be updated to reflect the loss of the child.
56 static void toptree_remove(struct toptree
*cand
)
58 struct toptree
*oldparent
;
60 list_del_init(&cand
->sibling
);
61 oldparent
= cand
->parent
;
63 toptree_update_mask(oldparent
);
67 * toptree_free - discard a tree node
68 * @cand: Pointer to the tree node to discard
70 * Checks if @cand is attached to a parent node. Detaches it
71 * cleanly using toptree_remove. Possible children are freed
72 * recursively. In the end @cand itself is freed.
74 void __ref
toptree_free(struct toptree
*cand
)
76 struct toptree
*child
, *tmp
;
80 toptree_for_each_child_safe(child
, tmp
, cand
)
82 if (slab_is_available())
85 memblock_free_early((unsigned long)cand
, sizeof(*cand
));
89 * toptree_update_mask - Update node bitmasks
90 * @cand: Pointer to a tree node
92 * The node's cpumask will be updated by combining all children's
93 * masks. Then toptree_update_mask is called recursively for the
94 * parent if applicable.
97 * This must not be called on leaves. If called on a leaf, its
98 * CPU mask is cleared and lost.
100 void toptree_update_mask(struct toptree
*cand
)
102 struct toptree
*child
;
104 cpumask_clear(&cand
->mask
);
105 list_for_each_entry(child
, &cand
->children
, sibling
)
106 cpumask_or(&cand
->mask
, &cand
->mask
, &child
->mask
);
108 toptree_update_mask(cand
->parent
);
112 * toptree_insert - Insert a tree node into tree
113 * @cand: Pointer to the node to insert
114 * @target: Pointer to the node to which @cand will added as a child
116 * Insert a tree node into a tree. Masks will be updated automatically.
119 * 0 on success, -1 if NULL is passed as argument or the node levels
122 static int toptree_insert(struct toptree
*cand
, struct toptree
*target
)
124 if (!cand
|| !target
)
126 if (target
->level
!= (cand
->level
+ 1))
128 list_add_tail(&cand
->sibling
, &target
->children
);
129 cand
->parent
= target
;
130 toptree_update_mask(target
);
135 * toptree_move_children - Move all child nodes of a node to a new place
136 * @cand: Pointer to the node whose children are to be moved
137 * @target: Pointer to the node to which @cand's children will be attached
139 * Take all child nodes of @cand and move them using toptree_move.
141 static void toptree_move_children(struct toptree
*cand
, struct toptree
*target
)
143 struct toptree
*child
, *tmp
;
145 toptree_for_each_child_safe(child
, tmp
, cand
)
146 toptree_move(child
, target
);
150 * toptree_unify - Merge children with same ID
151 * @cand: Pointer to node whose direct children should be made unique
153 * When mangling the tree it is possible that a node has two or more children
154 * which have the same ID. This routine merges these children into one and
155 * moves all children of the merged nodes into the unified node.
157 void toptree_unify(struct toptree
*cand
)
159 struct toptree
*child
, *tmp
, *cand_copy
;
161 /* Threads cannot be split, cores are not split */
165 cand_copy
= toptree_alloc(cand
->level
, 0);
166 toptree_for_each_child_safe(child
, tmp
, cand
) {
167 struct toptree
*tmpchild
;
169 if (!cpumask_empty(&child
->mask
)) {
170 tmpchild
= toptree_get_child(cand_copy
, child
->id
);
171 toptree_move_children(child
, tmpchild
);
175 toptree_move_children(cand_copy
, cand
);
176 toptree_free(cand_copy
);
178 toptree_for_each_child(child
, cand
)
179 toptree_unify(child
);
183 * toptree_move - Move a node to another context
184 * @cand: Pointer to the node to move
185 * @target: Pointer to the node where @cand should go
187 * In the easiest case @cand is exactly on the level below @target
188 * and will be immediately moved to the target.
190 * If @target's level is not the direct parent level of @cand,
191 * nodes for the missing levels are created and put between
192 * @cand and @target. The "stacking" nodes' IDs are taken from
195 * After this it is likely to have redundant nodes in the tree
196 * which are addressed by means of toptree_unify.
198 void toptree_move(struct toptree
*cand
, struct toptree
*target
)
200 struct toptree
*stack_target
, *real_insert_point
, *ptr
, *tmp
;
202 if (cand
->level
+ 1 == target
->level
) {
203 toptree_remove(cand
);
204 toptree_insert(cand
, target
);
208 real_insert_point
= NULL
;
214 stack_target
= toptree_alloc(ptr
->level
+ 1,
216 toptree_insert(tmp
, stack_target
);
217 if (!real_insert_point
)
218 real_insert_point
= stack_target
;
220 } while (stack_target
->level
< (target
->level
- 1));
222 toptree_remove(cand
);
223 toptree_insert(cand
, real_insert_point
);
224 toptree_insert(stack_target
, target
);
228 * toptree_get_child - Access a tree node's child by its ID
229 * @cand: Pointer to tree node whose child is to access
230 * @id: The desired child's ID
232 * @cand's children are searched for a child with matching ID.
233 * If no match can be found, a new child with the desired ID
234 * is created and returned.
236 struct toptree
*toptree_get_child(struct toptree
*cand
, int id
)
238 struct toptree
*child
;
240 toptree_for_each_child(child
, cand
)
243 child
= toptree_alloc(cand
->level
-1, id
);
244 toptree_insert(child
, cand
);
249 * toptree_first - Find the first descendant on specified level
250 * @context: Pointer to tree node whose descendants are to be used
251 * @level: The level of interest
254 * @context's first descendant on the specified level, or NULL
255 * if there is no matching descendant
257 struct toptree
*toptree_first(struct toptree
*context
, int level
)
259 struct toptree
*child
, *tmp
;
261 if (context
->level
== level
)
264 if (!list_empty(&context
->children
)) {
265 list_for_each_entry(child
, &context
->children
, sibling
) {
266 tmp
= toptree_first(child
, level
);
275 * toptree_next_sibling - Return next sibling
276 * @cur: Pointer to a tree node
279 * If @cur has a parent and is not the last in the parent's children list,
280 * the next sibling is returned. Or NULL when there are no siblings left.
282 static struct toptree
*toptree_next_sibling(struct toptree
*cur
)
284 if (cur
->parent
== NULL
)
287 if (cur
== list_last_entry(&cur
->parent
->children
,
288 struct toptree
, sibling
))
290 return (struct toptree
*) list_next_entry(cur
, sibling
);
294 * toptree_next - Tree traversal function
295 * @cur: Pointer to current element
296 * @context: Pointer to the root node of the tree or subtree to
298 * @level: The level of interest.
301 * Pointer to the next node on level @level
302 * or NULL when there is no next node.
304 struct toptree
*toptree_next(struct toptree
*cur
, struct toptree
*context
,
307 struct toptree
*cur_context
, *tmp
;
312 if (context
->level
== level
)
315 tmp
= toptree_next_sibling(cur
);
320 while (cur_context
->level
< context
->level
- 1) {
322 cur_context
= cur_context
->parent
;
324 tmp
= toptree_next_sibling(cur_context
);
327 tmp
= toptree_first(tmp
, level
);
336 * toptree_count - Count descendants on specified level
337 * @context: Pointer to node whose descendants are to be considered
338 * @level: Only descendants on the specified level will be counted
341 * Number of descendants on the specified level
343 int toptree_count(struct toptree
*context
, int level
)
348 toptree_for_each(cur
, context
, level
)