aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorGautham R Shenoy <ego@in.ibm.com>2007-05-09 05:34:02 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:30:51 -0400
commit6f7cc11aa6c7d5002e16096c7590944daece70ed (patch)
tree68a11e4b67189c44ac0f3ab579e52e134d479cf5 /include/linux
parent7c9cb38302e78d24e37f7d8a2ea7eed4ae5f2fa7 (diff)
Extend notifier_call_chain to count nr_calls made
Since 2.6.18-something, the community has been bugged by the problem to provide a clean and a stable mechanism to postpone a cpu-hotplug event as lock_cpu_hotplug was badly broken. This is another proposal towards solving that problem. This one is along the lines of the solution provided in kernel/workqueue.c Instead of having a global mechanism like lock_cpu_hotplug, we allow the subsytems to define their own per-subsystem hot cpu mutexes. These would be taken(released) where ever we are currently calling lock_cpu_hotplug(unlock_cpu_hotplug). Also, in the per-subsystem hotcpu callback function,we take this mutex before we handle any pre-cpu-hotplug events and release it once we finish handling the post-cpu-hotplug events. A standard means for doing this has been provided in [PATCH 2/4] and demonstrated in [PATCH 3/4]. The ordering of these per-subsystem mutexes might still prove to be a problem, but hopefully lockdep should help us get out of that muddle. The patch set to be applied against linux-2.6.19-rc5 is as follows: [PATCH 1/4] : Extend notifier_call_chain with an option to specify the number of notifications to be sent and also count the number of notifications actually sent. [PATCH 2/4] : Define events CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE and send out notifications for these in _cpu_up and _cpu_down. This would help us standardise the acquire and release of the subsystem locks in the hotcpu callback functions of these subsystems. [PATCH 3/4] : Eliminate lock_cpu_hotplug from kernel/sched.c. [PATCH 4/4] : In workqueue_cpu_callback function, acquire(release) the workqueue_mutex while handling CPU_LOCK_ACQUIRE(CPU_LOCK_RELEASE). If the per-subsystem-locking approach survives the test of time, we can expect a slow phasing out of lock_cpu_hotplug, which has not yet been eliminated in these patches :) This patch: Provide notifier_call_chain with an option to call only a specified number of notifiers and also record the number of call to notifiers made. The need for this enhancement was identified in the post entitled "Slab - Eliminate lock_cpu_hotplug from slab" (http://lkml.org/lkml/2006/10/28/92) by Ravikiran G Thirumalai and Andrew Morton. This patch adds two additional parameters to notifier_call_chain API namely - int nr_to_calls : Number of notifier_functions to be called. The don't care value is -1. - unsigned int *nr_calls : Records the total number of notifier_funtions called by notifier_call_chain. The don't care value is NULL. [michal.k.k.piotrowski@gmail.com: build fix] Credit: Andrew Morton <akpm@osdl.org> Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> Signed-off-by: Michal Piotrowski <michal.k.k.piotrowski@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/notifier.h52
1 files changed, 30 insertions, 22 deletions
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 10a43ed0527e..e34221bf8946 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -112,32 +112,40 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
112 112
113#ifdef __KERNEL__ 113#ifdef __KERNEL__
114 114
115extern int atomic_notifier_chain_register(struct atomic_notifier_head *, 115extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
116 struct notifier_block *); 116 struct notifier_block *nb);
117extern int blocking_notifier_chain_register(struct blocking_notifier_head *, 117extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
118 struct notifier_block *); 118 struct notifier_block *nb);
119extern int raw_notifier_chain_register(struct raw_notifier_head *, 119extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
120 struct notifier_block *); 120 struct notifier_block *nb);
121extern int srcu_notifier_chain_register(struct srcu_notifier_head *, 121extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
122 struct notifier_block *); 122 struct notifier_block *nb);
123 123
124extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *, 124extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
125 struct notifier_block *); 125 struct notifier_block *nb);
126extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *, 126extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
127 struct notifier_block *); 127 struct notifier_block *nb);
128extern int raw_notifier_chain_unregister(struct raw_notifier_head *, 128extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
129 struct notifier_block *); 129 struct notifier_block *nb);
130extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *, 130extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
131 struct notifier_block *); 131 struct notifier_block *nb);
132 132
133extern int atomic_notifier_call_chain(struct atomic_notifier_head *, 133extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
134 unsigned long val, void *v); 134 unsigned long val, void *v);
135extern int blocking_notifier_call_chain(struct blocking_notifier_head *, 135extern int __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
136 unsigned long val, void *v, int nr_to_call, int *nr_calls);
137extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
136 unsigned long val, void *v); 138 unsigned long val, void *v);
137extern int raw_notifier_call_chain(struct raw_notifier_head *, 139extern int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
140 unsigned long val, void *v, int nr_to_call, int *nr_calls);
141extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
138 unsigned long val, void *v); 142 unsigned long val, void *v);
139extern int srcu_notifier_call_chain(struct srcu_notifier_head *, 143extern int __raw_notifier_call_chain(struct raw_notifier_head *nh,
144 unsigned long val, void *v, int nr_to_call, int *nr_calls);
145extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
140 unsigned long val, void *v); 146 unsigned long val, void *v);
147extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
148 unsigned long val, void *v, int nr_to_call, int *nr_calls);
141 149
142#define NOTIFY_DONE 0x0000 /* Don't care */ 150#define NOTIFY_DONE 0x0000 /* Don't care */
143#define NOTIFY_OK 0x0001 /* Suits me */ 151#define NOTIFY_OK 0x0001 /* Suits me */