blob: fab42d6aff8007176793316528a862ee7cc67fcd [file] [log] [blame]
#
# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import textwrap
from validation_error import ValidationError
ANDROID_SDK_VERSION_T = 33
def create_ftrace_events_string(predefined_ftrace_events,
excluded_ftrace_events, included_ftrace_events):
if excluded_ftrace_events is not None:
for event in excluded_ftrace_events:
if event in predefined_ftrace_events:
predefined_ftrace_events.remove(event)
else:
return None, ValidationError(("Cannot remove ftrace event %s from"
" config because it is not one"
" of the config's ftrace events."
% event),
("Please specify one of the following"
" possible ftrace events:\n\t %s"
% "\n\t ".join(predefined_ftrace_events)))
if included_ftrace_events is not None:
for event in included_ftrace_events:
if event not in predefined_ftrace_events:
predefined_ftrace_events.append(event)
else:
return None, ValidationError(("Cannot add ftrace event %s to config"
" because it is already one of the"
" config's ftrace events." % event),
("Please do not specify any of the"
" following ftrace events that are"
" already included:\n\t %s"
% "\n\t ".join(predefined_ftrace_events)))
ftrace_events_string = ("ftrace_events: \"%s\"" % ("""\"
ftrace_events: \"""".join(predefined_ftrace_events)))
return ftrace_events_string, None
def build_default_config(command, android_sdk_version):
if command.dur_ms is None:
# This is always defined because it has a default value that is always
# set in torq.py.
raise ValueError("Cannot create config because a valid dur_ms was not set.")
predefined_ftrace_events = [
"dmabuf_heap/dma_heap_stat",
"ftrace/print",
"gpu_mem/gpu_mem_total",
"ion/ion_stat",
"kmem/ion_heap_grow",
"kmem/ion_heap_shrink",
"kmem/rss_stat",
"lowmemorykiller/lowmemory_kill",
"mm_event/mm_event_record",
"oom/mark_victim",
"oom/oom_score_adj_update",
"power/cpu_frequency",
"power/cpu_idle",
"power/gpu_frequency",
"power/suspend_resume",
"power/wakeup_source_activate",
"power/wakeup_source_deactivate",
"sched/sched_blocked_reason",
"sched/sched_process_exit",
"sched/sched_process_free",
"sched/sched_switch",
"sched/sched_wakeup",
"sched/sched_wakeup_new",
"sched/sched_waking",
"task/task_newtask",
"task/task_rename",
"vmscan/*",
"workqueue/*",
]
ftrace_events_string, error = create_ftrace_events_string(
predefined_ftrace_events, command.excluded_ftrace_events,
command.included_ftrace_events)
if error is not None:
return None, error
cpufreq_period_string = "cpufreq_period_ms: 500"
if android_sdk_version < ANDROID_SDK_VERSION_T:
cpufreq_period_string = ""
config = f'''\
<<EOF
buffers: {{
size_kb: 4096
fill_policy: RING_BUFFER
}}
buffers {{
size_kb: 4096
fill_policy: RING_BUFFER
}}
buffers: {{
size_kb: 260096
fill_policy: RING_BUFFER
}}
data_sources: {{
config {{
name: "linux.process_stats"
process_stats_config {{
scan_all_processes_on_start: true
}}
}}
}}
data_sources: {{
config {{
name: "android.log"
android_log_config {{
}}
}}
}}
data_sources {{
config {{
name: "android.packages_list"
}}
}}
data_sources: {{
config {{
name: "linux.sys_stats"
target_buffer: 1
sys_stats_config {{
stat_period_ms: 500
stat_counters: STAT_CPU_TIMES
stat_counters: STAT_FORK_COUNT
meminfo_period_ms: 1000
meminfo_counters: MEMINFO_ACTIVE_ANON
meminfo_counters: MEMINFO_ACTIVE_FILE
meminfo_counters: MEMINFO_INACTIVE_ANON
meminfo_counters: MEMINFO_INACTIVE_FILE
meminfo_counters: MEMINFO_KERNEL_STACK
meminfo_counters: MEMINFO_MLOCKED
meminfo_counters: MEMINFO_SHMEM
meminfo_counters: MEMINFO_SLAB
meminfo_counters: MEMINFO_SLAB_UNRECLAIMABLE
meminfo_counters: MEMINFO_VMALLOC_USED
meminfo_counters: MEMINFO_MEM_FREE
meminfo_counters: MEMINFO_SWAP_FREE
vmstat_period_ms: 1000
vmstat_counters: VMSTAT_PGFAULT
vmstat_counters: VMSTAT_PGMAJFAULT
vmstat_counters: VMSTAT_PGFREE
vmstat_counters: VMSTAT_PGPGIN
vmstat_counters: VMSTAT_PGPGOUT
vmstat_counters: VMSTAT_PSWPIN
vmstat_counters: VMSTAT_PSWPOUT
vmstat_counters: VMSTAT_PGSCAN_DIRECT
vmstat_counters: VMSTAT_PGSTEAL_DIRECT
vmstat_counters: VMSTAT_PGSCAN_KSWAPD
vmstat_counters: VMSTAT_PGSTEAL_KSWAPD
vmstat_counters: VMSTAT_WORKINGSET_REFAULT
{cpufreq_period_string}
}}
}}
}}
data_sources: {{
config {{
name: "android.surfaceflinger.frametimeline"
target_buffer: 2
}}
}}
data_sources: {{
config {{
name: "linux.ftrace"
target_buffer: 2
ftrace_config {{
{ftrace_events_string}
atrace_categories: "aidl"
atrace_categories: "am"
atrace_categories: "dalvik"
atrace_categories: "binder_lock"
atrace_categories: "binder_driver"
atrace_categories: "bionic"
atrace_categories: "camera"
atrace_categories: "disk"
atrace_categories: "freq"
atrace_categories: "idle"
atrace_categories: "gfx"
atrace_categories: "hal"
atrace_categories: "input"
atrace_categories: "pm"
atrace_categories: "power"
atrace_categories: "res"
atrace_categories: "rro"
atrace_categories: "sched"
atrace_categories: "sm"
atrace_categories: "ss"
atrace_categories: "thermal"
atrace_categories: "video"
atrace_categories: "view"
atrace_categories: "wm"
atrace_apps: "lmkd"
atrace_apps: "system_server"
atrace_apps: "com.android.systemui"
atrace_apps: "com.google.android.gms"
atrace_apps: "com.google.android.gms.persistent"
atrace_apps: "android:ui"
atrace_apps: "com.google.android.apps.maps"
atrace_apps: "*"
buffer_size_kb: 16384
drain_period_ms: 150
symbolize_ksyms: true
}}
}}
}}
duration_ms: {command.dur_ms}
write_into_file: true
file_write_period_ms: 5000
max_file_size_bytes: 100000000000
flush_period_ms: 5000
incremental_state_config {{
clear_period_ms: 5000
}}
EOF'''
return textwrap.dedent(config), None
def build_lightweight_config(command, android_sdk_version):
raise NotImplementedError
def build_memory_config(command, android_sdk_version):
raise NotImplementedError
PREDEFINED_PERFETTO_CONFIGS = {
'default': build_default_config,
'lightweight': build_lightweight_config,
'memory': build_memory_config
}
def build_custom_config(command):
file_content = ""
duration_prefix = "duration_ms:"
appended_duration = duration_prefix + " " + str(command.dur_ms)
try:
with open(command.perfetto_config, "r") as file:
for line in file:
stripped_line = line.strip()
if stripped_line.startswith(duration_prefix):
duration = stripped_line[len(duration_prefix):].strip()
appended_duration = ""
command.dur_ms = int(duration)
file_content += line
except ValueError:
return None, ValidationError(("Failed to parse custom perfetto-config on"
" local file path: %s. Invalid duration_ms"
" field in config."
% command.perfetto_config),
("Make sure the perfetto config passed via"
" arguments has a valid duration_ms value."))
except Exception as e:
return None, ValidationError(("Failed to parse custom perfetto-config on"
" local file path: %s. %s"
% (command.perfetto_config, str(e))), None)
config_string = f"<<EOF\n\n{file_content}\n{appended_duration}\n\nEOF"
return config_string, None