* [patch 0/2] stop_machine: create kstop threads only when needed
@ 2008-12-22 11:36 Heiko Carstens
2008-12-22 11:36 ` [patch 1/2] stop_machine: introduce stop_machine_create/destroy Heiko Carstens
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Heiko Carstens @ 2008-12-22 11:36 UTC (permalink / raw)
To: Andrew Morton, Rusty Russell; +Cc: linux-kernel, Heiko Carstens
Introduce stop_machine_create/destroy. With this interface subsystems
that need a non-failing stop_machine environment can create the
stop_machine threads before actually calling stop_machine.
When the threads aren't needed anymore they can be killed with
stop_machine_destroy again.
When stop_machine gets called and the threads aren't present they
will be created and destroyed automatically.
This restores the old behaviour of stop_machine from 2.6.27 and thus
we get rid of the normally not needed kstop threads.
The second patch converts the module loader/unloder code to the new
interface, since it needs a non-failing stop_machine infrastructure.
Looks like there are more users that need a non-failing version.
I'll take care of them when I'm back from vacation.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [patch 1/2] stop_machine: introduce stop_machine_create/destroy.
2008-12-22 11:36 [patch 0/2] stop_machine: create kstop threads only when needed Heiko Carstens
@ 2008-12-22 11:36 ` Heiko Carstens
2009-01-27 8:04 ` [Bug 12492] " Andrew Morton
2008-12-22 11:36 ` [patch 2/2] module: convert to stop_machine_create/destroy Heiko Carstens
2008-12-25 13:07 ` [patch 0/2] stop_machine: create kstop threads only when needed Rusty Russell
2 siblings, 1 reply; 7+ messages in thread
From: Heiko Carstens @ 2008-12-22 11:36 UTC (permalink / raw)
To: Andrew Morton, Rusty Russell; +Cc: linux-kernel, Heiko Carstens
[-- Attachment #1: 001_stop.diff --]
[-- Type: text/plain, Size: 5299 bytes --]
From: Heiko Carstens <heiko.carstens@de.ibm.com>
Introduce stop_machine_create/destroy. With this interface subsystems
that need a non-failing stop_machine environment can create the
stop_machine machine threads before actually calling stop_machine.
When the threads aren't needed anymore they can be killed with
stop_machine_destroy again.
When stop_machine gets called and the threads aren't present they
will be created and destroyed automatically. This restores the old
behaviour of stop_machine.
This patch also converts cpu hotplug to the new interface since it
is special: cpu_down calls __stop_machine instead of stop_machine.
However the kstop threads will only be created when stop_machine
gets called.
Changing the code so that the threads would be created automatically
on __stop_machine is currently not possible: when __stop_machine gets
called we hold cpu_add_remove_lock, which is the same lock that
create_rt_workqueue would take. So the workqueue needs to be created
before the cpu hotplug code locks cpu_add_remove_lock.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
include/linux/stop_machine.h | 22 +++++++++++++++++
kernel/cpu.c | 6 +++-
kernel/stop_machine.c | 55 +++++++++++++++++++++++++++++++++++--------
3 files changed, 72 insertions(+), 11 deletions(-)
Index: linux-2.6/kernel/stop_machine.c
===================================================================
--- linux-2.6.orig/kernel/stop_machine.c
+++ linux-2.6/kernel/stop_machine.c
@@ -38,7 +38,10 @@ struct stop_machine_data {
static unsigned int num_threads;
static atomic_t thread_ack;
static DEFINE_MUTEX(lock);
-
+/* setup_lock protects refcount, stop_machine_wq and stop_machine_work. */
+static DEFINE_MUTEX(setup_lock);
+/* Users of stop_machine. */
+static int refcount;
static struct workqueue_struct *stop_machine_wq;
static struct stop_machine_data active, idle;
static const cpumask_t *active_cpus;
@@ -109,6 +112,43 @@ static int chill(void *unused)
return 0;
}
+int stop_machine_create(void)
+{
+ mutex_lock(&setup_lock);
+ if (refcount)
+ goto done;
+ stop_machine_wq = create_rt_workqueue("kstop");
+ if (!stop_machine_wq)
+ goto err_out;
+ stop_machine_work = alloc_percpu(struct work_struct);
+ if (!stop_machine_work)
+ goto err_out;
+done:
+ refcount++;
+ mutex_unlock(&setup_lock);
+ return 0;
+
+err_out:
+ if (stop_machine_wq)
+ destroy_workqueue(stop_machine_wq);
+ mutex_unlock(&setup_lock);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(stop_machine_create);
+
+void stop_machine_destroy(void)
+{
+ mutex_lock(&setup_lock);
+ refcount--;
+ if (refcount)
+ goto done;
+ destroy_workqueue(stop_machine_wq);
+ free_percpu(stop_machine_work);
+done:
+ mutex_unlock(&setup_lock);
+}
+EXPORT_SYMBOL_GPL(stop_machine_destroy);
+
int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
{
struct work_struct *sm_work;
@@ -146,19 +186,14 @@ int stop_machine(int (*fn)(void *), void
{
int ret;
+ ret = stop_machine_create();
+ if (ret)
+ return ret;
/* No CPUs can come up or down during this. */
get_online_cpus();
ret = __stop_machine(fn, data, cpus);
put_online_cpus();
-
+ stop_machine_destroy();
return ret;
}
EXPORT_SYMBOL_GPL(stop_machine);
-
-static int __init stop_machine_init(void)
-{
- stop_machine_wq = create_rt_workqueue("kstop");
- stop_machine_work = alloc_percpu(struct work_struct);
- return 0;
-}
-core_initcall(stop_machine_init);
Index: linux-2.6/kernel/cpu.c
===================================================================
--- linux-2.6.orig/kernel/cpu.c
+++ linux-2.6/kernel/cpu.c
@@ -290,8 +290,11 @@ out_release:
int __ref cpu_down(unsigned int cpu)
{
- int err = 0;
+ int err;
+ err = stop_machine_create();
+ if (err)
+ return err;
cpu_maps_update_begin();
if (cpu_hotplug_disabled) {
@@ -318,6 +321,7 @@ int __ref cpu_down(unsigned int cpu)
out:
cpu_maps_update_done();
+ stop_machine_destroy();
return err;
}
EXPORT_SYMBOL(cpu_down);
Index: linux-2.6/include/linux/stop_machine.h
===================================================================
--- linux-2.6.orig/include/linux/stop_machine.h
+++ linux-2.6/include/linux/stop_machine.h
@@ -35,6 +35,24 @@ int stop_machine(int (*fn)(void *), void
* won't come or go while it's being called. Used by hotplug cpu.
*/
int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus);
+
+/**
+ * stop_machine_create: create all stop_machine threads
+ *
+ * Description: This causes all stop_machine threads to be created before
+ * stop_machine actually gets called. This can be used by subsystems that
+ * need a non failing stop_machine infrastructure.
+ */
+int stop_machine_create(void);
+
+/**
+ * stop_machine_destroy: destroy all stop_machine threads
+ *
+ * Description: This causes all stop_machine threads which were created with
+ * stop_machine_create to be destroyed again.
+ */
+void stop_machine_destroy(void);
+
#else
static inline int stop_machine(int (*fn)(void *), void *data,
@@ -46,5 +64,9 @@ static inline int stop_machine(int (*fn)
local_irq_enable();
return ret;
}
+
+static inline int stop_machine_create(void) { return 0; }
+static inline void stop_machine_destroy(void) { }
+
#endif /* CONFIG_SMP */
#endif /* _LINUX_STOP_MACHINE */
--
^ permalink raw reply [flat|nested] 7+ messages in thread
* [patch 2/2] module: convert to stop_machine_create/destroy.
2008-12-22 11:36 [patch 0/2] stop_machine: create kstop threads only when needed Heiko Carstens
2008-12-22 11:36 ` [patch 1/2] stop_machine: introduce stop_machine_create/destroy Heiko Carstens
@ 2008-12-22 11:36 ` Heiko Carstens
2008-12-25 13:07 ` [patch 0/2] stop_machine: create kstop threads only when needed Rusty Russell
2 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2008-12-22 11:36 UTC (permalink / raw)
To: Andrew Morton, Rusty Russell; +Cc: linux-kernel, Heiko Carstens
[-- Attachment #1: 002_module.diff --]
[-- Type: text/plain, Size: 1967 bytes --]
From: Heiko Carstens <heiko.carstens@de.ibm.com>
The module code relies on a non-failing stop_machine call. So we create
the kstop threads in advance and with that make sure the call won't fail.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
kernel/module.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
Index: linux-2.6/kernel/module.c
===================================================================
--- linux-2.6.orig/kernel/module.c
+++ linux-2.6/kernel/module.c
@@ -757,8 +757,16 @@ sys_delete_module(const char __user *nam
return -EFAULT;
name[MODULE_NAME_LEN-1] = '\0';
- if (mutex_lock_interruptible(&module_mutex) != 0)
- return -EINTR;
+ /* Create stop_machine threads since free_module relies on
+ * a non-failing stop_machine call. */
+ ret = stop_machine_create();
+ if (ret)
+ return ret;
+
+ if (mutex_lock_interruptible(&module_mutex) != 0) {
+ ret = -EINTR;
+ goto out_stop;
+ }
mod = find_module(name);
if (!mod) {
@@ -817,6 +825,8 @@ sys_delete_module(const char __user *nam
out:
mutex_unlock(&module_mutex);
+out_stop:
+ stop_machine_destroy();
return ret;
}
@@ -1865,6 +1875,13 @@ static noinline struct module *load_modu
/* vmalloc barfs on "unusual" numbers. Check here */
if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
return ERR_PTR(-ENOMEM);
+
+ /* Create stop_machine threads since the error path relies on
+ * a non-failing stop_machine call. */
+ err = stop_machine_create();
+ if (err)
+ goto free_hdr;
+
if (copy_from_user(hdr, umod, len) != 0) {
err = -EFAULT;
goto free_hdr;
@@ -2257,6 +2274,7 @@ static noinline struct module *load_modu
/* Get rid of temporary copy */
vfree(hdr);
+ stop_machine_destroy();
/* Done! */
return mod;
@@ -2279,6 +2297,7 @@ static noinline struct module *load_modu
kfree(args);
free_hdr:
vfree(hdr);
+ stop_machine_destroy();
return ERR_PTR(err);
truncated:
--
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [patch 0/2] stop_machine: create kstop threads only when needed
2008-12-22 11:36 [patch 0/2] stop_machine: create kstop threads only when needed Heiko Carstens
2008-12-22 11:36 ` [patch 1/2] stop_machine: introduce stop_machine_create/destroy Heiko Carstens
2008-12-22 11:36 ` [patch 2/2] module: convert to stop_machine_create/destroy Heiko Carstens
@ 2008-12-25 13:07 ` Rusty Russell
2 siblings, 0 replies; 7+ messages in thread
From: Rusty Russell @ 2008-12-25 13:07 UTC (permalink / raw)
To: Heiko Carstens; +Cc: Andrew Morton, linux-kernel
On Monday 22 December 2008 22:06:29 Heiko Carstens wrote:
> Introduce stop_machine_create/destroy. With this interface subsystems
> that need a non-failing stop_machine environment can create the
> stop_machine threads before actually calling stop_machine.
> When the threads aren't needed anymore they can be killed with
> stop_machine_destroy again.
Thanks, this is straightforward and effective.
I've applied both patches,
Rusty.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug 12492] Re: [patch 1/2] stop_machine: introduce stop_machine_create/destroy.
2008-12-22 11:36 ` [patch 1/2] stop_machine: introduce stop_machine_create/destroy Heiko Carstens
@ 2009-01-27 8:04 ` Andrew Morton
2009-01-27 9:52 ` Andrew Morton
0 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2009-01-27 8:04 UTC (permalink / raw)
To: Heiko Carstens; +Cc: Rusty Russell, linux-kernel, Tomas Carnecky, bugme-daemon
On Mon, 22 Dec 2008 12:36:30 +0100 Heiko Carstens <heiko.carstens@de.ibm.com> wrote:
> Introduce stop_machine_create/destroy. With this interface subsystems
> that need a non-failing stop_machine environment can create the
> stop_machine machine threads before actually calling stop_machine.
> When the threads aren't needed anymore they can be killed with
> stop_machine_destroy again.
>
> When stop_machine gets called and the threads aren't present they
> will be created and destroyed automatically. This restores the old
> behaviour of stop_machine.
>
> This patch also converts cpu hotplug to the new interface since it
> is special: cpu_down calls __stop_machine instead of stop_machine.
> However the kstop threads will only be created when stop_machine
> gets called.
>
> Changing the code so that the threads would be created automatically
> on __stop_machine is currently not possible: when __stop_machine gets
> called we hold cpu_add_remove_lock, which is the same lock that
> create_rt_workqueue would take. So the workqueue needs to be created
> before the cpu hotplug code locks cpu_add_remove_lock.
In http://bugzilla.kernel.org/show_bug.cgi?id=12492, Thomas (cc'ed
here) reports
Commit 9ea09af3bd3090e8349ca2899ca2011bd94cda85 introduced a
regression that caused the kernel to fail to suspend. The 'sleeping'
LED on the laptop just keeps blinking and the laptop never shuts
down. I think this was eventually fixed because with 2.6.29-rc1 and
-rc2 the laptop suspends fine, but fails to resume. When I try to
resume, all I see is a blinking cursor in the top left corner of the
screen.
I'm using acpi_sleep=s3_bios,s3_mode, suspending using a script
that does: echo mem > /sys/power/state.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 12492] Re: [patch 1/2] stop_machine: introduce stop_machine_create/destroy.
2009-01-27 8:04 ` [Bug 12492] " Andrew Morton
@ 2009-01-27 9:52 ` Andrew Morton
2009-01-27 10:09 ` Heiko Carstens
0 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2009-01-27 9:52 UTC (permalink / raw)
To: Heiko Carstens, Rusty Russell, linux-kernel, Tomas Carnecky,
bugme-daemon
On Tue, 27 Jan 2009 00:04:32 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
> On Mon, 22 Dec 2008 12:36:30 +0100 Heiko Carstens <heiko.carstens@de.ibm.com> wrote:
>
> > Introduce stop_machine_create/destroy. With this interface subsystems
> > that need a non-failing stop_machine environment can create the
> > stop_machine machine threads before actually calling stop_machine.
> > When the threads aren't needed anymore they can be killed with
> > stop_machine_destroy again.
> >
> > When stop_machine gets called and the threads aren't present they
> > will be created and destroyed automatically. This restores the old
> > behaviour of stop_machine.
> >
> > This patch also converts cpu hotplug to the new interface since it
> > is special: cpu_down calls __stop_machine instead of stop_machine.
> > However the kstop threads will only be created when stop_machine
> > gets called.
> >
> > Changing the code so that the threads would be created automatically
> > on __stop_machine is currently not possible: when __stop_machine gets
> > called we hold cpu_add_remove_lock, which is the same lock that
> > create_rt_workqueue would take. So the workqueue needs to be created
> > before the cpu hotplug code locks cpu_add_remove_lock.
>
> In http://bugzilla.kernel.org/show_bug.cgi?id=12492, Thomas (cc'ed
> here) reports
>
> Commit 9ea09af3bd3090e8349ca2899ca2011bd94cda85 introduced a
> regression that caused the kernel to fail to suspend. The 'sleeping'
> LED on the laptop just keeps blinking and the laptop never shuts
> down. I think this was eventually fixed because with 2.6.29-rc1 and
> -rc2 the laptop suspends fine, but fails to resume. When I try to
> resume, all I see is a blinking cursor in the top left corner of the
> screen.
>
> I'm using acpi_sleep=s3_bios,s3_mode, suspending using a script
> that does: echo mem > /sys/power/state.
>
hm. Re-reading this, it seems to be saying that
9ea09af3bd3090e8349ca2899ca2011bd94cda85 might be innocent, and that
some other patch might have caused the resume regression?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 12492] Re: [patch 1/2] stop_machine: introduce stop_machine_create/destroy.
2009-01-27 9:52 ` Andrew Morton
@ 2009-01-27 10:09 ` Heiko Carstens
0 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2009-01-27 10:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: Rusty Russell, linux-kernel, Tomas Carnecky, bugme-daemon
On Tue, 27 Jan 2009 01:52:02 -0800
Andrew Morton <akpm@linux-foundation.org> wrote:
> On Tue, 27 Jan 2009 00:04:32 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
> > Commit 9ea09af3bd3090e8349ca2899ca2011bd94cda85 introduced a
> > regression that caused the kernel to fail to suspend. The 'sleeping'
> > LED on the laptop just keeps blinking and the laptop never shuts
> > down. I think this was eventually fixed because with 2.6.29-rc1 and
> > -rc2 the laptop suspends fine, but fails to resume. When I try to
> > resume, all I see is a blinking cursor in the top left corner of the
> > screen.
> >
> > I'm using acpi_sleep=s3_bios,s3_mode, suspending using a script
> > that does: echo mem > /sys/power/state.
>
> hm. Re-reading this, it seems to be saying that
> 9ea09af3bd3090e8349ca2899ca2011bd94cda85 might be innocent, and that
> some other patch might have caused the resume regression?
Yes, I already updated the bugzilla entry at kernel.org:
The bug introduced with the introduction of stop_machine_create/destroy
was fixed with a0e280e0f33f6c859a235fb69a875ed8f3420388
"stop_machine/cpu hotplug: fix disable_nonboot_cpus".
Must be something else.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-01-27 10:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-22 11:36 [patch 0/2] stop_machine: create kstop threads only when needed Heiko Carstens
2008-12-22 11:36 ` [patch 1/2] stop_machine: introduce stop_machine_create/destroy Heiko Carstens
2009-01-27 8:04 ` [Bug 12492] " Andrew Morton
2009-01-27 9:52 ` Andrew Morton
2009-01-27 10:09 ` Heiko Carstens
2008-12-22 11:36 ` [patch 2/2] module: convert to stop_machine_create/destroy Heiko Carstens
2008-12-25 13:07 ` [patch 0/2] stop_machine: create kstop threads only when needed Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox