Commit dc102a8fae2d0d6bf5223fc549247f2e23959ae6
Committed by
Thomas Gleixner
1 parent
3eefae994d
Exists in
master
and in
7 other branches
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>
Showing 2 changed files with 19 additions and 22 deletions Side-by-side Diff
include/linux/marker.h
... | ... | @@ -44,8 +44,8 @@ |
44 | 44 | */ |
45 | 45 | char state; /* Marker state. */ |
46 | 46 | char ptype; /* probe type : 0 : single, 1 : multi */ |
47 | - void (*call)(const struct marker *mdata, /* Probe wrapper */ | |
48 | - void *call_private, const char *fmt, ...); | |
47 | + /* Probe wrapper */ | |
48 | + void (*call)(const struct marker *mdata, void *call_private, ...); | |
49 | 49 | struct marker_probe_closure single; |
50 | 50 | struct marker_probe_closure *multi; |
51 | 51 | } __attribute__((aligned(8))); |
... | ... | @@ -72,8 +72,7 @@ |
72 | 72 | __mark_check_format(format, ## args); \ |
73 | 73 | if (unlikely(__mark_##name.state)) { \ |
74 | 74 | (*__mark_##name.call) \ |
75 | - (&__mark_##name, call_private, \ | |
76 | - format, ## args); \ | |
75 | + (&__mark_##name, call_private, ## args);\ | |
77 | 76 | } \ |
78 | 77 | } while (0) |
79 | 78 | |
80 | 79 | |
... | ... | @@ -117,9 +116,9 @@ |
117 | 116 | extern marker_probe_func __mark_empty_function; |
118 | 117 | |
119 | 118 | extern void marker_probe_cb(const struct marker *mdata, |
120 | - void *call_private, const char *fmt, ...); | |
119 | + void *call_private, ...); | |
121 | 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 | 124 | * Connect a probe to a marker. |
kernel/marker.c
... | ... | @@ -55,8 +55,8 @@ |
55 | 55 | struct marker_entry { |
56 | 56 | struct hlist_node hlist; |
57 | 57 | char *format; |
58 | - void (*call)(const struct marker *mdata, /* Probe wrapper */ | |
59 | - void *call_private, const char *fmt, ...); | |
58 | + /* Probe wrapper */ | |
59 | + void (*call)(const struct marker *mdata, void *call_private, ...); | |
60 | 60 | struct marker_probe_closure single; |
61 | 61 | struct marker_probe_closure *multi; |
62 | 62 | int refcount; /* Number of times armed. 0 if disarmed. */ |
63 | 63 | |
... | ... | @@ -91,15 +91,13 @@ |
91 | 91 | * marker_probe_cb Callback that prepares the variable argument list for probes. |
92 | 92 | * @mdata: pointer of type struct marker |
93 | 93 | * @call_private: caller site private data |
94 | - * @fmt: format string | |
95 | 94 | * @...: Variable argument list. |
96 | 95 | * |
97 | 96 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we |
98 | 97 | * need to put a full smp_rmb() in this branch. This is why we do not use |
99 | 98 | * rcu_dereference() for the pointer read. |
100 | 99 | */ |
101 | -void marker_probe_cb(const struct marker *mdata, void *call_private, | |
102 | - const char *fmt, ...) | |
100 | +void marker_probe_cb(const struct marker *mdata, void *call_private, ...) | |
103 | 101 | { |
104 | 102 | va_list args; |
105 | 103 | char ptype; |
... | ... | @@ -120,8 +118,9 @@ |
120 | 118 | /* Must read the ptr before private data. They are not data |
121 | 119 | * dependant, so we put an explicit smp_rmb() here. */ |
122 | 120 | smp_rmb(); |
123 | - va_start(args, fmt); | |
124 | - func(mdata->single.probe_private, call_private, fmt, &args); | |
121 | + va_start(args, call_private); | |
122 | + func(mdata->single.probe_private, call_private, mdata->format, | |
123 | + &args); | |
125 | 124 | va_end(args); |
126 | 125 | } else { |
127 | 126 | struct marker_probe_closure *multi; |
... | ... | @@ -136,9 +135,9 @@ |
136 | 135 | smp_read_barrier_depends(); |
137 | 136 | multi = mdata->multi; |
138 | 137 | for (i = 0; multi[i].func; i++) { |
139 | - va_start(args, fmt); | |
140 | - multi[i].func(multi[i].probe_private, call_private, fmt, | |
141 | - &args); | |
138 | + va_start(args, call_private); | |
139 | + multi[i].func(multi[i].probe_private, call_private, | |
140 | + mdata->format, &args); | |
142 | 141 | va_end(args); |
143 | 142 | } |
144 | 143 | } |
145 | 144 | |
... | ... | @@ -150,13 +149,11 @@ |
150 | 149 | * marker_probe_cb Callback that does not prepare the variable argument list. |
151 | 150 | * @mdata: pointer of type struct marker |
152 | 151 | * @call_private: caller site private data |
153 | - * @fmt: format string | |
154 | 152 | * @...: Variable argument list. |
155 | 153 | * |
156 | 154 | * Should be connected to markers "MARK_NOARGS". |
157 | 155 | */ |
158 | -void marker_probe_cb_noarg(const struct marker *mdata, | |
159 | - void *call_private, const char *fmt, ...) | |
156 | +void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) | |
160 | 157 | { |
161 | 158 | va_list args; /* not initialized */ |
162 | 159 | char ptype; |
... | ... | @@ -172,7 +169,8 @@ |
172 | 169 | /* Must read the ptr before private data. They are not data |
173 | 170 | * dependant, so we put an explicit smp_rmb() here. */ |
174 | 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 | 174 | } else { |
177 | 175 | struct marker_probe_closure *multi; |
178 | 176 | int i; |
... | ... | @@ -186,8 +184,8 @@ |
186 | 184 | smp_read_barrier_depends(); |
187 | 185 | multi = mdata->multi; |
188 | 186 | for (i = 0; multi[i].func; i++) |
189 | - multi[i].func(multi[i].probe_private, call_private, fmt, | |
190 | - &args); | |
187 | + multi[i].func(multi[i].probe_private, call_private, | |
188 | + mdata->format, &args); | |
191 | 189 | } |
192 | 190 | preempt_enable(); |
193 | 191 | } |