if (!hierarchy)
return ERR_PTR(-ENOMEM);
+ hierarchy->cpumask = kzalloc(cpumask_size(), GFP_KERNEL);
+ if (!hierarchy->cpumask)
+ goto err;
+
hierarchy->level_list = kzalloc_objs(struct list_head, tmigr_hierarchy_levels);
- if (!hierarchy->level_list) {
- kfree(hierarchy);
- hierarchy = NULL;
- return ERR_PTR(-ENOMEM);
- }
+ if (!hierarchy->level_list)
+ goto err;
for (int i = 0; i < tmigr_hierarchy_levels; i++)
INIT_LIST_HEAD(&hierarchy->level_list[i]);
return hierarchy;
+err:
+ kfree(hierarchy->cpumask);
+ kfree(hierarchy);
+ hierarchy = NULL;
+ return ERR_PTR(-ENOMEM);
}
static int tmigr_add_cpu(unsigned int cpu)
ret = tmigr_setup_groups(hier, cpu, node, NULL, false);
+ if (ret < 0)
+ return ret;
+
/* Root has changed? Connect the old one to the new */
- if (ret >= 0 && old_root && old_root != hier->root) {
+ if (old_root && old_root != hier->root) {
/*
* The target CPU must never do the prepare work, except
* on early boot when the boot CPU is the target. Otherwise
ret = tmigr_setup_groups(hier, -1, old_root->numa_node, old_root, true);
}
+ if (ret >= 0)
+ cpumask_set_cpu(cpu, hier->cpumask);
+
return ret;
}
/**
* struct tmigr_hierarchy - a hierarchy associated to a given CPU capacity.
* @level_list: Per level lists of tmigr groups
+ * @cpumask: CPUs belonging to this hierarchy
* @root: The current root of the hierarchy
*/
struct tmigr_hierarchy {
struct list_head *level_list;
+ struct cpumask *cpumask;
struct tmigr_group *root;
};