lib/idr.c
Source file repositories/reference/linux-study-clean/lib/idr.c
File Facts
- System
- Linux kernel
- Corpus path
lib/idr.c- Extension
.c- Size
- 19520 bytes
- Lines
- 669
- Domain
- Kernel Services
- Bucket
- lib
- Inferred role
- Kernel Services: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitmap.hlinux/bug.hlinux/export.hlinux/idr.hlinux/slab.hlinux/spinlock.hlinux/xarray.h
Detected Declarations
function idr_alloc_u32function idr_allocfunction idr_alloc_cyclicfunction idr_removefunction idr_findfunction idr_for_eachfunction radix_tree_for_each_slotfunction idr_get_next_ulfunction idr_get_nextfunction idr_replacefunction ida_alloc_rangefunction ida_find_first_rangefunction ida_freefunction ida_destroyfunction ida_dump_entryfunction ida_dumpexport idr_alloc_u32export idr_allocexport idr_alloc_cyclicexport idr_removeexport idr_findexport idr_for_eachexport idr_get_next_ulexport idr_get_nextexport idr_replaceexport ida_alloc_rangeexport ida_find_first_rangeexport ida_freeexport ida_destroy
Annotated Snippet
if (bit < BITS_PER_XA_VALUE) {
bit = find_next_zero_bit(&tmp, BITS_PER_XA_VALUE, bit);
if (xas.xa_index * IDA_BITMAP_BITS + bit > max)
goto nospc;
if (bit < BITS_PER_XA_VALUE) {
tmp |= 1UL << bit;
xas_store(&xas, xa_mk_value(tmp));
goto out;
}
}
bitmap = alloc;
if (!bitmap)
bitmap = kzalloc_obj(*bitmap, GFP_NOWAIT);
if (!bitmap)
goto alloc;
bitmap->bitmap[0] = tmp;
xas_store(&xas, bitmap);
if (xas_error(&xas)) {
bitmap->bitmap[0] = 0;
goto out;
}
}
if (bitmap) {
bit = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, bit);
if (xas.xa_index * IDA_BITMAP_BITS + bit > max)
goto nospc;
if (bit == IDA_BITMAP_BITS)
goto next;
__set_bit(bit, bitmap->bitmap);
if (bitmap_full(bitmap->bitmap, IDA_BITMAP_BITS))
xas_clear_mark(&xas, XA_FREE_MARK);
} else {
if (bit < BITS_PER_XA_VALUE) {
bitmap = xa_mk_value(1UL << bit);
} else {
bitmap = alloc;
if (!bitmap)
bitmap = kzalloc_obj(*bitmap, GFP_NOWAIT);
if (!bitmap)
goto alloc;
__set_bit(bit, bitmap->bitmap);
}
xas_store(&xas, bitmap);
}
out:
xas_unlock_irqrestore(&xas, flags);
if (xas_nomem(&xas, gfp)) {
xas.xa_index = min / IDA_BITMAP_BITS;
bit = min % IDA_BITMAP_BITS;
goto retry;
}
if (bitmap != alloc)
kfree(alloc);
if (xas_error(&xas))
return xas_error(&xas);
return xas.xa_index * IDA_BITMAP_BITS + bit;
alloc:
xas_unlock_irqrestore(&xas, flags);
alloc = kzalloc_obj(*bitmap, gfp);
if (!alloc)
return -ENOMEM;
xas_set(&xas, min / IDA_BITMAP_BITS);
bit = min % IDA_BITMAP_BITS;
goto retry;
nospc:
xas_unlock_irqrestore(&xas, flags);
kfree(alloc);
return -ENOSPC;
}
EXPORT_SYMBOL(ida_alloc_range);
/**
* ida_find_first_range - Get the lowest used ID.
* @ida: IDA handle.
* @min: Lowest ID to get.
* @max: Highest ID to get.
*
* Get the lowest used ID between @min and @max, inclusive. The returned
* ID will not exceed %INT_MAX, even if @max is larger.
*
* Context: Any context. Takes and releases the xa_lock.
* Return: The lowest used ID, or errno if no used ID is found.
*/
int ida_find_first_range(struct ida *ida, unsigned int min, unsigned int max)
{
unsigned long index = min / IDA_BITMAP_BITS;
unsigned int offset = min % IDA_BITMAP_BITS;
unsigned long *addr, size, bit;
Annotation
- Immediate include surface: `linux/bitmap.h`, `linux/bug.h`, `linux/export.h`, `linux/idr.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/xarray.h`.
- Detected declarations: `function idr_alloc_u32`, `function idr_alloc`, `function idr_alloc_cyclic`, `function idr_remove`, `function idr_find`, `function idr_for_each`, `function radix_tree_for_each_slot`, `function idr_get_next_ul`, `function idr_get_next`, `function idr_replace`.
- Atlas domain: Kernel Services / lib.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.