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