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