[PATCH] SRCU: report out-of-memory errors
Alan Stern [Wed, 4 Oct 2006 09:17:05 +0000 (02:17 -0700)]
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>

include/linux/srcu.h
kernel/srcu.c
kernel/sys.c

index 8a45367..aca0eee 100644 (file)
@@ -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);
index 7e1979f..3507cab 100644 (file)
  * 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);
 }
 
 /*
index fd5c710..98489d8 100644 (file)
@@ -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;
 }