static LIST_HEAD(ovcs_list);
-static DEFINE_IDR(ovcs_idr);
+static DEFINE_XARRAY_ALLOC1(ovcs_array);
static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain);
* nodes and the __symbols__ node. Any other top level node will be ignored.
*
* Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
- * detected in @tree, or -ENOSPC if idr_alloc() error.
+ * detected in @tree, or -EBUSY if id allocation fails.
*/
static int init_overlay_changeset(struct overlay_changeset *ovcs,
const void *fdt, struct device_node *tree)
struct device_node *node, *overlay_node;
struct fragment *fragment;
struct fragment *fragments;
- int cnt, id, ret;
+ int cnt, ret;
/*
* Warn for some issues. Can not return -EINVAL for these until
of_changeset_init(&ovcs->cset);
- id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
- if (id <= 0)
- return id;
+ ret = xa_alloc(&ovcs_array, &ovcs->id, ovcs, xa_limit_32b, GFP_KERNEL);
+ if (ret < 0)
+ return ret;
cnt = 0;
fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
if (!fragments) {
ret = -ENOMEM;
- goto err_free_idr;
+ goto err_erase;
}
cnt = 0;
goto err_free_fragments;
}
- ovcs->id = id;
ovcs->count = cnt;
ovcs->fragments = fragments;
err_free_fragments:
kfree(fragments);
-err_free_idr:
- idr_remove(&ovcs_idr, id);
+err_erase:
+ xa_erase(&ovcs_array, ovcs->id);
pr_err("%s() failed, ret = %d\n", __func__, ret);
of_changeset_destroy(&ovcs->cset);
if (ovcs->id)
- idr_remove(&ovcs_idr, ovcs->id);
+ xa_erase(&ovcs_array, ovcs->id);
for (i = 0; i < ovcs->count; i++) {
of_node_put(ovcs->fragments[i].target);
mutex_lock(&of_mutex);
- ovcs = idr_find(&ovcs_idr, *ovcs_id);
+ ovcs = xa_load(&ovcs_array, *ovcs_id);
if (!ovcs) {
ret = -ENODEV;
pr_err("remove: Could not find overlay #%d\n", *ovcs_id);