[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Import raw notifier subsystem from Linux.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1273828410 -3600
# Node ID 9ff084bae83a1506f731ff6a926fefcccec5b1b1
# Parent  baccadfd9418b8dee931945e5752cb118f5bf3cb
Import raw notifier subsystem from Linux.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/common/Makefile        |    1 
 xen/common/notifier.c      |  153 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/notifier.h |   89 ++++++++++++++++++++++++++
 3 files changed, 243 insertions(+)

diff -r baccadfd9418 -r 9ff084bae83a xen/common/Makefile
--- a/xen/common/Makefile       Fri May 14 08:05:05 2010 +0100
+++ b/xen/common/Makefile       Fri May 14 10:13:30 2010 +0100
@@ -11,6 +11,7 @@ obj-y += lib.o
 obj-y += lib.o
 obj-y += memory.o
 obj-y += multicall.o
+obj-y += notifier.o
 obj-y += page_alloc.o
 obj-y += rangeset.o
 obj-y += sched_credit.o
diff -r baccadfd9418 -r 9ff084bae83a xen/common/notifier.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/notifier.c     Fri May 14 10:13:30 2010 +0100
@@ -0,0 +1,153 @@
+/******************************************************************************
+ * common/notifier.c
+ *
+ * Routines to manage notifier chains for passing status changes to any
+ * interested routines.
+ *
+ * Original code from Linux kernel 2.6.27 (Alan Cox <Alan.Cox@xxxxxxxxx>)
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/notifier.h>
+#include <xen/rcupdate.h>
+
+/*
+ * Notifier chain core routines.  The exported routines below
+ * are layered on top of these, with appropriate locking added.
+ */
+
+static int notifier_chain_register(
+    struct notifier_block **nl, struct notifier_block *n)
+{
+    while ( (*nl) != NULL )
+    {
+        if ( n->priority > (*nl)->priority )
+            break;
+        nl = &((*nl)->next);
+    }
+    n->next = *nl;
+    rcu_assign_pointer(*nl, n);
+    return 0;
+}
+
+static int notifier_chain_unregister(
+    struct notifier_block **nl, struct notifier_block *n)
+{
+    while ( (*nl) != NULL )
+    {
+        if ( (*nl) == n )
+        {
+            rcu_assign_pointer(*nl, n->next);
+            return 0;
+        }
+        nl = &((*nl)->next);
+    }
+    return -ENOENT;
+}
+
+/**
+ * notifier_call_chain - Informs the registered notifiers about an event.
+ * @nl:  Pointer to head of the blocking notifier chain
+ * @val:  Value passed unmodified to notifier function
+ * @v:  Pointer passed unmodified to notifier function
+ * @nr_to_call: Number of notifier functions to be called. Don't care
+ *   value of this parameter is -1.
+ * @nr_calls: Records the number of notifications sent. Don't care
+ *   value of this field is NULL.
+ * @returns: notifier_call_chain returns the value returned by the
+ *   last notifier function called.
+ */
+static int notifier_call_chain(
+    struct notifier_block **nl, unsigned long val, void *v,
+    int nr_to_call, int *nr_calls)
+{
+    int ret = NOTIFY_DONE;
+    struct notifier_block *nb, *next_nb;
+
+    nb = rcu_dereference(*nl);
+
+    while ( nb && nr_to_call )
+    {
+        next_nb = rcu_dereference(nb->next);
+        ret = nb->notifier_call(nb, val, v);
+
+        if ( nr_calls )
+            (*nr_calls)++;
+
+        if ( (ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK )
+            break;
+        nb = next_nb;
+        nr_to_call--;
+    }
+    return ret;
+}
+
+/*
+ * Raw notifier chain routines.  There is no protection;
+ * the caller must provide it.  Use at your own risk!
+ */
+
+/**
+ * raw_notifier_chain_register - Add notifier to a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to a raw notifier chain.
+ * All locking must be provided by the caller.
+ *
+ * Currently always returns zero.
+ */
+int raw_notifier_chain_register(
+    struct raw_notifier_head *nh, struct notifier_block *n)
+{
+    return notifier_chain_register(&nh->head, n);
+}
+
+/**
+ * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @n: Entry to remove from notifier chain
+ *
+ * Removes a notifier from a raw notifier chain.
+ * All locking must be provided by the caller.
+ *
+ * Returns zero on success or %-ENOENT on failure.
+ */
+int raw_notifier_chain_unregister(
+    struct raw_notifier_head *nh, struct notifier_block *n)
+{
+    return notifier_chain_unregister(&nh->head, n);
+}
+
+/**
+ * __raw_notifier_call_chain - Call functions in a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: See comment for notifier_call_chain.
+ * @nr_calls: See comment for notifier_call_chain
+ *
+ * Calls each function in a notifier chain in turn.  The functions
+ * run in an undefined context.
+ * All locking must be provided by the caller.
+ *
+ * If the return value of the notifier can be and'ed
+ * with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise the return value is the return value
+ * of the last notifier function called.
+ */
+int __raw_notifier_call_chain(
+    struct raw_notifier_head *nh, unsigned long val, void *v,
+    int nr_to_call, int *nr_calls)
+{
+    return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+}
+
+int raw_notifier_call_chain(
+    struct raw_notifier_head *nh, unsigned long val, void *v)
+{
+    return __raw_notifier_call_chain(nh, val, v, -1, NULL);
+}
diff -r baccadfd9418 -r 9ff084bae83a xen/include/xen/notifier.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/notifier.h        Fri May 14 10:13:30 2010 +0100
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * include/xen/notifier.h
+ *
+ * Routines to manage notifier chains for passing status changes to any
+ * interested routines.
+ *
+ * Original code from Linux kernel 2.6.27 (Alan Cox <Alan.Cox@xxxxxxxxx>)
+ */
+ 
+#ifndef __XEN_NOTIFIER_H__
+#define __XEN_NOTIFIER_H__
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/errno.h>
+
+/*
+ * Xen includes only one type of notifier chains inherited from Linux:
+ *     Raw notifier chains: There are no restrictions on callbacks,
+ *        registration, or unregistration.  All locking and protection
+ *        must be provided by the caller.
+ */
+
+struct notifier_block {
+    int (*notifier_call)(struct notifier_block *, unsigned long, void *);
+    struct notifier_block *next;
+    int priority;
+};
+
+struct raw_notifier_head {
+    struct notifier_block *head;
+};
+
+#define RAW_INIT_NOTIFIER_HEAD(name) do {       \
+    (name)->head = NULL;                        \
+} while (0)
+
+#define RAW_NOTIFIER_INIT(name) { .head = NULL }
+
+#define RAW_NOTIFIER_HEAD(name) \
+    struct raw_notifier_head name = RAW_NOTIFIER_INIT(name)
+
+int raw_notifier_chain_register(
+    struct raw_notifier_head *nh, struct notifier_block *nb);
+
+int raw_notifier_chain_unregister(
+    struct raw_notifier_head *nh, struct notifier_block *nb);
+
+int raw_notifier_call_chain(
+    struct raw_notifier_head *nh, unsigned long val, void *v);
+int __raw_notifier_call_chain(
+    struct raw_notifier_head *nh, unsigned long val, void *v,
+    int nr_to_call, int *nr_calls);
+
+#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 */
+/*
+ * Clean way to return from the notifier and stop further calls.
+ */
+#define NOTIFY_STOP  (NOTIFY_OK|NOTIFY_STOP_MASK)
+
+/* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */
+static inline int notifier_from_errno(int err)
+{
+    return NOTIFY_STOP_MASK | (NOTIFY_OK - err);
+}
+
+/* Restore (negative) errno value from notify return value. */
+static inline int notifier_to_errno(int ret)
+{
+    ret &= ~NOTIFY_STOP_MASK;
+    return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0;
+}
+
+#define CPU_ONLINE  0x0002 /* CPU (unsigned)v is up */
+#define CPU_UP_PREPARE  0x0003 /* CPU (unsigned)v coming up */
+#define CPU_UP_CANCELED  0x0004 /* CPU (unsigned)v NOT coming up */
+#define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */
+#define CPU_DOWN_FAILED  0x0006 /* CPU (unsigned)v NOT going down */
+#define CPU_DEAD  0x0007 /* CPU (unsigned)v dead */
+#define CPU_DYING  0x0008 /* CPU (unsigned)v not running any task,
+                           * not handling interrupts, soon dead */
+#define CPU_POST_DEAD  0x0009 /* CPU (unsigned)v dead, cpu_hotplug
+                               * lock is dropped */
+
+#endif /* __XEN_NOTIFIER_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.