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.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c
index 9b22d03cc581..f45b75b713c0 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);
@@ -81,6 +79,12 @@ void __gcov_merge_delta(gcov_type *counters, unsigned int n_counters)
81} 79}
82EXPORT_SYMBOL(__gcov_merge_delta); 80EXPORT_SYMBOL(__gcov_merge_delta);
83 81
82void __gcov_merge_ior(gcov_type *counters, unsigned int n_counters)
83{
84 /* Unused. */
85}
86EXPORT_SYMBOL(__gcov_merge_ior);
87
84/** 88/**
85 * gcov_enable_events - enable event reporting through gcov_event() 89 * gcov_enable_events - enable event reporting through gcov_event()
86 * 90 *
@@ -91,13 +95,15 @@ EXPORT_SYMBOL(__gcov_merge_delta);
91 */ 95 */
92void gcov_enable_events(void) 96void gcov_enable_events(void)
93{ 97{
94 struct gcov_info *info; 98 struct gcov_info *info = NULL;
95 99
96 mutex_lock(&gcov_lock); 100 mutex_lock(&gcov_lock);
97 gcov_events_enabled = 1; 101 gcov_events_enabled = 1;
102
98 /* Perform event callback for previously registered entries. */ 103 /* Perform event callback for previously registered entries. */
99 for (info = gcov_info_head; info; info = info->next) 104 while ((info = gcov_info_next(info)))
100 gcov_event(GCOV_ADD, info); 105 gcov_event(GCOV_ADD, info);
106
101 mutex_unlock(&gcov_lock); 107 mutex_unlock(&gcov_lock);
102} 108}
103 109
@@ -112,25 +118,23 @@ static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
112 void *data) 118 void *data)
113{ 119{
114 struct module *mod = data; 120 struct module *mod = data;
115 struct gcov_info *info; 121 struct gcov_info *info = NULL;
116 struct gcov_info *prev; 122 struct gcov_info *prev = NULL;
117 123
118 if (event != MODULE_STATE_GOING) 124 if (event != MODULE_STATE_GOING)
119 return NOTIFY_OK; 125 return NOTIFY_OK;
120 mutex_lock(&gcov_lock); 126 mutex_lock(&gcov_lock);
121 prev = NULL; 127
122 /* Remove entries located in module from linked list. */ 128 /* Remove entries located in module from linked list. */
123 for (info = gcov_info_head; info; info = info->next) { 129 while ((info = gcov_info_next(info))) {
124 if (within(info, mod->module_core, mod->core_size)) { 130 if (within(info, mod->module_core, mod->core_size)) {
125 if (prev) 131 gcov_info_unlink(prev, info);
126 prev->next = info->next;
127 else
128 gcov_info_head = info->next;
129 if (gcov_events_enabled) 132 if (gcov_events_enabled)
130 gcov_event(GCOV_REMOVE, info); 133 gcov_event(GCOV_REMOVE, info);
131 } else 134 } else
132 prev = info; 135 prev = info;
133 } 136 }
137
134 mutex_unlock(&gcov_lock); 138 mutex_unlock(&gcov_lock);
135 139
136 return NOTIFY_OK; 140 return NOTIFY_OK;