* [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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.