1
0
mirror of https://github.com/openbsd/src.git synced 2026-04-21 04:34:20 +00:00

add idr_alloc_cyclic() for 6.18.21 drm

This commit is contained in:
jsg
2026-04-07 09:11:15 +00:00
parent 4d83098c9f
commit 321c78384e
2 changed files with 44 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: drm_linux.c,v 1.134 2026/03/31 08:54:14 jsg Exp $ */
/* $OpenBSD: drm_linux.c,v 1.135 2026/04/07 09:11:15 jsg Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -810,6 +810,7 @@ void
idr_init(struct idr *idr)
{
SPLAY_INIT(&idr->tree);
idr->next = 0;
}
void
@@ -867,6 +868,44 @@ idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
return id->id;
}
/* [start, end) */
int
idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
{
int flags = (gfp_mask & GFP_NOWAIT) ? PR_NOWAIT : PR_WAITOK;
struct idr_entry *id;
KERNEL_ASSERT_LOCKED();
if (idr_entry_cache) {
id = idr_entry_cache;
idr_entry_cache = NULL;
} else {
id = pool_get(&idr_pool, flags);
if (id == NULL)
return -ENOMEM;
}
if (end <= 0)
end = INT_MAX;
id->id = idr->next;
while (SPLAY_INSERT(idr_tree, &idr->tree, id)) {
id->id++;
if (id->id == end) {
id->id = start;
} else if (id->id == idr->next) {
pool_put(&idr_pool, id);
return -ENOSPC;
}
}
id->ptr = ptr;
idr->next = id->id + 1;
if (idr->next == end)
idr->next = start;
return id->id;
}
void *
idr_replace(struct idr *idr, void *ptr, unsigned long id)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: idr.h,v 1.9 2026/04/07 09:04:16 jsg Exp $ */
/* $OpenBSD: idr.h,v 1.10 2026/04/07 09:11:15 jsg Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
*
@@ -31,16 +31,19 @@ struct idr_entry {
struct idr {
SPLAY_HEAD(idr_tree, idr_entry) tree;
unsigned long next;
};
#define DEFINE_IDR(name) \
struct idr name = { \
.tree = SPLAY_INITIALIZER(&name.idr.tree), \
.next = 0 \
}
void idr_init(struct idr *);
void idr_preload(unsigned int);
int idr_alloc(struct idr *, void *, int, int, gfp_t);
int idr_alloc_cyclic(struct idr *, void *, int, int, gfp_t);
void *idr_find(struct idr *, unsigned long);
void *idr_replace(struct idr *, void *, unsigned long);
void *idr_remove(struct idr *, unsigned long);