|
7 | 7 | from typing import Any |
8 | 8 | from typing import Iterator |
9 | 9 | from typing import List |
| 10 | +from typing import Tuple |
10 | 11 |
|
11 | 12 | from drgn import NULL |
12 | 13 | from drgn import Object |
13 | 14 | from drgn import Program |
14 | 15 | from drgn.helpers.common.format import escape_ascii_string |
15 | 16 | from drgn.helpers.linux.cpumask import for_each_present_cpu |
| 17 | +from drgn.helpers.linux.mapletree import mtree_load |
16 | 18 | from drgn.helpers.linux.percpu import per_cpu_ptr |
17 | 19 | from drgn.helpers.linux.radixtree import radix_tree_lookup |
18 | 20 |
|
|
22 | 24 | from drgn_tools.util import uek4_radix_tree_lookup |
23 | 25 |
|
24 | 26 |
|
25 | | -def _sparse_irq_supported(prog: Program) -> bool: |
| 27 | +def _sparse_irq_supported(prog: Program) -> Tuple[bool, str]: |
26 | 28 | try: |
27 | | - _ = prog["irq_desc_tree"] |
28 | | - return True |
| 29 | + # Since Linux kernel commit 721255b9826b ("genirq: Use a maple |
| 30 | + # tree for interrupt descriptor management") (in v6.5), sparse |
| 31 | + # irq descriptors are stored in a maple tree. |
| 32 | + _ = prog["sparse_irqs"] |
| 33 | + return True, "maple" |
29 | 34 | except KeyError: |
30 | | - return False |
| 35 | + # Before that, they are in radix tree. |
| 36 | + try: |
| 37 | + _ = prog["irq_desc_tree"] |
| 38 | + return True, "radix" |
| 39 | + except KeyError: |
| 40 | + return False, "" |
31 | 41 |
|
32 | 42 |
|
33 | 43 | def _kstat_irqs_cpu(prog: Program, irq: int, cpu: int) -> int: |
@@ -139,18 +149,24 @@ def irq_to_desc(prog: Program, irq: int) -> Object: |
139 | 149 | :return: ``struct irq_desc *`` object if irq descriptor is found. |
140 | 150 | NULL otherwise |
141 | 151 | """ |
142 | | - if _sparse_irq_supported(prog): |
143 | | - try: |
144 | | - if prog.type("struct radix_tree_node").has_member("shift"): |
| 152 | + _, tree_type = _sparse_irq_supported(prog) |
| 153 | + if tree_type: |
| 154 | + if tree_type == "radix": |
| 155 | + try: |
| 156 | + if prog.type("struct radix_tree_node").has_member("shift"): |
| 157 | + addr = radix_tree_lookup( |
| 158 | + prog["irq_desc_tree"].address_of_(), irq |
| 159 | + ) |
| 160 | + else: |
| 161 | + addr = uek4_radix_tree_lookup( |
| 162 | + prog["irq_desc_tree"].address_of_(), irq |
| 163 | + ) |
| 164 | + except LookupError: |
145 | 165 | addr = radix_tree_lookup( |
146 | 166 | prog["irq_desc_tree"].address_of_(), irq |
147 | 167 | ) |
148 | | - else: |
149 | | - addr = uek4_radix_tree_lookup( |
150 | | - prog["irq_desc_tree"].address_of_(), irq |
151 | | - ) |
152 | | - except LookupError: |
153 | | - addr = radix_tree_lookup(prog["irq_desc_tree"].address_of_(), irq) |
| 168 | + else: |
| 169 | + addr = mtree_load(prog["sparse_irqs"].address_of_(), irq) |
154 | 170 |
|
155 | 171 | if addr: |
156 | 172 | return Object(prog, "struct irq_desc", address=addr).address_of_() |
|
0 commit comments