aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-12-07 13:16:54 -0500
committerIngo Molnar <mingo@kernel.org>2016-12-07 13:16:54 -0500
commit080c25914e6db40c5d7606d22fd592ae3d8c3e59 (patch)
tree347ecc9037c323e9578207f2cde67191381fe3f6 /tools
parent34c4a42791bbc455e65a15d12dcd0b6b3c52ad13 (diff)
parent108a7c103b761309ccbd997002e8428808cf1e04 (diff)
Merge tag 'perf-core-for-mingo-20161207' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: Improvements: - Improve error message when analyzing file with required events in 'perf sched timehist' (David Ahern) Fixes: - Force fixdep compilation to be done at the start of the build, fixing some build race conditions in high core count machines (Jiri Olsa) - Fix handling a zero sample->tid in 'perf sched timehist', as sometimes that isn't the idle thread (Namhyung Kim) Infrastructure changes: - Check minimal accepted LLVM version in its feature check, 3.9 at this time (Wang Nan) Documentation changes: - Explicitly document that --children is enabled by default (Yannick Brosseau) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/build/feature/Makefile8
-rw-r--r--tools/build/feature/test-llvm-version.cpp11
-rw-r--r--tools/build/feature/test-llvm.cpp5
-rw-r--r--tools/perf/Documentation/perf-report.txt3
-rw-r--r--tools/perf/Documentation/perf-top.txt1
-rw-r--r--tools/perf/Makefile.config8
-rw-r--r--tools/perf/Makefile.perf68
-rw-r--r--tools/perf/builtin-sched.c26
-rw-r--r--tools/perf/util/callchain.c27
-rw-r--r--tools/perf/util/callchain.h3
10 files changed, 122 insertions, 38 deletions
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 303196c16019..b564a2eea039 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -231,14 +231,18 @@ $(OUTPUT)test-jvmti.bin:
231 $(BUILD) 231 $(BUILD)
232 232
233$(OUTPUT)test-llvm.bin: 233$(OUTPUT)test-llvm.bin:
234 $(BUILDXX) -std=gnu++11 \ 234 $(BUILDXX) -std=gnu++11 \
235 -I$(shell $(LLVM_CONFIG) --includedir) \ 235 -I$(shell $(LLVM_CONFIG) --includedir) \
236 -L$(shell $(LLVM_CONFIG) --libdir) \ 236 -L$(shell $(LLVM_CONFIG) --libdir) \
237 $(shell $(LLVM_CONFIG) --libs Core BPF) \ 237 $(shell $(LLVM_CONFIG) --libs Core BPF) \
238 $(shell $(LLVM_CONFIG) --system-libs) 238 $(shell $(LLVM_CONFIG) --system-libs)
239 239
240$(OUTPUT)test-llvm-version.bin:
241 $(BUILDXX) -std=gnu++11 \
242 -I$(shell $(LLVM_CONFIG) --includedir)
243
240$(OUTPUT)test-clang.bin: 244$(OUTPUT)test-clang.bin:
241 $(BUILDXX) -std=gnu++11 \ 245 $(BUILDXX) -std=gnu++11 \
242 -I$(shell $(LLVM_CONFIG) --includedir) \ 246 -I$(shell $(LLVM_CONFIG) --includedir) \
243 -L$(shell $(LLVM_CONFIG) --libdir) \ 247 -L$(shell $(LLVM_CONFIG) --libdir) \
244 -Wl,--start-group -lclangBasic -lclangDriver \ 248 -Wl,--start-group -lclangBasic -lclangDriver \
diff --git a/tools/build/feature/test-llvm-version.cpp b/tools/build/feature/test-llvm-version.cpp
new file mode 100644
index 000000000000..896d31724568
--- /dev/null
+++ b/tools/build/feature/test-llvm-version.cpp
@@ -0,0 +1,11 @@
1#include <cstdio>
2#include "llvm/Config/llvm-config.h"
3
4#define NUM_VERSION (((LLVM_VERSION_MAJOR) << 16) + (LLVM_VERSION_MINOR << 8) + LLVM_VERSION_PATCH)
5#define pass int main() {printf("%x\n", NUM_VERSION); return 0;}
6
7#if NUM_VERSION >= 0x030900
8pass
9#else
10# error This LLVM is not tested yet.
11#endif
diff --git a/tools/build/feature/test-llvm.cpp b/tools/build/feature/test-llvm.cpp
index d8d2cee35345..455a332dc8a8 100644
--- a/tools/build/feature/test-llvm.cpp
+++ b/tools/build/feature/test-llvm.cpp
@@ -1,5 +1,10 @@
1#include "llvm/Support/ManagedStatic.h" 1#include "llvm/Support/ManagedStatic.h"
2#include "llvm/Support/raw_ostream.h" 2#include "llvm/Support/raw_ostream.h"
3#define NUM_VERSION (((LLVM_VERSION_MAJOR) << 16) + (LLVM_VERSION_MINOR << 8) + LLVM_VERSION_PATCH)
4
5#if NUM_VERSION < 0x030900
6# error "LLVM version too low"
7#endif
3int main() 8int main()
4{ 9{
5 llvm::errs() << "Hello World!\n"; 10 llvm::errs() << "Hello World!\n";
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 3a166ae4a4d3..f2914f03ae7b 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -239,7 +239,8 @@ OPTIONS
239 Accumulate callchain of children to parent entry so that then can 239 Accumulate callchain of children to parent entry so that then can
240 show up in the output. The output will have a new "Children" column 240 show up in the output. The output will have a new "Children" column
241 and will be sorted on the data. It requires callchains are recorded. 241 and will be sorted on the data. It requires callchains are recorded.
242 See the `overhead calculation' section for more details. 242 See the `overhead calculation' section for more details. Enabled by
243 default, disable with --no-children.
243 244
244--max-stack:: 245--max-stack::
245 Set the stack depth limit when parsing the callchain, anything 246 Set the stack depth limit when parsing the callchain, anything
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 91d638df3a6b..e71d63843f45 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -170,6 +170,7 @@ Default is to monitor all CPUS.
170 show up in the output. The output will have a new "Children" column 170 show up in the output. The output will have a new "Children" column
171 and will be sorted on the data. It requires -g/--call-graph option 171 and will be sorted on the data. It requires -g/--call-graph option
172 enabled. See the `overhead calculation' section for more details. 172 enabled. See the `overhead calculation' section for more details.
173 Enabled by default, disable with --no-children.
173 174
174--max-stack:: 175--max-stack::
175 Set the stack depth limit when parsing the callchain, anything 176 Set the stack depth limit when parsing the callchain, anything
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 09c2a9874f2f..76c84f0eec52 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -802,12 +802,13 @@ ifdef LIBCLANGLLVM
802 msg := $(warning No g++ found, disable clang and llvm support. Please install g++) 802 msg := $(warning No g++ found, disable clang and llvm support. Please install g++)
803 else 803 else
804 $(call feature_check,llvm) 804 $(call feature_check,llvm)
805 $(call feature_check,llvm-version)
805 ifneq ($(feature-llvm), 1) 806 ifneq ($(feature-llvm), 1)
806 msg := $(warning No libLLVM found, disable clang and llvm support. Please install llvm-dev) 807 msg := $(warning No suitable libLLVM found, disabling builtin clang and LLVM support. Please install llvm-dev(el) (>= 3.9.0))
807 else 808 else
808 $(call feature_check,clang) 809 $(call feature_check,clang)
809 ifneq ($(feature-clang), 1) 810 ifneq ($(feature-clang), 1)
810 msg := $(warning No libclang found, disable clang and llvm support. Please install libclang-dev) 811 msg := $(warning No suitable libclang found, disabling builtin clang and LLVM support. Please install libclang-dev(el) (>= 3.9.0))
811 else 812 else
812 CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT 813 CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT
813 CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) --includedir) 814 CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) --includedir)
@@ -816,6 +817,9 @@ ifdef LIBCLANGLLVM
816 USE_CXX = 1 817 USE_CXX = 1
817 USE_LLVM = 1 818 USE_LLVM = 1
818 USE_CLANG = 1 819 USE_CLANG = 1
820 ifneq ($(feature-llvm-version),1)
821 msg := $(warning This version of LLVM is not tested. May cause build errors)
822 endif
819 endif 823 endif
820 endif 824 endif
821 endif 825 endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 10495c9dbe71..8f1c258b151a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -128,10 +128,6 @@ endif
128# (this improves performance and avoids hard-to-debug behaviour); 128# (this improves performance and avoids hard-to-debug behaviour);
129MAKEFLAGS += -r 129MAKEFLAGS += -r
130 130
131$(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
132 $(Q)$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
133 $(Q)touch $(OUTPUT)PERF-VERSION-FILE
134
135# Makefiles suck: This macro sets a default value of $(2) for the 131# Makefiles suck: This macro sets a default value of $(2) for the
136# variable named by $(1), unless the variable has been set by 132# variable named by $(1), unless the variable has been set by
137# environment or command line. This is necessary for CC and AR 133# environment or command line. This is necessary for CC and AR
@@ -168,11 +164,6 @@ BISON = bison
168STRIP = strip 164STRIP = strip
169AWK = awk 165AWK = awk
170 166
171LIB_DIR = $(srctree)/tools/lib/api/
172TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
173BPF_DIR = $(srctree)/tools/lib/bpf/
174SUBCMD_DIR = $(srctree)/tools/lib/subcmd/
175
176# include Makefile.config by default and rule out 167# include Makefile.config by default and rule out
177# non-config cases 168# non-config cases
178config := 1 169config := 1
@@ -185,6 +176,40 @@ ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
185endif 176endif
186endif 177endif
187 178
179# The fixdep build - we force fixdep tool to be built as
180# the first target in the separate make session not to be
181# disturbed by any parallel make jobs. Once fixdep is done
182# we issue the requested build with FIXDEP=1 variable.
183#
184# The fixdep build is disabled for $(NON_CONFIG_TARGETS)
185# targets, because it's not necessary.
186
187ifdef FIXDEP
188 force_fixdep := 0
189else
190 force_fixdep := $(config)
191endif
192
193export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
194export HOSTCC HOSTLD HOSTAR
195
196include $(srctree)/tools/build/Makefile.include
197
198ifeq ($(force_fixdep),1)
199goals := $(filter-out all sub-make, $(MAKECMDGOALS))
200
201$(goals) all: sub-make
202
203sub-make: fixdep
204 $(Q)$(MAKE) FIXDEP=1 -f Makefile.perf $(goals)
205
206else # force_fixdep
207
208LIB_DIR = $(srctree)/tools/lib/api/
209TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
210BPF_DIR = $(srctree)/tools/lib/bpf/
211SUBCMD_DIR = $(srctree)/tools/lib/subcmd/
212
188# Set FEATURE_TESTS to 'all' so all possible feature checkers are executed. 213# Set FEATURE_TESTS to 'all' so all possible feature checkers are executed.
189# Without this setting the output feature dump file misses some features, for 214# Without this setting the output feature dump file misses some features, for
190# example, liberty. Select all checkers so we won't get an incomplete feature 215# example, liberty. Select all checkers so we won't get an incomplete feature
@@ -369,10 +394,6 @@ strip: $(PROGRAMS) $(OUTPUT)perf
369 394
370PERF_IN := $(OUTPUT)perf-in.o 395PERF_IN := $(OUTPUT)perf-in.o
371 396
372export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
373export HOSTCC HOSTLD HOSTAR
374include $(srctree)/tools/build/Makefile.include
375
376JEVENTS := $(OUTPUT)pmu-events/jevents 397JEVENTS := $(OUTPUT)pmu-events/jevents
377JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o 398JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o
378 399
@@ -491,7 +512,7 @@ $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_L
491 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ 512 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
492 $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ 513 $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
493 514
494$(GTK_IN): fixdep FORCE 515$(GTK_IN): FORCE
495 $(Q)$(MAKE) $(build)=gtk 516 $(Q)$(MAKE) $(build)=gtk
496 517
497$(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) 518$(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS)
@@ -505,6 +526,10 @@ $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
505$(SCRIPTS) : % : %.sh 526$(SCRIPTS) : % : %.sh
506 $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@' 527 $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
507 528
529$(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
530 $(Q)$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
531 $(Q)touch $(OUTPUT)PERF-VERSION-FILE
532
508# These can record PERF_VERSION 533# These can record PERF_VERSION
509perf.spec $(SCRIPTS) \ 534perf.spec $(SCRIPTS) \
510 : $(OUTPUT)PERF-VERSION-FILE 535 : $(OUTPUT)PERF-VERSION-FILE
@@ -536,7 +561,7 @@ endif
536__build-dir = $(subst $(OUTPUT),,$(dir $@)) 561__build-dir = $(subst $(OUTPUT),,$(dir $@))
537build-dir = $(if $(__build-dir),$(__build-dir),.) 562build-dir = $(if $(__build-dir),$(__build-dir),.)
538 563
539prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders 564prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders
540 565
541$(OUTPUT)%.o: %.c prepare FORCE 566$(OUTPUT)%.o: %.c prepare FORCE
542 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 567 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -586,7 +611,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
586 611
587LIBPERF_IN := $(OUTPUT)libperf-in.o 612LIBPERF_IN := $(OUTPUT)libperf-in.o
588 613
589$(LIBPERF_IN): prepare fixdep FORCE 614$(LIBPERF_IN): prepare FORCE
590 $(Q)$(MAKE) $(build)=libperf 615 $(Q)$(MAKE) $(build)=libperf
591 616
592$(LIB_FILE): $(LIBPERF_IN) 617$(LIB_FILE): $(LIBPERF_IN)
@@ -594,10 +619,10 @@ $(LIB_FILE): $(LIBPERF_IN)
594 619
595LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 620LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ)
596 621
597$(LIBTRACEEVENT): fixdep FORCE 622$(LIBTRACEEVENT): FORCE
598 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a 623 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a
599 624
600libtraceevent_plugins: fixdep FORCE 625libtraceevent_plugins: FORCE
601 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins 626 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
602 627
603$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins 628$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
@@ -610,21 +635,21 @@ $(LIBTRACEEVENT)-clean:
610install-traceevent-plugins: libtraceevent_plugins 635install-traceevent-plugins: libtraceevent_plugins
611 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins 636 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins
612 637
613$(LIBAPI): fixdep FORCE 638$(LIBAPI): FORCE
614 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a 639 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
615 640
616$(LIBAPI)-clean: 641$(LIBAPI)-clean:
617 $(call QUIET_CLEAN, libapi) 642 $(call QUIET_CLEAN, libapi)
618 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null 643 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
619 644
620$(LIBBPF): fixdep FORCE 645$(LIBBPF): FORCE
621 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) 646 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT)
622 647
623$(LIBBPF)-clean: 648$(LIBBPF)-clean:
624 $(call QUIET_CLEAN, libbpf) 649 $(call QUIET_CLEAN, libbpf)
625 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null 650 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
626 651
627$(LIBSUBCMD): fixdep FORCE 652$(LIBSUBCMD): FORCE
628 $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a 653 $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a
629 654
630$(LIBSUBCMD)-clean: 655$(LIBSUBCMD)-clean:
@@ -832,3 +857,4 @@ FORCE:
832.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare 857.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
833.PHONY: libtraceevent_plugins archheaders 858.PHONY: libtraceevent_plugins archheaders
834 859
860endif # force_fixdep
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 870d94cd20ba..1a3f1be93372 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2010,7 +2010,7 @@ static int init_idle_threads(int ncpu)
2010 if (!idle_threads) 2010 if (!idle_threads)
2011 return -ENOMEM; 2011 return -ENOMEM;
2012 2012
2013 idle_max_cpu = ncpu - 1; 2013 idle_max_cpu = ncpu;
2014 2014
2015 /* allocate the actual thread struct if needed */ 2015 /* allocate the actual thread struct if needed */
2016 for (i = 0; i < ncpu; ++i) { 2016 for (i = 0; i < ncpu; ++i) {
@@ -2031,7 +2031,7 @@ static void free_idle_threads(void)
2031 if (idle_threads == NULL) 2031 if (idle_threads == NULL)
2032 return; 2032 return;
2033 2033
2034 for (i = 0; i <= idle_max_cpu; ++i) { 2034 for (i = 0; i < idle_max_cpu; ++i) {
2035 if ((idle_threads[i])) 2035 if ((idle_threads[i]))
2036 thread__delete(idle_threads[i]); 2036 thread__delete(idle_threads[i]);
2037 } 2037 }
@@ -2054,8 +2054,7 @@ static struct thread *get_idle_thread(int cpu)
2054 return NULL; 2054 return NULL;
2055 2055
2056 idle_threads = (struct thread **) p; 2056 idle_threads = (struct thread **) p;
2057 i = idle_max_cpu ? idle_max_cpu + 1 : 0; 2057 for (i = idle_max_cpu; i < j; ++i)
2058 for (; i < j; ++i)
2059 idle_threads[i] = NULL; 2058 idle_threads[i] = NULL;
2060 2059
2061 idle_max_cpu = j; 2060 idle_max_cpu = j;
@@ -2118,7 +2117,9 @@ static struct thread *timehist_get_thread(struct perf_sched *sched,
2118 pr_err("Failed to get idle thread for cpu %d.\n", sample->cpu); 2117 pr_err("Failed to get idle thread for cpu %d.\n", sample->cpu);
2119 2118
2120 } else { 2119 } else {
2121 thread = machine__findnew_thread(machine, sample->pid, sample->tid); 2120 /* there were samples with tid 0 but non-zero pid */
2121 thread = machine__findnew_thread(machine, sample->pid,
2122 sample->tid ?: sample->pid);
2122 if (thread == NULL) { 2123 if (thread == NULL) {
2123 pr_debug("Failed to get thread for tid %d. skipping sample.\n", 2124 pr_debug("Failed to get thread for tid %d. skipping sample.\n",
2124 sample->tid); 2125 sample->tid);
@@ -2493,7 +2494,7 @@ static void timehist_print_summary(struct perf_sched *sched,
2493 return; 2494 return;
2494 2495
2495 printf("\nIdle stats:\n"); 2496 printf("\nIdle stats:\n");
2496 for (i = 0; i <= idle_max_cpu; ++i) { 2497 for (i = 0; i < idle_max_cpu; ++i) {
2497 t = idle_threads[i]; 2498 t = idle_threads[i];
2498 if (!t) 2499 if (!t)
2499 continue; 2500 continue;
@@ -2583,6 +2584,7 @@ static int perf_sched__timehist(struct perf_sched *sched)
2583 struct perf_data_file file = { 2584 struct perf_data_file file = {
2584 .path = input_name, 2585 .path = input_name,
2585 .mode = PERF_DATA_MODE_READ, 2586 .mode = PERF_DATA_MODE_READ,
2587 .force = sched->force,
2586 }; 2588 };
2587 2589
2588 struct perf_session *session; 2590 struct perf_session *session;
@@ -2629,8 +2631,12 @@ static int perf_sched__timehist(struct perf_sched *sched)
2629 if (perf_session__set_tracepoints_handlers(session, handlers)) 2631 if (perf_session__set_tracepoints_handlers(session, handlers))
2630 goto out; 2632 goto out;
2631 2633
2632 if (!perf_session__has_traces(session, "record -R")) 2634 /* sched_switch event at a minimum needs to exist */
2635 if (!perf_evlist__find_tracepoint_by_name(session->evlist,
2636 "sched:sched_switch")) {
2637 pr_err("No sched_switch events found. Have you run 'perf sched record'?\n");
2633 goto out; 2638 goto out;
2639 }
2634 2640
2635 if (sched->show_migrations && 2641 if (sched->show_migrations &&
2636 perf_session__set_tracepoints_handlers(session, migrate_handlers)) 2642 perf_session__set_tracepoints_handlers(session, migrate_handlers))
@@ -2984,6 +2990,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
2984 "be more verbose (show symbol address, etc)"), 2990 "be more verbose (show symbol address, etc)"),
2985 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 2991 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
2986 "dump raw trace in ASCII"), 2992 "dump raw trace in ASCII"),
2993 OPT_BOOLEAN('f', "force", &sched.force, "don't complain, do it"),
2987 OPT_END() 2994 OPT_END()
2988 }; 2995 };
2989 const struct option latency_options[] = { 2996 const struct option latency_options[] = {
@@ -2991,8 +2998,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
2991 "sort by key(s): runtime, switch, avg, max"), 2998 "sort by key(s): runtime, switch, avg, max"),
2992 OPT_INTEGER('C', "CPU", &sched.profile_cpu, 2999 OPT_INTEGER('C', "CPU", &sched.profile_cpu,
2993 "CPU to profile on"), 3000 "CPU to profile on"),
2994 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
2995 "dump raw trace in ASCII"),
2996 OPT_BOOLEAN('p', "pids", &sched.skip_merge, 3001 OPT_BOOLEAN('p', "pids", &sched.skip_merge,
2997 "latency stats per pid instead of per comm"), 3002 "latency stats per pid instead of per comm"),
2998 OPT_PARENT(sched_options) 3003 OPT_PARENT(sched_options)
@@ -3000,9 +3005,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
3000 const struct option replay_options[] = { 3005 const struct option replay_options[] = {
3001 OPT_UINTEGER('r', "repeat", &sched.replay_repeat, 3006 OPT_UINTEGER('r', "repeat", &sched.replay_repeat,
3002 "repeat the workload replay N times (-1: infinite)"), 3007 "repeat the workload replay N times (-1: infinite)"),
3003 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
3004 "dump raw trace in ASCII"),
3005 OPT_BOOLEAN('f', "force", &sched.force, "don't complain, do it"),
3006 OPT_PARENT(sched_options) 3008 OPT_PARENT(sched_options)
3007 }; 3009 };
3008 const struct option map_options[] = { 3010 const struct option map_options[] = {
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 823befd8209a..42922512c1c6 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -1234,3 +1234,30 @@ out:
1234 } 1234 }
1235 return -ENOMEM; 1235 return -ENOMEM;
1236} 1236}
1237
1238int callchain_cursor__copy(struct callchain_cursor *dst,
1239 struct callchain_cursor *src)
1240{
1241 int rc = 0;
1242
1243 callchain_cursor_reset(dst);
1244 callchain_cursor_commit(src);
1245
1246 while (true) {
1247 struct callchain_cursor_node *node;
1248
1249 node = callchain_cursor_current(src);
1250 if (node == NULL)
1251 break;
1252
1253 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
1254 node->branch, &node->branch_flags,
1255 node->nr_loop_iter, node->samples);
1256 if (rc)
1257 break;
1258
1259 callchain_cursor_advance(src);
1260 }
1261
1262 return rc;
1263}
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index d9c70dccf06a..35c8e379530f 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -216,6 +216,9 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
216 cursor->pos++; 216 cursor->pos++;
217} 217}
218 218
219int callchain_cursor__copy(struct callchain_cursor *dst,
220 struct callchain_cursor *src);
221
219struct option; 222struct option;
220struct hist_entry; 223struct hist_entry;
221 224