From d65ed2c41adc85cf0cb97732217d5b5110498478 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 13 Mar 2023 16:02:42 +0000 Subject: [PATCH 1/2] lisa.trace: Fix Trace.from_target() with kernel module FIX FtraceCollector.get_data() yields a broken trace when some events are coming from the kernel modules, since the trace is extracted from the kernel after the module has been unloaded so the event format is unknown. --- lisa/trace.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lisa/trace.py b/lisa/trace.py index 2a21e565b..488964d17 100644 --- a/lisa/trace.py +++ b/lisa/trace.py @@ -3708,7 +3708,6 @@ class Trace(Loggable, TraceBase): :Variable keyword arguments: Forwarded to :class:`Trace`. """ - ftrace_coll = FtraceCollector(target, events=events, buffer_size=buffer_size) plat_info = target.plat_info class TraceProxy(TraceBase): @@ -3726,9 +3725,6 @@ class Trace(Loggable, TraceBase): proxy = TraceProxy() - with ftrace_coll: - yield proxy - if filepath: cm = nullcontext(filepath) else: @@ -3740,7 +3736,10 @@ class Trace(Loggable, TraceBase): cm = cm_func() with cm as path: - ftrace_coll.get_data(path) + ftrace_coll = FtraceCollector(target, events=events, buffer_size=buffer_size, output_path=path) + with ftrace_coll: + yield proxy + trace = cls( path, events=events, -- GitLab From 38496386dc726c2c62a2e43c6c34dc63e8f5da6f Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 13 Mar 2023 16:08:04 +0000 Subject: [PATCH 2/2] lisa.trace: Avoid broken trace in FtraceCollector.get_data() FIX When FtraceCollector.get_data() is called after the kernel module unload, the event format is missing and the trace is therefore broken (appears to not contain that event). Close that gap by raising an explicit error in that scenario. --- lisa/trace.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lisa/trace.py b/lisa/trace.py index 488964d17..a5056da51 100644 --- a/lisa/trace.py +++ b/lisa/trace.py @@ -5669,7 +5669,8 @@ class FtraceCollector(CollectorBase, Configurable): needed_from_kmod = missing_events | missing_optional_events kmod = None kmod_cm = None - if needed_from_kmod and kmod_auto_load: + need_kmod = needed_from_kmod and kmod_auto_load + if need_kmod: self.logger.info(f'Building kernel module to try to provide the following events that are not currently available on the target: {", ".join(sorted(needed_from_kmod))}') try: kmod, kmod_cm = self._get_kmod( @@ -5688,7 +5689,9 @@ class FtraceCollector(CollectorBase, Configurable): ) from e else: self.logger.error(f'{msg}: {e}') + need_kmod = False + self._need_kmod = need_kmod self._kmod_cm = kmod_cm if kmod is not None: @@ -5789,8 +5792,15 @@ class FtraceCollector(CollectorBase, Configurable): x = self._cm.__exit__(*args, **kwargs) finally: self._cm = None + self._kmod_cm = None return x + def get_data(self, *args, **kwargs): + if self._need_kmod and not self._kmod_cm: + raise ValueError('FtraceCollector.get_data() cannot be called after the kernel module was unloaded.') + else: + return super().get_data(*args, **kwargs) + @staticmethod def _target_available_events(target, tracing_path): events = target.read_value(target.path.join(tracing_path, 'available_events')) -- GitLab