aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/gcov/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gcov/base.c')
-rw-r--r--kernel/gcov/base.c26
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
23static struct gcov_info *gcov_info_head;
24static int gcov_events_enabled; 23static int gcov_events_enabled;
25static DEFINE_MUTEX(gcov_lock); 24static 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 */
92void gcov_enable_events(void) 90void 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;