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

Reply via email to