[PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR()
From: Yury Norov
Date: Mon Sep 14 2026 - 23:14:55 EST
DEFINE_IDR() is documented as defining a statically allocated IDR. Enforce
that contract with ASSERT_STATIC_STORAGE(), matching DEFINE_IDA().
Normal IDR operations use external synchronization and do not acquire the
embedded XArray lock. This change enforces the declaration API contract;
it does not fix a lockdep failure in ordinary IDR operations.
Convert the seven automatic IDRs in the userspace tests to plain
declarations and runtime initialization. Two already use idr_init_base().
Keep direct IDR_INIT() and IDR_INIT_BASE() initializers unchanged.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@xxxxxxxxxx>
---
include/linux/idr.h | 4 +++-
tools/testing/radix-tree/idr-test.c | 29 ++++++++++++++++++++---------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/include/linux/idr.h b/include/linux/idr.h
index e2a4b6298511..d0393b7fe985 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -55,7 +55,9 @@ struct idr {
* An IDR defined using this macro is ready for use with no additional
* initialisation required. It contains no IDs.
*/
-#define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
+#define DEFINE_IDR(name) \
+ struct idr name = IDR_INIT(name); \
+ ASSERT_STATIC_STORAGE(name)
/**
* idr_get_cursor - Return the current position of the cyclic allocator
diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c
index 6fcba5b5870b..4668c6a4f6ea 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -33,7 +33,9 @@ void item_idr_remove(struct idr *idr, int id)
void idr_alloc_test(void)
{
unsigned long i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0, 0x4000, GFP_KERNEL) == 0);
assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0x3ffd, 0x4000, GFP_KERNEL) == 0x3ffd);
@@ -79,7 +81,9 @@ void idr_alloc2_test(void)
void idr_replace_test(void)
{
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
idr_alloc(&idr, (void *)-1, 10, 11, GFP_KERNEL);
idr_replace(&idr, &idr, 10);
@@ -96,7 +100,9 @@ void idr_replace_test(void)
void idr_null_test(void)
{
int i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
assert(idr_is_empty(&idr));
@@ -150,7 +156,9 @@ void idr_null_test(void)
void idr_nowait_test(void)
{
unsigned int i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
idr_preload(GFP_KERNEL);
@@ -169,11 +177,11 @@ void idr_get_next_test(int base)
{
unsigned long i;
int nextid;
- DEFINE_IDR(idr);
- idr_init_base(&idr, base);
-
+ struct idr idr;
int indices[] = {4, 7, 9, 15, 65, 128, 1000, 99999, 0};
+ idr_init_base(&idr, base);
+
for(i = 0; indices[i]; i++) {
struct item *item = item_create(indices[i], 0);
assert(idr_alloc(&idr, item, indices[i], indices[i+1],
@@ -229,7 +237,8 @@ void idr_u32_test1(struct idr *idr, u32 handle)
void idr_u32_test(int base)
{
- DEFINE_IDR(idr);
+ struct idr idr;
+
idr_init_base(&idr, base);
idr_u32_test1(&idr, 10);
idr_u32_test1(&idr, 0x7fffffff);
@@ -360,7 +369,9 @@ void idr_find_test(void)
void idr_checks(void)
{
unsigned long i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
for (i = 0; i < 10000; i++) {
struct item *item = item_create(i, 0);
--
2.53.0