diff options
author | Paul Mackerras <paulus@samba.org> | 2007-02-08 15:03:11 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-02-08 15:03:11 +1100 |
commit | d5112a4f31a361409d3c57dc9d58dd69f8014bef (patch) | |
tree | 64771300b2191cb94d9aaf60355661a01c2ccd1a /kernel/sys.c | |
parent | 12e86f92fcfe4f0bcab0ad7fa4088a64c60d9b38 (diff) | |
parent | 5fad293bcbd48d9a2370020cf60e4b4a42559b12 (diff) |
Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc into for-2.6.21
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index c7675c1bfdf..6e2101dec0f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -323,11 +323,18 @@ EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); int blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v) { - int ret; + int ret = NOTIFY_DONE; - down_read(&nh->rwsem); - ret = notifier_call_chain(&nh->head, val, v); - up_read(&nh->rwsem); + /* + * We check the head outside the lock, but if this access is + * racy then it does not matter what the result of the test + * is, we re-check the list after having taken the lock anyway: + */ + if (rcu_dereference(nh->head)) { + down_read(&nh->rwsem); + ret = notifier_call_chain(&nh->head, val, v); + up_read(&nh->rwsem); + } return ret; } |