1// Copyright (C) 2024 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {RecordSubpage, RecordProbe} from '../config/config_interfaces'; 16import {FTRACE_DS, TraceConfigBuilder} from '../config/trace_config_builder'; 17import {TypedMultiselect} from './widgets/multiselect'; 18import {Slider} from './widgets/slider'; 19import {Toggle} from './widgets/toggle'; 20 21export const ADV_PROC_ASSOC_PROBE_ID = 'adv_proc_thread_assoc'; 22export const PROC_STATS_DS_NAME = 'linux.process_stats'; 23export const ADV_FTRACE_PROBE_ID = 'advanced_ftrace'; 24 25export function advancedRecordSection(): RecordSubpage { 26 return { 27 kind: 'PROBES_PAGE', 28 id: 'advanced', 29 title: 'Advanced settings', 30 subtitle: 'For ftrace wizards', 31 icon: 'settings', 32 probes: [ftraceCfg(), procThreadAssociation()], 33 }; 34} 35 36function ftraceCfg(): RecordProbe { 37 const settings = { 38 ksyms: new Toggle({ 39 title: 'Resolve kernel symbols', 40 default: true, 41 descr: 42 'Enables lookup via /proc/kallsyms for workqueue, ' + 43 'sched_blocked_reason and other events ' + 44 '(userdebug/eng builds only).', 45 }), 46 genericEvents: new Toggle({ 47 title: 'Enable generic events (slow)', 48 descr: 49 'Enables capture of ftrace events that are not known at build time ' + 50 'by perfetto as key-value string pairs. This is slow and expensive.', 51 }), 52 bufSize: new Slider({ 53 title: 'Buf size', 54 cssClass: '.thin', 55 values: [0, 512, 1024, 2 * 1024, 4 * 1024, 16 * 1024, 32 * 1024], 56 unit: 'KB', 57 zeroIsDefault: true, 58 }), 59 drainRate: new Slider({ 60 title: 'trace_pipe_raw read interval', 61 cssClass: '.thin', 62 values: [0, 100, 250, 500, 1000, 2500, 5000], 63 unit: 'ms', 64 zeroIsDefault: true, 65 }), 66 groups: new TypedMultiselect<string>({ 67 title: 'Event groups', 68 options: new Map( 69 Object.entries({ 70 binder: 'binder/*', 71 block: 'block/*', 72 clk: 'clk/*', 73 devfreq: 'devfreq/*', 74 ext4: 'ext4/*', 75 f2fs: 'f2fs/*', 76 i2c: 'i2c/*', 77 irq: 'irq/*', 78 kmem: 'kmem/*', 79 memory_bus: 'memory_bus/*', 80 mmc: 'mmc/*', 81 oom: 'oom/*', 82 power: 'power/*', 83 regulator: 'regulator/*', 84 sched: 'sched/*', 85 sync: 'sync/*', 86 task: 'task/*', 87 vmscan: 'vmscan/*', 88 fastrpc: 'fastrpc/*', 89 }), 90 ), 91 }), 92 }; 93 return { 94 id: ADV_FTRACE_PROBE_ID, 95 title: 'Advanced ftrace config', 96 image: 'rec_ftrace.png', 97 description: 98 'Enable individual events and tune the kernel-tracing (ftrace) ' + 99 'module. The events enabled here are in addition to those from ' + 100 'enabled by other probes.', 101 supportedPlatforms: ['ANDROID', 'CHROME_OS', 'LINUX'], 102 settings, 103 genConfig: function (tc: TraceConfigBuilder) { 104 const ds = tc.addDataSource(FTRACE_DS); 105 const cfg = (ds.ftraceConfig ??= {}); 106 cfg.bufferSizeKb = settings.bufSize.value || undefined; 107 cfg.drainPeriodMs = settings.drainRate.value || undefined; 108 cfg.symbolizeKsyms = settings.ksyms.enabled ? true : undefined; 109 cfg.disableGenericEvents = !settings.genericEvents.enabled; 110 cfg.ftraceEvents ??= []; 111 cfg.ftraceEvents.push(...settings.groups.selectedValues()); 112 }, 113 }; 114} 115 116function procThreadAssociation(): RecordProbe { 117 const ftraceEvents = [ 118 'sched/sched_process_exit', 119 'sched/sched_process_free', 120 'task/task_newtask', 121 'task/task_rename', 122 ]; 123 const settings = { 124 initialScan: new Toggle({ 125 title: 'Scan all processes at startup', 126 descr: 'Reports all /proc/* processes when starting', 127 default: true, 128 }), 129 }; 130 return { 131 id: ADV_PROC_ASSOC_PROBE_ID, 132 title: 'Process<>thread association', 133 description: 134 'A union of ftrace events and /proc scrapers to capture thread<>process' + 135 'associations as soon as they are seen from the cpu_pipe_raw. This is ' + 136 'to capture the information about the whole process (e.g., cmdline).', 137 supportedPlatforms: ['ANDROID', 'CHROME_OS', 'LINUX'], 138 settings, 139 genConfig: function (tc: TraceConfigBuilder) { 140 tc.addFtraceEvents(...ftraceEvents); 141 const bufId = 'proc_assoc'; 142 // Set to 1/16th of the main buffer size, with reasonable limits. 143 const minMax = [256, 8 * 1024]; 144 const bufSizeKb = Math.min( 145 Math.max(tc.defaultBuffer.sizeKb / 16, minMax[0]), 146 minMax[1], 147 ); 148 tc.addBuffer(bufId, bufSizeKb); 149 150 const ds = tc.addDataSource(PROC_STATS_DS_NAME); 151 const cfg = (ds.processStatsConfig ??= {}); 152 cfg.scanAllProcessesOnStart = settings.initialScan.enabled || undefined; 153 }, 154 }; 155} 156