diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch new file mode 100644 index 0000000000..db518b36eb --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch | |||
@@ -0,0 +1,133 @@ | |||
1 | From ac9103dd8e4dc65c110d6cba9a3380c6c617ffa7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Arjan van de Ven <arjan@linux.intel.com> | ||
3 | Date: Fri, 18 Jul 2008 15:16:08 -0700 | ||
4 | Subject: [PATCH] fastboot: create a "asynchronous" initlevel | ||
5 | |||
6 | This patch creates an asynchronous initlevel (6a) which is at the same | ||
7 | level as the normal device initcalls, but with the difference that they | ||
8 | are run asynchronous from all the other initcalls. The purpose of this | ||
9 | *selective* level is that we can move long waiting inits that are not | ||
10 | boot-critical to this level one at a time. | ||
11 | |||
12 | To keep things not totally insane, the asynchronous initcalls are async | ||
13 | to the other initcalls, but are still ordered to themselves; think of it | ||
14 | as "bottom-half-not-softirq". This has the benefit that async drivers | ||
15 | still have stable device ordering between them. | ||
16 | |||
17 | Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> | ||
18 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | ||
19 | --- | ||
20 | include/asm-generic/vmlinux.lds.h | 3 +++ | ||
21 | include/linux/init.h | 6 ++++++ | ||
22 | init/main.c | 35 ++++++++++++++++++++++++++++++++--- | ||
23 | 3 files changed, 41 insertions(+), 3 deletions(-) | ||
24 | |||
25 | Index: linux-2.6.27/include/asm-generic/vmlinux.lds.h | ||
26 | =================================================================== | ||
27 | --- linux-2.6.27.orig/include/asm-generic/vmlinux.lds.h 2008-10-14 16:55:43.000000000 +0200 | ||
28 | +++ linux-2.6.27/include/asm-generic/vmlinux.lds.h 2008-10-14 17:00:59.000000000 +0200 | ||
29 | @@ -376,6 +376,9 @@ | ||
30 | *(.initcall5.init) \ | ||
31 | *(.initcall5s.init) \ | ||
32 | *(.initcallrootfs.init) \ | ||
33 | + __async_initcall_start = .; \ | ||
34 | + *(.initcall6a.init) \ | ||
35 | + __async_initcall_end = .; \ | ||
36 | *(.initcall6.init) \ | ||
37 | *(.initcall6s.init) \ | ||
38 | *(.initcall7.init) \ | ||
39 | Index: linux-2.6.27/include/linux/init.h | ||
40 | =================================================================== | ||
41 | --- linux-2.6.27.orig/include/linux/init.h 2008-10-14 16:55:45.000000000 +0200 | ||
42 | +++ linux-2.6.27/include/linux/init.h 2008-10-14 17:00:59.000000000 +0200 | ||
43 | @@ -197,11 +197,13 @@ extern void (*late_time_init)(void); | ||
44 | #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) | ||
45 | #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) | ||
46 | #define device_initcall(fn) __define_initcall("6",fn,6) | ||
47 | +#define device_initcall_async(fn) __define_initcall("6a", fn, 6a) | ||
48 | #define device_initcall_sync(fn) __define_initcall("6s",fn,6s) | ||
49 | #define late_initcall(fn) __define_initcall("7",fn,7) | ||
50 | #define late_initcall_sync(fn) __define_initcall("7s",fn,7s) | ||
51 | |||
52 | #define __initcall(fn) device_initcall(fn) | ||
53 | +#define __initcall_async(fn) device_initcall_async(fn) | ||
54 | |||
55 | #define __exitcall(fn) \ | ||
56 | static exitcall_t __exitcall_##fn __exit_call = fn | ||
57 | @@ -257,6 +259,7 @@ void __init parse_early_param(void); | ||
58 | * be one per module. | ||
59 | */ | ||
60 | #define module_init(x) __initcall(x); | ||
61 | +#define module_init_async(x) __initcall_async(x); | ||
62 | |||
63 | /** | ||
64 | * module_exit() - driver exit entry point | ||
65 | @@ -279,10 +282,13 @@ void __init parse_early_param(void); | ||
66 | #define subsys_initcall(fn) module_init(fn) | ||
67 | #define fs_initcall(fn) module_init(fn) | ||
68 | #define device_initcall(fn) module_init(fn) | ||
69 | +#define device_initcall_async(fn) module_init(fn) | ||
70 | #define late_initcall(fn) module_init(fn) | ||
71 | |||
72 | #define security_initcall(fn) module_init(fn) | ||
73 | |||
74 | +#define module_init_async(fn) module_init(fn) | ||
75 | + | ||
76 | /* Each module must use one module_init(). */ | ||
77 | #define module_init(initfn) \ | ||
78 | static inline initcall_t __inittest(void) \ | ||
79 | Index: linux-2.6.27/init/main.c | ||
80 | =================================================================== | ||
81 | --- linux-2.6.27.orig/init/main.c 2008-10-14 16:55:47.000000000 +0200 | ||
82 | +++ linux-2.6.27/init/main.c 2008-10-14 17:00:59.000000000 +0200 | ||
83 | @@ -745,18 +745,47 @@ int do_one_initcall(initcall_t fn) | ||
84 | |||
85 | |||
86 | extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; | ||
87 | +extern initcall_t __async_initcall_start[], __async_initcall_end[]; | ||
88 | |||
89 | -static void __init do_initcalls(void) | ||
90 | +static void __init do_async_initcalls(struct work_struct *dummy) | ||
91 | { | ||
92 | initcall_t *call; | ||
93 | |||
94 | - for (call = __early_initcall_end; call < __initcall_end; call++) | ||
95 | + for (call = __async_initcall_start; call < __async_initcall_end; call++) | ||
96 | do_one_initcall(*call); | ||
97 | +} | ||
98 | + | ||
99 | +static struct workqueue_struct *async_init_wq; | ||
100 | + | ||
101 | +static void __init do_initcalls(void) | ||
102 | +{ | ||
103 | + initcall_t *call; | ||
104 | + static DECLARE_WORK(async_work, do_async_initcalls); | ||
105 | + int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */ | ||
106 | + | ||
107 | + async_init_wq = create_singlethread_workqueue("kasyncinit"); | ||
108 | + | ||
109 | + for (call = __early_initcall_end; call < __initcall_end; call++) { | ||
110 | + if (phase == 0 && call >= __async_initcall_start) { | ||
111 | + phase = 1; | ||
112 | + queue_work(async_init_wq, &async_work); | ||
113 | + } | ||
114 | + if (phase == 1 && call >= __async_initcall_end) | ||
115 | + phase = 2; | ||
116 | + if (phase != 1) | ||
117 | + do_one_initcall(*call); | ||
118 | + } | ||
119 | |||
120 | - /* Make sure there is no pending stuff from the initcall sequence */ | ||
121 | + /* | ||
122 | + * Make sure there is no pending stuff from the initcall sequence, | ||
123 | + * including the async initcalls | ||
124 | + */ | ||
125 | flush_scheduled_work(); | ||
126 | + flush_workqueue(async_init_wq); | ||
127 | + destroy_workqueue(async_init_wq); | ||
128 | } | ||
129 | |||
130 | + | ||
131 | /* | ||
132 | * Ok, the machine is now initialized. None of the devices | ||
133 | * have been touched yet, but the CPU subsystem is up and | ||