aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-record.c15
-rw-r--r--tools/perf/tests/attr/test-record-group1
-rw-r--r--tools/perf/tests/attr/test-record-group11
-rw-r--r--tools/perf/util/evsel.c42
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
15mmap=0 15mmap=0
16comm=0 16comm=0
17enable_on_exec=0 17enable_on_exec=0
18disabled=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
16mmap=0 16mmap=0
17comm=0 17comm=0
18enable_on_exec=0 18enable_on_exec=0
19disabled=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 */
407void perf_evsel__config(struct perf_evsel *evsel, 435void 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}