Thank you for the update, Kazu. On Wed, Jul 12, 2023 at 4:55 PM <crash-utility-requ...@redhat.com> wrote:
> Date: Wed, 12 Jul 2023 08:55:29 +0000 > From: HAGIO KAZUHITO(?????) <k-hagio...@nec.com> > To: "crash-utility@redhat.com" <crash-utility@redhat.com> > Cc: "liji...@redhat.com" <liji...@redhat.com> > Subject: [Crash-utility] [PATCH v2 2/2] Fix "irq [-a|-s]" options on > Linux 6.5-rc1 and later > Message-ID: <1689152127-28057-1-git-send-email-k-hagio...@nec.com> > Content-Type: text/plain; charset="iso-2022-jp" > > From: Kazuhito Hagio <k-hagio...@nec.com> > > Kernel commit 721255b982 ("genirq: Use a maple tree for interrupt > descriptor management"), which is contained in Linux 6.5-rc1 and later > kernels, replaced irq_desc_tree with a maple tree sparse_irqs. > > Without the patch, "irq [-a|-s]" options fail with an error, e.g. the > following on x86_64, on kernels configured with CONFIG_SPARSE_IRQ=y. > > crash> irq > irq: x86_64_dump_irq: irq_desc[] or irq_desc_tree do not exist? > > Signed-off-by: Kazuhito Hagio <k-hagio...@nec.com> > --- > v1 -> v2 > - Fixed a typo in the commit log: s/SPARSE_IRQS/SPARSE_IRQ/ > - Reverted the unintendedly removed line in x86_64_show_interrupts() > - Added sparse_irqs support to ia64_dump_irq() > > The v2 looks good to me. For the patches: Ack [1] [PATCH 1/2] Exclude NULL entries from do_maple_tree() return value <https://listman.redhat.com/archives/crash-utility/2023-July/010832.html> [2] [PATCH v2 2/2] Fix "irq [-a|-s]" options on Linux 6.5-rc1 and later <https://listman.redhat.com/archives/crash-utility/2023-July/010847.html> Thanks. Lianbo defs.h | 2 ++ > ia64.c | 3 ++- > kernel.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- > symbols.c | 1 + > x86_64.c | 9 ++++++--- > 5 files changed, 59 insertions(+), 7 deletions(-) > > diff --git a/defs.h b/defs.h > index 26afe232cc3e..358f365585cf 100644 > --- a/defs.h > +++ b/defs.h > @@ -676,6 +676,7 @@ struct new_utsname { > #define IRQ_DESC_TREE_XARRAY (0x80ULL) > #define KMOD_PAX (0x100ULL) > #define KMOD_MEMORY (0x200ULL) > +#define IRQ_DESC_TREE_MAPLE (0x400ULL) > > #define XEN() (kt->flags & ARCH_XEN) > #define OPENVZ() (kt->flags & ARCH_OPENVZ) > @@ -2222,6 +2223,7 @@ struct offset_table { /* stash of > commonly-used offsets */ > long module_mem; > long module_memory_base; > long module_memory_size; > + long irq_data_irq; > }; > > struct size_table { /* stash of commonly-used sizes */ > diff --git a/ia64.c b/ia64.c > index 2e1d15fe6042..d3e0a3b01869 100644 > --- a/ia64.c > +++ b/ia64.c > @@ -791,7 +791,8 @@ ia64_back_trace_cmd(struct bt_info *bt) > static void > ia64_dump_irq(int irq) > { > - if (symbol_exists("irq_desc") || symbol_exists("_irq_desc") || > + if (kernel_symbol_exists("sparse_irqs") || > + symbol_exists("irq_desc") || symbol_exists("_irq_desc") || > kernel_symbol_exists("irq_desc_ptrs")) { > machdep->dump_irq = generic_dump_irq; > return(generic_dump_irq(irq)); > diff --git a/kernel.c b/kernel.c > index 0fc77c19f12a..546eed95eebd 100644 > --- a/kernel.c > +++ b/kernel.c > @@ -541,7 +541,10 @@ kernel_init() > MEMBER_OFFSET_INIT(irqaction_dev_id, "irqaction", "dev_id"); > MEMBER_OFFSET_INIT(irqaction_next, "irqaction", "next"); > > - if (kernel_symbol_exists("irq_desc_tree")) { > + /* 6.5 and later: CONFIG_SPARSE_IRQ */ > + if (kernel_symbol_exists("sparse_irqs")) > + kt->flags2 |= IRQ_DESC_TREE_MAPLE; > + else if (kernel_symbol_exists("irq_desc_tree")) { > get_symbol_type("irq_desc_tree", NULL, &req); > if (STREQ(req.type_tag_name, "xarray")) { > kt->flags2 |= IRQ_DESC_TREE_XARRAY; > @@ -554,6 +557,7 @@ kernel_init() > } > STRUCT_SIZE_INIT(irq_data, "irq_data"); > if (VALID_STRUCT(irq_data)) { > + MEMBER_OFFSET_INIT(irq_data_irq, "irq_data", "irq"); > MEMBER_OFFSET_INIT(irq_data_chip, "irq_data", "chip"); > MEMBER_OFFSET_INIT(irq_data_affinity, "irq_data", > "affinity"); > MEMBER_OFFSET_INIT(irq_desc_irq_data, "irq_desc", > "irq_data"); > @@ -6180,6 +6184,8 @@ dump_kernel_table(int verbose) > fprintf(fp, "%sIRQ_DESC_TREE_RADIX", others++ ? "|" : ""); > if (kt->flags2 & IRQ_DESC_TREE_XARRAY) > fprintf(fp, "%sIRQ_DESC_TREE_XARRAY", others++ ? "|" : ""); > + if (kt->flags2 & IRQ_DESC_TREE_MAPLE) > + fprintf(fp, "%sIRQ_DESC_TREE_MAPLE", others++ ? "|" : ""); > if (kt->flags2 & KMOD_PAX) > fprintf(fp, "%sKMOD_PAX", others++ ? "|" : ""); > if (kt->flags2 & KMOD_MEMORY) > @@ -6652,6 +6658,45 @@ get_irq_desc_addr(int irq) > readmem(ptr, KVADDR, &addr, > sizeof(void *), "irq_desc_ptrs entry", > FAULT_ON_ERROR); > + } else if (kt->flags2 & IRQ_DESC_TREE_MAPLE) { > + unsigned int i; > + > + if (kt->highest_irq && (irq > kt->highest_irq)) > + return addr; > + > + cnt = do_maple_tree(symbol_value("sparse_irqs"), > MAPLE_TREE_COUNT, NULL); > + > + len = sizeof(struct list_pair) * (cnt+1); > + lp = (struct list_pair *)GETBUF(len); > + lp[0].index = cnt; /* maxcount */ > + > + cnt = do_maple_tree(symbol_value("sparse_irqs"), > MAPLE_TREE_GATHER, lp); > + > + /* > + * NOTE: We cannot use lp.index like Radix Tree or XArray > because > + * it's not an absolute index and just counter in Maple > Tree. > + */ > + if (kt->highest_irq == 0) { > + readmem((ulong)lp[cnt-1].value + > + OFFSET(irq_desc_irq_data) + > OFFSET(irq_data_irq), > + KVADDR, &kt->highest_irq, sizeof(int), > "irq_data.irq", > + FAULT_ON_ERROR); > + } > + > + for (c = 0; c < cnt; c++) { > + readmem((ulong)lp[c].value + > + OFFSET(irq_desc_irq_data) + > OFFSET(irq_data_irq), > + KVADDR, &i, sizeof(int), "irq_data.irq", > FAULT_ON_ERROR); > + if (i == irq) { > + if (CRASHDEBUG(1)) > + fprintf(fp, "index: %d value: > %lx\n", > + i, (ulong)lp[c].value); > + addr = (ulong)lp[c].value; > + break; > + } > + } > + FREEBUF(lp); > + > } else if (kt->flags2 & > (IRQ_DESC_TREE_RADIX|IRQ_DESC_TREE_XARRAY)) { > if (kt->highest_irq && (irq > kt->highest_irq)) > return addr; > @@ -6700,8 +6745,8 @@ get_irq_desc_addr(int irq) > FREEBUF(lp); > } else { > error(FATAL, > - "neither irq_desc, _irq_desc, irq_desc_ptrs " > - "or irq_desc_tree symbols exist\n"); > + "neither irq_desc, _irq_desc, irq_desc_ptrs, " > + "irq_desc_tree or sparse_irqs symbols exist\n"); > } > > return addr; > diff --git a/symbols.c b/symbols.c > index 82529a6785c9..876be7aea90e 100644 > --- a/symbols.c > +++ b/symbols.c > @@ -10375,6 +10375,7 @@ dump_offset_table(char *spec, ulong makestruct) > OFFSET(irq_desc_t_kstat_irqs)); > fprintf(fp, " irq_desc_t_affinity: %ld\n", > OFFSET(irq_desc_t_affinity)); > + fprintf(fp, " irq_data_irq: %ld\n", > OFFSET(irq_data_irq)); > fprintf(fp, " irq_data_chip: %ld\n", > OFFSET(irq_data_chip)); > fprintf(fp, " irq_data_affinity: %ld\n", > diff --git a/x86_64.c b/x86_64.c > index 87e87ae6e1e8..42ade4817ad9 100644 > --- a/x86_64.c > +++ b/x86_64.c > @@ -5391,7 +5391,8 @@ get_x86_64_frame(struct bt_info *bt, ulong *getpc, > ulong *getsp) > static void > x86_64_dump_irq(int irq) > { > - if (symbol_exists("irq_desc") || > + if (kernel_symbol_exists("sparse_irqs") || > + symbol_exists("irq_desc") || > kernel_symbol_exists("irq_desc_ptrs") || > kernel_symbol_exists("irq_desc_tree")) { > machdep->dump_irq = generic_dump_irq; > @@ -5405,7 +5406,8 @@ x86_64_dump_irq(int irq) > static void > x86_64_get_irq_affinity(int irq) > { > - if (symbol_exists("irq_desc") || > + if (kernel_symbol_exists("sparse_irqs") || > + symbol_exists("irq_desc") || > kernel_symbol_exists("irq_desc_ptrs") || > kernel_symbol_exists("irq_desc_tree")) { > machdep->get_irq_affinity = generic_get_irq_affinity; > @@ -5419,7 +5421,8 @@ x86_64_get_irq_affinity(int irq) > static void > x86_64_show_interrupts(int irq, ulong *cpus) > { > - if (symbol_exists("irq_desc") || > + if (kernel_symbol_exists("sparse_irqs") || > + symbol_exists("irq_desc") || > kernel_symbol_exists("irq_desc_ptrs") || > kernel_symbol_exists("irq_desc_tree")) { > machdep->show_interrupts = generic_show_interrupts; > -- > 2.31.1 >
-- Crash-utility mailing list Crash-utility@redhat.com https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki