diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2008-05-12 15:21:09 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 16:25:27 -0400 |
commit | dc102a8fae2d0d6bf5223fc549247f2e23959ae6 (patch) | |
tree | ccb36b8bfd106ef70d2a9a83629ca502a497d9f3 | |
parent | 3eefae994d9224fb7771a3ddb683868363c23510 (diff) |
Markers - remove extra format argument
Denys Vlasenko <vda.linux@googlemail.com> :
> Not in this patch, but I noticed:
>
> #define __trace_mark(name, call_private, format, args...) \
> do { \
> static const char __mstrtab_##name[] \
> __attribute__((section("__markers_strings"))) \
> = #name "\0" format; \
> static struct marker __mark_##name \
> __attribute__((section("__markers"), aligned(8))) = \
> { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \
> 0, 0, marker_probe_cb, \
> { __mark_empty_function, NULL}, NULL }; \
> __mark_check_format(format, ## args); \
> if (unlikely(__mark_##name.state)) { \
> (*__mark_##name.call) \
> (&__mark_##name, call_private, \
> format, ## args); \
> } \
> } while (0)
>
> In this call:
>
> (*__mark_##name.call) \
> (&__mark_##name, call_private, \
> format, ## args); \
>
> you make gcc allocate duplicate format string. You can use
> &__mstrtab_##name[sizeof(#name)] instead since it holds the same string,
> or drop ", format," above and "const char *fmt" from here:
>
> void (*call)(const struct marker *mdata, /* Probe wrapper */
> void *call_private, const char *fmt, ...);
>
> since mdata->format is the same and all callees which need it can take it there.
Very good point. I actually thought about dropping it, since it would
remove an unnecessary argument from the stack. And actually, since I now
have the marker_probe_cb sitting between the marker site and the
callbacks, there is no API change required. Thanks :)
Mathieu
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
CC: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | include/linux/marker.h | 11 | ||||
-rw-r--r-- | kernel/marker.c | 30 |
2 files changed, 19 insertions, 22 deletions
diff --git a/include/linux/marker.h b/include/linux/marker.h index 430f6adf9762..338533abb47b 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
@@ -44,8 +44,8 @@ struct marker { | |||
44 | */ | 44 | */ |
45 | char state; /* Marker state. */ | 45 | char state; /* Marker state. */ |
46 | char ptype; /* probe type : 0 : single, 1 : multi */ | 46 | char ptype; /* probe type : 0 : single, 1 : multi */ |
47 | void (*call)(const struct marker *mdata, /* Probe wrapper */ | 47 | /* Probe wrapper */ |
48 | void *call_private, const char *fmt, ...); | 48 | void (*call)(const struct marker *mdata, void *call_private, ...); |
49 | struct marker_probe_closure single; | 49 | struct marker_probe_closure single; |
50 | struct marker_probe_closure *multi; | 50 | struct marker_probe_closure *multi; |
51 | } __attribute__((aligned(8))); | 51 | } __attribute__((aligned(8))); |
@@ -72,8 +72,7 @@ struct marker { | |||
72 | __mark_check_format(format, ## args); \ | 72 | __mark_check_format(format, ## args); \ |
73 | if (unlikely(__mark_##name.state)) { \ | 73 | if (unlikely(__mark_##name.state)) { \ |
74 | (*__mark_##name.call) \ | 74 | (*__mark_##name.call) \ |
75 | (&__mark_##name, call_private, \ | 75 | (&__mark_##name, call_private, ## args);\ |
76 | format, ## args); \ | ||
77 | } \ | 76 | } \ |
78 | } while (0) | 77 | } while (0) |
79 | 78 | ||
@@ -117,9 +116,9 @@ static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) | |||
117 | extern marker_probe_func __mark_empty_function; | 116 | extern marker_probe_func __mark_empty_function; |
118 | 117 | ||
119 | extern void marker_probe_cb(const struct marker *mdata, | 118 | extern void marker_probe_cb(const struct marker *mdata, |
120 | void *call_private, const char *fmt, ...); | 119 | void *call_private, ...); |
121 | extern void marker_probe_cb_noarg(const struct marker *mdata, | 120 | extern void marker_probe_cb_noarg(const struct marker *mdata, |
122 | void *call_private, const char *fmt, ...); | 121 | void *call_private, ...); |
123 | 122 | ||
124 | /* | 123 | /* |
125 | * Connect a probe to a marker. | 124 | * Connect a probe to a marker. |
diff --git a/kernel/marker.c b/kernel/marker.c index b5a9fe1d50d5..1abfb923b761 100644 --- a/kernel/marker.c +++ b/kernel/marker.c | |||
@@ -55,8 +55,8 @@ static DEFINE_MUTEX(markers_mutex); | |||
55 | struct marker_entry { | 55 | struct marker_entry { |
56 | struct hlist_node hlist; | 56 | struct hlist_node hlist; |
57 | char *format; | 57 | char *format; |
58 | void (*call)(const struct marker *mdata, /* Probe wrapper */ | 58 | /* Probe wrapper */ |
59 | void *call_private, const char *fmt, ...); | 59 | void (*call)(const struct marker *mdata, void *call_private, ...); |
60 | struct marker_probe_closure single; | 60 | struct marker_probe_closure single; |
61 | struct marker_probe_closure *multi; | 61 | struct marker_probe_closure *multi; |
62 | int refcount; /* Number of times armed. 0 if disarmed. */ | 62 | int refcount; /* Number of times armed. 0 if disarmed. */ |
@@ -91,15 +91,13 @@ EXPORT_SYMBOL_GPL(__mark_empty_function); | |||
91 | * marker_probe_cb Callback that prepares the variable argument list for probes. | 91 | * marker_probe_cb Callback that prepares the variable argument list for probes. |
92 | * @mdata: pointer of type struct marker | 92 | * @mdata: pointer of type struct marker |
93 | * @call_private: caller site private data | 93 | * @call_private: caller site private data |
94 | * @fmt: format string | ||
95 | * @...: Variable argument list. | 94 | * @...: Variable argument list. |
96 | * | 95 | * |
97 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we | 96 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we |
98 | * need to put a full smp_rmb() in this branch. This is why we do not use | 97 | * need to put a full smp_rmb() in this branch. This is why we do not use |
99 | * rcu_dereference() for the pointer read. | 98 | * rcu_dereference() for the pointer read. |
100 | */ | 99 | */ |
101 | void marker_probe_cb(const struct marker *mdata, void *call_private, | 100 | void marker_probe_cb(const struct marker *mdata, void *call_private, ...) |
102 | const char *fmt, ...) | ||
103 | { | 101 | { |
104 | va_list args; | 102 | va_list args; |
105 | char ptype; | 103 | char ptype; |
@@ -120,8 +118,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, | |||
120 | /* Must read the ptr before private data. They are not data | 118 | /* Must read the ptr before private data. They are not data |
121 | * dependant, so we put an explicit smp_rmb() here. */ | 119 | * dependant, so we put an explicit smp_rmb() here. */ |
122 | smp_rmb(); | 120 | smp_rmb(); |
123 | va_start(args, fmt); | 121 | va_start(args, call_private); |
124 | func(mdata->single.probe_private, call_private, fmt, &args); | 122 | func(mdata->single.probe_private, call_private, mdata->format, |
123 | &args); | ||
125 | va_end(args); | 124 | va_end(args); |
126 | } else { | 125 | } else { |
127 | struct marker_probe_closure *multi; | 126 | struct marker_probe_closure *multi; |
@@ -136,9 +135,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, | |||
136 | smp_read_barrier_depends(); | 135 | smp_read_barrier_depends(); |
137 | multi = mdata->multi; | 136 | multi = mdata->multi; |
138 | for (i = 0; multi[i].func; i++) { | 137 | for (i = 0; multi[i].func; i++) { |
139 | va_start(args, fmt); | 138 | va_start(args, call_private); |
140 | multi[i].func(multi[i].probe_private, call_private, fmt, | 139 | multi[i].func(multi[i].probe_private, call_private, |
141 | &args); | 140 | mdata->format, &args); |
142 | va_end(args); | 141 | va_end(args); |
143 | } | 142 | } |
144 | } | 143 | } |
@@ -150,13 +149,11 @@ EXPORT_SYMBOL_GPL(marker_probe_cb); | |||
150 | * marker_probe_cb Callback that does not prepare the variable argument list. | 149 | * marker_probe_cb Callback that does not prepare the variable argument list. |
151 | * @mdata: pointer of type struct marker | 150 | * @mdata: pointer of type struct marker |
152 | * @call_private: caller site private data | 151 | * @call_private: caller site private data |
153 | * @fmt: format string | ||
154 | * @...: Variable argument list. | 152 | * @...: Variable argument list. |
155 | * | 153 | * |
156 | * Should be connected to markers "MARK_NOARGS". | 154 | * Should be connected to markers "MARK_NOARGS". |
157 | */ | 155 | */ |
158 | void marker_probe_cb_noarg(const struct marker *mdata, | 156 | void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) |
159 | void *call_private, const char *fmt, ...) | ||
160 | { | 157 | { |
161 | va_list args; /* not initialized */ | 158 | va_list args; /* not initialized */ |
162 | char ptype; | 159 | char ptype; |
@@ -172,7 +169,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, | |||
172 | /* Must read the ptr before private data. They are not data | 169 | /* Must read the ptr before private data. They are not data |
173 | * dependant, so we put an explicit smp_rmb() here. */ | 170 | * dependant, so we put an explicit smp_rmb() here. */ |
174 | smp_rmb(); | 171 | smp_rmb(); |
175 | func(mdata->single.probe_private, call_private, fmt, &args); | 172 | func(mdata->single.probe_private, call_private, mdata->format, |
173 | &args); | ||
176 | } else { | 174 | } else { |
177 | struct marker_probe_closure *multi; | 175 | struct marker_probe_closure *multi; |
178 | int i; | 176 | int i; |
@@ -186,8 +184,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, | |||
186 | smp_read_barrier_depends(); | 184 | smp_read_barrier_depends(); |
187 | multi = mdata->multi; | 185 | multi = mdata->multi; |
188 | for (i = 0; multi[i].func; i++) | 186 | for (i = 0; multi[i].func; i++) |
189 | multi[i].func(multi[i].probe_private, call_private, fmt, | 187 | multi[i].func(multi[i].probe_private, call_private, |
190 | &args); | 188 | mdata->format, &args); |
191 | } | 189 | } |
192 | preempt_enable(); | 190 | preempt_enable(); |
193 | } | 191 | } |