aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2009-03-23 04:26:48 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-23 04:30:37 -0400
commitc4cff064be678f1e8344d907499f2a81282edc19 (patch)
tree8c020dd399a8eba7ae279283e9a3eeb074c74d88 /kernel/trace
parentee6cdabc820a29bd607f38d9cb335c3ceddc673b (diff)
tracing/filters: clean up filter_add_subsystem_pred()
Impact: cleanup, memory leak fix This patch cleans up filter_add_subsystem_pred(): - searches for the field before creating a copy of the pred - fixes memory leak in the case a predicate isn't applied - if -ENOMEM, makes sure there's no longer a reference to the pred so the caller can free the half-finished filter - changes the confusing i == MAX_FILTER_PRED - 1 comparison previously remarked upon This affects only per-subsystem event filtering. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: =?ISO-8859-1?Q?Fr=E9d=E9ric?= Weisbecker <fweisbec@gmail.com> LKML-Reference: <1237796808.7527.40.camel@charm-linux> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace_events.c1
-rw-r--r--kernel/trace/trace_events_filter.c31
2 files changed, 25 insertions, 7 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 19f61dd23219..fdab30d6c835 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -585,6 +585,7 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
585 } 585 }
586 586
587 if (filter_add_subsystem_pred(system, pred)) { 587 if (filter_add_subsystem_pred(system, pred)) {
588 filter_free_subsystem_preds(system);
588 filter_free_pred(pred); 589 filter_free_pred(pred);
589 return -EINVAL; 590 return -EINVAL;
590 } 591 }
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index fd01d8022ad1..4117c2ebc245 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -318,22 +318,39 @@ int filter_add_subsystem_pred(struct event_subsystem *system,
318 system->preds[i] = pred; 318 system->preds[i] = pred;
319 break; 319 break;
320 } 320 }
321 if (i == MAX_FILTER_PRED - 1)
322 return -EINVAL;
323 } 321 }
324 322
323 if (i == MAX_FILTER_PRED)
324 return -EINVAL;
325
325 events_for_each(call) { 326 events_for_each(call) {
327 int err;
328
326 if (!call->name || !call->regfunc) 329 if (!call->name || !call->regfunc)
327 continue; 330 continue;
328 331
329 if (!strcmp(call->system, system->name)) { 332 if (strcmp(call->system, system->name))
330 event_pred = copy_pred(pred); 333 continue;
331 if (event_pred) 334
332 filter_add_pred(call, event_pred); 335 if (!find_event_field(call, pred->field_name))
333 } 336 continue;
337
338 event_pred = copy_pred(pred);
339 if (!event_pred)
340 goto oom;
341
342 err = filter_add_pred(call, event_pred);
343 if (err)
344 filter_free_pred(event_pred);
345 if (err == -ENOMEM)
346 goto oom;
334 } 347 }
335 348
336 return 0; 349 return 0;
350
351oom:
352 system->preds[i] = NULL;
353 return -ENOMEM;
337} 354}
338 355
339int filter_parse(char **pbuf, struct filter_pred *pred) 356int filter_parse(char **pbuf, struct filter_pred *pred)