diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index bd2c56d8cdc0..2351f7b4f5fc 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -293,7 +293,7 @@ OPTIONS --call-graph:: Setup and enable call-graph (stack chain/backtrace) recording, - implies -g. Default is "fp" (for user space). + implies -g. Default is "fp" for user space (s390 uses "dwarf"). The unwinding method used for kernel space is dependent on the unwinder used by the active kernel configuration, i.e @@ -329,6 +329,11 @@ OPTIONS enable deferred user callchain which will collect user-space callchains when the thread returns to the user space. + On s390, the "fp" method uses back chain instead of frame pointers, + which requires user space to maintain a back chain (e.g. compiler + option -mbackchain). Without a maintained back chain this produces + bogus call graphs. In that case use "dwarf" instead. + -q:: --quiet:: Don't print any warnings or messages, useful for scripting. diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index dd468716f424..a2e9a31c1472 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1096,9 +1096,9 @@ static void __evsel__config_callchain(struct evsel *evsel, const struct record_o bool function = evsel__is_function_event(evsel); struct perf_event_attr *attr = &evsel->core.attr; - if (EM_HOST == EM_S390 && param->record_mode == CALLCHAIN_FP) { - pr_warning_once( - "Framepointer unwinding lacks kernel support. Use '--call-graph dwarf'\n"); + if (EM_HOST == EM_S390 && evsel->pmu && !perf_pmu__is_software(evsel->pmu)) { + pr_warning_once("Cannot use hardware PMU 'cpum_cf' / 'cpum_sf' event with callchain. " + "Use a software 'cpu-clock' / 'task-clock' event.\n"); } evsel__set_sample_bit(evsel, CALLCHAIN);