• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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