xref: /linux/tools/sched/root_domains_dump.py (revision bf76f23aa1c178e9115eba17f699fa726aed669b)
1*9fdb12c8SJuri Lelli#!/usr/bin/env drgn
2*9fdb12c8SJuri Lelli# SPDX-License-Identifier: GPL-2.0
3*9fdb12c8SJuri Lelli# Copyright (C) 2025 Juri Lelli <juri.lelli@redhat.com>
4*9fdb12c8SJuri Lelli# Copyright (C) 2025 Red Hat, Inc.
5*9fdb12c8SJuri Lelli
6*9fdb12c8SJuri Lellidesc = """
7*9fdb12c8SJuri LelliThis is a drgn script to show the current root domains configuration. For more
8*9fdb12c8SJuri Lelliinfo on drgn, visit https://github.com/osandov/drgn.
9*9fdb12c8SJuri Lelli
10*9fdb12c8SJuri LelliRoot domains are only printed once, as multiple CPUs might be attached to the
11*9fdb12c8SJuri Lellisame root domain.
12*9fdb12c8SJuri Lelli"""
13*9fdb12c8SJuri Lelli
14*9fdb12c8SJuri Lelliimport os
15*9fdb12c8SJuri Lelliimport argparse
16*9fdb12c8SJuri Lelli
17*9fdb12c8SJuri Lelliimport drgn
18*9fdb12c8SJuri Lellifrom drgn import FaultError
19*9fdb12c8SJuri Lellifrom drgn.helpers.common import *
20*9fdb12c8SJuri Lellifrom drgn.helpers.linux import *
21*9fdb12c8SJuri Lelli
22*9fdb12c8SJuri Lellidef print_root_domains_info():
23*9fdb12c8SJuri Lelli
24*9fdb12c8SJuri Lelli    # To store unique root domains found
25*9fdb12c8SJuri Lelli    seen_root_domains = set()
26*9fdb12c8SJuri Lelli
27*9fdb12c8SJuri Lelli    print("Retrieving (unique) Root Domain Information:")
28*9fdb12c8SJuri Lelli
29*9fdb12c8SJuri Lelli    runqueues = prog['runqueues']
30*9fdb12c8SJuri Lelli    def_root_domain = prog['def_root_domain']
31*9fdb12c8SJuri Lelli
32*9fdb12c8SJuri Lelli    for cpu_id in for_each_possible_cpu(prog):
33*9fdb12c8SJuri Lelli        try:
34*9fdb12c8SJuri Lelli            rq = per_cpu(runqueues, cpu_id)
35*9fdb12c8SJuri Lelli
36*9fdb12c8SJuri Lelli            root_domain = rq.rd
37*9fdb12c8SJuri Lelli
38*9fdb12c8SJuri Lelli            # Check if we've already processed this root domain to avoid duplicates
39*9fdb12c8SJuri Lelli            # Use the memory address of the root_domain as a unique identifier
40*9fdb12c8SJuri Lelli            root_domain_cast = int(root_domain)
41*9fdb12c8SJuri Lelli            if root_domain_cast in seen_root_domains:
42*9fdb12c8SJuri Lelli                continue
43*9fdb12c8SJuri Lelli            seen_root_domains.add(root_domain_cast)
44*9fdb12c8SJuri Lelli
45*9fdb12c8SJuri Lelli            if root_domain_cast == int(def_root_domain.address_):
46*9fdb12c8SJuri Lelli                print(f"\n--- Root Domain @ def_root_domain ---")
47*9fdb12c8SJuri Lelli            else:
48*9fdb12c8SJuri Lelli                print(f"\n--- Root Domain @ 0x{root_domain_cast:x} ---")
49*9fdb12c8SJuri Lelli
50*9fdb12c8SJuri Lelli            print(f"  From CPU: {cpu_id}") # This CPU belongs to this root domain
51*9fdb12c8SJuri Lelli
52*9fdb12c8SJuri Lelli            # Access and print relevant fields from struct root_domain
53*9fdb12c8SJuri Lelli            print(f"  Span       : {cpumask_to_cpulist(root_domain.span[0])}")
54*9fdb12c8SJuri Lelli            print(f"  Online     : {cpumask_to_cpulist(root_domain.span[0])}")
55*9fdb12c8SJuri Lelli
56*9fdb12c8SJuri Lelli        except drgn.FaultError as fe:
57*9fdb12c8SJuri Lelli            print(f"  (CPU {cpu_id}: Fault accessing kernel memory: {fe})")
58*9fdb12c8SJuri Lelli        except AttributeError as ae:
59*9fdb12c8SJuri Lelli            print(f"  (CPU {cpu_id}: Missing attribute for root_domain (kernel struct change?): {ae})")
60*9fdb12c8SJuri Lelli        except Exception as e:
61*9fdb12c8SJuri Lelli            print(f"  (CPU {cpu_id}: An unexpected error occurred: {e})")
62*9fdb12c8SJuri Lelli
63*9fdb12c8SJuri Lelliif __name__ == "__main__":
64*9fdb12c8SJuri Lelli    parser = argparse.ArgumentParser(description=desc,
65*9fdb12c8SJuri Lelli                                     formatter_class=argparse.RawTextHelpFormatter)
66*9fdb12c8SJuri Lelli    args = parser.parse_args()
67*9fdb12c8SJuri Lelli
68*9fdb12c8SJuri Lelli    print_root_domains_info()
69