Skip to contentSkip to conversation

: Interface change to the notifier chain mechanism - basic fix

RFC PATCH New Chandra Seetharaman 1 participant 1 message Nov 19, 2005

lore
Share & tools
lore
#0 lore raw

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.

-----

 include/linux/notifier.h |   69 ++++++++++++++++++++++++++++++++--
 kernel/sys.c             |   93 ++++++++++++++++++++++++++++-------------------
 2 files changed, 121 insertions(+), 41 deletions(-)
include/linux/notifier.h +64 -5
Index: l2615-rc1-notifiers/include/linux/notifier.h
===================================================================
@@ -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.
----------------------------------------------------------------------