2 * NUMA support for s390
4 * A tree structure used for machine topology mangling
6 * Copyright IBM Corp. 2015
9 #include <linux/kernel.h>
10 #include <linux/cpumask.h>
11 #include <linux/list.h>
12 #include <linux/list_sort.h>
13 #include <linux/slab.h>
19 * toptree_alloc - Allocate and initialize a new tree node.
20 * @level: The node's vertical level; level 0 contains the leaves.
21 * @id: ID number, explicitly not unique beyond scope of node's siblings
23 * Allocate a new tree node and initialize it.
26 * Pointer to the new tree node or NULL on error
28 struct toptree *toptree_alloc(int level, int id)
30 struct toptree *res = kzalloc(sizeof(struct toptree), GFP_KERNEL);
35 INIT_LIST_HEAD(&res->children);
36 INIT_LIST_HEAD(&res->sibling);
37 cpumask_clear(&res->mask);
44 * toptree_remove - Remove a tree node from a tree
45 * @cand: Pointer to the node to remove
47 * The node is detached from its parent node. The parent node's
48 * masks will be updated to reflect the loss of the child.
50 static void toptree_remove(struct toptree *cand)
52 struct toptree *oldparent;
54 list_del_init(&cand->sibling);
55 oldparent = cand->parent;
57 toptree_update_mask(oldparent);
61 * toptree_free - discard a tree node
62 * @cand: Pointer to the tree node to discard
64 * Checks if @cand is attached to a parent node. Detaches it
65 * cleanly using toptree_remove. Possible children are freed
66 * recursively. In the end @cand itself is freed.
68 void toptree_free(struct toptree *cand)
70 struct toptree *child, *tmp;
74 toptree_for_each_child_safe(child, tmp, cand)
80 * toptree_update_mask - Update node bitmasks
81 * @cand: Pointer to a tree node
83 * The node's cpumask will be updated by combining all children's
84 * masks. Then toptree_update_mask is called recursively for the
85 * parent if applicable.
88 * This must not be called on leaves. If called on a leaf, its
89 * CPU mask is cleared and lost.
91 void toptree_update_mask(struct toptree *cand)
93 struct toptree *child;
95 cpumask_clear(&cand->mask);
96 list_for_each_entry(child, &cand->children, sibling)
97 cpumask_or(&cand->mask, &cand->mask, &child->mask);
99 toptree_update_mask(cand->parent);
103 * toptree_insert - Insert a tree node into tree
104 * @cand: Pointer to the node to insert
105 * @target: Pointer to the node to which @cand will added as a child
107 * Insert a tree node into a tree. Masks will be updated automatically.
110 * 0 on success, -1 if NULL is passed as argument or the node levels
113 static int toptree_insert(struct toptree *cand, struct toptree *target)
115 if (!cand || !target)
117 if (target->level != (cand->level + 1))
119 list_add_tail(&cand->sibling, &target->children);
120 cand->parent = target;
121 toptree_update_mask(target);
126 * toptree_move_children - Move all child nodes of a node to a new place
127 * @cand: Pointer to the node whose children are to be moved
128 * @target: Pointer to the node to which @cand's children will be attached
130 * Take all child nodes of @cand and move them using toptree_move.
132 static void toptree_move_children(struct toptree *cand, struct toptree *target)
134 struct toptree *child, *tmp;
136 toptree_for_each_child_safe(child, tmp, cand)
137 toptree_move(child, target);
141 * toptree_unify - Merge children with same ID
142 * @cand: Pointer to node whose direct children should be made unique
144 * When mangling the tree it is possible that a node has two or more children
145 * which have the same ID. This routine merges these children into one and
146 * moves all children of the merged nodes into the unified node.
148 void toptree_unify(struct toptree *cand)
150 struct toptree *child, *tmp, *cand_copy;
152 /* Threads cannot be split, cores are not split */
156 cand_copy = toptree_alloc(cand->level, 0);
157 toptree_for_each_child_safe(child, tmp, cand) {
158 struct toptree *tmpchild;
160 if (!cpumask_empty(&child->mask)) {
161 tmpchild = toptree_get_child(cand_copy, child->id);
162 toptree_move_children(child, tmpchild);
166 toptree_move_children(cand_copy, cand);
167 toptree_free(cand_copy);
169 toptree_for_each_child(child, cand)
170 toptree_unify(child);
174 * toptree_move - Move a node to another context
175 * @cand: Pointer to the node to move
176 * @target: Pointer to the node where @cand should go
178 * In the easiest case @cand is exactly on the level below @target
179 * and will be immediately moved to the target.
181 * If @target's level is not the direct parent level of @cand,
182 * nodes for the missing levels are created and put between
183 * @cand and @target. The "stacking" nodes' IDs are taken from
186 * After this it is likely to have redundant nodes in the tree
187 * which are addressed by means of toptree_unify.
189 void toptree_move(struct toptree *cand, struct toptree *target)
191 struct toptree *stack_target, *real_insert_point, *ptr, *tmp;
193 if (cand->level + 1 == target->level) {
194 toptree_remove(cand);
195 toptree_insert(cand, target);
199 real_insert_point = NULL;
205 stack_target = toptree_alloc(ptr->level + 1,
207 toptree_insert(tmp, stack_target);
208 if (!real_insert_point)
209 real_insert_point = stack_target;
211 } while (stack_target->level < (target->level - 1));
213 toptree_remove(cand);
214 toptree_insert(cand, real_insert_point);
215 toptree_insert(stack_target, target);
219 * toptree_get_child - Access a tree node's child by its ID
220 * @cand: Pointer to tree node whose child is to access
221 * @id: The desired child's ID
223 * @cand's children are searched for a child with matching ID.
224 * If no match can be found, a new child with the desired ID
225 * is created and returned.
227 struct toptree *toptree_get_child(struct toptree *cand, int id)
229 struct toptree *child;
231 toptree_for_each_child(child, cand)
234 child = toptree_alloc(cand->level-1, id);
235 toptree_insert(child, cand);
240 * toptree_first - Find the first descendant on specified level
241 * @context: Pointer to tree node whose descendants are to be used
242 * @level: The level of interest
245 * @context's first descendant on the specified level, or NULL
246 * if there is no matching descendant
248 struct toptree *toptree_first(struct toptree *context, int level)
250 struct toptree *child, *tmp;
252 if (context->level == level)
255 if (!list_empty(&context->children)) {
256 list_for_each_entry(child, &context->children, sibling) {
257 tmp = toptree_first(child, level);
266 * toptree_next_sibling - Return next sibling
267 * @cur: Pointer to a tree node
270 * If @cur has a parent and is not the last in the parent's children list,
271 * the next sibling is returned. Or NULL when there are no siblings left.
273 static struct toptree *toptree_next_sibling(struct toptree *cur)
275 if (cur->parent == NULL)
278 if (cur == list_last_entry(&cur->parent->children,
279 struct toptree, sibling))
281 return (struct toptree *) list_next_entry(cur, sibling);
285 * toptree_next - Tree traversal function
286 * @cur: Pointer to current element
287 * @context: Pointer to the root node of the tree or subtree to
289 * @level: The level of interest.
292 * Pointer to the next node on level @level
293 * or NULL when there is no next node.
295 struct toptree *toptree_next(struct toptree *cur, struct toptree *context,
298 struct toptree *cur_context, *tmp;
303 if (context->level == level)
306 tmp = toptree_next_sibling(cur);
311 while (cur_context->level < context->level - 1) {
313 cur_context = cur_context->parent;
315 tmp = toptree_next_sibling(cur_context);
318 tmp = toptree_first(tmp, level);
327 * toptree_count - Count descendants on specified level
328 * @context: Pointer to node whose descendants are to be considered
329 * @level: Only descendants on the specified level will be counted
332 * Number of descendants on the specified level
334 int toptree_count(struct toptree *context, int level)
339 toptree_for_each(cur, context, level)