1*0304a3b7STomas Glozar#!/usr/bin/env python3 2*0304a3b7STomas Glozar# SPDX-License-Identifier: GPL-2.0-only 3*0304a3b7STomas Glozar# 4*0304a3b7STomas Glozar# Copyright (C) 2024 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org> 5*0304a3b7STomas Glozar# 6*0304a3b7STomas Glozar# This is a sample code about how to use timerlat's timer by any workload 7*0304a3b7STomas Glozar# so rtla can measure and provide auto-analysis for the overall latency (IOW 8*0304a3b7STomas Glozar# the response time) for a task. 9*0304a3b7STomas Glozar# 10*0304a3b7STomas Glozar# Before running it, you need to dispatch timerlat with -U option in a terminal. 11*0304a3b7STomas Glozar# Then # run this script pinned to a CPU on another terminal. For example: 12*0304a3b7STomas Glozar# 13*0304a3b7STomas Glozar# timerlat_load.py 1 -p 95 14*0304a3b7STomas Glozar# 15*0304a3b7STomas Glozar# The "Timerlat IRQ" is the IRQ latency, The thread latency is the latency 16*0304a3b7STomas Glozar# for the python process to get the CPU. The Ret from user Timer Latency is 17*0304a3b7STomas Glozar# the overall latency. In other words, it is the response time for that 18*0304a3b7STomas Glozar# activation. 19*0304a3b7STomas Glozar# 20*0304a3b7STomas Glozar# This is just an example, the load is reading 20MB of data from /dev/full 21*0304a3b7STomas Glozar# It is in python because it is easy to read :-) 22*0304a3b7STomas Glozar 23*0304a3b7STomas Glozarimport argparse 24*0304a3b7STomas Glozarimport sys 25*0304a3b7STomas Glozarimport os 26*0304a3b7STomas Glozar 27*0304a3b7STomas Glozarparser = argparse.ArgumentParser(description='user-space timerlat thread in Python') 28*0304a3b7STomas Glozarparser.add_argument("cpu", type=int, help='CPU to run timerlat thread') 29*0304a3b7STomas Glozarparser.add_argument("-p", "--prio", type=int, help='FIFO priority') 30*0304a3b7STomas Glozarargs = parser.parse_args() 31*0304a3b7STomas Glozar 32*0304a3b7STomas Glozartry: 33*0304a3b7STomas Glozar affinity_mask = {args.cpu} 34*0304a3b7STomas Glozar os.sched_setaffinity(0, affinity_mask) 35*0304a3b7STomas Glozarexcept Exception as e: 36*0304a3b7STomas Glozar print(f"Error setting affinity: {e}") 37*0304a3b7STomas Glozar sys.exit(1) 38*0304a3b7STomas Glozar 39*0304a3b7STomas Glozarif args.prio: 40*0304a3b7STomas Glozar try: 41*0304a3b7STomas Glozar param = os.sched_param(args.prio) 42*0304a3b7STomas Glozar os.sched_setscheduler(0, os.SCHED_FIFO, param) 43*0304a3b7STomas Glozar except Exception as e: 44*0304a3b7STomas Glozar print(f"Error setting priority: {e}") 45*0304a3b7STomas Glozar sys.exit(1) 46*0304a3b7STomas Glozar 47*0304a3b7STomas Glozartry: 48*0304a3b7STomas Glozar timerlat_path = f"/sys/kernel/tracing/osnoise/per_cpu/cpu{args.cpu}/timerlat_fd" 49*0304a3b7STomas Glozar timerlat_fd = open(timerlat_path, 'r') 50*0304a3b7STomas Glozarexcept PermissionError: 51*0304a3b7STomas Glozar print("Permission denied. Please check your access rights.") 52*0304a3b7STomas Glozar sys.exit(1) 53*0304a3b7STomas Glozarexcept OSError: 54*0304a3b7STomas Glozar print("Error opening timerlat fd, did you run timerlat -U?") 55*0304a3b7STomas Glozar sys.exit(1) 56*0304a3b7STomas Glozar 57*0304a3b7STomas Glozartry: 58*0304a3b7STomas Glozar data_fd = open("/dev/full", 'r') 59*0304a3b7STomas Glozarexcept Exception as e: 60*0304a3b7STomas Glozar print(f"Error opening data fd: {e}") 61*0304a3b7STomas Glozar sys.exit(1) 62*0304a3b7STomas Glozar 63*0304a3b7STomas Glozarwhile True: 64*0304a3b7STomas Glozar try: 65*0304a3b7STomas Glozar timerlat_fd.read(1) 66*0304a3b7STomas Glozar data_fd.read(20 * 1024 * 1024) 67*0304a3b7STomas Glozar except KeyboardInterrupt: 68*0304a3b7STomas Glozar print("Leaving") 69*0304a3b7STomas Glozar break 70*0304a3b7STomas Glozar except IOError as e: 71*0304a3b7STomas Glozar print(f"I/O error occurred: {e}") 72*0304a3b7STomas Glozar break 73*0304a3b7STomas Glozar except Exception as e: 74*0304a3b7STomas Glozar print(f"Unexpected error: {e}") 75*0304a3b7STomas Glozar break 76*0304a3b7STomas Glozar 77*0304a3b7STomas Glozartimerlat_fd.close() 78*0304a3b7STomas Glozardata_fd.close() 79