]> code.ossystems Code Review - openembedded-core.git/blob
d1ff95a39f6f887333f1c1ca80b246e23263139f
[openembedded-core.git] /
1 From 660625fb93f2fc0e633da9cb71d13d895b385f64 Mon Sep 17 00:00:00 2001
2 From: Arjan van de Ven <arjan@linux.intel.com>
3 Date: Sun, 20 Jul 2008 09:00:41 -0700
4 Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
5
6 Rene Herman points out several cases where it's basically needed to have
7 all level 6/6a/6s calls done before the level 7 (late_initcall) code
8 runs. This patch adds a sync point in the transition from the 6's to the
9 7's.
10
11 Second, this patch makes sure that level 6s (sync) happens before the
12 async code starts, and puts a user in driver/pci in this category that
13 needs to happen before device init.
14
15 Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
16 Signed-off-by: Ingo Molnar <mingo@elte.hu>
17 ---
18  drivers/pci/pci.c                 |    2 +-
19  include/asm-generic/vmlinux.lds.h |    3 ++-
20  init/main.c                       |   14 +++++++++++++-
21  3 files changed, 16 insertions(+), 3 deletions(-)
22
23 Index: linux-2.6.27/drivers/pci/pci.c
24 ===================================================================
25 --- linux-2.6.27.orig/drivers/pci/pci.c 2008-10-14 16:55:30.000000000 +0200
26 +++ linux-2.6.27/drivers/pci/pci.c      2008-10-14 17:01:42.000000000 +0200
27 @@ -1909,7 +1909,7 @@ static int __devinit pci_setup(char *str
28  }
29  early_param("pci", pci_setup);
30  
31 -device_initcall(pci_init);
32 +device_initcall_sync(pci_init);
33  
34  EXPORT_SYMBOL(pci_reenable_device);
35  EXPORT_SYMBOL(pci_enable_device_io);
36 Index: linux-2.6.27/include/asm-generic/vmlinux.lds.h
37 ===================================================================
38 --- linux-2.6.27.orig/include/asm-generic/vmlinux.lds.h 2008-10-14 17:00:59.000000000 +0200
39 +++ linux-2.6.27/include/asm-generic/vmlinux.lds.h      2008-10-14 17:01:42.000000000 +0200
40 @@ -376,11 +376,12 @@
41         *(.initcall5.init)                                              \
42         *(.initcall5s.init)                                             \
43         *(.initcallrootfs.init)                                         \
44 +       *(.initcall6s.init)                                             \
45         __async_initcall_start = .;                                     \
46         *(.initcall6a.init)                                             \
47         __async_initcall_end = .;                                       \
48         *(.initcall6.init)                                              \
49 -       *(.initcall6s.init)                                             \
50 +       __device_initcall_end = .;                                      \
51         *(.initcall7.init)                                              \
52         *(.initcall7s.init)
53  
54 Index: linux-2.6.27/init/main.c
55 ===================================================================
56 --- linux-2.6.27.orig/init/main.c       2008-10-14 17:01:38.000000000 +0200
57 +++ linux-2.6.27/init/main.c    2008-10-14 17:01:42.000000000 +0200
58 @@ -746,6 +746,7 @@ int do_one_initcall(initcall_t fn)
59  
60  extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
61  extern initcall_t __async_initcall_start[], __async_initcall_end[];
62 +extern initcall_t __device_initcall_end[];
63  
64  static void __init do_async_initcalls(struct work_struct *dummy)
65  {
66 @@ -767,7 +768,13 @@ static void __init do_initcalls(void)
67  {
68         initcall_t *call;
69         static DECLARE_WORK(async_work, do_async_initcalls);
70 -       int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
71 +       /*
72 +        * 0 = levels 0 - 6,
73 +        * 1 = level 6a,
74 +        * 2 = after level 6a,
75 +        * 3 = after level 6
76 +        */
77 +       int phase = 0;
78  
79         async_init_wq = create_singlethread_workqueue("kasyncinit");
80  
81 @@ -778,6 +785,11 @@ static void __init do_initcalls(void)
82                 }
83                 if (phase == 1 && call >= __async_initcall_end)
84                         phase = 2;
85 +               if (phase == 2 && call >= __device_initcall_end) {
86 +                       phase = 3;
87 +                       /* make sure all async work is done before level 7 */
88 +                       flush_workqueue(async_init_wq);
89 +               }
90                 if (phase != 1)
91                         do_one_initcall(*call);
92         }