public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arjan van de Ven <arjan@infradead.org>
To: linux-kernel@vger.kernel.org
Cc: Arjan van de Ven <arjan@infradead.org>, mingo@elte.hu
Subject: [patch 1/3] fastboot: Create a "asynchronous" initlevel
Date: Fri, 18 Jul 2008 15:16:08 -0700	[thread overview]
Message-ID: <20080718151608.46dc17c0@infradead.org> (raw)
In-Reply-To: <20080718151524.5ef9e29b@infradead.org>

>From 7cdd9446f49f430ff29bfb2d2e20759cc9f2d9e8 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Fri, 18 Jul 2008 11:30:52 -0700
Subject: [PATCH] fastboot: Create a "asynchronous" initlevel

This patch creates an asynchronous initlevel (6a) which is at the same level as
the normal device initcalls, but with the difference that they are run asynchronous
from all the other initcalls. The purpose of this *selective* level is that we can
move long waiting inits that are not boot-critical to this level one at a time.

To keep things not totally insane, the asynchronous initcalls are async to the other
initcalls, but are still ordered to themselves; think of it as "bottom-half-not-softirq".
This has the benefit that async drivers still have stable device ordering between them.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
 include/asm-generic/vmlinux.lds.h |    3 +++
 include/linux/init.h              |    6 ++++++
 init/main.c                       |   37 ++++++++++++++++++++++++++++++++++---
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 729f6b0..72691e8 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -372,6 +372,9 @@
   	*(.initcall5.init)						\
   	*(.initcall5s.init)						\
 	*(.initcallrootfs.init)						\
+	__async_initcall_start = .;					\
+	*(.initcall6a.init)						\
+	__async_initcall_end = .;					\
   	*(.initcall6.init)						\
   	*(.initcall6s.init)						\
   	*(.initcall7.init)						\
diff --git a/include/linux/init.h b/include/linux/init.h
index 21d658c..96474ff 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -189,11 +189,13 @@ extern void (*late_time_init)(void);
 #define fs_initcall_sync(fn)		__define_initcall("5s",fn,5s)
 #define rootfs_initcall(fn)		__define_initcall("rootfs",fn,rootfs)
 #define device_initcall(fn)		__define_initcall("6",fn,6)
+#define device_initcall_async(fn)	__define_initcall("6a", fn, 6a)
 #define device_initcall_sync(fn)	__define_initcall("6s",fn,6s)
 #define late_initcall(fn)		__define_initcall("7",fn,7)
 #define late_initcall_sync(fn)		__define_initcall("7s",fn,7s)
 
 #define __initcall(fn) device_initcall(fn)
+#define __initcall_async(fn) device_initcall_async(fn)
 
 #define __exitcall(fn) \
 	static exitcall_t __exitcall_##fn __exit_call = fn
@@ -249,6 +251,7 @@ void __init parse_early_param(void);
  * be one per module.
  */
 #define module_init(x)	__initcall(x);
+#define module_init_async(x)	__initcall_async(x);
 
 /**
  * module_exit() - driver exit entry point
@@ -271,10 +274,13 @@ void __init parse_early_param(void);
 #define subsys_initcall(fn)		module_init(fn)
 #define fs_initcall(fn)			module_init(fn)
 #define device_initcall(fn)		module_init(fn)
+#define device_initcall_async(fn)	module_init(fn)
 #define late_initcall(fn)		module_init(fn)
 
 #define security_initcall(fn)		module_init(fn)
 
+#define module_init_async(fn)		module_init(fn)
+
 /* These macros create a dummy inline: gcc 2.9x does not count alias
  as usage, hence the `unused function' warning when __init functions
  are declared static. We use the dummy __*_module_inline functions
diff --git a/init/main.c b/init/main.c
index edeace0..42d5a5f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -738,16 +738,46 @@ static void __init do_one_initcall(initcall_t fn)
 
 
 extern initcall_t __initcall_start[], __initcall_end[];
+extern initcall_t __async_initcall_start[], __async_initcall_end[];
 
-static void __init do_initcalls(void)
+static void __init do_async_initcalls(struct work_struct *dummy)
 {
 	initcall_t *call;
 
-	for (call = __initcall_start; call < __initcall_end; call++)
+	for (call = __async_initcall_start; call < __async_initcall_end; call++)
 		do_one_initcall(*call);
+}
+
+static struct workqueue_struct *async_init_wq;
 
-	/* Make sure there is no pending stuff from the initcall sequence */
+
+
+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 */
+
+	async_init_wq = create_singlethread_workqueue("kasyncinit");
+
+	for (call = __initcall_start; call < __initcall_end; call++) {
+		if (phase == 0 && call >= __async_initcall_start) {
+			phase = 1;
+			queue_work(async_init_wq, &async_work);
+		}
+		if (phase == 1 && call >= __async_initcall_end)
+			phase = 2;
+		if (phase != 1)
+			do_one_initcall(*call);
+	}
+
+	/*
+	 * Make sure there is no pending stuff from the initcall sequence,
+	 * including the async initcalls
+	 */
 	flush_scheduled_work();
+	flush_workqueue(async_init_wq);
+	destroy_workqueue(async_init_wq);
 }
 
 /*
-- 
1.5.5.1


  reply	other threads:[~2008-07-18 22:18 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-18 22:15 [patch 0/3] fastboot patches series 1 Arjan van de Ven
2008-07-18 22:16 ` Arjan van de Ven [this message]
2008-07-19  1:22   ` [patch 1/3] fastboot: Create a "asynchronous" initlevel Daniel Walker
2008-07-19  3:44     ` Arjan van de Ven
2008-07-19  4:11       ` Daniel Walker
2008-07-19  4:58         ` Arjan van de Ven
2008-07-19  5:20         ` Arjan van de Ven
2008-07-19 15:24           ` Daniel Walker
2008-07-19 15:35             ` Arjan van de Ven
2008-07-19 16:08               ` Daniel Walker
2008-07-19 16:14                 ` Arjan van de Ven
2008-07-19  4:28       ` Daniel Walker
2008-07-19  7:53   ` Rene Herman
2008-07-19  8:10     ` Rene Herman
2008-07-19 15:44       ` Arjan van de Ven
2008-07-20  7:23         ` Rene Herman
2008-07-20 11:10           ` Arjan van de Ven
2008-07-20 14:20             ` Rene Herman
2008-07-20 15:35               ` Arjan van de Ven
2008-07-18 22:16 ` [patch 2/3] fastboot: turn the USB hostcontroller initcalls into async initcalls Arjan van de Ven
2008-07-18 22:17 ` [patch 3/3] fastboot: convert a few non-critical ACPI drivers to " Arjan van de Ven
2008-07-19  4:51 ` [patch 0/3] fastboot patches series 1 Simon Arlott
2008-07-19  5:16   ` Arjan van de Ven
2008-07-19  5:47     ` Simon Arlott
2008-07-19 10:22     ` Andi Kleen
2008-07-20  8:31 ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080718151608.46dc17c0@infradead.org \
    --to=arjan@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox