Lines Matching +full:max +full:- +full:functions
1 // SPDX-License-Identifier: GPL-2.0
22 * struct ioasid_allocator_data - Internal data structure to hold information
25 * - Default allocator always has its own XArray to track the IOASIDs allocated.
26 * - Custom allocators may share allocation helpers with different private data.
27 * Custom allocators that share the same helper functions also share the same
34 * 3. When all custom allocators sharing the same helper functions are
38 * functions, outstanding IOASIDs are preserved.
42 * @ops: allocator helper functions and its data
62 static ioasid_t default_alloc(ioasid_t min, ioasid_t max, void *opaque);
78 static ioasid_t default_alloc(ioasid_t min, ioasid_t max, void *opaque) in default_alloc() argument
82 if (xa_alloc(&default_allocator.xa, &id, opaque, XA_LIMIT(min, max), GFP_ATOMIC)) { in default_alloc()
83 pr_err("Failed to alloc ioasid from %d to %d\n", min, max); in default_alloc()
98 /* Allocate and initialize a new custom allocator with its helper functions */
107 xa_init_flags(&ia_data->xa, XA_FLAGS_ALLOC); in ioasid_alloc_allocator()
108 INIT_LIST_HEAD(&ia_data->slist); in ioasid_alloc_allocator()
109 ia_data->flags |= IOASID_ALLOCATOR_CUSTOM; in ioasid_alloc_allocator()
110 ia_data->ops = ops; in ioasid_alloc_allocator()
113 list_add_tail(&ops->list, &ia_data->slist); in ioasid_alloc_allocator()
120 return (a->free == b->free) && (a->alloc == b->alloc); in use_same_ops()
124 * ioasid_register_allocator - register a custom allocator
149 ret = -ENOMEM; in ioasid_register_allocator()
161 if (xa_empty(&active_allocator->xa)) { in ioasid_register_allocator()
163 list_add_tail(&ia_data->list, &allocators_list); in ioasid_register_allocator()
167 ret = -EAGAIN; in ioasid_register_allocator()
173 if (pallocator->ops == ops) { in ioasid_register_allocator()
175 ret = -EEXIST; in ioasid_register_allocator()
177 } else if (use_same_ops(pallocator->ops, ops)) { in ioasid_register_allocator()
183 list_add_tail(&ops->list, &pallocator->slist); in ioasid_register_allocator()
187 list_add_tail(&ia_data->list, &allocators_list); in ioasid_register_allocator()
200 * ioasid_unregister_allocator - Remove a custom IOASID allocator ops
219 if (!use_same_ops(pallocator->ops, ops)) in ioasid_unregister_allocator()
222 if (list_is_singular(&pallocator->slist)) { in ioasid_unregister_allocator()
223 /* No shared helper functions */ in ioasid_unregister_allocator()
224 list_del(&pallocator->list); in ioasid_unregister_allocator()
230 WARN_ON(!xa_empty(&pallocator->xa)); in ioasid_unregister_allocator()
247 list_for_each_entry(sops, &pallocator->slist, list) { in ioasid_unregister_allocator()
249 list_del(&ops->list); in ioasid_unregister_allocator()
262 * ioasid_set_data - Set private data for an allocated ioasid
275 ioasid_data = xa_load(&active_allocator->xa, ioasid); in ioasid_set_data()
277 rcu_assign_pointer(ioasid_data->private, data); in ioasid_set_data()
279 ret = -ENOENT; in ioasid_set_data()
294 * ioasid_alloc - Allocate an IOASID
297 * @max: the maximum ID (inclusive)
300 * Allocate an ID between @min and @max. The @private pointer is stored
305 ioasid_t ioasid_alloc(struct ioasid_set *set, ioasid_t min, ioasid_t max, in ioasid_alloc() argument
316 data->set = set; in ioasid_alloc()
317 data->private = private; in ioasid_alloc()
318 refcount_set(&data->refs, 1); in ioasid_alloc()
325 adata = active_allocator->flags & IOASID_ALLOCATOR_CUSTOM ? active_allocator->ops->pdata : data; in ioasid_alloc()
326 id = active_allocator->ops->alloc(min, max, adata); in ioasid_alloc()
328 pr_err("Failed ASID allocation %lu\n", active_allocator->flags); in ioasid_alloc()
332 if ((active_allocator->flags & IOASID_ALLOCATOR_CUSTOM) && in ioasid_alloc()
333 xa_alloc(&active_allocator->xa, &id, data, XA_LIMIT(id, id), GFP_ATOMIC)) { in ioasid_alloc()
336 active_allocator->ops->free(id, active_allocator->ops->pdata); in ioasid_alloc()
339 data->id = id; in ioasid_alloc()
351 * ioasid_get - obtain a reference to the IOASID
358 ioasid_data = xa_load(&active_allocator->xa, ioasid); in ioasid_get()
360 refcount_inc(&ioasid_data->refs); in ioasid_get()
368 * ioasid_put - Release a reference to an ioasid
382 ioasid_data = xa_load(&active_allocator->xa, ioasid); in ioasid_put()
388 free = refcount_dec_and_test(&ioasid_data->refs); in ioasid_put()
392 active_allocator->ops->free(ioasid, active_allocator->ops->pdata); in ioasid_put()
394 if (active_allocator->flags & IOASID_ALLOCATOR_CUSTOM) { in ioasid_put()
395 ioasid_data = xa_erase(&active_allocator->xa, ioasid); in ioasid_put()
406 * ioasid_find - Find IOASID data
428 ioasid_data = xa_load(&idata->xa, ioasid); in ioasid_find()
430 priv = ERR_PTR(-ENOENT); in ioasid_find()
433 if (set && ioasid_data->set != set) { in ioasid_find()
435 priv = ERR_PTR(-EACCES); in ioasid_find()
439 priv = rcu_dereference(ioasid_data->private); in ioasid_find()
449 MODULE_AUTHOR("Jean-Philippe Brucker <jean-philippe.brucker@arm.com>");