diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-10-04 02:17:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 07:55:30 -0700 |
commit | e6a92013ba458804161c0c5b6d134d82204dc233 (patch) | |
tree | ecee5fdcef80d1dba0ac6ea87370931ea39ffecd | |
parent | eabc069401bcf45bcc3f19e643017bf761780aa8 (diff) |
[PATCH] SRCU: report out-of-memory errors
Currently the init_srcu_struct() routine has no way to report out-of-memory
errors. This patch (as761) makes it return -ENOMEM when the per-cpu data
allocation fails.
The patch also makes srcu_init_notifier_head() report a BUG if a notifier
head can't be initialized. Perhaps it should return -ENOMEM instead, but
in the most likely cases where this might occur I don't think any recovery
is possible. Notifier chains generally are not created dynamically.
[akpm@osdl.org: avoid statement-with-side-effect in macro]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Paul E. McKenney <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/srcu.h | 2 | ||||
-rw-r--r-- | kernel/srcu.c | 5 | ||||
-rw-r--r-- | kernel/sys.c | 3 |
3 files changed, 6 insertions, 4 deletions
diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 8a45367b5f3a..aca0eee53930 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -43,7 +43,7 @@ struct srcu_struct { #define srcu_barrier() #endif /* #else #ifndef CONFIG_PREEMPT */ -void init_srcu_struct(struct srcu_struct *sp); +int init_srcu_struct(struct srcu_struct *sp); void cleanup_srcu_struct(struct srcu_struct *sp); int srcu_read_lock(struct srcu_struct *sp) __acquires(sp); void srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp); diff --git a/kernel/srcu.c b/kernel/srcu.c index 7e1979f624ba..3507cabe963b 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c @@ -42,11 +42,12 @@ * to any other function. Each srcu_struct represents a separate domain * of SRCU protection. */ -void init_srcu_struct(struct srcu_struct *sp) +int init_srcu_struct(struct srcu_struct *sp) { sp->completed = 0; - sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); mutex_init(&sp->mutex); + sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); + return (sp->per_cpu_ref ? 0 : -ENOMEM); } /* diff --git a/kernel/sys.c b/kernel/sys.c index fd5c71006775..98489d82801b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -517,7 +517,8 @@ EXPORT_SYMBOL_GPL(srcu_notifier_call_chain); void srcu_init_notifier_head(struct srcu_notifier_head *nh) { mutex_init(&nh->mutex); - init_srcu_struct(&nh->srcu); + if (init_srcu_struct(&nh->srcu) < 0) + BUG(); nh->head = NULL; } |