aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2009-04-13 04:17:50 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-13 18:03:55 -0400
commit0a19e53c1514ad8e9c3cbab40c6c3f52c86f403d (patch)
tree1089246a64f65b2b3c2ba29182ed4f9ce9ad375e
parentb5c851a88a369854c04e511cefb84ea2d0cfa209 (diff)
tracing/filters: allow on-the-fly filter switching
This patch allows event filters to be safely removed or switched on-the-fly while avoiding the use of rcu or the suspension of tracing of previous versions. It does it by adding a new filter_pred_none() predicate function which does nothing and by never deallocating either the predicates or any of the filter_pred members used in matching; the predicate lists are allocated and initialized during ftrace_event_calls initialization. Whenever a filter is removed or replaced, the filter_pred_* functions currently in use by the affected ftrace_event_call are immediately switched over to to the filter_pred_none() function, while the rest of the filter_pred members are left intact, allowing any currently executing filter_pred_* functions to finish up, using the values they're currently using. In the case of filter replacement, the new predicate values are copied into the old predicates after the above step, and the filter_pred_none() functions are replaced by the filter_pred_* functions for the new filter. In this case, it is possible though very unlikely that a previous filter_pred_* is still running even after the filter_pred_none() switch and the switch to the new filter_pred_*. In that case, however, because nothing has been deallocated in the filter_pred, the worst that can happen is that the old filter_pred_* function sees the new values and as a result produces either a false positive or a false negative, depending on the values it finds. So one downside to this method is that rarely, it can produce a bad match during the filter switch, but it should be possible to live with that, IMHO. The other downside is that at least in this patch the predicate lists are always pre-allocated, taking up memory from the start. They could probably be allocated on first-use, and de-allocated when tracing is completely stopped - if this patch makes sense, I could create another one to do that later on. Oh, and it also places a restriction on the size of __arrays in events, currently set to 128, since they can't be larger than the now embedded str_val arrays in the filter_pred struct. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: paulmck@linux.vnet.ibm.com LKML-Reference: <1239610670.6660.49.camel@tropicana> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/trace/trace.h14
-rw-r--r--kernel/trace/trace_events.c9
-rw-r--r--kernel/trace/trace_events_filter.c252
-rw-r--r--kernel/trace/trace_events_stage_2.h1
-rw-r--r--kernel/trace/trace_events_stage_3.h1
-rw-r--r--kernel/trace/trace_export.c1
6 files changed, 150 insertions, 128 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 9729d14767d8..b05b6ac982a1 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -813,6 +813,7 @@ struct ftrace_event_call {
813 int (*show_format)(struct trace_seq *s); 813 int (*show_format)(struct trace_seq *s);
814 int (*define_fields)(void); 814 int (*define_fields)(void);
815 struct list_head fields; 815 struct list_head fields;
816 int n_preds;
816 struct filter_pred **preds; 817 struct filter_pred **preds;
817 818
818#ifdef CONFIG_EVENT_PROFILE 819#ifdef CONFIG_EVENT_PROFILE
@@ -826,6 +827,7 @@ struct event_subsystem {
826 struct list_head list; 827 struct list_head list;
827 const char *name; 828 const char *name;
828 struct dentry *entry; 829 struct dentry *entry;
830 int n_preds;
829 struct filter_pred **preds; 831 struct filter_pred **preds;
830}; 832};
831 833
@@ -834,7 +836,8 @@ struct event_subsystem {
834 (unsigned long)event < (unsigned long)__stop_ftrace_events; \ 836 (unsigned long)event < (unsigned long)__stop_ftrace_events; \
835 event++) 837 event++)
836 838
837#define MAX_FILTER_PRED 8 839#define MAX_FILTER_PRED 8
840#define MAX_FILTER_STR_VAL 128
838 841
839struct filter_pred; 842struct filter_pred;
840 843
@@ -843,7 +846,7 @@ typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
843struct filter_pred { 846struct filter_pred {
844 filter_pred_fn_t fn; 847 filter_pred_fn_t fn;
845 u64 val; 848 u64 val;
846 char *str_val; 849 char str_val[MAX_FILTER_STR_VAL];
847 int str_len; 850 int str_len;
848 char *field_name; 851 char *field_name;
849 int offset; 852 int offset;
@@ -855,13 +858,14 @@ struct filter_pred {
855 858
856int trace_define_field(struct ftrace_event_call *call, char *type, 859int trace_define_field(struct ftrace_event_call *call, char *type,
857 char *name, int offset, int size); 860 char *name, int offset, int size);
861extern int init_preds(struct ftrace_event_call *call);
858extern void filter_free_pred(struct filter_pred *pred); 862extern void filter_free_pred(struct filter_pred *pred);
859extern void filter_print_preds(struct filter_pred **preds, 863extern void filter_print_preds(struct filter_pred **preds, int n_preds,
860 struct trace_seq *s); 864 struct trace_seq *s);
861extern int filter_parse(char **pbuf, struct filter_pred *pred); 865extern int filter_parse(char **pbuf, struct filter_pred *pred);
862extern int filter_add_pred(struct ftrace_event_call *call, 866extern int filter_add_pred(struct ftrace_event_call *call,
863 struct filter_pred *pred); 867 struct filter_pred *pred);
864extern void filter_free_preds(struct ftrace_event_call *call); 868extern void filter_disable_preds(struct ftrace_event_call *call);
865extern int filter_match_preds(struct ftrace_event_call *call, void *rec); 869extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
866extern void filter_free_subsystem_preds(struct event_subsystem *system); 870extern void filter_free_subsystem_preds(struct event_subsystem *system);
867extern int filter_add_subsystem_pred(struct event_subsystem *system, 871extern int filter_add_subsystem_pred(struct event_subsystem *system,
@@ -875,7 +879,7 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
875 struct ring_buffer *buffer, 879 struct ring_buffer *buffer,
876 struct ring_buffer_event *event) 880 struct ring_buffer_event *event)
877{ 881{
878 if (unlikely(call->preds) && !filter_match_preds(call, rec)) { 882 if (unlikely(call->n_preds) && !filter_match_preds(call, rec)) {
879 ring_buffer_discard_commit(buffer, event); 883 ring_buffer_discard_commit(buffer, event);
880 return 1; 884 return 1;
881 } 885 }
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 789e14eb09a5..ead68ac99191 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -481,7 +481,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
481 481
482 trace_seq_init(s); 482 trace_seq_init(s);
483 483
484 filter_print_preds(call->preds, s); 484 filter_print_preds(call->preds, call->n_preds, s);
485 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); 485 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
486 486
487 kfree(s); 487 kfree(s);
@@ -516,7 +516,7 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
516 } 516 }
517 517
518 if (pred->clear) { 518 if (pred->clear) {
519 filter_free_preds(call); 519 filter_disable_preds(call);
520 filter_free_pred(pred); 520 filter_free_pred(pred);
521 return cnt; 521 return cnt;
522 } 522 }
@@ -527,6 +527,8 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
527 return err; 527 return err;
528 } 528 }
529 529
530 filter_free_pred(pred);
531
530 *ppos += cnt; 532 *ppos += cnt;
531 533
532 return cnt; 534 return cnt;
@@ -549,7 +551,7 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
549 551
550 trace_seq_init(s); 552 trace_seq_init(s);
551 553
552 filter_print_preds(system->preds, s); 554 filter_print_preds(system->preds, system->n_preds, s);
553 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); 555 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
554 556
555 kfree(s); 557 kfree(s);
@@ -712,6 +714,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
712 list_add(&system->list, &event_subsystems); 714 list_add(&system->list, &event_subsystems);
713 715
714 system->preds = NULL; 716 system->preds = NULL;
717 system->n_preds = 0;
715 718
716 entry = debugfs_create_file("filter", 0644, system->entry, system, 719 entry = debugfs_create_file("filter", 0644, system->entry, system,
717 &ftrace_subsystem_filter_fops); 720 &ftrace_subsystem_filter_fops);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 9f8ecca34a59..de42dad42a88 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -82,25 +82,27 @@ static int filter_pred_string(struct filter_pred *pred, void *event)
82 return match; 82 return match;
83} 83}
84 84
85static int filter_pred_none(struct filter_pred *pred, void *event)
86{
87 return 0;
88}
89
85/* return 1 if event matches, 0 otherwise (discard) */ 90/* return 1 if event matches, 0 otherwise (discard) */
86int filter_match_preds(struct ftrace_event_call *call, void *rec) 91int filter_match_preds(struct ftrace_event_call *call, void *rec)
87{ 92{
88 int i, matched, and_failed = 0; 93 int i, matched, and_failed = 0;
89 struct filter_pred *pred; 94 struct filter_pred *pred;
90 95
91 for (i = 0; i < MAX_FILTER_PRED; i++) { 96 for (i = 0; i < call->n_preds; i++) {
92 if (call->preds[i]) { 97 pred = call->preds[i];
93 pred = call->preds[i]; 98 if (and_failed && !pred->or)
94 if (and_failed && !pred->or) 99 continue;
95 continue; 100 matched = pred->fn(pred, rec);
96 matched = pred->fn(pred, rec); 101 if (!matched && !pred->or) {
97 if (!matched && !pred->or) { 102 and_failed = 1;
98 and_failed = 1; 103 continue;
99 continue; 104 } else if (matched && pred->or)
100 } else if (matched && pred->or) 105 return 1;
101 return 1;
102 } else
103 break;
104 } 106 }
105 107
106 if (and_failed) 108 if (and_failed)
@@ -109,31 +111,29 @@ int filter_match_preds(struct ftrace_event_call *call, void *rec)
109 return 1; 111 return 1;
110} 112}
111 113
112void filter_print_preds(struct filter_pred **preds, struct trace_seq *s) 114void filter_print_preds(struct filter_pred **preds, int n_preds,
115 struct trace_seq *s)
113{ 116{
114 char *field_name; 117 char *field_name;
115 struct filter_pred *pred; 118 struct filter_pred *pred;
116 int i; 119 int i;
117 120
118 if (!preds) { 121 if (!n_preds) {
119 trace_seq_printf(s, "none\n"); 122 trace_seq_printf(s, "none\n");
120 return; 123 return;
121 } 124 }
122 125
123 for (i = 0; i < MAX_FILTER_PRED; i++) { 126 for (i = 0; i < n_preds; i++) {
124 if (preds[i]) { 127 pred = preds[i];
125 pred = preds[i]; 128 field_name = pred->field_name;
126 field_name = pred->field_name; 129 if (i)
127 if (i) 130 trace_seq_printf(s, pred->or ? "|| " : "&& ");
128 trace_seq_printf(s, pred->or ? "|| " : "&& "); 131 trace_seq_printf(s, "%s ", field_name);
129 trace_seq_printf(s, "%s ", field_name); 132 trace_seq_printf(s, pred->not ? "!= " : "== ");
130 trace_seq_printf(s, pred->not ? "!= " : "== "); 133 if (pred->str_len)
131 if (pred->str_val) 134 trace_seq_printf(s, "%s\n", pred->str_val);
132 trace_seq_printf(s, "%s\n", pred->str_val); 135 else
133 else 136 trace_seq_printf(s, "%llu\n", pred->val);
134 trace_seq_printf(s, "%llu\n", pred->val);
135 } else
136 break;
137 } 137 }
138} 138}
139 139
@@ -156,20 +156,69 @@ void filter_free_pred(struct filter_pred *pred)
156 return; 156 return;
157 157
158 kfree(pred->field_name); 158 kfree(pred->field_name);
159 kfree(pred->str_val);
160 kfree(pred); 159 kfree(pred);
161} 160}
162 161
163void filter_free_preds(struct ftrace_event_call *call) 162static void filter_clear_pred(struct filter_pred *pred)
163{
164 kfree(pred->field_name);
165 pred->field_name = NULL;
166 pred->str_len = 0;
167}
168
169static int filter_set_pred(struct filter_pred *dest,
170 struct filter_pred *src,
171 filter_pred_fn_t fn)
172{
173 *dest = *src;
174 dest->field_name = kstrdup(src->field_name, GFP_KERNEL);
175 if (!dest->field_name)
176 return -ENOMEM;
177 dest->fn = fn;
178
179 return 0;
180}
181
182void filter_disable_preds(struct ftrace_event_call *call)
164{ 183{
165 int i; 184 int i;
166 185
167 if (call->preds) { 186 call->n_preds = 0;
168 for (i = 0; i < MAX_FILTER_PRED; i++) 187
188 for (i = 0; i < MAX_FILTER_PRED; i++)
189 call->preds[i]->fn = filter_pred_none;
190}
191
192int init_preds(struct ftrace_event_call *call)
193{
194 struct filter_pred *pred;
195 int i;
196
197 call->n_preds = 0;
198
199 call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
200 if (!call->preds)
201 return -ENOMEM;
202
203 for (i = 0; i < MAX_FILTER_PRED; i++) {
204 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
205 if (!pred)
206 goto oom;
207 pred->fn = filter_pred_none;
208 call->preds[i] = pred;
209 }
210
211 return 0;
212
213oom:
214 for (i = 0; i < MAX_FILTER_PRED; i++) {
215 if (call->preds[i])
169 filter_free_pred(call->preds[i]); 216 filter_free_pred(call->preds[i]);
170 kfree(call->preds);
171 call->preds = NULL;
172 } 217 }
218 kfree(call->preds);
219 call->preds = NULL;
220
221 return -ENOMEM;
173} 222}
174 223
175void filter_free_subsystem_preds(struct event_subsystem *system) 224void filter_free_subsystem_preds(struct event_subsystem *system)
@@ -177,11 +226,12 @@ void filter_free_subsystem_preds(struct event_subsystem *system)
177 struct ftrace_event_call *call = __start_ftrace_events; 226 struct ftrace_event_call *call = __start_ftrace_events;
178 int i; 227 int i;
179 228
180 if (system->preds) { 229 if (system->n_preds) {
181 for (i = 0; i < MAX_FILTER_PRED; i++) 230 for (i = 0; i < system->n_preds; i++)
182 filter_free_pred(system->preds[i]); 231 filter_free_pred(system->preds[i]);
183 kfree(system->preds); 232 kfree(system->preds);
184 system->preds = NULL; 233 system->preds = NULL;
234 system->n_preds = 0;
185 } 235 }
186 236
187 events_for_each(call) { 237 events_for_each(call) {
@@ -189,33 +239,31 @@ void filter_free_subsystem_preds(struct event_subsystem *system)
189 continue; 239 continue;
190 240
191 if (!strcmp(call->system, system->name)) 241 if (!strcmp(call->system, system->name))
192 filter_free_preds(call); 242 filter_disable_preds(call);
193 } 243 }
194} 244}
195 245
196static int __filter_add_pred(struct ftrace_event_call *call, 246static int __filter_add_pred(struct ftrace_event_call *call,
197 struct filter_pred *pred) 247 struct filter_pred *pred,
248 filter_pred_fn_t fn)
198{ 249{
199 int i; 250 int idx, err;
200 251
201 if (call->preds && !pred->compound) 252 if (call->n_preds && !pred->compound)
202 filter_free_preds(call); 253 filter_disable_preds(call);
203 254
204 if (!call->preds) { 255 if (call->n_preds == MAX_FILTER_PRED)
205 call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), 256 return -ENOSPC;
206 GFP_KERNEL);
207 if (!call->preds)
208 return -ENOMEM;
209 }
210 257
211 for (i = 0; i < MAX_FILTER_PRED; i++) { 258 idx = call->n_preds;
212 if (!call->preds[i]) { 259 filter_clear_pred(call->preds[idx]);
213 call->preds[i] = pred; 260 err = filter_set_pred(call->preds[idx], pred, fn);
214 return 0; 261 if (err)
215 } 262 return err;
216 } 263
264 call->n_preds++;
217 265
218 return -ENOSPC; 266 return 0;
219} 267}
220 268
221static int is_string_field(const char *type) 269static int is_string_field(const char *type)
@@ -229,98 +277,66 @@ static int is_string_field(const char *type)
229int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred) 277int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred)
230{ 278{
231 struct ftrace_event_field *field; 279 struct ftrace_event_field *field;
280 filter_pred_fn_t fn;
232 281
233 field = find_event_field(call, pred->field_name); 282 field = find_event_field(call, pred->field_name);
234 if (!field) 283 if (!field)
235 return -EINVAL; 284 return -EINVAL;
236 285
286 pred->fn = filter_pred_none;
237 pred->offset = field->offset; 287 pred->offset = field->offset;
238 288
239 if (is_string_field(field->type)) { 289 if (is_string_field(field->type)) {
240 if (!pred->str_val) 290 if (!pred->str_len)
241 return -EINVAL; 291 return -EINVAL;
242 pred->fn = filter_pred_string; 292 fn = filter_pred_string;
243 pred->str_len = field->size; 293 pred->str_len = field->size;
244 return __filter_add_pred(call, pred); 294 return __filter_add_pred(call, pred, fn);
245 } else { 295 } else {
246 if (pred->str_val) 296 if (pred->str_len)
247 return -EINVAL; 297 return -EINVAL;
248 } 298 }
249 299
250 switch (field->size) { 300 switch (field->size) {
251 case 8: 301 case 8:
252 pred->fn = filter_pred_64; 302 fn = filter_pred_64;
253 break; 303 break;
254 case 4: 304 case 4:
255 pred->fn = filter_pred_32; 305 fn = filter_pred_32;
256 break; 306 break;
257 case 2: 307 case 2:
258 pred->fn = filter_pred_16; 308 fn = filter_pred_16;
259 break; 309 break;
260 case 1: 310 case 1:
261 pred->fn = filter_pred_8; 311 fn = filter_pred_8;
262 break; 312 break;
263 default: 313 default:
264 return -EINVAL; 314 return -EINVAL;
265 } 315 }
266 316
267 return __filter_add_pred(call, pred); 317 return __filter_add_pred(call, pred, fn);
268}
269
270static struct filter_pred *copy_pred(struct filter_pred *pred)
271{
272 struct filter_pred *new_pred = kmalloc(sizeof(*pred), GFP_KERNEL);
273 if (!new_pred)
274 return NULL;
275
276 memcpy(new_pred, pred, sizeof(*pred));
277
278 if (pred->field_name) {
279 new_pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
280 if (!new_pred->field_name) {
281 kfree(new_pred);
282 return NULL;
283 }
284 }
285
286 if (pred->str_val) {
287 new_pred->str_val = kstrdup(pred->str_val, GFP_KERNEL);
288 if (!new_pred->str_val) {
289 filter_free_pred(new_pred);
290 return NULL;
291 }
292 }
293
294 return new_pred;
295} 318}
296 319
297int filter_add_subsystem_pred(struct event_subsystem *system, 320int filter_add_subsystem_pred(struct event_subsystem *system,
298 struct filter_pred *pred) 321 struct filter_pred *pred)
299{ 322{
300 struct ftrace_event_call *call = __start_ftrace_events; 323 struct ftrace_event_call *call = __start_ftrace_events;
301 struct filter_pred *event_pred;
302 int i;
303 324
304 if (system->preds && !pred->compound) 325 if (system->n_preds && !pred->compound)
305 filter_free_subsystem_preds(system); 326 filter_free_subsystem_preds(system);
306 327
307 if (!system->preds) { 328 if (!system->n_preds) {
308 system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), 329 system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
309 GFP_KERNEL); 330 GFP_KERNEL);
310 if (!system->preds) 331 if (!system->preds)
311 return -ENOMEM; 332 return -ENOMEM;
312 } 333 }
313 334
314 for (i = 0; i < MAX_FILTER_PRED; i++) { 335 if (system->n_preds == MAX_FILTER_PRED)
315 if (!system->preds[i]) {
316 system->preds[i] = pred;
317 break;
318 }
319 }
320
321 if (i == MAX_FILTER_PRED)
322 return -ENOSPC; 336 return -ENOSPC;
323 337
338 system->preds[system->n_preds] = pred;
339
324 events_for_each(call) { 340 events_for_each(call) {
325 int err; 341 int err;
326 342
@@ -333,22 +349,16 @@ int filter_add_subsystem_pred(struct event_subsystem *system,
333 if (!find_event_field(call, pred->field_name)) 349 if (!find_event_field(call, pred->field_name))
334 continue; 350 continue;
335 351
336 event_pred = copy_pred(pred); 352 err = filter_add_pred(call, pred);
337 if (!event_pred) 353 if (err == -ENOMEM) {
338 goto oom; 354 system->preds[system->n_preds] = NULL;
339 355 return err;
340 err = filter_add_pred(call, event_pred); 356 }
341 if (err)
342 filter_free_pred(event_pred);
343 if (err == -ENOMEM)
344 goto oom;
345 } 357 }
346 358
347 return 0; 359 system->n_preds++;
348 360
349oom: 361 return 0;
350 system->preds[i] = NULL;
351 return -ENOMEM;
352} 362}
353 363
354int filter_parse(char **pbuf, struct filter_pred *pred) 364int filter_parse(char **pbuf, struct filter_pred *pred)
@@ -410,7 +420,8 @@ int filter_parse(char **pbuf, struct filter_pred *pred)
410 } 420 }
411 } 421 }
412 422
413 if (!val_str) { 423 if (!val_str || !strlen(val_str)
424 || strlen(val_str) >= MAX_FILTER_STR_VAL) {
414 pred->field_name = NULL; 425 pred->field_name = NULL;
415 return -EINVAL; 426 return -EINVAL;
416 } 427 }
@@ -419,11 +430,12 @@ int filter_parse(char **pbuf, struct filter_pred *pred)
419 if (!pred->field_name) 430 if (!pred->field_name)
420 return -ENOMEM; 431 return -ENOMEM;
421 432
433 pred->str_len = 0;
422 pred->val = simple_strtoull(val_str, &tmp, 0); 434 pred->val = simple_strtoull(val_str, &tmp, 0);
423 if (tmp == val_str) { 435 if (tmp == val_str) {
424 pred->str_val = kstrdup(val_str, GFP_KERNEL); 436 strncpy(pred->str_val, val_str, MAX_FILTER_STR_VAL);
425 if (!pred->str_val) 437 pred->str_len = strlen(val_str);
426 return -ENOMEM; 438 pred->str_val[pred->str_len] = '\0';
427 } else if (*tmp != '\0') 439 } else if (*tmp != '\0')
428 return -EINVAL; 440 return -EINVAL;
429 441
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
index 02fb710193ed..59cfd7dfe68d 100644
--- a/kernel/trace/trace_events_stage_2.h
+++ b/kernel/trace/trace_events_stage_2.h
@@ -140,6 +140,7 @@ ftrace_format_##call(struct trace_seq *s) \
140 140
141#undef __array 141#undef __array
142#define __array(type, item, len) \ 142#define __array(type, item, len) \
143 BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
143 ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 144 ret = trace_define_field(event_call, #type "[" #len "]", #item, \
144 offsetof(typeof(field), item), \ 145 offsetof(typeof(field), item), \
145 sizeof(field.item)); \ 146 sizeof(field.item)); \
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h
index b2b298269eb0..5bb1b7ffbdb6 100644
--- a/kernel/trace/trace_events_stage_3.h
+++ b/kernel/trace/trace_events_stage_3.h
@@ -255,6 +255,7 @@ static int ftrace_raw_init_event_##call(void) \
255 return -ENODEV; \ 255 return -ENODEV; \
256 event_##call.id = id; \ 256 event_##call.id = id; \
257 INIT_LIST_HEAD(&event_##call.fields); \ 257 INIT_LIST_HEAD(&event_##call.fields); \
258 init_preds(&event_##call); \
258 return 0; \ 259 return 0; \
259} \ 260} \
260 \ 261 \
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 77c494f5e1d6..48fc02fe73a0 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -122,6 +122,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
122static int ftrace_raw_init_event_##call(void) \ 122static int ftrace_raw_init_event_##call(void) \
123{ \ 123{ \
124 INIT_LIST_HEAD(&event_##call.fields); \ 124 INIT_LIST_HEAD(&event_##call.fields); \
125 init_preds(&event_##call); \
125 return 0; \ 126 return 0; \
126} \ 127} \
127 128