Re: [PATCH 1/5] lib: introduce call_once()

Akinobu Mita
2008-03-15T04:09:39Z

> Of course it can be used in those places. Here's the idr.c conversion:
>
> --- a/lib/idr.c~a
> +++ a/lib/idr.c
> @@ -585,14 +585,6 @@ static void idr_cache_ctor(struct kmem_c
> memset(idr_layer, 0, sizeof(struct idr_layer));
> }
>
> -static int init_id_cache(void)
> -{
> - if (!idr_layer_cache)
> - idr_layer_cache = kmem_cache_create("idr_layer_cache",
> - sizeof(struct idr_layer), 0, 0, idr_cache_ctor);
> - return 0;
> -}
> -
> /**
> * idr_init - initialize idr handle
> * @idp: idr handle
> @@ -602,7 +594,9 @@ static int init_id_cache(void)
> */
> void idr_init(struct idr *idp)
> {
> - init_id_cache();
> + if (ONCE())
> + idr_layer_cache = kmem_cache_create("idr_layer_cache",
> + sizeof(struct idr_layer), 0, 0, idr_cache_ctor);
> memset(idp, 0, sizeof(struct idr));
> spin_lock_init(&idp->lock);
> }
>
>

Maybe this doesn't handle kmem_cache_create() failure.

Anyhow this is the alternative patch to fix what the patch 1/5 was
trying to fix.

Subject: idr: create idr_layer_cache at boot time

This patch checks kmem_cache_create() failure by SLAB_PANIC
by creating idr_layer_cache unconditionary at boot time rather than
creates when idr_init() is called first time by someone.

This change also enables to eliminate unnecessary check every time
idr_init() is called.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
include/linux/idr.h | 2 ++
init/main.c | 2 ++
lib/idr.c | 10 ++++------
3 files changed, 8 insertions(+), 6 deletions(-)

Index: 2.6-rc/lib/idr.c
===================================================================
--- 2.6-rc.orig/lib/idr.c
+++ 2.6-rc/lib/idr.c
@@ -585,12 +585,11 @@ static void idr_cache_ctor(struct kmem_c
memset(idr_layer, 0, sizeof(struct idr_layer));
}

-static int init_id_cache(void)
+void __init init_id_cache(void)
{
- if (!idr_layer_cache)
- idr_layer_cache = kmem_cache_create("idr_layer_cache",
- sizeof(struct idr_layer), 0, 0, idr_cache_ctor);
- return 0;
+ idr_layer_cache = kmem_cache_create("idr_layer_cache",
+ sizeof(struct idr_layer), 0, SLAB_PANIC,
+ idr_cache_ctor);
}

/**
@@ -602,7 +601,6 @@ static int init_id_cache(void)
*/
void idr_init(struct idr *idp)
{
- init_id_cache();
memset(idp, 0, sizeof(struct idr));
spin_lock_init(&idp->lock);
}
Index: 2.6-rc/include/linux/idr.h
===================================================================
--- 2.6-rc.orig/include/linux/idr.h
+++ 2.6-rc/include/linux/idr.h
@@ -115,4 +115,6 @@ void ida_remove(struct ida *ida, int id)
void ida_destroy(struct ida *ida);
void ida_init(struct ida *ida);

+void __init init_id_cache(void);
+
#endif /* __IDR_H__ */
Index: 2.6-rc/init/main.c
===================================================================
--- 2.6-rc.orig/init/main.c
+++ 2.6-rc/init/main.c
@@ -58,6 +58,7 @@
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/signal.h>
+#include <linux/idr.h>

#include <asm/io.h>
#include <asm/bugs.h>
@@ -616,6 +617,7 @@ asmlinkage void __init start_kernel(void
enable_debug_pagealloc();
cpu_hotplug_init();
kmem_cache_init();
+ init_id_cache();
setup_per_cpu_pageset();
numa_policy_init();
if (late_time_init)