diff options
-rw-r--r-- | tools/perf/builtin-record.c | 15 | ||||
-rw-r--r-- | tools/perf/tests/attr/test-record-group | 1 | ||||
-rw-r--r-- | tools/perf/tests/attr/test-record-group1 | 1 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 42 |
4 files changed, 56 insertions, 3 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 371702785d68..268b356391fc 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -701,7 +701,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
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 | * Let the child rip | 713 | * Let the child rip |
@@ -724,7 +730,12 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
724 | waking++; | 730 | waking++; |
725 | } | 731 | } |
726 | 732 | ||
727 | if (done) | 733 | /* |
734 | * When perf is starting the traced process, at the end events | ||
735 | * die with the process and we wait for that. Thus no need to | ||
736 | * disable events in this case. | ||
737 | */ | ||
738 | if (done && !perf_target__none(&opts->target)) | ||
728 | perf_evlist__disable(evsel_list); | 739 | perf_evlist__disable(evsel_list); |
729 | } | 740 | } |
730 | 741 | ||
diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group index b945f770dc9e..a6599e9a19d3 100644 --- a/tools/perf/tests/attr/test-record-group +++ b/tools/perf/tests/attr/test-record-group | |||
@@ -15,3 +15,4 @@ sample_type=327 | |||
15 | mmap=0 | 15 | mmap=0 |
16 | comm=0 | 16 | comm=0 |
17 | enable_on_exec=0 | 17 | enable_on_exec=0 |
18 | disabled=0 | ||
diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 index 013572f23605..5a8359da38af 100644 --- a/tools/perf/tests/attr/test-record-group1 +++ b/tools/perf/tests/attr/test-record-group1 | |||
@@ -16,3 +16,4 @@ sample_type=327 | |||
16 | mmap=0 | 16 | mmap=0 |
17 | comm=0 | 17 | comm=0 |
18 | enable_on_exec=0 | 18 | enable_on_exec=0 |
19 | disabled=0 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6d4a5f6ed75a..fc4faaa7afb9 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -404,13 +404,40 @@ const char *perf_evsel__name(struct perf_evsel *evsel) | |||
404 | return evsel->name ?: "unknown"; | 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 | void perf_evsel__config(struct perf_evsel *evsel, | 435 | void perf_evsel__config(struct perf_evsel *evsel, |
408 | struct perf_record_opts *opts) | 436 | struct perf_record_opts *opts) |
409 | { | 437 | { |
410 | struct perf_event_attr *attr = &evsel->attr; | 438 | struct perf_event_attr *attr = &evsel->attr; |
411 | int track = !evsel->idx; /* only the first counter needs these */ | 439 | int track = !evsel->idx; /* only the first counter needs these */ |
412 | 440 | ||
413 | attr->disabled = 1; | ||
414 | attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; | 441 | attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; |
415 | attr->inherit = !opts->no_inherit; | 442 | attr->inherit = !opts->no_inherit; |
416 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | | 443 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | |
@@ -486,6 +513,19 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
486 | attr->mmap = track; | 513 | attr->mmap = track; |
487 | attr->comm = track; | 514 | attr->comm = track; |
488 | 515 | ||
516 | /* | ||
517 | * XXX see the function comment above | ||
518 | * | ||
519 | * Disabling only independent events or group leaders, | ||
520 | * keeping group members enabled. | ||
521 | */ | ||
522 | if (!evsel->leader) | ||
523 | attr->disabled = 1; | ||
524 | |||
525 | /* | ||
526 | * Setting enable_on_exec for independent events and | ||
527 | * group leaders for traced executed by perf. | ||
528 | */ | ||
489 | if (perf_target__none(&opts->target) && (!evsel->leader)) | 529 | if (perf_target__none(&opts->target) && (!evsel->leader)) |
490 | attr->enable_on_exec = 1; | 530 | attr->enable_on_exec = 1; |
491 | } | 531 | } |