: Interface change to the notifier chain mechanism - basic fix
RFC PATCH 1/7 : Interface change to the notifier chain mechanism - basic fix
This has the core interface change and the fix for the original problem. It is same as what I posted last Friday, plus the changes suggested by Paul McKenney.
Signed-off-by Chandra Seetharaman <[email protected]>
Signed-off-by Alan Stern <[email protected]>
-----
include/linux/notifier.h | 69 ++++++++++++++++++++++++++++++++-- kernel/sys.c | 93 ++++++++++++++++++++++++++++------------------- 2 files changed, 121 insertions(+), 41 deletions(-)
include/linux/notifier.h +64 -5
@@ -10,25 +10,84 @@#ifndef _LINUX_NOTIFIER_H#define _LINUX_NOTIFIER_H#include <linux/errno.h> +#include <linux/rwsem.h> + +/* +* Notifier chains are of two types: +* Atomic notifier chains: Chain callbacks run in interrupt/atomic +* context. Callouts are not allowed to block. +* Blocking notifier chains: Chain callback run in process context. +* Callouts are allowed to block. +* +* Type of a chain is defined in its head. +* +* notifier_chain_register() and notifier_chain_unregister() should be +* called only from process context. +* +* notifier_chain_unregister() _should not_ be called from the +* corresponding call chain. +* +*/ +enum notifier_type { +ATOMIC_NOTIFIER , +BLOCKING_NOTIFIER , +};struct notifier_block { -int (*notifier_call)(struct notifier_block *self,unsigned long ,void *); +int (*notifier_call)(struct notifier_block *,unsigned long ,void *);struct notifier_block *next;int priority; }; +struct notifier_head { +enum notifier_type type; +struct rw_semaphore rwsem; +struct notifier_block *head; +}; + +#define NOTIFIER_HEAD_INIT (name, head_type) { \ + .type = head_type, \ + .rwsem = __RWSEM_INITIALIZER((name).rwsem), \ + .head = NULL } + +#define NOTIFIER_HEAD (name, head_type) \ + struct notifier_head name = NOTIFIER_HEAD_INIT(name, head_type) + +#define INIT_NOTIFIER_HEAD (name, head_type) do { \ + (name)->type = head_type; \ + init_rwsem(&(name)->rwsem); \ + (name)->head = NULL; \ +} while (0) + +#define ATOMIC_NOTIFIER_HEAD_INIT (name) \ + NOTIFIER_HEAD_INIT(name, ATOMIC_NOTIFIER) +#define ATOMIC_NOTIFIER_HEAD (name) \ + NOTIFIER_HEAD(name, ATOMIC_NOTIFIER) +#define ATOMIC_INIT_NOTIFIER_HEAD (name) \ + INIT_NOTIFIER_HEAD(name, ATOMIC_NOTIFIER) + +#define BLOCKING_NOTIFIER_HEAD_INIT (name) \ + NOTIFIER_HEAD_INIT(name, BLOCKING_NOTIFIER) +#define BLOCKING_NOTIFIER_HEAD (name) \ + NOTIFIER_HEAD(name, BLOCKING_NOTIFIER) +#define BLOCKING_INIT_NOTIFIER_HEAD (name) \ + INIT_NOTIFIER_HEAD(name, BLOCKING_NOTIFIER)#ifdef __KERNEL__ -extern int notifier_chain_register (struct notifier_block **list,struct notifier_block *n); -extern int notifier_chain_unregister (struct notifier_block **nl,struct notifier_block *n); -extern int notifier_call_chain (struct notifier_block **n,unsigned long val,void *v); +extern int notifier_chain_register (struct notifier_head *, +struct notifier_block *); +extern int notifier_chain_unregister (struct notifier_head *, +struct notifier_block *); +extern int notifier_call_chain (struct notifier_head *, +unsigned long val,void *v);#define NOTIFY_DONE 0x0000/* Don't care */ #define NOTIFY_OK 0x0001/* Suits me */ #define NOTIFY_STOP_MASK 0x8000/* Don't call further */ -#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002)/* Bad/Veto action */ +#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) +/* Bad/Veto action */ /* * Clean way to return from the notifier and stop further calls. */
kernel/sys.c +57 -36
147 lines not on this page · raw message
Signature · 4 lines
----------------------------------------------------------------------
Chandra Seetharaman | Be careful what you choose....
- [email protected] | .......you may get it.
----------------------------------------------------------------------