-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow using trace-cmd record that continuously dump the trace to disk, allowing to overcome the buffer size limitations when recording for extended periods of time.
- Loading branch information
1 parent
50e7a40
commit 8d55c17
Showing
1 changed file
with
57 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
import sys | ||
import contextlib | ||
from shlex import quote | ||
import signal | ||
|
||
from devlib.collector import (CollectorBase, CollectorOutput, | ||
CollectorOutputEntry) | ||
|
@@ -71,6 +72,7 @@ def __init__(self, target, | |
report_on_target=False, | ||
trace_clock='local', | ||
saved_cmdlines_nr=4096, | ||
mode='write-to-memory', | ||
): | ||
super(FtraceCollector, self).__init__(target) | ||
self.events = events if events is not None else DEFAULT_EVENTS | ||
|
@@ -98,6 +100,8 @@ def __init__(self, target, | |
self.trace_clock = trace_clock | ||
self.saved_cmdlines_nr = saved_cmdlines_nr | ||
self._reset_needed = True | ||
self.mode = mode | ||
self._bg_cmd = None | ||
|
||
# pylint: disable=bad-whitespace | ||
# Setup tracing paths | ||
|
@@ -276,18 +280,33 @@ async def start(self): | |
with contextlib.suppress(TargetStableError): | ||
self.target.write_value('/proc/sys/kernel/kptr_restrict', 0) | ||
|
||
self.target.execute( | ||
'{} start -B devlib {buffer_size} {cmdlines_size} {clock} {events} {tracer} {functions}'.format( | ||
self.target_binary, | ||
events=self.event_string, | ||
tracer=tracer_string, | ||
functions=tracecmd_functions, | ||
buffer_size='-b {}'.format(self.buffer_size) if self.buffer_size is not None else '', | ||
clock='-C {}'.format(self.trace_clock) if self.trace_clock else '', | ||
cmdlines_size='--cmdlines-size {}'.format(self.saved_cmdlines_nr) if self.saved_cmdlines_nr is not None else '', | ||
), | ||
as_root=True, | ||
params = '-B devlib {buffer_size} {cmdlines_size} {clock} {events} {tracer} {functions}'.format( | ||
events=self.event_string, | ||
tracer=tracer_string, | ||
functions=tracecmd_functions, | ||
buffer_size='-b {}'.format(self.buffer_size) if self.buffer_size is not None else '', | ||
clock='-C {}'.format(self.trace_clock) if self.trace_clock else '', | ||
cmdlines_size='--cmdlines-size {}'.format(self.saved_cmdlines_nr) if self.saved_cmdlines_nr is not None else '', | ||
) | ||
|
||
mode = self.mode | ||
if mode == 'write-to-disk': | ||
bg_cmd = self.target.background( | ||
# cd into the working_directory first to workaround this issue: | ||
# https://lore.kernel.org/linux-trace-devel/[email protected]/ | ||
f'cd {self.target.working_directory} && devlib-signal-target {self.target_binary} record -o {quote(self.target_output_file)} {params}', | ||
as_root=True, | ||
) | ||
assert self._bg_cmd is None | ||
self._bg_cmd = bg_cmd.__enter__() | ||
elif mode == 'write-to-memory': | ||
self.target.execute( | ||
f'{self.target_binary} start {params}', | ||
as_root=True, | ||
) | ||
else: | ||
raise ValueError(f'Unknown mode {mode}') | ||
|
||
if self.automark: | ||
self.mark_start() | ||
if 'cpufreq' in self.target.modules: | ||
|
@@ -322,8 +341,21 @@ def stop(self): | |
self.stop_time = time.time() | ||
if self.automark: | ||
self.mark_stop() | ||
self.target.execute('{} stop -B devlib'.format(self.target_binary), | ||
timeout=TIMEOUT, as_root=True) | ||
|
||
mode = self.mode | ||
if mode == 'write-to-disk': | ||
bg_cmd = self._bg_cmd | ||
self._bg_cmd = None | ||
assert bg_cmd is not None | ||
bg_cmd.send_signal(signal.SIGINT) | ||
bg_cmd.communicate() | ||
bg_cmd.__exit__(None, None, None) | ||
elif mode == 'write-to-memory': | ||
self.target.execute('{} stop -B devlib'.format(self.target_binary), | ||
timeout=TIMEOUT, as_root=True) | ||
else: | ||
raise ValueError(f'Unknown mode {mode}') | ||
|
||
self._reset_needed = True | ||
|
||
def set_output(self, output_path): | ||
|
@@ -334,9 +366,18 @@ def set_output(self, output_path): | |
def get_data(self): | ||
if self.output_path is None: | ||
raise RuntimeError("Output path was not set.") | ||
self.target.execute('{0} extract -B devlib -o {1}; chmod 666 {1}'.format(self.target_binary, | ||
self.target_output_file), | ||
timeout=TIMEOUT, as_root=True) | ||
|
||
busybox = quote(self.target.busybox) | ||
|
||
mode = self.mode | ||
if mode == 'write-to-disk': | ||
# Interrupting trace-cmd record will make it create the file | ||
pass | ||
elif mode == 'write-to-memory': | ||
cmd = f'{self.target_binary} extract -B devlib -o {self.target_output_file} && {busybox} chmod 666 {self.target_output_file}' | ||
self.target.execute(cmd, timeout=TIMEOUT, as_root=True) | ||
else: | ||
raise ValueError(f'Unknown mode {mode}') | ||
|
||
# The size of trace.dat will depend on how long trace-cmd was running. | ||
# Therefore timout for the pull command must also be adjusted | ||
|