Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Fix 'disabled' attribute config for record command

Currently the record command sets all events initially as disabled.

There's non conditional perf_evlist__enable call, that enables all
events before we exec tracee program. That actually screws whole
enable_on_exec logic, because the event is enabled before the traced
program got executed.

What we actually want is:

1) For any type of traced program:
- all independent events and group leaders are disabled
- all group members are enabled

Group members are ruled by group leaders. They need to
be enabled, because the group scheduling relies on that.

2) For traced programs executed by perf:
- all independent events and group leaders have
enable_on_exec set
- we don't specifically enable or disable any event during
the record command

Independent events and group leaders are initially disabled
and get enabled by exec. Group members are ruled by group
leaders as stated in 1).

3) For traced programs attached by perf (pid/tid):
- we specifically enable or disable all events during
the record command

When attaching events to already running traced we
enable/disable events specifically, as there's no
initial traced exec call.

Fixing appropriate perf_event_attr test case to cover this change.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1352741644-16809-3-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
774cb499 cac21425

+56 -3
+13 -2
tools/perf/builtin-record.c
··· 701 701 } 702 702 } 703 703 704 - perf_evlist__enable(evsel_list); 704 + /* 705 + * When perf is starting the traced process, all the events 706 + * (apart from group members) have enable_on_exec=1 set, 707 + * so don't spoil it by prematurely enabling them. 708 + */ 709 + if (!perf_target__none(&opts->target)) 710 + perf_evlist__enable(evsel_list); 705 711 706 712 /* 707 713 * Let the child rip ··· 730 724 waking++; 731 725 } 732 726 733 - if (done) 727 + /* 728 + * When perf is starting the traced process, at the end events 729 + * die with the process and we wait for that. Thus no need to 730 + * disable events in this case. 731 + */ 732 + if (done && !perf_target__none(&opts->target)) 734 733 perf_evlist__disable(evsel_list); 735 734 } 736 735
+1
tools/perf/tests/attr/test-record-group
··· 15 15 mmap=0 16 16 comm=0 17 17 enable_on_exec=0 18 + disabled=0
+1
tools/perf/tests/attr/test-record-group1
··· 16 16 mmap=0 17 17 comm=0 18 18 enable_on_exec=0 19 + disabled=0
+41 -1
tools/perf/util/evsel.c
··· 404 404 return evsel->name ?: "unknown"; 405 405 } 406 406 407 + /* 408 + * The enable_on_exec/disabled value strategy: 409 + * 410 + * 1) For any type of traced program: 411 + * - all independent events and group leaders are disabled 412 + * - all group members are enabled 413 + * 414 + * Group members are ruled by group leaders. They need to 415 + * be enabled, because the group scheduling relies on that. 416 + * 417 + * 2) For traced programs executed by perf: 418 + * - all independent events and group leaders have 419 + * enable_on_exec set 420 + * - we don't specifically enable or disable any event during 421 + * the record command 422 + * 423 + * Independent events and group leaders are initially disabled 424 + * and get enabled by exec. Group members are ruled by group 425 + * leaders as stated in 1). 426 + * 427 + * 3) For traced programs attached by perf (pid/tid): 428 + * - we specifically enable or disable all events during 429 + * the record command 430 + * 431 + * When attaching events to already running traced we 432 + * enable/disable events specifically, as there's no 433 + * initial traced exec call. 434 + */ 407 435 void perf_evsel__config(struct perf_evsel *evsel, 408 436 struct perf_record_opts *opts) 409 437 { 410 438 struct perf_event_attr *attr = &evsel->attr; 411 439 int track = !evsel->idx; /* only the first counter needs these */ 412 440 413 - attr->disabled = 1; 414 441 attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; 415 442 attr->inherit = !opts->no_inherit; 416 443 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | ··· 513 486 attr->mmap = track; 514 487 attr->comm = track; 515 488 489 + /* 490 + * XXX see the function comment above 491 + * 492 + * Disabling only independent events or group leaders, 493 + * keeping group members enabled. 494 + */ 495 + if (!evsel->leader) 496 + attr->disabled = 1; 497 + 498 + /* 499 + * Setting enable_on_exec for independent events and 500 + * group leaders for traced executed by perf. 501 + */ 516 502 if (perf_target__none(&opts->target) && (!evsel->leader)) 517 503 attr->enable_on_exec = 1; 518 504 }