Commit dc102a8fae2d0d6bf5223fc549247f2e23959ae6

Authored by Mathieu Desnoyers
Committed by Thomas Gleixner
1 parent 3eefae994d

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.
... ... @@ -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 }