From: Chandra Seetharaman <sekharan@us.ibm.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Kernel development list <linux-kernel@vger.kernel.org>
Subject: Re: Notifier chains are unsafe
Date: Tue, 25 Oct 2005 16:30:36 -0700 [thread overview]
Message-ID: <1130283036.3586.148.camel@linuxchandra> (raw)
In-Reply-To: <Pine.LNX.4.44L0.0510241634410.4448-100000@iolanthe.rowland.org>
On Mon, 2005-10-24 at 16:48 -0400, Alan Stern wrote:
Hi Alan,
I agree with your approach of having a notifier_head to have both the
head of the notifier_list and the corresponding lock (instead of having
a single global rwlock to protect all notifier lists).
But, I am confused about the need for three data structures and two next
pointers. I think we can achieve the same by 2 data structures:
notifier_head {
spinlock_t lock;
list_head head;
};
notifier_block {
int (*notifier_call)(struct notifier_block *self,
unsigned long, void *);
list_head lists;
int priority;
};
I think that having multiple data structures make the code hard to
follow.
No. of register/unregister would be a lot lesser than a
notifier_call_chain() calls, so IMHO, rwlock would be a better option.
<snip>
> /**
> * notifier_call_chain - Call functions in a notifier chain
> - * @n: Pointer to root pointer of notifier chain
> + * @nh: Pointer to head of the notifier chain
> * @val: Value passed unmodified to notifier function
> * @v: Pointer passed unmodified to notifier function
> *
> @@ -167,20 +194,28 @@ EXPORT_SYMBOL(notifier_chain_unregister)
> * of the last notifier function called.
> */
>
> -int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
> +int notifier_call_chain(struct notifier_head *nh, unsigned long val, void *v)
> {
> - int ret=NOTIFY_DONE;
> - struct notifier_block *nb = *n;
> + int ret = NOTIFY_DONE;
> + struct notifier_caller caller;
> + struct notifier_block *n;
>
> - while(nb)
> - {
> - ret=nb->notifier_call(nb,val,v);
> - if(ret&NOTIFY_STOP_MASK)
> - {
> - return ret;
> - }
> - nb=nb->next;
> + spin_lock(&nh->lock);
> + caller.next = nh->first;
> + list_add(&caller.node, &nh->callers);
> +
> + while (caller.next) {
> + n = caller.next;
> + caller.next = n->next;
> + spin_unlock(&nh->lock);
> + ret = n->notifier_call(n, val, v);
> + spin_lock(&nh->lock);
> + if (ret & NOTIFY_STOP_MASK)
> + break;
> }
Since the lock is being dropped while calling notifier_call, how are we
guaranteed caller.next is valid ? It might have been unregistered.
> +
> + list_del(&caller.node);
> + spin_unlock(&nh->lock);
> return ret;
> }
>
--
----------------------------------------------------------------------
Chandra Seetharaman | Be careful what you choose....
- sekharan@us.ibm.com | .......you may get it.
----------------------------------------------------------------------
next prev parent reply other threads:[~2005-10-25 23:30 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-24 20:48 Notifier chains are unsafe Alan Stern
2005-10-25 16:59 ` Joe Seigh
2005-10-25 23:30 ` Chandra Seetharaman [this message]
2005-10-26 18:46 ` Alan Stern
2005-10-26 19:05 ` Andreas Kleen
2005-10-26 20:40 ` Alan Stern
2005-10-26 21:44 ` Andi Kleen
2005-10-26 23:20 ` Chandra Seetharaman
2005-10-27 1:17 ` Joe Seigh
2005-10-28 1:36 ` Chandra Seetharaman
2005-10-27 14:13 ` Alan Stern
2005-10-26 22:40 ` Chandra Seetharaman
2005-10-27 15:28 ` Alan Stern
2005-10-27 20:43 ` Chandra Seetharaman
2005-10-27 21:21 ` Alan Stern
2005-10-27 23:02 ` Chandra Seetharaman
2005-10-28 0:48 ` Keith Owens
2005-10-28 1:34 ` Chandra Seetharaman
2005-10-28 14:23 ` Alan Stern
2005-10-28 22:15 ` Chandra Seetharaman
2005-10-29 14:51 ` Alan Stern
2005-10-31 22:22 ` Chandra Seetharaman
2005-11-01 15:24 ` Alan Stern
2005-11-01 20:20 ` Chandra Seetharaman
2005-11-01 21:20 ` Alan Stern
2005-11-02 9:50 ` Keith Owens
2005-11-02 16:03 ` Alan Stern
[not found] ` <mailman.1130460600.30060.linux-kernel2news@redhat.com>
2005-10-28 4:35 ` Pete Zaitcev
2005-10-25 23:43 ` Andi Kleen
2005-10-26 0:01 ` Chandra Seetharaman
2005-10-26 17:11 ` Andreas Kleen
2005-10-27 2:46 ` Herbert Xu
2005-10-29 12:25 ` Joe Seigh
2005-10-26 6:11 ` Keith Owens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1130283036.3586.148.camel@linuxchandra \
--to=sekharan@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.