[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |