aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 7e910bab1097..352fbd7ff4a1 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -87,7 +87,7 @@ static int run_count = 1;
87static bool no_inherit = false; 87static bool no_inherit = false;
88static bool scale = true; 88static bool scale = true;
89static enum aggr_mode aggr_mode = AGGR_GLOBAL; 89static enum aggr_mode aggr_mode = AGGR_GLOBAL;
90static pid_t child_pid = -1; 90static volatile pid_t child_pid = -1;
91static bool null_run = false; 91static bool null_run = false;
92static int detailed_run = 0; 92static int detailed_run = 0;
93static bool big_num = true; 93static bool big_num = true;
@@ -924,7 +924,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
924static void print_aggr(char *prefix) 924static void print_aggr(char *prefix)
925{ 925{
926 struct perf_evsel *counter; 926 struct perf_evsel *counter;
927 int cpu, s, s2, id, nr; 927 int cpu, cpu2, s, s2, id, nr;
928 u64 ena, run, val; 928 u64 ena, run, val;
929 929
930 if (!(aggr_map || aggr_get_id)) 930 if (!(aggr_map || aggr_get_id))
@@ -936,7 +936,8 @@ static void print_aggr(char *prefix)
936 val = ena = run = 0; 936 val = ena = run = 0;
937 nr = 0; 937 nr = 0;
938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
939 s2 = aggr_get_id(evsel_list->cpus, cpu); 939 cpu2 = perf_evsel__cpus(counter)->map[cpu];
940 s2 = aggr_get_id(evsel_list->cpus, cpu2);
940 if (s2 != id) 941 if (s2 != id)
941 continue; 942 continue;
942 val += counter->counts->cpu[cpu].val; 943 val += counter->counts->cpu[cpu].val;
@@ -948,7 +949,7 @@ static void print_aggr(char *prefix)
948 fprintf(output, "%s", prefix); 949 fprintf(output, "%s", prefix);
949 950
950 if (run == 0 || ena == 0) { 951 if (run == 0 || ena == 0) {
951 aggr_printout(counter, cpu, nr); 952 aggr_printout(counter, id, nr);
952 953
953 fprintf(output, "%*s%s%*s", 954 fprintf(output, "%*s%s%*s",
954 csv_output ? 0 : 18, 955 csv_output ? 0 : 18,
@@ -1148,13 +1149,34 @@ static void skip_signal(int signo)
1148 done = 1; 1149 done = 1;
1149 1150
1150 signr = signo; 1151 signr = signo;
1152 /*
1153 * render child_pid harmless
1154 * won't send SIGTERM to a random
1155 * process in case of race condition
1156 * and fast PID recycling
1157 */
1158 child_pid = -1;
1151} 1159}
1152 1160
1153static void sig_atexit(void) 1161static void sig_atexit(void)
1154{ 1162{
1163 sigset_t set, oset;
1164
1165 /*
1166 * avoid race condition with SIGCHLD handler
1167 * in skip_signal() which is modifying child_pid
1168 * goal is to avoid send SIGTERM to a random
1169 * process
1170 */
1171 sigemptyset(&set);
1172 sigaddset(&set, SIGCHLD);
1173 sigprocmask(SIG_BLOCK, &set, &oset);
1174
1155 if (child_pid != -1) 1175 if (child_pid != -1)
1156 kill(child_pid, SIGTERM); 1176 kill(child_pid, SIGTERM);
1157 1177
1178 sigprocmask(SIG_SETMASK, &oset, NULL);
1179
1158 if (signr == -1) 1180 if (signr == -1)
1159 return; 1181 return;
1160 1182