Typical LISA experiment

This notebook shows a typical LISA-use case:

  • Connecting to a target

  • Configuring an rt-app workload

  • Collecting a trace while executing a workload

  • Displaying the trace

  • Analysing the trace

It can serve as a template for different kind of experiments, - you could only change the workload to execute & the trace events to collect

[1]:
import logging
from lisa.utils import setup_logging
setup_logging()
2021-07-01 17:08:58,411 INFO    : root         : Using LISA logging configuration: /home/dourai01/Work/lisa/lisa/logging.conf

Target configuration

Target communication is abstracted away under a Target class. We’re going to create an instance of it and that’ll let us run whatever experiment we want on a given target.

Relevant documentation:

[2]:
from lisa.target import Target, TargetConf
[3]:
# target = Target(
#     kind='linux',
#     name='myhikey960',
#     host='192.168.0.1',
#     username='root',
#     password='root',
# )
# Uses settings from target_conf.yml
target = Target.from_default_conf()
2021-07-01 17:09:01,454 INFO    : lisa.target.Target : Target configuration:
+- devlib:
    |- excluded-modules from default (list): []
    +- platform:
        |- class from default (str): devlib.platform.Platform
|- host from user (str): 10.7.6.218
|- kind from user (str): linux
|- lazy-platinfo from default (bool): False
|- name from user (str): juno-r0
|- password from user (str): <password>
|- strict-host-check from user (bool): False
|- tools from default (list): []
|- username from user (str): root
+- wait-boot:
    |- enable from default (bool): True
    |- timeout from default (int): 10
2021-07-01 17:09:01,564 INFO    : lisa.target.Target : Creating result directory: /home/dourai01/Work/lisa/lisa/results/Target-juno-r0-20210701_170901.564655
2021-07-01 17:09:01,565 INFO    : lisa.target.Target : User-defined platform information:

2021-07-01 17:09:05,344 INFO    : lisa.target.Target : Connected to target juno-r0
2021-07-01 17:09:05,648 INFO    : lisa.energy_model.EnergyModel.from_target : Attempting to load EM using LinuxEnergyModel
2021-07-01 17:09:07,192 INFO    : lisa.target.Target : Loading target devlib module cpuidle
2021-07-01 17:09:09,126 INFO    : lisa.target.Target : Loading target devlib module cpufreq
2021-07-01 17:09:10,581 INFO    : lisa.target.Target : Loading target devlib module sched
2021-07-01 17:09:11,964 INFO    : sched        : Scheduler sched_domain procfs entries not found
2021-07-01 17:09:11,974 INFO    : sched        : Detected kernel compiled with SCHED_DEBUG=n
2021-07-01 17:09:11,977 INFO    : sched        : CPU capacity sysfs entries found
2021-07-01 17:09:14,965 INFO    : lisa.target.Target : Effective platform information:
|- abi from target (str): arm64
+- cpu-capacities:
    |- orig from target (dict): {0: 446, 1: 1024, 2: 1024, 3: 446, 4: 446, 5: 446}
    |- writeable from target (bool): True
    |- rtapp from target(platform-info/rtapp/calib),target(platform-info/cpu-capacities/orig),target(platform-info/cpu-capacities/writeable) (str): <depends on lazy keys: platform-info/rtapp/calib>
|- cpus-count from target (int): 6
|- freq-domains from target (list): [[0, 3, 4, 5], [1, 2]]
|- freqs from target (dict): {0: [450000, 575000, 700000, 775000, 850000], 1: [450000, 625000, 800000, 950000, 1100000], 2: [450000, 625000, 800000, 950000, 1100000], 3: [450000, 575000, 700000, 775000, 850000], 4: [450000, 575000, 700000, 775000, 850000], 5: [450000, 575000, 700000, 775000, 850000]}
+- kernel:
    |- config from target (TypedKernelConfig): <kernel config>
    |- symbols-address from target (DeferredValue): <symbols address>
    |- version from target (KernelVersion): 5.13.0-rc3-g5c95b23cc7dd 1 SMP PREEMPT Thu Jul 1 16:07:56 BST 2021
|- name from target-conf (str): juno-r0
|- nrg-model from target (LinuxEnergyModel): <lisa.energy_model.LinuxEnergyModel object at 0x7f598c2faee0>
|- numa-nodes-count from target (int): 1
|- os from target (str): linux
+- rtapp:
    |- calib from target (DeferredValue): <lazy value of RTA.get_cpu_calibrations>
|- capacity-classes from target(platform-info/cpu-capacities/orig) (list): [[0, 3, 4, 5], [1, 2]]

Setting up an rt-app workload

rt-app is very convenient for scheduler experiments, and the majority of the tests within LISA rely on it. Here we’re going to create a somewhat useless workload just to show off the API.

Relevant documentation:

[4]:
from lisa.wlgen.rta import RTA, RTAPhase, PeriodicWload
[5]:
rtapp_profile = {
    f'tsk{cpu}_{i}': RTAPhase(
        prop_wload=PeriodicWload(
            duty_cycle_pct=20,
            period=16e-3,
            duration=1,
        )
    )
    for cpu in range(target.number_of_cpus)
    for i in range(3)
}

rt-app needs some calibration information (20% duty cycle isn’t the same amount of work on all platforms!). It can be manually specified like so:

[6]:
def provide_calibration(calibration):
    target.plat_info["rtapp"].add_src("user", {"calib" : calibration})
[7]:
# Uncomment if you want to use this
# provide_calibration({0: 307, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155})

However, it is automatically collected when first creating an rt-app workload if it is not specified, so you can forego the above step and let the calibration happen on-demand:

[8]:
wload = RTA.from_profile(target, rtapp_profile, name='experiment_workload')
2021-07-01 17:09:15,029 INFO    : lisa.target.Target : Creating result directory: /home/dourai01/Work/lisa/lisa/results/Target-juno-r0-20210701_170901.564655/RTA-experiment_workload-20210701_170915.028850
2021-07-01 17:09:19,224 INFO    : lisa.target.Target : Disabling idle states for all domains
2021-07-01 17:09:24,703 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_170924_e999fea4ccb94f3889f8de836d4a7918
2021-07-01 17:09:25,374 INFO    : lisa.target.Target : Loading target devlib module cgroups
2021-07-01 17:09:25,574 INFO    : CGroups      : Available controllers:
2021-07-01 17:09:26,004 INFO    : CGroups      :   cpuset       : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:26,443 INFO    : CGroups      :   cpu          : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:26,878 INFO    : CGroups      :   cpuacct      : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:27,308 INFO    : CGroups      :   blkio        : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:27,747 INFO    : CGroups      :   memory       : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:28,210 INFO    : CGroups      :   devices      : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:28,877 INFO    : CGroups      :   freezer      : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:29,319 INFO    : CGroups      :   perf_event   : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:29,749 INFO    : CGroups      :   hugetlb      : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:30,200 INFO    : CGroups      :   pids         : /root/devlib-target/cgroups/devlib_cgh1
2021-07-01 17:09:30,331 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:09:33,663 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_170924_e999fea4ccb94f3889f8de836d4a7918/rta_calib_cpu0.json 2>&1
2021-07-01 17:09:40,224 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:09:40,782 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_170924_e999fea4ccb94f3889f8de836d4a7918
2021-07-01 17:09:41,039 INFO    : lisa.wlgen.rta.RTA : CPU0 calibration=335
2021-07-01 17:09:41,348 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_170941_ea3bba3f9ae6408ab7026db86fb3f3da
2021-07-01 17:09:41,676 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:09:44,843 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_170941_ea3bba3f9ae6408ab7026db86fb3f3da/rta_calib_cpu1.json 2>&1
2021-07-01 17:09:51,248 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:09:51,832 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_170941_ea3bba3f9ae6408ab7026db86fb3f3da
2021-07-01 17:09:52,091 INFO    : lisa.wlgen.rta.RTA : CPU1 calibration=206
2021-07-01 17:09:52,456 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_170952_37f23292cad449c19fba0c7d35b93e9c
2021-07-01 17:09:52,894 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:09:56,014 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_170952_37f23292cad449c19fba0c7d35b93e9c/rta_calib_cpu2.json 2>&1
2021-07-01 17:10:02,572 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:10:03,134 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_170952_37f23292cad449c19fba0c7d35b93e9c
2021-07-01 17:10:03,389 INFO    : lisa.wlgen.rta.RTA : CPU2 calibration=191
2021-07-01 17:10:03,722 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_171003_6ce86454f5f04772b0ed1641fa14f1f4
2021-07-01 17:10:04,030 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:10:07,140 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_171003_6ce86454f5f04772b0ed1641fa14f1f4/rta_calib_cpu3.json 2>&1
2021-07-01 17:10:13,801 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:10:14,380 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_171003_6ce86454f5f04772b0ed1641fa14f1f4
2021-07-01 17:10:14,624 INFO    : lisa.wlgen.rta.RTA : CPU3 calibration=335
2021-07-01 17:10:15,064 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_171014_41170e6e2b254b5084418c62243e247f
2021-07-01 17:10:15,367 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:10:18,450 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_171014_41170e6e2b254b5084418c62243e247f/rta_calib_cpu4.json 2>&1
2021-07-01 17:10:24,967 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:10:25,545 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_171014_41170e6e2b254b5084418c62243e247f
2021-07-01 17:10:25,809 INFO    : lisa.wlgen.rta.RTA : CPU4 calibration=335
2021-07-01 17:10:26,154 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_171025_3113de7c35de4ed191cef0d13122a690
2021-07-01 17:10:26,470 INFO    : lisa.target.Target : Freezing all tasks except: init,systemd[^-],dbus,sh,ssh,rsyslogd,jbd2
2021-07-01 17:10:29,547 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_171025_3113de7c35de4ed191cef0d13122a690/rta_calib_cpu5.json 2>&1
2021-07-01 17:10:36,132 INFO    : lisa.target.Target : Un-freezing userspace tasks
2021-07-01 17:10:36,709 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_171025_3113de7c35de4ed191cef0d13122a690
2021-07-01 17:10:36,975 INFO    : lisa.wlgen.rta.RTA : CPU5 calibration=335
2021-07-01 17:10:37,010 INFO    : lisa.wlgen.rta.RTA : Platform info rt-app calibration configuration:
platform-info:
    conf:
        cpu-capacities: {}
        kernel: {}
        rtapp:
            calib:
                0: 335
                1: 206
                2: 191
                3: 335
                4: 335
                5: 335

2021-07-01 17:10:37,043 INFO    : lisa.wlgen.rta.RTA : CPU capacities according to rt-app workload: {0: 606, 3: 606, 4: 606, 5: 606, 1: 1024, 2: 1024}
2021-07-01 17:10:37,044 WARNING : lisa.wlgen.rta.RTA : The calibration values are not inversely proportional to the CPU capacities, the duty cycles will be up to 35.87% off on some CPUs: {0: 135.8744394618834, 1: 100.0, 2: 100.0, 3: 135.8744394618834, 4: 135.8744394618834, 5: 135.8744394618834}
2021-07-01 17:10:37,045 WARNING : lisa.wlgen.rta.RTA : The calibration values are not inversely proportional to the CPU capacities. Either rt-app calibration failed, or the rt-app busy loops has a very different instruction mix compared to the workload used to establish the CPU capacities: {0: 135.8744394618834, 1: 100.0, 2: 100.0, 3: 135.8744394618834, 4: 135.8744394618834, 5: 135.8744394618834}
2021-07-01 17:10:37,045 INFO    : lisa.target.Target : Re-enabling idle states for all domains

Running the workload

[9]:
import os
from lisa.trace import FtraceCollector

We need to specify the trace events we want to record. We could list what’s available like so:

[10]:
available_events = target.execute("cat /sys/kernel/debug/tracing/available_events").splitlines()

# That's gonna be a pretty big list, let's focus on the scheduler events
sched_events = [
    event
    for event in available_events
    if (
        event.startswith("sched:") or
        event.startswith("task:")
    )
]
print(sched_events)
['task:task_rename', 'task:task_newtask', 'sched:sched_wake_idle_without_ipi', 'sched:sched_swap_numa', 'sched:sched_stick_numa', 'sched:sched_move_numa', 'sched:sched_pi_setprio', 'sched:sched_stat_runtime', 'sched:sched_stat_blocked', 'sched:sched_stat_iowait', 'sched:sched_stat_sleep', 'sched:sched_stat_wait', 'sched:sched_process_exec', 'sched:sched_process_fork', 'sched:sched_process_wait', 'sched:sched_wait_task', 'sched:sched_process_exit', 'sched:sched_process_free', 'sched:sched_migrate_task', 'sched:sched_switch', 'sched:sched_wakeup_new', 'sched:sched_wakeup', 'sched:sched_waking', 'sched:sched_kthread_work_execute_end', 'sched:sched_kthread_work_execute_start', 'sched:sched_kthread_work_queue_work', 'sched:sched_kthread_stop_ret', 'sched:sched_kthread_stop', 'sched:sched_cpu_capacity', 'sched:uclamp_util_cfs', 'sched:uclamp_util_se', 'sched:sched_util_est_cfs', 'sched:sched_util_est_se', 'sched:sched_overutilized', 'sched:sched_pelt_se', 'sched:sched_pelt_irq', 'sched:sched_pelt_dl', 'sched:sched_pelt_rt', 'sched:sched_pelt_cfs']

Let’s just collect the base events required to plot task scheduling:

[11]:
events = [
    'sched_switch',
    'sched_wakeup',
    'sched_wakeup_new',
    'task_rename',
]

And now we can actually record traces while running our workload:

[12]:
trace_path = os.path.join(wload.res_dir, "trace.dat")
ftrace_coll = FtraceCollector(target, events=events, buffer_size=10240, output_path=trace_path)

with wload, ftrace_coll:
    wload.run()
2021-07-01 17:10:49,741 INFO    : lisa.wlgen.rta.RTA : Created workload's run target directory: /root/devlib-target/lisa/wlgen/20210701_170915_915f1b7cc21d4dadb9eac4de0ec2f72e
2021-07-01 17:10:50,039 INFO    : lisa.wlgen.rta.RTA : Will update CPU capacities in sysfs: {0: 606, 3: 606, 4: 606, 5: 606, 1: 1024, 2: 1024}
2021-07-01 17:11:00,847 INFO    : lisa.wlgen.rta.RTA : Execution start: rt-app /root/devlib-target/lisa/wlgen/20210701_170915_915f1b7cc21d4dadb9eac4de0ec2f72e/experiment_workload.json 2>&1
2021-07-01 17:11:11,142 INFO    : lisa.wlgen.rta.RTA : Wiping target run directory: /root/devlib-target/lisa/wlgen/20210701_170915_915f1b7cc21d4dadb9eac4de0ec2f72e

Loading up the trace

We have a Trace class that lets us easily access trace events. It can also do some post-processing to provide different kinds of analysis.

[13]:
from lisa.trace import Trace

We also save some platform information (number of CPUs, available frequencies, kernel version…) that comes in handy for doing some analysis:

[14]:
print(target.plat_info)
|- abi from target (str): arm64
+- cpu-capacities:
    |- orig from target (dict): {0: 446, 1: 1024, 2: 1024, 3: 446, 4: 446, 5: 446}
    |- writeable from target (bool): True
    |- rtapp from target(platform-info/rtapp/calib),target(platform-info/cpu-capacities/orig),target(platform-info/cpu-capacities/writeable) (dict): {0: 606, 3: 606, 4: 606, 5: 606, 1: 1024, 2: 1024}
|- cpus-count from target (int): 6
|- freq-domains from target (list): [[0, 3, 4, 5], [1, 2]]
|- freqs from target (dict): {0: [450000, 575000, 700000, 775000, 850000], 1: [450000, 625000, 800000, 950000, 1100000], 2: [450000, 625000, 800000, 950000, 1100000], 3: [450000, 575000, 700000, 775000, 850000], 4: [450000, 575000, 700000, 775000, 850000], 5: [450000, 575000, 700000, 775000, 850000]}
+- kernel:
    |- config from target (TypedKernelConfig): <kernel config>
    |- symbols-address from target (DeferredValue): <symbols address>
    |- version from target (KernelVersion): 5.13.0-rc3-g5c95b23cc7dd 1 SMP PREEMPT Thu Jul 1 16:07:56 BST 2021
|- name from target-conf (str): juno-r0
|- nrg-model from target (LinuxEnergyModel): <lisa.energy_model.LinuxEnergyModel object at 0x7f598c1fccd0>
|- numa-nodes-count from target (int): 1
|- os from target (str): linux
+- rtapp:
    |- calib from target (dict): {0: 335, 1: 206, 2: 191, 3: 335, 4: 335, 5: 335}
|- capacity-classes from target(platform-info/cpu-capacities/orig) (list): [[0, 3, 4, 5], [1, 2]]

You can pass the platform info directly from the Target:

[15]:
trace_path = os.path.join(wload.res_dir, 'trace.dat')
trace = Trace(trace_path, target.plat_info, events=events)
2021-07-01 17:11:12,517 INFO    : lisa.platforms.platinfo.PlatformInfo : Attempting to read kallsyms from target

… But it’s a good idea to save it on the disk so that you can re-run whatever analysis code you want several months down the line after the platform was lost in a tragic fire.

It’s why we save this information somewhere instead of polling the target when we want to use them - we can run analysis code offline.

Here we show how to save to/restore this platform information from the disk.

[16]:
plat_info_path = os.path.join(wload.res_dir, "platinfo.yaml")
target.plat_info.to_yaml_map(plat_info_path)
[17]:
from lisa.platforms.platinfo import PlatformInfo
[18]:
plat_info = PlatformInfo.from_yaml_map(plat_info_path)
trace = Trace(trace_path, plat_info, events=events)

Looking at the trace

Kernelshark can be opened from the notebook:

[19]:
# trace.show()

Analysing the trace

Relevant documentation: https://tooling.sites.arm.com/lisa/latest/trace_analysis.html

Reading trace events

[20]:
df = trace.df_event("sched_switch")
df
[20]:
__comm __pid __cpu next_pid prev_comm prev_prio next_comm prev_pid next_prio prev_state
Time
2745.781282 trace-cmd 5635 0 3981 trace-cmd 120 sshd 5635 120 256
2745.781622 <idle> 0 5 12 swapper/5 120 rcu_preempt 0 120 0
2745.781709 sshd 3981 0 5635 sshd 120 trace-cmd 3981 120 2
2745.781749 rcu_preempt 12 5 0 rcu_preempt 120 swapper/5 12 120 128
2745.781848 trace-cmd 5635 0 3981 trace-cmd 120 sshd 5635 120 256
... ... ... ... ... ... ... ... ... ... ...
2747.986134 <idle> 0 3 12 swapper/3 120 rcu_preempt 0 120 0
2747.986260 rcu_preempt 12 3 0 rcu_preempt 120 swapper/3 12 120 128
2747.987432 <idle> 0 0 3981 swapper/0 120 sshd 0 120 0
2747.987845 sshd 3981 0 0 sshd 120 swapper/0 3981 120 1
2747.993821 <idle> 0 3 12 swapper/3 120 rcu_preempt 0 120 0

2644 rows × 10 columns

The standard DataFrame operations are available, so you can filter/slice it however you wish:

[21]:
df[df.next_comm == "tsk4_1"][1.5:2]
[21]:
__comm __pid __cpu next_pid prev_comm prev_prio next_comm prev_pid next_prio prev_state
Time

Using the trace analysis

Example dataframes

LISA ships a number of namespaced trace analysis methods. They can all be called on a trace with trace.ana.<analysis name>.<method name>(). They fall mostly into two categories: * Method starting with df_: returns a pandas DataFrame * Method starting with plot_: returns a holoviews element ready to be displayed

[22]:
trace.ana.tasks.df_tasks_runtime()
[22]:
runtime comm
pid
0 1.389661 swapper/4
5659 0.362221 tsk2_0-6
5662 0.361775 tsk3_0-9
5657 0.356759 tsk1_1-4
5658 0.351268 tsk1_2-5
5670 0.332309 tsk5_2-17
5654 0.331242 tsk0_1-1
5669 0.330871 tsk5_1-16
5664 0.319778 tsk3_2-11
5655 0.316757 tsk0_2-2
5668 0.308678 tsk5_0-15
5661 0.279637 tsk2_2-8
5663 0.269628 tsk3_1-10
5660 0.267880 tsk2_1-7
5656 0.263531 tsk1_0-3
5667 0.260929 tsk4_2-14
5666 0.252416 tsk4_1-13
5665 0.239848 tsk4_0-12
5653 0.227776 tsk0_0-0
3981 0.108538 sshd
5652 0.078533 rt-app
5639 0.077796 shutils
5637 0.064597 shutils
5671 0.063522 shutils
5674 0.048984 sh
5636 0.045780 sh
5673 0.045675 sh
5640 0.026702 true
5648 0.025580 true
5646 0.025421 true
5650 0.024910 true
5638 0.023517 busybox
5644 0.022757 true
5672 0.020670 busybox
5642 0.020435 true
12 0.015584 rcu_preempt
5641 0.014737 busybox
5649 0.014633 busybox
5647 0.013716 busybox
5643 0.012695 busybox
5645 0.012236 busybox
5651 0.008759 busybox
1 0.001109 init
10 0.001085 kworker/0:1
11 0.000950 ksoftirqd/0
46 0.000875 kworker/4:1
5635 0.000815 trace-cmd
26 0.000666 migration/3
47 0.000633 kworker/5:1
44 0.000618 kworker/2:1
3980 0.000540 kworker/u12:0
36 0.000439 migration/5
45 0.000385 kworker/3:1
22 0.000329 ksoftirqd/2
126 0.000307 kworker/1:2
51 0.000286 kcompactd0
31 0.000282 migration/4
[23]:
df = trace.ana.tasks.df_task_states("tsk4_1-13", stringify=True)
df

[23]:
target_cpu cpu curr_state next_state delta curr_state_str next_state_str
Time
2746.543802 -1 3.0 1 512 0.011418 S W
2746.555220 2 2.0 512 8192 0.000046 W A
2746.555266 -1 2.0 8192 256 0.000061 A
2746.555327 -1 2.0 256 8192 0.000157 A
2746.555484 -1 2.0 8192 1 0.000071 A S
... ... ... ... ... ... ... ...
2747.530640 -1 2.0 8192 1 0.003432 A S
2747.534072 -1 2.0 1 512 0.012552 S W
2747.546624 2 2.0 512 8192 0.000019 W A
2747.546642 -1 2.0 8192 16 0.000205 A X
2747.546847 -1 2.0 16 -1 NaN X U

211 rows × 7 columns

The trace.ana object can be used to set default values to analysis methods. Simply calling it with keyword arguments will set default values, which can later be overridden when the method is called if necessary.

This avoids repetition of fixed parameters such as ŧask, tasks, cpu etc. Just be careful as some methods might take more parameters than you expect: some task-related methods also accept a cpu parameter to restrict to a given CPU, so it might be a good idea to have a proxy object for all CPU-related calls and another one for task-related calls.

[24]:
ana = trace.ana(task='tsk4_1-13')

df = ana.tasks.df_task_states(stringify=True)

# Default values can be overridden by calling it again
ana2 = ana(task='trace-cmd')
# And overridden again when calling the method
df = ana2.tasks.df_task_states(task='tsk4_1-13', stringify=True)
[25]:
from lisa.analysis.tasks import TaskState
[26]:
df[df.curr_state == TaskState.TASK_ACTIVE][1:1.2]
[26]:
target_cpu cpu curr_state next_state delta curr_state_str next_state_str
Time

Example plots

[30]:
import holoviews as hv
# Before rendering any plot, a plotting backend for holoviews has to be chosen.
# Bokeh provides much better interactive (and HTML) plots than matplotlib.

# THIS MUST BE DONE AFTER ALL IMPORTS.
# Otherwise there might be issues that lead to
# not displaying plots until hv.extension() is called again.

hv.extension('bokeh')
[31]:
trace.ana.tasks.plot_task_total_residency("tsk4_1-13")
[31]:
[35]:
trace.ana.tasks.plot_tasks_wakeups_heatmap(bins=200)
[35]:
[36]:
trace.ana.tasks.plot_tasks_forks_heatmap(bins=200)
[36]:
[ ]: