if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR)))
idr->idr_rt.xa_flags |= IDR_RT_MARKER;
id = (id < base) ? 0 : id - base;
radix_tree_iter_init(&iter, id);
slot = idr_get_free(&idr->idr_rt, &iter, gfp, max - base); if (IS_ERR(slot)) return PTR_ERR(slot);
*nextid = iter.index + base; /* there is a memory barrier inside radix_tree_iter_replace() */
radix_tree_iter_replace(&idr->idr_rt, &iter, slot, ptr);
radix_tree_iter_tag_clear(&idr->idr_rt, &iter, IDR_FREE);
return0;
}
EXPORT_SYMBOL_GPL(idr_alloc_u32);
/** *idr_alloc()-AllocateanID. *@idr:IDRhandle. *@ptr:PointertobeassociatedwiththenewID. *@start:TheminimumID(inclusive). *@end:ThemaximumID(exclusive). *@gfp:Memoryallocationflags. * *AllocatesanunusedIDintherangespecifiedby@startand@end.If *@endis<=0,itistreatedasonelargerthan%INT_MAX.Thisallows *callerstouse@start+Nas@endaslongasNiswithinintegerrange. * *Thecallershouldprovidetheirownlockingtoensurethattwo *concurrentmodificationstotheIDRarenotpossible.Read-only *accessestotheIDRmaybedoneundertheRCUreadlockormay *excludesimultaneouswriters. * *Return:ThenewlyallocatedID,-ENOMEMifmemoryallocationfailed, *or-ENOSPCifnofreeIDscouldbefound.
*/ int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp)
{
u32 id = start; int ret;
if (WARN_ON_ONCE(start < 0)) return -EINVAL;
ret = idr_alloc_u32(idr, ptr, &id, end > 0 ? end - 1 : INT_MAX, gfp); if (ret) return ret;
return id;
}
EXPORT_SYMBOL_GPL(idr_alloc);
/** *idr_alloc_cyclic()-AllocateanIDcyclically. *@idr:IDRhandle. *@ptr:PointertobeassociatedwiththenewID. *@start:TheminimumID(inclusive). *@end:ThemaximumID(exclusive). *@gfp:Memoryallocationflags. * *AllocatesanunusedIDintherangespecifiedby@startand@end.If *@endis<=0,itistreatedasonelargerthan%INT_MAX.Thisallows *callerstouse@start+Nas@endaslongasNiswithinintegerrange. *ThesearchforanunusedIDwillstartatthelastIDallocatedandwill *wraparoundto@startifnofreeIDsarefoundbeforereaching@end. * *Thecallershouldprovidetheirownlockingtoensurethattwo *concurrentmodificationstotheIDRarenotpossible.Read-only *accessestotheIDRmaybedoneundertheRCUreadlockormay *excludesimultaneouswriters. * *Return:ThenewlyallocatedID,-ENOMEMifmemoryallocationfailed, *or-ENOSPCifnofreeIDscouldbefound.
*/ int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp)
{
u32 id = idr->idr_next; int err, max = end > 0 ? end - 1 : INT_MAX;
if ((int)id < start)
id = start;
err = idr_alloc_u32(idr, ptr, &id, max, gfp); if ((err == -ENOSPC) && (id > start)) {
id = start;
err = idr_alloc_u32(idr, ptr, &id, max, gfp);
} if (err) return err;
idr->idr_next = id + 1; return id;
}
EXPORT_SYMBOL(idr_alloc_cyclic);
/** *ida_alloc_range()-AllocateanunusedID. *@ida:IDAhandle. *@min:LowestIDtoallocate. *@max:HighestIDtoallocate. *@gfp:Memoryallocationflags. * *AllocateanIDbetween@minand@max,inclusive.TheallocatedIDwill *notexceed%INT_MAX,evenif@maxislarger. * *Context:Anycontext.Itissafetocallthisfunctionwithout *lockinginyourcode. *Return:TheallocatedID,or%-ENOMEMifmemorycouldnotbeallocated, *or%-ENOSPCiftherearenofreeIDs.
*/ int ida_alloc_range(struct ida *ida, unsignedint min, unsignedint max,
gfp_t gfp)
{
XA_STATE(xas, &ida->xa, min / IDA_BITMAP_BITS); unsigned bit = min % IDA_BITMAP_BITS; unsignedlong flags; struct ida_bitmap *bitmap, *alloc = NULL;
if ((int)min < 0) return -ENOSPC;
if ((int)max < 0)
max = INT_MAX;
retry:
xas_lock_irqsave(&xas, flags);
next:
bitmap = xas_find_marked(&xas, max / IDA_BITMAP_BITS, XA_FREE_MARK); if (xas.xa_index > min / IDA_BITMAP_BITS)
bit = 0; if (xas.xa_index * IDA_BITMAP_BITS + bit > max) goto nospc;
if (xa_is_value(bitmap)) { unsignedlong tmp = xa_to_value(bitmap);
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(sizeof(*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(sizeof(*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(sizeof(*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-GetthelowestusedID. *@ida:IDAhandle. *@min:LowestIDtoget. *@max:HighestIDtoget. * *GetthelowestusedIDbetween@minand@max,inclusive.Thereturned *IDwillnotexceed%INT_MAX,evenif@maxislarger. * *Context:Anycontext.Takesandreleasesthexa_lock. *Return:ThelowestusedID,orerrnoifnousedIDisfound.
*/ int ida_find_first_range(struct ida *ida, unsignedint min, unsignedint max)
{ unsignedlong index = min / IDA_BITMAP_BITS; unsignedint offset = min % IDA_BITMAP_BITS; unsignedlong *addr, size, bit; unsignedlong tmp = 0; unsignedlong flags; void *entry; int ret;
if ((int)min < 0) return -EINVAL; if ((int)max < 0)
max = INT_MAX;
xa_lock_irqsave(&ida->xa, flags);
entry = xa_find(&ida->xa, &index, max / IDA_BITMAP_BITS, XA_PRESENT); if (!entry) {
ret = -ENOENT; goto err_unlock;
}
if (index > min / IDA_BITMAP_BITS)
offset = 0; if (index * IDA_BITMAP_BITS + offset > max) {
ret = -ENOENT; goto err_unlock;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.18Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.