[patch 4/3] fastboot: hold the BKL over the async init call sequence

Linux Kernel Mailing List, post #232,217
Author:
Date:
Subject:
 Arjan van de Ven
 2008-07-20 08:59:24
 [patch 4/3] fastboot: hold the BKL over the async init call sequence
From: Arjan van de Ven <[email protected]>
Subject: [PATCH] fastboot: hold the BKL over the async init call sequence

Regular init calls are called with the BKL held; make sure
the async init calls are also called with the BKL held.
While this reduces parallelism a little, it does provide
lock-for-lock compatibility. The hit to prallelism isn't too
bad, most of the init calls are done immediately or actually
block for their delays.

Signed-off-by: Arjan van de Ven <[email protected]>
---
init/main.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/init/main.c b/init/main.c
index bf79b83..dcb2c32 100644
--- a/init/main.c
+++ b/init/main.c
@@ -746,8 +746,14 @@ static void __init do_async_initcalls(struct work_struct *dummy)
{
initcall_t *call;

+ /*
+ * For compatibility with normal init calls... take the BKL
+ * not pretty, not desirable, but compatibility first
+ */
+ lock_kernel();
for (call = __async_initcall_start; call < __async_initcall_end; call++)
do_one_initcall(*call);
+ unlock_kernel();
}

static struct workqueue_struct *async_init_wq;
--
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Author:
Date:
Subject:
 Arjan van de Ven
 2008-07-20 09:00:41
 [patch 5/3] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
From: Arjan van de Ven <[email protected]>
Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first

Rene Herman points out several cases where it's basically needed to have all
level 6/6a/6s calls done before the level 7 (late_initcall) code runs. This patch
adds a sync point in the transition from the 6's to the 7's.

Second, this patch makes sure that level 6s (sync) happens before the async code starts,
and puts a user in driver/pci in this category that needs to happen before device init.

Signed-off-by: Arjan van de Ven <[email protected]>
---
drivers/pci/pci.c | 2 +-
include/asm-generic/vmlinux.lds.h | 3 ++-
init/main.c | 8 +++++++-
3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 44a46c9..d75295d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1889,7 +1889,7 @@ static int __devinit pci_setup(char *str)
}
early_param("pci", pci_setup);

-device_initcall(pci_init);
+device_initcall_sync(pci_init);

EXPORT_SYMBOL(pci_reenable_device);
EXPORT_SYMBOL(pci_enable_device_io);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 39c1afc..514dbdf 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -372,11 +372,12 @@
*(.initcall5.init) \
*(.initcall5s.init) \
*(.initcallrootfs.init) \
+ *(.initcall6s.init) \
__async_initcall_start = .; \
*(.initcall6a.init) \
__async_initcall_end = .; \
*(.initcall6.init) \
- *(.initcall6s.init) \
+ __device_initcall_end = .; \
*(.initcall7.init) \
*(.initcall7s.init)

diff --git a/init/main.c b/init/main.c
index dcb2c32..5c9e90e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -741,6 +741,7 @@ int do_one_initcall(initcall_t fn)

extern initcall_t __initcall_start[], __initcall_end[];
extern initcall_t __async_initcall_start[], __async_initcall_end[];
+extern initcall_t __device_initcall_end[];

static void __init do_async_initcalls(struct work_struct *dummy)
{
@@ -764,7 +765,7 @@ static void __init do_initcalls(void)
{
initcall_t *call;
static DECLARE_WORK(async_work, do_async_initcalls);
- int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
+ int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a, 3 = after level 6 */

async_init_wq = create_singlethread_workqueue("kasyncinit");

@@ -775,6 +776,11 @@ static void __init do_initcalls(void)
}
if (phase == 1 && call >= __async_initcall_end)
phase = 2;
+ if (phase == 2 && call >= __device_initcall_end) {
+ phase = 3;
+ /* make sure all async work is done before level 7 */
+ flush_workqueue(async_init_wq);
+ }
if (phase != 1)
do_one_initcall(*call);
}
--
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Author:
Date:
Subject:
 Ingo Molnar
 2008-07-20 18:40:00
 Re: [patch 5/3] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
* Arjan van de Ven <[email protected]> wrote:

> From: Arjan van de Ven <[email protected]>
> Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
>
> Rene Herman points out several cases where it's basically needed to
> have all level 6/6a/6s calls done before the level 7 (late_initcall)
> code runs. This patch adds a sync point in the transition from the 6's
> to the 7's.
>
> Second, this patch makes sure that level 6s (sync) happens before the
> async code starts, and puts a user in driver/pci in this category that
> needs to happen before device init.

incidentally, this fixed an USB related boot hang i found today on one
of my testsystems running tip/master (which had patches 1-2-3 already),
which i was about to report. Good spotting Rene! I've applied patches
4/5 to tip/fastboot.

Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Author:
Date:
Subject:
 Daniel Walker
 2008-07-20 14:14:59
 Re: [patch 5/3] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
On Sun, 2008-07-20 at 09:00 -0700, Arjan van de Ven wrote:
> @@ -775,6 +776,11 @@ static void __init do_initcalls(void)
> }
> if (phase == 1 && call >= __async_initcall_end)
> phase = 2;
> + if (phase == 2 && call >= __device_initcall_end) {
> + phase = 3;
> + /* make sure all async work is done before level 7 */
> + flush_workqueue(async_init_wq);
> + }
> if (phase != 1)
> do_one_initcall(*call);
> }

Did this impact the boot time improvements at all?

Daniel

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Author:
Date:
Subject:
 Simon Arlott
 2008-07-20 22:23:07
 Re: [patch 5/3] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
On 20/07/08 22:14, Daniel Walker wrote:
> On Sun, 2008-07-20 at 09:00 -0700, Arjan van de Ven wrote:
>> @@ -775,6 +776,11 @@ static void __init do_initcalls(void)
>> }
>> if (phase == 1 && call >= __async_initcall_end)
>> phase = 2;
>> + if (phase == 2 && call >= __device_initcall_end) {
>> + phase = 3;
>> + /* make sure all async work is done before level 7 */
>> + flush_workqueue(async_init_wq);
>> + }
>> if (phase != 1)
>> do_one_initcall(*call);
>> }
>
> Did this impact the boot time improvements at all?

The USB HCD initcalls take so little time to complete (100ms
each) that ensuring they have finished makes no difference.

USB devices get detected after those initcalls finish in
parallel with the rest of the boot process (and there's
about 1.5s before the first USB device driver initcall
runs).

--
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/