Commit f7897430950ee94fb2dc4d6a5ca658d4909d9d85

Authored by Anthony Liguori
1 parent 4af39611

Fix module initialization when more than 1 class is in use

Now that we're using enums for module types, it makes no sense to bother keeping
a list of module types when we know exactly how many they are.

Switching to an array simplifies the code and eliminates the aforementioned bug.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 2 changed files with 26 additions and 36 deletions
module.c
@@ -22,44 +22,36 @@ typedef struct ModuleEntry @@ -22,44 +22,36 @@ typedef struct ModuleEntry
22 TAILQ_ENTRY(ModuleEntry) node; 22 TAILQ_ENTRY(ModuleEntry) node;
23 } ModuleEntry; 23 } ModuleEntry;
24 24
25 -typedef struct ModuleTypeList  
26 -{  
27 - module_init_type type;  
28 - TAILQ_HEAD(, ModuleEntry) entry_list;  
29 - TAILQ_ENTRY(ModuleTypeList) node;  
30 -} ModuleTypeList; 25 +typedef TAILQ_HEAD(, ModuleEntry) ModuleTypeList;
31 26
32 -static TAILQ_HEAD(, ModuleTypeList) init_type_list; 27 +static ModuleTypeList init_type_list[MODULE_INIT_MAX];
33 28
34 -static ModuleTypeList *find_type_or_alloc(module_init_type type, int alloc) 29 +static void init_types(void)
35 { 30 {
36 - ModuleTypeList *n; 31 + static int inited;
  32 + int i;
37 33
38 - TAILQ_FOREACH(n, &init_type_list, node) {  
39 - if (type >= n->type)  
40 - break; 34 + if (inited) {
  35 + return;
41 } 36 }
42 37
43 - if (!n || n->type != type) {  
44 - ModuleTypeList *o; 38 + for (i = 0; i < MODULE_INIT_MAX; i++) {
  39 + TAILQ_INIT(&init_type_list[i]);
  40 + }
45 41
46 - if (!alloc)  
47 - return NULL; 42 + inited = 1;
  43 +}
48 44
49 - o = qemu_mallocz(sizeof(*o));  
50 - o->type = type;  
51 - TAILQ_INIT(&o->entry_list);  
52 45
53 - if (n) {  
54 - TAILQ_INSERT_AFTER(&init_type_list, n, o, node);  
55 - } else {  
56 - TAILQ_INSERT_HEAD(&init_type_list, o, node);  
57 - } 46 +static ModuleTypeList *find_type(module_init_type type)
  47 +{
  48 + ModuleTypeList *l;
58 49
59 - n = o;  
60 - } 50 + init_types();
  51 +
  52 + l = &init_type_list[type];
61 53
62 - return n; 54 + return l;
63 } 55 }
64 56
65 void register_module_init(void (*fn)(void), module_init_type type) 57 void register_module_init(void (*fn)(void), module_init_type type)
@@ -70,9 +62,9 @@ void register_module_init(void (*fn)(void), module_init_type type) @@ -70,9 +62,9 @@ void register_module_init(void (*fn)(void), module_init_type type)
70 e = qemu_mallocz(sizeof(*e)); 62 e = qemu_mallocz(sizeof(*e));
71 e->init = fn; 63 e->init = fn;
72 64
73 - l = find_type_or_alloc(type, 1); 65 + l = find_type(type);
74 66
75 - TAILQ_INSERT_TAIL(&l->entry_list, e, node); 67 + TAILQ_INSERT_TAIL(l, e, node);
76 } 68 }
77 69
78 void module_call_init(module_init_type type) 70 void module_call_init(module_init_type type)
@@ -80,12 +72,9 @@ void module_call_init(module_init_type type) @@ -80,12 +72,9 @@ void module_call_init(module_init_type type)
80 ModuleTypeList *l; 72 ModuleTypeList *l;
81 ModuleEntry *e; 73 ModuleEntry *e;
82 74
83 - l = find_type_or_alloc(type, 0);  
84 - if (!l) {  
85 - return;  
86 - } 75 + l = find_type(type);
87 76
88 - TAILQ_FOREACH(e, &l->entry_list, node) { 77 + TAILQ_FOREACH(e, l, node) {
89 e->init(); 78 e->init();
90 } 79 }
91 } 80 }
module.h
@@ -17,12 +17,13 @@ @@ -17,12 +17,13 @@
17 /* This should not be used directly. Use block_init etc. instead. */ 17 /* This should not be used directly. Use block_init etc. instead. */
18 #define module_init(function, type) \ 18 #define module_init(function, type) \
19 static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \ 19 static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \
20 - register_module_init(function, type); \ 20 + register_module_init(function, type); \
21 } 21 }
22 22
23 typedef enum { 23 typedef enum {
24 MODULE_INIT_BLOCK, 24 MODULE_INIT_BLOCK,
25 - MODULE_INIT_DEVICE 25 + MODULE_INIT_DEVICE,
  26 + MODULE_INIT_MAX
26 } module_init_type; 27 } module_init_type;
27 28
28 #define block_init(function) module_init(function, MODULE_INIT_BLOCK) 29 #define block_init(function) module_init(function, MODULE_INIT_BLOCK)