* [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes. @ 2006-11-14 12:18 Gautham R Shenoy 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy 2006-11-15 0:47 ` [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Andrew Morton 0 siblings, 2 replies; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-14 12:18 UTC (permalink / raw) To: akpm, torvalds; +Cc: linux-kernel, vatsa, dipankar, davej, mingo, kiran Hello everyone, 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 :) Awaiting your feedback. Thanks, gautham. PS: These patches are intended for post 2.6.19, since most of the warnings with respect to cpu_hotplug_locking (including the cpufreq ones) seem to have disappeared in 2.6.19-rc5. -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-14 12:18 [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Gautham R Shenoy @ 2006-11-14 12:20 ` Gautham R Shenoy 2006-11-14 12:22 ` [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE Gautham R Shenoy ` (2 more replies) 2006-11-15 0:47 ` [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Andrew Morton 1 sibling, 3 replies; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-14 12:20 UTC (permalink / raw) To: Gautham R Shenoy Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran 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. Credit : Andrew Morton <akpm@osdl.org> Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> -- include/linux/notifier.h | 8 +++ kernel/sys.c | 97 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 16 deletions(-) Index: hotplug/kernel/sys.c =================================================================== --- hotplug.orig/kernel/sys.c +++ hotplug/kernel/sys.c @@ -134,19 +134,41 @@ static int notifier_chain_unregister(str 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. + * + * RETURN VALUE: notifier_call_chain returns the value returned by the + * last notifier function called. + */ + static int __kprobes notifier_call_chain(struct notifier_block **nl, - unsigned long val, void *v) + unsigned long val, void *v, + int nr_to_call, unsigned int *nr_calls) { int ret = NOTIFY_DONE; struct notifier_block *nb, *next_nb; nb = rcu_dereference(*nl); - while (nb) { + + 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; } @@ -205,10 +227,13 @@ int atomic_notifier_chain_unregister(str EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); /** - * atomic_notifier_call_chain - Call functions in an atomic notifier chain + * __atomic_notifier_call_chain - Call functions in an atomic notifier + * chain * @nh: Pointer to head of the atomic notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function + * @nr_to_call: See the comment for notifier_call_chain. + * @nr_calls: See the comment for notifier_call_chain. * * Calls each function in a notifier chain in turn. The functions * run in an atomic context, so they must not block. @@ -222,19 +247,27 @@ EXPORT_SYMBOL_GPL(atomic_notifier_chain_ * of the last notifier function called. */ -int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, - unsigned long val, void *v) +int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, unsigned int *nr_calls) { int ret; rcu_read_lock(); - ret = notifier_call_chain(&nh->head, val, v); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); rcu_read_unlock(); return ret; } -EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); +EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain); +int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v) +{ + return __atomic_notifier_call_chain(nh, val, v, -1, NULL); +} + +EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); /* * Blocking notifier chain routines. All access to the chain is * synchronized by an rwsem. @@ -304,10 +337,13 @@ int blocking_notifier_chain_unregister(s EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); /** - * blocking_notifier_call_chain - Call functions in a blocking notifier chain + * __blocking_notifier_call_chain - Call functions in a blocking notifier + * chain * @nh: 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: 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 a process context, so they are allowed to block. @@ -320,17 +356,26 @@ EXPORT_SYMBOL_GPL(blocking_notifier_chai * of the last notifier function called. */ -int blocking_notifier_call_chain(struct blocking_notifier_head *nh, - unsigned long val, void *v) +int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, unsigned int * nr_calls) { int ret; down_read(&nh->rwsem); - ret = notifier_call_chain(&nh->head, val, v); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); up_read(&nh->rwsem); return ret; } +EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain); + +int blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v) +{ + return __blocking_notifier_call_chain(nh, val, v, -1, NULL); +} + EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); /* @@ -376,10 +421,12 @@ int raw_notifier_chain_unregister(struct EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister); /** - * raw_notifier_call_chain - Call functions in a raw notifier chain + * __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. @@ -393,10 +440,19 @@ EXPORT_SYMBOL_GPL(raw_notifier_chain_unr * 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, unsigned int *nr_calls) +{ + return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); +} + +EXPORT_SYMBOL_GPL(__raw_notifier_call_chain); + int raw_notifier_call_chain(struct raw_notifier_head *nh, unsigned long val, void *v) { - return notifier_call_chain(&nh->head, val, v); + return __raw_notifier_call_chain(nh, val, v, -1, NULL); } EXPORT_SYMBOL_GPL(raw_notifier_call_chain); @@ -475,6 +531,8 @@ EXPORT_SYMBOL_GPL(srcu_notifier_chain_un * @nh: Pointer to head of the SRCU 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 a process context, so they are allowed to block. @@ -487,18 +545,25 @@ EXPORT_SYMBOL_GPL(srcu_notifier_chain_un * of the last notifier function called. */ -int srcu_notifier_call_chain(struct srcu_notifier_head *nh, - unsigned long val, void *v) +int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, unsigned int *nr_calls) { int ret; int idx; idx = srcu_read_lock(&nh->srcu); - ret = notifier_call_chain(&nh->head, val, v); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); srcu_read_unlock(&nh->srcu, idx); return ret; } +EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain); +int srcu_notifier_call_chain(struct srcu_notifier_head *nh, + unsigned long val, void *v) +{ + return __srcu_notifier_call_chain(nh, val, v, -1, NULL); +} EXPORT_SYMBOL_GPL(srcu_notifier_call_chain); /** Index: hotplug/include/linux/notifier.h =================================================================== --- hotplug.orig/include/linux/notifier.h +++ hotplug/include/linux/notifier.h @@ -132,12 +132,20 @@ extern int srcu_notifier_chain_unregiste extern int atomic_notifier_call_chain(struct atomic_notifier_head *, unsigned long val, void *v); +extern int __atomic_notifier_call_chain(struct atomic_notifier_head *, + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); extern int blocking_notifier_call_chain(struct blocking_notifier_head *, unsigned long val, void *v); +extern int __blocking_notifier_call_chain(struct blocking_notifier_head *, + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); extern int raw_notifier_call_chain(struct raw_notifier_head *, unsigned long val, void *v); +extern int __raw_notifier_call_chain(struct raw_notifier_head *, + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); extern int srcu_notifier_call_chain(struct srcu_notifier_head *, unsigned long val, void *v); +extern int __srcu_notifier_call_chain(struct srcu_notifier_head *, + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); #define NOTIFY_DONE 0x0000 /* Don't care */ #define NOTIFY_OK 0x0001 /* Suits me */ -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE. 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy @ 2006-11-14 12:22 ` Gautham R Shenoy 2006-11-14 12:23 ` [PATCH 3/4] Eliminate lock_cpu_hotplug in kernel/sched.c Gautham R Shenoy 2006-11-14 18:18 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Randy Dunlap 2006-11-21 6:19 ` [PATCH 1/4] Extend " Andrew Morton 2 siblings, 1 reply; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-14 12:22 UTC (permalink / raw) To: Gautham R Shenoy Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran This is an attempt to provide an alternate mechanism for postponing a hotplug event instead of using a global mechanism like lock_cpu_hotplug. The proposal is to add two new events namely CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE. The notification for these two events would be sent out before and after a cpu_hotplug event respectively. During the CPU_LOCK_ACQUIRE event, a cpu-hotplug-aware subsystem is supposed to acquire any per-subsystem hotcpu mutex ( Eg. workqueue_mutex in kernel/workqueue.c ). During the CPU_LOCK_RELEASE release event the cpu-hotplug-aware subsystem is supposed to release the per-subsystem hotcpu mutex. The reasons for defining new events as opposed to reusing the existing events like CPU_UP_PREPARE/CPU_UP_FAILED/CPU_ONLINE for locking/unlocking of per-subsystem hotcpu mutexes are as follow: - CPU_LOCK_ACQUIRE: All hotcpu mutexes are taken before subsystems start handling pre-hotplug events like CPU_UP_PREPARE/CPU_DOWN_PREPARE etc, thus ensuring a clean handling of these events. - CPU_LOCK_RELEASE: The hotcpu mutexes will be released only after all subsystems have handled post-hotplug events like CPU_DOWN_FAILED, CPU_DEAD,CPU_ONLINE etc thereby ensuring that there are no subsequent clashes amongst the interdependent subsystems after a cpu hotplugs. This patch also uses __raw_notifier_call chain in _cpu_up to take care of the dependency between the two consequetive calls to raw_notifier_call_chain. Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> -- include/linux/notifier.h | 2 ++ kernel/cpu.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) Index: hotplug/kernel/cpu.c =================================================================== --- hotplug.orig/kernel/cpu.c +++ hotplug/kernel/cpu.c @@ -132,6 +132,8 @@ static int _cpu_down(unsigned int cpu) if (!cpu_online(cpu)) return -EINVAL; + raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, + (void *)(long)cpu); err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, (void *)(long)cpu); if (err == NOTIFY_BAD) { @@ -185,6 +187,8 @@ out_thread: err = kthread_stop(p); out_allowed: set_cpus_allowed(current, old_allowed); + raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, + (void *)(long)cpu); return err; } @@ -206,13 +210,15 @@ int cpu_down(unsigned int cpu) /* Requires cpu_add_remove_lock to be held */ static int __devinit _cpu_up(unsigned int cpu) { - int ret; + int ret, nr_calls = 0; void *hcpu = (void *)(long)cpu; if (cpu_online(cpu) || !cpu_present(cpu)) return -EINVAL; - ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); + raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); + ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, + -1, &nr_calls); if (ret == NOTIFY_BAD) { printk("%s: attempt to bring up CPU %u failed\n", __FUNCTION__, cpu); @@ -233,8 +239,9 @@ static int __devinit _cpu_up(unsigned in out_notify: if (ret != 0) - raw_notifier_call_chain(&cpu_chain, - CPU_UP_CANCELED, hcpu); + __raw_notifier_call_chain(&cpu_chain, + CPU_UP_CANCELED, hcpu, nr_calls, NULL); + raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); return ret; } Index: hotplug/include/linux/notifier.h =================================================================== --- hotplug.orig/include/linux/notifier.h +++ hotplug/include/linux/notifier.h @@ -194,6 +194,8 @@ extern int __srcu_notifier_call_chain(st #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_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ +#define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ #endif /* __KERNEL__ */ #endif /* _LINUX_NOTIFIER_H */ -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/4] Eliminate lock_cpu_hotplug in kernel/sched.c 2006-11-14 12:22 ` [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE Gautham R Shenoy @ 2006-11-14 12:23 ` Gautham R Shenoy 2006-11-14 12:24 ` [PATCH 4/4] Handle CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE in workqueue_cpu_callback Gautham R Shenoy 0 siblings, 1 reply; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-14 12:23 UTC (permalink / raw) To: Gautham R Shenoy Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran Eliminate lock_cpu_hotplug from kernel/sched.c and use sched_hotcpu_mutex instead to postpone a hotplug event. In the migration_call hotcpu callback function, take sched_hotcpu_mutex while handling the event CPU_LOCK_ACQUIRE and release it while handling CPU_LOCK_RELEASE event. Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> -- kernel/sched.c | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) Index: hotplug/kernel/sched.c =================================================================== --- hotplug.orig/kernel/sched.c +++ hotplug/kernel/sched.c @@ -267,6 +267,7 @@ struct rq { }; static DEFINE_PER_CPU(struct rq, runqueues); +static DEFINE_MUTEX(sched_hotcpu_mutex); static inline int cpu_of(struct rq *rq) { @@ -4327,13 +4328,13 @@ long sched_setaffinity(pid_t pid, cpumas struct task_struct *p; int retval; - lock_cpu_hotplug(); + mutex_lock(&sched_hotcpu_mutex); read_lock(&tasklist_lock); p = find_process_by_pid(pid); if (!p) { read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); + mutex_unlock(&sched_hotcpu_mutex); return -ESRCH; } @@ -4360,7 +4361,7 @@ long sched_setaffinity(pid_t pid, cpumas out_unlock: put_task_struct(p); - unlock_cpu_hotplug(); + mutex_unlock(&sched_hotcpu_mutex); return retval; } @@ -4417,7 +4418,7 @@ long sched_getaffinity(pid_t pid, cpumas struct task_struct *p; int retval; - lock_cpu_hotplug(); + mutex_lock(&sched_hotcpu_mutex); read_lock(&tasklist_lock); retval = -ESRCH; @@ -4433,7 +4434,7 @@ long sched_getaffinity(pid_t pid, cpumas out_unlock: read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); + mutex_unlock(&sched_hotcpu_mutex); if (retval) return retval; @@ -5225,6 +5226,10 @@ migration_call(struct notifier_block *nf struct rq *rq; switch (action) { + case CPU_LOCK_ACQUIRE: + mutex_lock(&sched_hotcpu_mutex); + break; + case CPU_UP_PREPARE: p = kthread_create(migration_thread, hcpu, "migration/%d",cpu); if (IS_ERR(p)) @@ -5270,7 +5275,7 @@ migration_call(struct notifier_block *nf BUG_ON(rq->nr_running != 0); /* No need to migrate the tasks: it was best-effort if - * they didn't do lock_cpu_hotplug(). Just wake up + * they didn't take sched_hotcpu_mutex. Just wake up * the requestors. */ spin_lock_irq(&rq->lock); while (!list_empty(&rq->migration_queue)) { @@ -5283,6 +5288,10 @@ migration_call(struct notifier_block *nf } spin_unlock_irq(&rq->lock); break; + + case CPU_LOCK_RELEASE: + mutex_unlock(&sched_hotcpu_mutex); + break; #endif } return NOTIFY_OK; @@ -6652,10 +6661,10 @@ int arch_reinit_sched_domains(void) { int err; - lock_cpu_hotplug(); + mutex_lock(&sched_hotcpu_mutex); detach_destroy_domains(&cpu_online_map); err = arch_init_sched_domains(&cpu_online_map); - unlock_cpu_hotplug(); + mutex_unlock(&sched_hotcpu_mutex); return err; } @@ -6763,12 +6772,12 @@ void __init sched_init_smp(void) { cpumask_t non_isolated_cpus; - lock_cpu_hotplug(); + mutex_lock(&sched_hotcpu_mutex); arch_init_sched_domains(&cpu_online_map); cpus_andnot(non_isolated_cpus, cpu_online_map, cpu_isolated_map); if (cpus_empty(non_isolated_cpus)) cpu_set(smp_processor_id(), non_isolated_cpus); - unlock_cpu_hotplug(); + mutex_unlock(&sched_hotcpu_mutex); /* XXX: Theoretical race here - CPU may be hotplugged now */ hotcpu_notifier(update_sched_domains, 0); -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/4] Handle CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE in workqueue_cpu_callback. 2006-11-14 12:23 ` [PATCH 3/4] Eliminate lock_cpu_hotplug in kernel/sched.c Gautham R Shenoy @ 2006-11-14 12:24 ` Gautham R Shenoy 0 siblings, 0 replies; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-14 12:24 UTC (permalink / raw) To: Gautham R Shenoy Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran In hot-cpu callback function workqueue_cpu_callback, lock the workqueue_mutex under CPU_LOCK_ACQUIRE and release it under CPU_LOCK_RELEASE. This eliminates handling of redundant events namely CPU_DOWN_PREPARE and CPU_DOWN_FAILED. Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> -- kernel/workqueue.c | 18 +++++++----------- 1 files changed, 7 insertions(+), 11 deletions(-) Index: hotplug/kernel/workqueue.c =================================================================== --- hotplug.orig/kernel/workqueue.c +++ hotplug/kernel/workqueue.c @@ -638,8 +638,11 @@ static int __devinit workqueue_cpu_callb struct workqueue_struct *wq; switch (action) { - case CPU_UP_PREPARE: + case CPU_LOCK_ACQUIRE: mutex_lock(&workqueue_mutex); + break; + + case CPU_UP_PREPARE: /* Create a new workqueue thread for it. */ list_for_each_entry(wq, &workqueues, list) { if (!create_workqueue_thread(wq, hotcpu)) { @@ -658,7 +661,6 @@ static int __devinit workqueue_cpu_callb kthread_bind(cwq->thread, hotcpu); wake_up_process(cwq->thread); } - mutex_unlock(&workqueue_mutex); break; case CPU_UP_CANCELED: @@ -670,15 +672,6 @@ static int __devinit workqueue_cpu_callb any_online_cpu(cpu_online_map)); cleanup_workqueue_thread(wq, hotcpu); } - mutex_unlock(&workqueue_mutex); - break; - - case CPU_DOWN_PREPARE: - mutex_lock(&workqueue_mutex); - break; - - case CPU_DOWN_FAILED: - mutex_unlock(&workqueue_mutex); break; case CPU_DEAD: @@ -686,6 +679,9 @@ static int __devinit workqueue_cpu_callb cleanup_workqueue_thread(wq, hotcpu); list_for_each_entry(wq, &workqueues, list) take_over_work(wq, hotcpu); + break; + + case CPU_LOCK_RELEASE: mutex_unlock(&workqueue_mutex); break; } -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy 2006-11-14 12:22 ` [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE Gautham R Shenoy @ 2006-11-14 18:18 ` Randy Dunlap 2006-11-15 4:59 ` Gautham R Shenoy 2006-11-15 8:29 ` [PATCH 1-fix/4] Fix extend " Gautham R Shenoy 2006-11-21 6:19 ` [PATCH 1/4] Extend " Andrew Morton 2 siblings, 2 replies; 12+ messages in thread From: Randy Dunlap @ 2006-11-14 18:18 UTC (permalink / raw) To: ego; +Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran On Tue, 14 Nov 2006 17:50:51 +0530 Gautham R Shenoy wrote: > 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. Those could (should?) be the same data type. > Credit : Andrew Morton <akpm@osdl.org> > Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> > > -- > include/linux/notifier.h | 8 +++ > kernel/sys.c | 97 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 16 deletions(-) > > Index: hotplug/kernel/sys.c > =================================================================== > --- hotplug.orig/kernel/sys.c > +++ hotplug/kernel/sys.c > @@ -134,19 +134,41 @@ static int notifier_chain_unregister(str > 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. > + * > + * RETURN VALUE: notifier_call_chain returns the value returned by the > + * last notifier function called. > + */ You can make that comment block be kernel-doc format by using /** as the comment introduction and removing the blank line after the function name & short description. > static int __kprobes notifier_call_chain(struct notifier_block **nl, > - unsigned long val, void *v) > + unsigned long val, void *v, > + int nr_to_call, unsigned int *nr_calls) > { > int ret = NOTIFY_DONE; > struct notifier_block *nb, *next_nb; ... > } > @@ -205,10 +227,13 @@ int atomic_notifier_chain_unregister(str > EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); > > /** > - * atomic_notifier_call_chain - Call functions in an atomic notifier chain > + * __atomic_notifier_call_chain - Call functions in an atomic notifier > + * chain Don't break the short function description line; kernel-doc does not support that. > * @nh: Pointer to head of the atomic notifier chain > * @val: Value passed unmodified to notifier function > * @v: Pointer passed unmodified to notifier function > + * @nr_to_call: See the comment for notifier_call_chain. > + * @nr_calls: See the comment for notifier_call_chain. > * > * Calls each function in a notifier chain in turn. The functions > * run in an atomic context, so they must not block. > @@ -222,19 +247,27 @@ EXPORT_SYMBOL_GPL(atomic_notifier_chain_ > * of the last notifier function called. > */ > > -int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, > - unsigned long val, void *v) > +int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, > + unsigned long val, void *v, > + int nr_to_call, unsigned int *nr_calls) > { ... > } > > -EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); > +EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain); > > +int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, > + unsigned long val, void *v) > +{ > + return __atomic_notifier_call_chain(nh, val, v, -1, NULL); > +} > + > +EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); > /* > * Blocking notifier chain routines. All access to the chain is > * synchronized by an rwsem. > @@ -304,10 +337,13 @@ int blocking_notifier_chain_unregister(s > EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); > > /** > - * blocking_notifier_call_chain - Call functions in a blocking notifier chain > + * __blocking_notifier_call_chain - Call functions in a blocking notifier > + * chain kernel-doc requires that the function description fit on one source line, so don't break it (even if it is > 80 columns; yes, I know it needs to be fixed) > * @nh: 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: 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 a process context, so they are allowed to block. > Index: hotplug/include/linux/notifier.h > =================================================================== > --- hotplug.orig/include/linux/notifier.h > +++ hotplug/include/linux/notifier.h > @@ -132,12 +132,20 @@ extern int srcu_notifier_chain_unregiste > > extern int atomic_notifier_call_chain(struct atomic_notifier_head *, > unsigned long val, void *v); > +extern int __atomic_notifier_call_chain(struct atomic_notifier_head *, While you are changing these lines, please put a prototype parameter name for all parameters; i.e., add something like "notifier" or "nh" after the '*' on all of these. > + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); > extern int blocking_notifier_call_chain(struct blocking_notifier_head *, > unsigned long val, void *v); > +extern int __blocking_notifier_call_chain(struct blocking_notifier_head *, > + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); > extern int raw_notifier_call_chain(struct raw_notifier_head *, > unsigned long val, void *v); > +extern int __raw_notifier_call_chain(struct raw_notifier_head *, > + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); > extern int srcu_notifier_call_chain(struct srcu_notifier_head *, > unsigned long val, void *v); > +extern int __srcu_notifier_call_chain(struct srcu_notifier_head *, > + unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); > > #define NOTIFY_DONE 0x0000 /* Don't care */ > #define NOTIFY_OK 0x0001 /* Suits me */ > -- --- ~Randy ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-14 18:18 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Randy Dunlap @ 2006-11-15 4:59 ` Gautham R Shenoy 2006-11-15 6:00 ` Randy Dunlap 2006-11-15 8:29 ` [PATCH 1-fix/4] Fix extend " Gautham R Shenoy 1 sibling, 1 reply; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-15 4:59 UTC (permalink / raw) To: Randy Dunlap Cc: ego, akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran On Tue, Nov 14, 2006 at 10:18:06AM -0800, Randy Dunlap wrote: > On Tue, 14 Nov 2006 17:50:51 +0530 Gautham R Shenoy wrote: > > > 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. > > Those could (should?) be the same data type. Whoops! Yes, they should be the same. I was trying to solve this problem with only one parameter (which we can, but the signature would look very confusing) and was using the unsigned int* there. Will change it to int *. Thanks for pointing that out. > > > Credit : Andrew Morton <akpm@osdl.org> > > Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> > > > > -- > > include/linux/notifier.h | 8 +++ > > kernel/sys.c | 97 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 16 deletions(-) > > > > Index: hotplug/kernel/sys.c > > =================================================================== > > --- hotplug.orig/kernel/sys.c > > +++ hotplug/kernel/sys.c > > @@ -134,19 +134,41 @@ static int notifier_chain_unregister(str > > 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. > > + * > > + * RETURN VALUE: notifier_call_chain returns the value returned by the > > + * last notifier function called. > > + */ > > You can make that comment block be kernel-doc format by using > /** > as the comment introduction and removing the blank line after the > function name & short description. Will do that. But out of curiousity, do the comments of even static functions get reflected in kernel doc ? :? > > > static int __kprobes notifier_call_chain(struct notifier_block **nl, > > - unsigned long val, void *v) > > + unsigned long val, void *v, > > + int nr_to_call, unsigned int *nr_calls) > > { > > int ret = NOTIFY_DONE; > > struct notifier_block *nb, *next_nb; > ... > > } > > @@ -205,10 +227,13 @@ int atomic_notifier_chain_unregister(str > > EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); > > > > /** > > - * atomic_notifier_call_chain - Call functions in an atomic notifier chain > > + * __atomic_notifier_call_chain - Call functions in an atomic notifier > > + * chain > > Don't break the short function description line; kernel-doc does not > support that. Ok. Didn't know that. Will correct it. > > > * @nh: Pointer to head of the atomic notifier chain [snip!] > > Index: hotplug/include/linux/notifier.h > > =================================================================== > > --- hotplug.orig/include/linux/notifier.h > > +++ hotplug/include/linux/notifier.h > > @@ -132,12 +132,20 @@ extern int srcu_notifier_chain_unregiste > > > > extern int atomic_notifier_call_chain(struct atomic_notifier_head *, > > unsigned long val, void *v); > > +extern int __atomic_notifier_call_chain(struct atomic_notifier_head *, > > While you are changing these lines, please put a prototype parameter > name for all parameters; i.e., add something like "notifier" > or "nh" after the '*' on all of these. > Yup. Will do. > --- > ~Randy thanks, gautham. -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-15 4:59 ` Gautham R Shenoy @ 2006-11-15 6:00 ` Randy Dunlap 0 siblings, 0 replies; 12+ messages in thread From: Randy Dunlap @ 2006-11-15 6:00 UTC (permalink / raw) To: ego; +Cc: akpm, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran Gautham R Shenoy wrote: > On Tue, Nov 14, 2006 at 10:18:06AM -0800, Randy Dunlap wrote: >> On Tue, 14 Nov 2006 17:50:51 +0530 Gautham R Shenoy wrote: >> >>> include/linux/notifier.h | 8 +++ >>> kernel/sys.c | 97 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 16 deletions(-) >>> >>> Index: hotplug/kernel/sys.c >>> =================================================================== >>> --- hotplug.orig/kernel/sys.c >>> +++ hotplug/kernel/sys.c >>> @@ -134,19 +134,41 @@ static int notifier_chain_unregister(str >>> 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. >>> + * >>> + * RETURN VALUE: notifier_call_chain returns the value returned by the >>> + * last notifier function called. >>> + */ >> You can make that comment block be kernel-doc format by using >> /** >> as the comment introduction and removing the blank line after the >> function name & short description. > > Will do that. But out of curiousity, do the comments of even static functions > get reflected in kernel doc ? :? They can be, but static functions are low priority for kernel-doc IMO, so it's not a big deal to me if you don't make that be kernel-doc. >>> static int __kprobes notifier_call_chain(struct notifier_block **nl, >>> - unsigned long val, void *v) >>> + unsigned long val, void *v, >>> + int nr_to_call, unsigned int *nr_calls) >>> { >>> int ret = NOTIFY_DONE; >>> struct notifier_block *nb, *next_nb; >> ... >>> } Thanks, -- ~Randy ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1-fix/4] Fix extend notifier_call_chain to count nr_calls made. 2006-11-14 18:18 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Randy Dunlap 2006-11-15 4:59 ` Gautham R Shenoy @ 2006-11-15 8:29 ` Gautham R Shenoy 1 sibling, 0 replies; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-15 8:29 UTC (permalink / raw) To: akpm Cc: ego, randy.dunlap, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran Hi Andrew, Please apply the following patch on top of extend-notifier_call_chain-to-count-nr_calls-made.patch. This patch incorporates the Randy's suggestions. thanks, gautham. This patch * Corrects the type of nr_calls to int * from unsigned int * in notifier_call_chain and it's subsequent callers. * Converts comments of notifier_call_chain to be compliant with kernel-docs standards. *Reverts the changes made to the comments of other *_notifier_call_chain. *Adds parameter names to a few functions prototypes in include/linux/notifier.h . Depends on patch: extend-notifier_call_chain-to-count-nr_calls-made.patch Cc: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> -- include/linux/notifier.h | 58 +++++++++++++++++++++++------------------------ kernel/sys.c | 24 ++++++++----------- 2 files changed, 39 insertions(+), 43 deletions(-) Index: hotplug/kernel/sys.c =================================================================== --- hotplug.orig/kernel/sys.c +++ hotplug/kernel/sys.c @@ -134,9 +134,8 @@ static int notifier_chain_unregister(str 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 @@ -144,14 +143,13 @@ static int notifier_chain_unregister(str * value of this parameter is -1. * @nr_calls: Records the number of notifications sent. Don't care * value of this field is NULL. - * - * RETURN VALUE: notifier_call_chain returns the value returned by the + * @returns: notifier_call_chain returns the value returned by the * last notifier function called. */ static int __kprobes notifier_call_chain(struct notifier_block **nl, unsigned long val, void *v, - int nr_to_call, unsigned int *nr_calls) + int nr_to_call, int *nr_calls) { int ret = NOTIFY_DONE; struct notifier_block *nb, *next_nb; @@ -227,8 +225,7 @@ int atomic_notifier_chain_unregister(str EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); /** - * __atomic_notifier_call_chain - Call functions in an atomic notifier - * chain + * __atomic_notifier_call_chain - Call functions in an atomic notifier chain * @nh: Pointer to head of the atomic notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function @@ -249,7 +246,7 @@ EXPORT_SYMBOL_GPL(atomic_notifier_chain_ int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v, - int nr_to_call, unsigned int *nr_calls) + int nr_to_call, int *nr_calls) { int ret; @@ -337,8 +334,7 @@ int blocking_notifier_chain_unregister(s EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); /** - * __blocking_notifier_call_chain - Call functions in a blocking notifier - * chain + * __blocking_notifier_call_chain - Call functions in a blocking notifier chain * @nh: Pointer to head of the blocking notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function @@ -358,7 +354,7 @@ EXPORT_SYMBOL_GPL(blocking_notifier_chai int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v, - int nr_to_call, unsigned int * nr_calls) + int nr_to_call, int *nr_calls) { int ret; @@ -442,7 +438,7 @@ EXPORT_SYMBOL_GPL(raw_notifier_chain_unr int __raw_notifier_call_chain(struct raw_notifier_head *nh, unsigned long val, void *v, - int nr_to_call, unsigned int *nr_calls) + int nr_to_call, int *nr_calls) { return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); } @@ -527,7 +523,7 @@ int srcu_notifier_chain_unregister(struc EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister); /** - * srcu_notifier_call_chain - Call functions in an SRCU notifier chain + * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain * @nh: Pointer to head of the SRCU notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function @@ -547,7 +543,7 @@ EXPORT_SYMBOL_GPL(srcu_notifier_chain_un int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v, - int nr_to_call, unsigned int *nr_calls) + int nr_to_call, int *nr_calls) { int ret; int idx; Index: hotplug/include/linux/notifier.h =================================================================== --- hotplug.orig/include/linux/notifier.h +++ hotplug/include/linux/notifier.h @@ -112,40 +112,40 @@ extern void srcu_init_notifier_head(stru #ifdef __KERNEL__ -extern int atomic_notifier_chain_register(struct atomic_notifier_head *, - struct notifier_block *); -extern int blocking_notifier_chain_register(struct blocking_notifier_head *, - struct notifier_block *); -extern int raw_notifier_chain_register(struct raw_notifier_head *, - struct notifier_block *); -extern int srcu_notifier_chain_register(struct srcu_notifier_head *, - struct notifier_block *); - -extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *, - struct notifier_block *); -extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *, - struct notifier_block *); -extern int raw_notifier_chain_unregister(struct raw_notifier_head *, - struct notifier_block *); -extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *, - struct notifier_block *); +extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, + struct notifier_block *nb); +extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh, + struct notifier_block *nb); +extern int raw_notifier_chain_register(struct raw_notifier_head *nh, + struct notifier_block *nb); +extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh, + struct notifier_block *nb); + +extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, + struct notifier_block *nb); +extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh, + struct notifier_block *nb); +extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh, + struct notifier_block *nb); +extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh, + struct notifier_block *nb); -extern int atomic_notifier_call_chain(struct atomic_notifier_head *, +extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v); -extern int __atomic_notifier_call_chain(struct atomic_notifier_head *, - unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); -extern int blocking_notifier_call_chain(struct blocking_notifier_head *, +extern int __atomic_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v, int nr_to_call, int *nr_calls); +extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v); -extern int __blocking_notifier_call_chain(struct blocking_notifier_head *, - unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); -extern int raw_notifier_call_chain(struct raw_notifier_head *, +extern int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v, int nr_to_call, int *nr_calls); +extern int raw_notifier_call_chain(struct raw_notifier_head *nh, unsigned long val, void *v); -extern int __raw_notifier_call_chain(struct raw_notifier_head *, - unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); -extern int srcu_notifier_call_chain(struct srcu_notifier_head *, +extern int __raw_notifier_call_chain(struct raw_notifier_head *nh, + unsigned long val, void *v, int nr_to_call, int *nr_calls); +extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v); -extern int __srcu_notifier_call_chain(struct srcu_notifier_head *, - unsigned long val, void *v, int nr_to_call, unsigned int *nr_calls); +extern int __srcu_notifier_call_chain(struct srcu_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 */ -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy 2006-11-14 12:22 ` [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE Gautham R Shenoy 2006-11-14 18:18 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Randy Dunlap @ 2006-11-21 6:19 ` Andrew Morton 2006-11-22 6:13 ` Gautham R Shenoy 2 siblings, 1 reply; 12+ messages in thread From: Andrew Morton @ 2006-11-21 6:19 UTC (permalink / raw) To: ego; +Cc: torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran On Tue, 14 Nov 2006 17:50:51 +0530 Gautham R Shenoy <ego@in.ibm.com> wrote: > 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. > > ... > > + > static int __kprobes notifier_call_chain(struct notifier_block **nl, > - unsigned long val, void *v) > + unsigned long val, void *v, > + int nr_to_call, unsigned int *nr_calls) > { > int ret = NOTIFY_DONE; > struct notifier_block *nb, *next_nb; > > nb = rcu_dereference(*nl); > - while (nb) { > + > + while (nb && nr_to_call) { > next_nb = rcu_dereference(nb->next); > ret = nb->notifier_call(nb, val, v); > + > + if (nr_calls) > + *nr_calls ++; This gets kernel/sys.c: In function 'notifier_call_chain': kernel/sys.c:164: warning: value computed is not used And indeed, this code doesn't work. What happened? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] Extend notifier_call_chain to count nr_calls made. 2006-11-21 6:19 ` [PATCH 1/4] Extend " Andrew Morton @ 2006-11-22 6:13 ` Gautham R Shenoy 0 siblings, 0 replies; 12+ messages in thread From: Gautham R Shenoy @ 2006-11-22 6:13 UTC (permalink / raw) To: Andrew Morton Cc: ego, torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran Hi Andrew, On Mon, Nov 20, 2006 at 10:19:41PM -0800, Andrew Morton wrote: > > + > > + if (nr_calls) > > + *nr_calls ++; > > This gets > > kernel/sys.c: In function 'notifier_call_chain': > kernel/sys.c:164: warning: value computed is not used > > > And indeed, this code doesn't work. > > What happened? I didn't get the warnings because my test box still has the prehistoric version 3.4.4 of gcc. I compiled the code with gcc 4.1.1 and got the warnings. The code does not work because of my carelessness. It should have been (*nr_calls)++ in the first place. I apologise. Thanks for fixing it. Regards gautham. -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes. 2006-11-14 12:18 [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Gautham R Shenoy 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy @ 2006-11-15 0:47 ` Andrew Morton 1 sibling, 0 replies; 12+ messages in thread From: Andrew Morton @ 2006-11-15 0:47 UTC (permalink / raw) To: ego; +Cc: torvalds, linux-kernel, vatsa, dipankar, davej, mingo, kiran On Tue, 14 Nov 2006 17:48:32 +0530 Gautham R Shenoy <ego@in.ibm.com> wrote: > 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 The approach seems sane to me. Sort-of direct, specific and transactional.. I applied this fixup: diff -puN kernel/cpu.c~define-and-use-new-eventscpu_lock_acquire-and-cpu_lock_release-fix kernel/cpu.c --- a/kernel/cpu.c~define-and-use-new-eventscpu_lock_acquire-and-cpu_lock_release-fix +++ a/kernel/cpu.c @@ -139,7 +139,8 @@ static int _cpu_down(unsigned int cpu) if (err == NOTIFY_BAD) { printk("%s: attempt to take down CPU %u failed\n", __FUNCTION__, cpu); - return -EINVAL; + err = -EINVAL; + goto out_release; } /* Ensure that we are not runnable on dying cpu */ @@ -187,6 +188,7 @@ out_thread: err = kthread_stop(p); out_allowed: set_cpus_allowed(current, old_allowed); +out_release: raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, (void *)(long)cpu); return err; _ please send a patch to fix up the kerneldoc things which Randy spotted, thanks. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-11-22 6:35 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-11-14 12:18 [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Gautham R Shenoy 2006-11-14 12:20 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Gautham R Shenoy 2006-11-14 12:22 ` [PATCH 2/4] Define and use new events,CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE Gautham R Shenoy 2006-11-14 12:23 ` [PATCH 3/4] Eliminate lock_cpu_hotplug in kernel/sched.c Gautham R Shenoy 2006-11-14 12:24 ` [PATCH 4/4] Handle CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE in workqueue_cpu_callback Gautham R Shenoy 2006-11-14 18:18 ` [PATCH 1/4] Extend notifier_call_chain to count nr_calls made Randy Dunlap 2006-11-15 4:59 ` Gautham R Shenoy 2006-11-15 6:00 ` Randy Dunlap 2006-11-15 8:29 ` [PATCH 1-fix/4] Fix extend " Gautham R Shenoy 2006-11-21 6:19 ` [PATCH 1/4] Extend " Andrew Morton 2006-11-22 6:13 ` Gautham R Shenoy 2006-11-15 0:47 ` [RFC 0/4] Cpu-Hotplug: Use per subsystem hot-cpu mutexes Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox