From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755169AbbCaOrB (ORCPT ); Tue, 31 Mar 2015 10:47:01 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:51947 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754624AbbCaOq6 (ORCPT ); Tue, 31 Mar 2015 10:46:58 -0400 From: David Ahern To: acme@kernel.org Cc: linux-kernel@vger.kernel.org, David Ahern , Ingo Molnar Subject: [PATCH] perf sched: Make cpu based arrays dynamic Date: Tue, 31 Mar 2015 10:46:49 -0400 Message-Id: <1427813209-4401-1-git-send-email-david.ahern@oracle.com> X-Mailer: git-send-email 1.7.1 X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Remove MAX_CPUS and static array sizing in favor of run time growth. Signed-off-by: David Ahern Cc: Ingo Molnar --- tools/perf/builtin-sched.c | 84 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 858d85396d81..1d111e66b6b3 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -30,7 +30,6 @@ #include #define PR_SET_NAME 15 /* Set process name */ -#define MAX_CPUS 4096 #define COMM_LEN 20 #define SYM_LEN 129 @@ -139,8 +138,6 @@ struct perf_sched { * weird events, such as a task being switched away that is not current. */ int max_cpu; - u32 curr_pid[MAX_CPUS]; - struct thread *curr_thread[MAX_CPUS]; char next_shortname1; char next_shortname2; unsigned int replay_repeat; @@ -170,10 +167,15 @@ struct perf_sched { u64 run_avg; u64 all_runtime; u64 all_count; - u64 cpu_last_switched[MAX_CPUS]; struct rb_root atom_root, sorted_atom_root; struct list_head sort_list, cmp_pid; + /* current allocation size for curr_pid and curr_thread */ + int alloc_cpu; + u32 *curr_pid; + struct thread **curr_thread; + u64 *cpu_last_switched; + /* options for timehist command */ bool summary; bool summary_only; @@ -733,6 +735,56 @@ replay_wakeup_event(struct perf_sched *sched, return 0; } +static int sched__expand_cpu_arrays(struct perf_sched *sched, int cpu) +{ + void *p; + int i; + + p = realloc(sched->curr_pid, cpu * sizeof(u32)); + if (p == NULL) { + pr_err("Failed to expand curr_pid array\n"); + return -1; + } + sched->curr_pid = p; + + p = realloc(sched->curr_thread, cpu * sizeof(struct thread *)); + if (p == NULL) { + pr_err("Failed to expand curr_thread array\n"); + return -1; + } + sched->curr_thread = p; + + p = realloc(sched->cpu_last_switched, cpu * sizeof(u64)); + if (p == NULL) { + pr_err("Failed to expand cpu_last_switched array\n"); + return -1; + } + sched->cpu_last_switched = p; + + /* initialize new slots */ + for (i = sched->alloc_cpu; i < cpu; ++i) { + sched->cpu_last_switched[i] = (u64) 0; + sched->curr_pid[i] = -1; + sched->curr_thread[i] = NULL; + } + + sched->alloc_cpu = cpu; + + return 0; +} + +static int sched__check_cpu_arrays(struct perf_sched *sched, int cpu) +{ + if (sched->alloc_cpu <= cpu) { + int n = __roundup_pow_of_two(cpu + 1); + + if (sched__expand_cpu_arrays(sched, n) != 0) + return -1; + } + + return 0; +} + static int replay_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, struct perf_sample *sample, @@ -751,9 +803,12 @@ static int replay_switch_event(struct perf_sched *sched, if (verbose) printf("sched_switch event %p\n", evsel); - if (cpu >= MAX_CPUS || cpu < 0) + if (cpu < 0) return 0; + if (sched__check_cpu_arrays(sched, cpu) != 0) + return -1; + timestamp0 = sched->cpu_last_switched[cpu]; if (timestamp0) delta = timestamp - timestamp0; @@ -983,7 +1038,10 @@ static int latency_switch_event(struct perf_sched *sched, int cpu = sample->cpu; s64 delta; - BUG_ON(cpu >= MAX_CPUS || cpu < 0); + BUG_ON(cpu < 0); + + if (sched__check_cpu_arrays(sched, cpu) != 0) + return -1; timestamp0 = sched->cpu_last_switched[cpu]; sched->cpu_last_switched[cpu] = timestamp; @@ -1046,7 +1104,7 @@ static int latency_runtime_event(struct perf_sched *sched, u64 timestamp = sample->time; int cpu = sample->cpu; - BUG_ON(cpu >= MAX_CPUS || cpu < 0); + BUG_ON(cpu < 0); if (!atoms) { if (thread_atoms_insert(sched, thread)) return -1; @@ -1335,11 +1393,14 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, s64 delta; int cpu, this_cpu = sample->cpu; - BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); + BUG_ON(this_cpu < 0); if (this_cpu > sched->max_cpu) sched->max_cpu = this_cpu; + if (sched__check_cpu_arrays(sched, this_cpu) != 0) + return -1; + timestamp0 = sched->cpu_last_switched[this_cpu]; sched->cpu_last_switched[this_cpu] = timestamp; if (timestamp0) @@ -1417,6 +1478,9 @@ static int process_sched_switch_event(struct perf_tool *tool, u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"), next_pid = perf_evsel__intval(evsel, sample, "next_pid"); + if (sched__check_cpu_arrays(sched, this_cpu) != 0) + return -1; + if (sched->curr_pid[this_cpu] != (u32)-1) { /* * Are we trying to switch away a PID that is @@ -2983,7 +3047,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) .switch_event = replay_switch_event, .fork_event = replay_fork_event, }; - unsigned int i; sched.pid_to_task = intlist__new(NULL); if (sched.pid_to_task == NULL) { @@ -2991,8 +3054,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) return -ENOMEM; } - for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++) - sched.curr_pid[i] = -1; + sched__expand_cpu_arrays(&sched, 16); argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands, sched_usage, PARSE_OPT_STOP_AT_NON_OPTION); -- 2.3.0