diff options
Diffstat (limited to 'kernel/gcov/base.c')
-rw-r--r-- | kernel/gcov/base.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c index 9b22d03cc581..912576a671d8 100644 --- a/kernel/gcov/base.c +++ b/kernel/gcov/base.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include "gcov.h" | 21 | #include "gcov.h" |
22 | 22 | ||
23 | static struct gcov_info *gcov_info_head; | ||
24 | static int gcov_events_enabled; | 23 | static int gcov_events_enabled; |
25 | static DEFINE_MUTEX(gcov_lock); | 24 | static DEFINE_MUTEX(gcov_lock); |
26 | 25 | ||
@@ -34,7 +33,7 @@ void __gcov_init(struct gcov_info *info) | |||
34 | 33 | ||
35 | mutex_lock(&gcov_lock); | 34 | mutex_lock(&gcov_lock); |
36 | if (gcov_version == 0) { | 35 | if (gcov_version == 0) { |
37 | gcov_version = info->version; | 36 | gcov_version = gcov_info_version(info); |
38 | /* | 37 | /* |
39 | * Printing gcc's version magic may prove useful for debugging | 38 | * Printing gcc's version magic may prove useful for debugging |
40 | * incompatibility reports. | 39 | * incompatibility reports. |
@@ -45,8 +44,7 @@ void __gcov_init(struct gcov_info *info) | |||
45 | * Add new profiling data structure to list and inform event | 44 | * Add new profiling data structure to list and inform event |
46 | * listener. | 45 | * listener. |
47 | */ | 46 | */ |
48 | info->next = gcov_info_head; | 47 | gcov_info_link(info); |
49 | gcov_info_head = info; | ||
50 | if (gcov_events_enabled) | 48 | if (gcov_events_enabled) |
51 | gcov_event(GCOV_ADD, info); | 49 | gcov_event(GCOV_ADD, info); |
52 | mutex_unlock(&gcov_lock); | 50 | mutex_unlock(&gcov_lock); |
@@ -91,13 +89,15 @@ EXPORT_SYMBOL(__gcov_merge_delta); | |||
91 | */ | 89 | */ |
92 | void gcov_enable_events(void) | 90 | void gcov_enable_events(void) |
93 | { | 91 | { |
94 | struct gcov_info *info; | 92 | struct gcov_info *info = NULL; |
95 | 93 | ||
96 | mutex_lock(&gcov_lock); | 94 | mutex_lock(&gcov_lock); |
97 | gcov_events_enabled = 1; | 95 | gcov_events_enabled = 1; |
96 | |||
98 | /* Perform event callback for previously registered entries. */ | 97 | /* Perform event callback for previously registered entries. */ |
99 | for (info = gcov_info_head; info; info = info->next) | 98 | while ((info = gcov_info_next(info))) |
100 | gcov_event(GCOV_ADD, info); | 99 | gcov_event(GCOV_ADD, info); |
100 | |||
101 | mutex_unlock(&gcov_lock); | 101 | mutex_unlock(&gcov_lock); |
102 | } | 102 | } |
103 | 103 | ||
@@ -112,25 +112,23 @@ static int gcov_module_notifier(struct notifier_block *nb, unsigned long event, | |||
112 | void *data) | 112 | void *data) |
113 | { | 113 | { |
114 | struct module *mod = data; | 114 | struct module *mod = data; |
115 | struct gcov_info *info; | 115 | struct gcov_info *info = NULL; |
116 | struct gcov_info *prev; | 116 | struct gcov_info *prev = NULL; |
117 | 117 | ||
118 | if (event != MODULE_STATE_GOING) | 118 | if (event != MODULE_STATE_GOING) |
119 | return NOTIFY_OK; | 119 | return NOTIFY_OK; |
120 | mutex_lock(&gcov_lock); | 120 | mutex_lock(&gcov_lock); |
121 | prev = NULL; | 121 | |
122 | /* Remove entries located in module from linked list. */ | 122 | /* Remove entries located in module from linked list. */ |
123 | for (info = gcov_info_head; info; info = info->next) { | 123 | while ((info = gcov_info_next(info))) { |
124 | if (within(info, mod->module_core, mod->core_size)) { | 124 | if (within(info, mod->module_core, mod->core_size)) { |
125 | if (prev) | 125 | gcov_info_unlink(prev, info); |
126 | prev->next = info->next; | ||
127 | else | ||
128 | gcov_info_head = info->next; | ||
129 | if (gcov_events_enabled) | 126 | if (gcov_events_enabled) |
130 | gcov_event(GCOV_REMOVE, info); | 127 | gcov_event(GCOV_REMOVE, info); |
131 | } else | 128 | } else |
132 | prev = info; | 129 | prev = info; |
133 | } | 130 | } |
131 | |||
134 | mutex_unlock(&gcov_lock); | 132 | mutex_unlock(&gcov_lock); |
135 | 133 | ||
136 | return NOTIFY_OK; | 134 | return NOTIFY_OK; |