Subject: Re: [PATCH 07/13] powerpc/xive: Add a debug_show handler to the XIVE irq_domain

From: Greg Kurz <[email-masked]>
Date: Wed, 9 Dec 2020 16:50:35 +0100

On Tue, 8 Dec 2020 16:11:18 +0100
Cédric Le Goater <[email-masked]> wrote:

> Full state of the Linux interrupt descriptors can be dumped under
> debugfs when compiled with CONFIG_GENERIC_IRQ_DEBUGFS. Add support for
> the XIVE interrupt controller.
> 
> Signed-off-by: Cédric Le Goater <[email-masked]>
> ---
>  arch/powerpc/sysdev/xive/common.c | 58 +++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
> 
> diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
> index 721617f0f854..411cba12d73b 100644
> --- a/arch/powerpc/sysdev/xive/common.c
> +++ b/arch/powerpc/sysdev/xive/common.c
> @@ -1303,11 +1303,69 @@ static int xive_irq_domain_match(struct irq_domain *h, struct device_node *node,
>  	return xive_ops->match(node);
>  }
>  
> +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
> +static const char * const esb_names[] = { "RESET", "OFF", "PENDING", "QUEUED" };
> +
> +static const struct {
> +	u64  mask;
> +	char *name;
> +} xive_irq_flags[] = {
> +	{ XIVE_IRQ_FLAG_STORE_EOI, "STORE_EOI" },
> +	{ XIVE_IRQ_FLAG_LSI,       "LSI"       },

> +	{ XIVE_IRQ_FLAG_SHIFT_BUG, "SHIFT_BUG" },
> +	{ XIVE_IRQ_FLAG_MASK_FW,   "MASK_FW"   },
> +	{ XIVE_IRQ_FLAG_EOI_FW,    "EOI_FW"    },

If seems that you don't even need these ^^ if you move this patch after
patch 11 actually.

> +	{ XIVE_IRQ_FLAG_H_INT_ESB, "H_INT_ESB" },
> +	{ XIVE_IRQ_FLAG_NO_EOI,    "NO_EOI"    },
> +};
> +
> +static void xive_irq_domain_debug_show(struct seq_file *m, struct irq_domain *d,
> +				       struct irq_data *irqd, int ind)
> +{
> +	struct xive_irq_data *xd;
> +	u64 val;
> +	int i;
> +
> +	/* No IRQ domain level information. To be done */
> +	if (!irqd)
> +		return;
> +
> +	if (!is_xive_irq(irq_data_get_irq_chip(irqd)))

Wouldn't it be a bug to get anything else but the XIVE irqchip here ?

WARN_ON_ONCE() ?

> +		return;
> +
> +	seq_printf(m, "%*sXIVE:\n", ind, "");
> +	ind++;
> +
> +	xd = irq_data_get_irq_handler_data(irqd);
> +	if (!xd) {
> +		seq_printf(m, "%*snot assigned\n", ind, "");
> +		return;
> +	}
> +
> +	val = xive_esb_read(xd, XIVE_ESB_GET);
> +	seq_printf(m, "%*sESB:      %s\n", ind, "", esb_names[val & 0x3]);
> +	seq_printf(m, "%*sPstate:   %s %s\n", ind, "", xd->stale_p ? "stale" : "",
> +		   xd->saved_p ? "saved" : "");
> +	seq_printf(m, "%*sTarget:   %d\n", ind, "", xd->target);
> +	seq_printf(m, "%*sChip:     %d\n", ind, "", xd->src_chip);
> +	seq_printf(m, "%*sTrigger:  0x%016llx\n", ind, "", xd->trig_page);
> +	seq_printf(m, "%*sEOI:      0x%016llx\n", ind, "", xd->eoi_page);
> +	seq_printf(m, "%*sFlags:    0x%llx\n", ind, "", xd->flags);
> +	for (i = 0; i < ARRAY_SIZE(xive_irq_flags); i++) {
> +		if (xd->flags & xive_irq_flags[i].mask)
> +			seq_printf(m, "%*s%s\n", ind + 12, "", xive_irq_flags[i].name);
> +	}
> +}
> +#endif
> +
>  static const struct irq_domain_ops xive_irq_domain_ops = {
>  	.match = xive_irq_domain_match,
>  	.map = xive_irq_domain_map,
>  	.unmap = xive_irq_domain_unmap,
>  	.xlate = xive_irq_domain_xlate,
> +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
> +	.debug_show = xive_irq_domain_debug_show,
> +#endif
>  };
>  
>  static void __init xive_init_host(struct device_node *np)