From 44b9c8ddcbc351d47ead974f0870d09bfc74b3f7 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:26 +0100 Subject: powerpc/xive: Replace pr_devel() by pr_debug() to ease debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These routines are not on hot code paths and pr_debug() is easier to activate. Also add a '0x' prefix to hex printed values (HW IRQ number). Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-2-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 7b69299c2912..442642be3505 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -451,6 +451,8 @@ static void xive_do_source_set_mask(struct xive_irq_data *xd, { u64 val; + pr_debug("%s: HW 0x%x %smask\n", __func__, xd->hw_irq, mask ? "" : "un"); + /* * If the interrupt had P set, it may be in a queue. * @@ -612,8 +614,8 @@ static unsigned int xive_irq_startup(struct irq_data *d) xd->saved_p = false; xd->stale_p = false; - pr_devel("xive_irq_startup: irq %d [0x%x] data @%p\n", - d->irq, hw_irq, d); + + pr_debug("%s: irq %d [0x%x] data @%p\n", __func__, d->irq, hw_irq, d); /* Pick a target */ target = xive_pick_irq_target(d, irq_data_get_affinity_mask(d)); @@ -654,8 +656,7 @@ static void xive_irq_shutdown(struct irq_data *d) struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); - pr_devel("xive_irq_shutdown: irq %d [0x%x] data @%p\n", - d->irq, hw_irq, d); + pr_debug("%s: irq %d [0x%x] data @%p\n", __func__, d->irq, hw_irq, d); if (WARN_ON(xd->target == XIVE_INVALID_TARGET)) return; @@ -679,7 +680,7 @@ static void xive_irq_unmask(struct irq_data *d) { struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); - pr_devel("xive_irq_unmask: irq %d data @%p\n", d->irq, xd); + pr_debug("%s: irq %d data @%p\n", __func__, d->irq, xd); xive_do_source_set_mask(xd, false); } @@ -688,7 +689,7 @@ static void xive_irq_mask(struct irq_data *d) { struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); - pr_devel("xive_irq_mask: irq %d data @%p\n", d->irq, xd); + pr_debug("%s: irq %d data @%p\n", __func__, d->irq, xd); xive_do_source_set_mask(xd, true); } @@ -702,7 +703,7 @@ static int xive_irq_set_affinity(struct irq_data *d, u32 target, old_target; int rc = 0; - pr_debug("%s: irq %d/%x\n", __func__, d->irq, hw_irq); + pr_debug("%s: irq %d/0x%x\n", __func__, d->irq, hw_irq); /* Is this valid ? */ if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) @@ -975,7 +976,7 @@ EXPORT_SYMBOL_GPL(is_xive_irq); void xive_cleanup_irq_data(struct xive_irq_data *xd) { - pr_debug("%s for HW %x\n", __func__, xd->hw_irq); + pr_debug("%s for HW 0x%x\n", __func__, xd->hw_irq); if (xd->eoi_mmio) { iounmap(xd->eoi_mmio); @@ -1211,8 +1212,8 @@ static int xive_setup_cpu_ipi(unsigned int cpu) pr_err("Failed to map IPI CPU %d\n", cpu); return -EIO; } - pr_devel("CPU %d HW IPI %x, virq %d, trig_mmio=%p\n", cpu, - xc->hw_ipi, xive_ipi_irq, xc->ipi_data.trig_mmio); + pr_debug("CPU %d HW IPI 0x%x, virq %d, trig_mmio=%p\n", cpu, + xc->hw_ipi, xive_ipi_irq, xc->ipi_data.trig_mmio); /* Unmask it */ xive_do_source_set_mask(&xc->ipi_data, false); @@ -1390,7 +1391,7 @@ static int xive_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, if (rc) return rc; - pr_debug("%s %d/%lx #%d\n", __func__, virq, hwirq, nr_irqs); + pr_debug("%s %d/0x%lx #%d\n", __func__, virq, hwirq, nr_irqs); for (i = 0; i < nr_irqs; i++) { /* TODO: call xive_irq_domain_map() */ @@ -1504,7 +1505,7 @@ static void xive_setup_cpu(void) #ifdef CONFIG_SMP void xive_smp_setup_cpu(void) { - pr_devel("SMP setup CPU %d\n", smp_processor_id()); + pr_debug("SMP setup CPU %d\n", smp_processor_id()); /* This will have already been done on the boot CPU */ if (smp_processor_id() != boot_cpuid) @@ -1650,10 +1651,10 @@ bool __init xive_core_init(struct device_node *np, const struct xive_ops *ops, ppc_md.get_irq = xive_get_irq; __xive_enabled = true; - pr_devel("Initializing host..\n"); + pr_debug("Initializing host..\n"); xive_init_host(np); - pr_devel("Initializing boot CPU..\n"); + pr_debug("Initializing boot CPU..\n"); /* Allocate per-CPU data and queues */ xive_prepare_cpu(smp_processor_id()); -- cgit v1.2.3 From bd5b00c6cf0c37fce1bcd94390044d7e1dd638e7 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:27 +0100 Subject: powerpc/xive: Introduce an helper to print out interrupt characteristics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and extend output of debugfs and xmon with addresses of the ESB management and trigger pages. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-3-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 442642be3505..b74b8f18b80c 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -227,6 +227,19 @@ static void xive_esb_write(struct xive_irq_data *xd, u32 offset, u64 data) out_be64(xd->eoi_mmio + offset, data); } +static void xive_irq_data_dump(struct xive_irq_data *xd, char *buffer, size_t size) +{ + u64 val = xive_esb_read(xd, XIVE_ESB_GET); + + snprintf(buffer, size, "flags=%c%c%c PQ=%c%c 0x%016llx 0x%016llx", + xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', + xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', + xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', + val & XIVE_ESB_VAL_P ? 'P' : '-', + val & XIVE_ESB_VAL_Q ? 'Q' : '-', + xd->trig_page, xd->eoi_page); +} + #ifdef CONFIG_XMON static notrace void xive_dump_eq(const char *name, struct xive_q *q) { @@ -252,11 +265,10 @@ notrace void xmon_xive_do_dump(int cpu) #ifdef CONFIG_SMP { - u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET); + char buffer[128]; - xmon_printf("IPI=0x%08x PQ=%c%c ", xc->hw_ipi, - val & XIVE_ESB_VAL_P ? 'P' : '-', - val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + xive_irq_data_dump(&xc->ipi_data, buffer, sizeof(buffer)); + xmon_printf("IPI=0x%08x %s", xc->hw_ipi, buffer); } #endif xive_dump_eq("EQ", &xc->queue[xive_irq_priority]); @@ -291,15 +303,11 @@ int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) d = xive_get_irq_data(hw_irq); if (d) { - struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); - u64 val = xive_esb_read(xd, XIVE_ESB_GET); - - xmon_printf("flags=%c%c%c PQ=%c%c", - xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', - xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', - xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', - val & XIVE_ESB_VAL_P ? 'P' : '-', - val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + char buffer[128]; + + xive_irq_data_dump(irq_data_get_irq_handler_data(d), + buffer, sizeof(buffer)); + xmon_printf("%s", buffer); } xmon_printf("\n"); @@ -1702,11 +1710,10 @@ static void xive_debug_show_cpu(struct seq_file *m, int cpu) #ifdef CONFIG_SMP { - u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET); + char buffer[128]; - seq_printf(m, "IPI=0x%08x PQ=%c%c ", xc->hw_ipi, - val & XIVE_ESB_VAL_P ? 'P' : '-', - val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + xive_irq_data_dump(&xc->ipi_data, buffer, sizeof(buffer)); + seq_printf(m, "IPI=0x%08x %s", xc->hw_ipi, buffer); } #endif { @@ -1733,8 +1740,7 @@ static void xive_debug_show_irq(struct seq_file *m, struct irq_data *d) u32 target; u8 prio; u32 lirq; - struct xive_irq_data *xd; - u64 val; + char buffer[128]; rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq); if (rc) { @@ -1745,14 +1751,8 @@ static void xive_debug_show_irq(struct seq_file *m, struct irq_data *d) seq_printf(m, "IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ", hw_irq, target, prio, lirq); - xd = irq_data_get_irq_handler_data(d); - val = xive_esb_read(xd, XIVE_ESB_GET); - seq_printf(m, "flags=%c%c%c PQ=%c%c", - xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', - xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', - xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', - val & XIVE_ESB_VAL_P ? 'P' : '-', - val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + xive_irq_data_dump(irq_data_get_irq_handler_data(d), buffer, sizeof(buffer)); + seq_puts(m, buffer); seq_puts(m, "\n"); } -- cgit v1.2.3 From 412877dfae3dc12733bc711ccbd3d02338803865 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:29 +0100 Subject: powerpc/xive: Introduce xive_core_debugfs_create() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and fix some compile issues when !CONFIG_DEBUG_FS. Signed-off-by: Cédric Le Goater [mpe: Add empty stub to fix !CONFIG_DEBUG_FS build] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-5-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index b74b8f18b80c..6c9092db74d0 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -227,6 +227,7 @@ static void xive_esb_write(struct xive_irq_data *xd, u32 offset, u64 data) out_be64(xd->eoi_mmio + offset, data); } +#if defined(CONFIG_XMON) || defined(CONFIG_DEBUG_FS) static void xive_irq_data_dump(struct xive_irq_data *xd, char *buffer, size_t size) { u64 val = xive_esb_read(xd, XIVE_ESB_GET); @@ -239,6 +240,7 @@ static void xive_irq_data_dump(struct xive_irq_data *xd, char *buffer, size_t si val & XIVE_ESB_VAL_Q ? 'Q' : '-', xd->trig_page, xd->eoi_page); } +#endif #ifdef CONFIG_XMON static notrace void xive_dump_eq(const char *name, struct xive_q *q) @@ -1700,6 +1702,7 @@ static int __init xive_off(char *arg) } __setup("xive=off", xive_off); +#ifdef CONFIG_DEBUG_FS static void xive_debug_show_cpu(struct seq_file *m, int cpu) { struct xive_cpu *xc = per_cpu(xive_cpu, cpu); @@ -1778,10 +1781,19 @@ static int xive_core_debug_show(struct seq_file *m, void *private) } DEFINE_SHOW_ATTRIBUTE(xive_core_debug); +static void xive_core_debugfs_create(void) +{ + debugfs_create_file("xive", 0400, arch_debugfs_dir, + NULL, &xive_core_debug_fops); +} +#else +static inline void xive_core_debugfs_create(void) { } +#endif /* CONFIG_DEBUG_FS */ + int xive_core_debug_init(void) { - if (xive_enabled()) - debugfs_create_file("xive", 0400, arch_debugfs_dir, - NULL, &xive_core_debug_fops); + if (xive_enabled() && IS_ENABLED(CONFIG_DEBUG_FS)) + xive_core_debugfs_create(); + return 0; } -- cgit v1.2.3 From baed14de78b5ee3ca04eae43c5b16e3eeb6e33a8 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:30 +0100 Subject: powerpc/xive: Change the debugfs file 'xive' into a directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a 'cpus' file to dump CPU states and 'interrupts' to dump IRQ states. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-6-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 6c9092db74d0..34bbae9ee963 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1759,17 +1759,10 @@ static void xive_debug_show_irq(struct seq_file *m, struct irq_data *d) seq_puts(m, "\n"); } -static int xive_core_debug_show(struct seq_file *m, void *private) +static int xive_irq_debug_show(struct seq_file *m, void *private) { unsigned int i; struct irq_desc *desc; - int cpu; - - if (xive_ops->debug_show) - xive_ops->debug_show(m, private); - - for_each_possible_cpu(cpu) - xive_debug_show_cpu(m, cpu); for_each_irq_desc(i, desc) { struct irq_data *d = irq_domain_get_irq_data(xive_irq_domain, i); @@ -1779,12 +1772,33 @@ static int xive_core_debug_show(struct seq_file *m, void *private) } return 0; } -DEFINE_SHOW_ATTRIBUTE(xive_core_debug); +DEFINE_SHOW_ATTRIBUTE(xive_irq_debug); + +static int xive_cpu_debug_show(struct seq_file *m, void *private) +{ + int cpu; + + if (xive_ops->debug_show) + xive_ops->debug_show(m, private); + + for_each_possible_cpu(cpu) + xive_debug_show_cpu(m, cpu); + return 0; +} +DEFINE_SHOW_ATTRIBUTE(xive_cpu_debug); static void xive_core_debugfs_create(void) { - debugfs_create_file("xive", 0400, arch_debugfs_dir, - NULL, &xive_core_debug_fops); + struct dentry *xive_dir; + + xive_dir = debugfs_create_dir("xive", arch_debugfs_dir); + if (IS_ERR(xive_dir)) + return; + + debugfs_create_file("cpus", 0400, xive_dir, + NULL, &xive_cpu_debug_fops); + debugfs_create_file("interrupts", 0400, xive_dir, + NULL, &xive_irq_debug_fops); } #else static inline void xive_core_debugfs_create(void) { } -- cgit v1.2.3 From 33e1d4a152ce55272b54a16884461218d12d4f1b Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:31 +0100 Subject: powerpc/xive: Rename the 'cpus' debugfs file to 'ipis' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and remove the EQ entries output which is not very useful since only the next two events of the queue are taken into account. We will improve the dump of the EQ in the next patches. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-7-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 34bbae9ee963..3ef3cc413b31 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1703,11 +1703,11 @@ static int __init xive_off(char *arg) __setup("xive=off", xive_off); #ifdef CONFIG_DEBUG_FS -static void xive_debug_show_cpu(struct seq_file *m, int cpu) +static void xive_debug_show_ipi(struct seq_file *m, int cpu) { struct xive_cpu *xc = per_cpu(xive_cpu, cpu); - seq_printf(m, "CPU %d:", cpu); + seq_printf(m, "CPU %d: ", cpu); if (xc) { seq_printf(m, "pp=%02x CPPR=%02x ", xc->pending_prio, xc->cppr); @@ -1719,19 +1719,6 @@ static void xive_debug_show_cpu(struct seq_file *m, int cpu) seq_printf(m, "IPI=0x%08x %s", xc->hw_ipi, buffer); } #endif - { - struct xive_q *q = &xc->queue[xive_irq_priority]; - u32 i0, i1, idx; - - if (q->qpage) { - idx = q->idx; - i0 = be32_to_cpup(q->qpage + idx); - idx = (idx + 1) & q->msk; - i1 = be32_to_cpup(q->qpage + idx); - seq_printf(m, "EQ idx=%d T=%d %08x %08x ...", - q->idx, q->toggle, i0, i1); - } - } } seq_puts(m, "\n"); } @@ -1774,7 +1761,7 @@ static int xive_irq_debug_show(struct seq_file *m, void *private) } DEFINE_SHOW_ATTRIBUTE(xive_irq_debug); -static int xive_cpu_debug_show(struct seq_file *m, void *private) +static int xive_ipi_debug_show(struct seq_file *m, void *private) { int cpu; @@ -1782,10 +1769,10 @@ static int xive_cpu_debug_show(struct seq_file *m, void *private) xive_ops->debug_show(m, private); for_each_possible_cpu(cpu) - xive_debug_show_cpu(m, cpu); + xive_debug_show_ipi(m, cpu); return 0; } -DEFINE_SHOW_ATTRIBUTE(xive_cpu_debug); +DEFINE_SHOW_ATTRIBUTE(xive_ipi_debug); static void xive_core_debugfs_create(void) { @@ -1795,8 +1782,8 @@ static void xive_core_debugfs_create(void) if (IS_ERR(xive_dir)) return; - debugfs_create_file("cpus", 0400, xive_dir, - NULL, &xive_cpu_debug_fops); + debugfs_create_file("ipis", 0400, xive_dir, + NULL, &xive_ipi_debug_fops); debugfs_create_file("interrupts", 0400, xive_dir, NULL, &xive_irq_debug_fops); } -- cgit v1.2.3 From 08f3f610214f395561bbda03344e641579f6e917 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:32 +0100 Subject: powerpc/xive: Add a debugfs file to dump EQs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XIVE driver under Linux uses a single interrupt priority and only one event queue is configured per CPU. Expose the contents under a 'xive/eqs/cpuX' debugfs file. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-8-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 3ef3cc413b31..ff6a2d1ed41d 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1774,9 +1774,40 @@ static int xive_ipi_debug_show(struct seq_file *m, void *private) } DEFINE_SHOW_ATTRIBUTE(xive_ipi_debug); +static void xive_eq_debug_show_one(struct seq_file *m, struct xive_q *q, u8 prio) +{ + int i; + + seq_printf(m, "EQ%d idx=%d T=%d\n", prio, q->idx, q->toggle); + if (q->qpage) { + for (i = 0; i < q->msk + 1; i++) { + if (!(i % 8)) + seq_printf(m, "%05d ", i); + seq_printf(m, "%08x%s", be32_to_cpup(q->qpage + i), + (i + 1) % 8 ? " " : "\n"); + } + } + seq_puts(m, "\n"); +} + +static int xive_eq_debug_show(struct seq_file *m, void *private) +{ + int cpu = (long)m->private; + struct xive_cpu *xc = per_cpu(xive_cpu, cpu); + + if (xc) + xive_eq_debug_show_one(m, &xc->queue[xive_irq_priority], + xive_irq_priority); + return 0; +} +DEFINE_SHOW_ATTRIBUTE(xive_eq_debug); + static void xive_core_debugfs_create(void) { struct dentry *xive_dir; + struct dentry *xive_eq_dir; + long cpu; + char name[16]; xive_dir = debugfs_create_dir("xive", arch_debugfs_dir); if (IS_ERR(xive_dir)) @@ -1786,6 +1817,12 @@ static void xive_core_debugfs_create(void) NULL, &xive_ipi_debug_fops); debugfs_create_file("interrupts", 0400, xive_dir, NULL, &xive_irq_debug_fops); + xive_eq_dir = debugfs_create_dir("eqs", xive_dir); + for_each_possible_cpu(cpu) { + snprintf(name, sizeof(name), "cpu%ld", cpu); + debugfs_create_file(name, 0400, xive_eq_dir, (void *)cpu, + &xive_eq_debug_fops); + } } #else static inline void xive_core_debugfs_create(void) { } -- cgit v1.2.3 From d7bc1e376cb786e9e8483455584d89cad4b5808f Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:33 +0100 Subject: powerpc/xive: Add a debugfs toggle for StoreEOI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be used to deactivate temporarily StoreEOI for tests or performance on platforms supporting the feature (POWER10) Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-9-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index ff6a2d1ed41d..b3b1dbf29d4d 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -84,6 +84,16 @@ static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu); /* An invalid CPU target */ #define XIVE_INVALID_TARGET (-1) +/* + * Global toggle to switch on/off StoreEOI + */ +static bool xive_store_eoi = true; + +static bool xive_is_store_eoi(struct xive_irq_data *xd) +{ + return xd->flags & XIVE_IRQ_FLAG_STORE_EOI && xive_store_eoi; +} + /* * Read the next entry in a queue, return its content if it's valid * or 0 if there is no new entry. @@ -208,7 +218,7 @@ static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset) { u64 val; - if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI) + if (offset == XIVE_ESB_SET_PQ_10 && xive_is_store_eoi(xd)) offset |= XIVE_ESB_LD_ST_MO; if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) @@ -233,7 +243,7 @@ static void xive_irq_data_dump(struct xive_irq_data *xd, char *buffer, size_t si u64 val = xive_esb_read(xd, XIVE_ESB_GET); snprintf(buffer, size, "flags=%c%c%c PQ=%c%c 0x%016llx 0x%016llx", - xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', + xive_is_store_eoi(xd) ? 'S' : ' ', xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', val & XIVE_ESB_VAL_P ? 'P' : '-', @@ -395,7 +405,7 @@ static void xive_do_source_eoi(struct xive_irq_data *xd) xd->stale_p = false; /* If the XIVE supports the new "store EOI facility, use it */ - if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) { + if (xive_is_store_eoi(xd)) { xive_esb_write(xd, XIVE_ESB_STORE_EOI, 0); return; } @@ -1823,6 +1833,7 @@ static void xive_core_debugfs_create(void) debugfs_create_file(name, 0400, xive_eq_dir, (void *)cpu, &xive_eq_debug_fops); } + debugfs_create_bool("store-eoi", 0600, xive_dir, &xive_store_eoi); } #else static inline void xive_core_debugfs_create(void) { } -- cgit v1.2.3 From c21ee04f11ae068aa132cce56d09f618d4a66259 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:34 +0100 Subject: powerpc/xive: Add a kernel parameter for StoreEOI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StoreEOI is activated by default on platforms supporting the feature (POWER10) and will be used as soon as firmware advertises its availability. The kernel parameter provides a way to deactivate its use. It can be still be reactivated through debugfs. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-10-clg@kaod.org --- Documentation/admin-guide/kernel-parameters.txt | 6 ++++++ arch/powerpc/sysdev/xive/common.c | 13 +++++++++++++ 2 files changed, 19 insertions(+) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 2711ddb4835a..6248a061788a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6446,6 +6446,12 @@ controller on both pseries and powernv platforms. Only useful on POWER9 and above. + xive.store-eoi=off [PPC] + By default on POWER10 and above, the kernel will use + stores for EOI handling when the XIVE interrupt mode + is active. This option allows the XIVE driver to use + loads instead, as on POWER9. + xhci-hcd.quirks [USB,KNL] A hex value specifying bitmask with supplemental xhci host controller quirks. Meaning of each bit can be diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index b3b1dbf29d4d..3b453973a5d2 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1712,6 +1712,19 @@ static int __init xive_off(char *arg) } __setup("xive=off", xive_off); +static int __init xive_store_eoi_cmdline(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strncmp(arg, "off", 3) == 0) { + pr_info("StoreEOI disabled on kernel command line\n"); + xive_store_eoi = false; + } + return 0; +} +__setup("xive.store-eoi=", xive_store_eoi_cmdline); + #ifdef CONFIG_DEBUG_FS static void xive_debug_show_ipi(struct seq_file *m, int cpu) { -- cgit v1.2.3 From 1e7684dc4fc70271c8bf86d397bd4fbfb3581e65 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Fri, 5 Nov 2021 11:26:35 +0100 Subject: powerpc/xive: Add a debugfs toggle for save-restore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On POWER10, the automatic "save & restore" of interrupt context is always available. Provide a way to deactivate it for tests or performance. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211105102636.1016378-11-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 1 + arch/powerpc/sysdev/xive/native.c | 2 +- arch/powerpc/sysdev/xive/xive-internal.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 3b453973a5d2..43f7f7df6407 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1847,6 +1847,7 @@ static void xive_core_debugfs_create(void) &xive_eq_debug_fops); } debugfs_create_bool("store-eoi", 0600, xive_dir, &xive_store_eoi); + debugfs_create_bool("save-restore", 0600, xive_dir, &xive_has_save_restore); } #else static inline void xive_core_debugfs_create(void) { } diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 7ec8911dad57..d6a091dc1bce 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -41,7 +41,7 @@ static u32 xive_queue_shift; static u32 xive_pool_vps = XIVE_INVALID_VP; static struct kmem_cache *xive_provision_cache; static bool xive_has_single_esc; -static bool xive_has_save_restore; +bool xive_has_save_restore; int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) { diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index 504e7edce358..e0941bc64430 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -72,5 +72,6 @@ static inline u32 xive_alloc_order(u32 queue_shift) } extern bool xive_cmdline_disabled; +extern bool xive_has_save_restore; #endif /* __XIVE_INTERNAL_H */ -- cgit v1.2.3 From 2a2ac8a7018b953cd23d770ebd28f8e1ea365df4 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Wed, 1 Dec 2021 17:54:18 +0100 Subject: powerpc/xive: Fix compile when !CONFIG_PPC_POWERNV. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The automatic "save & restore" of interrupt context is a POWER10/XIVE2 feature exploited by KVM under the PowerNV platform. It is not available under pSeries and the associated toggle should not be exposed under the XIVE debugfs directory. Introduce a platform handler for debugfs initialization and move the 'save-restore' entry under the native (PowerNV) backend to fix compile when !CONFIG_PPC_POWERNV. Fixes: 1e7684dc4fc7 ("powerpc/xive: Add a debugfs toggle for save-restore") Reported-by: kernel test robot Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211201165418.1041842-1-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 4 +++- arch/powerpc/sysdev/xive/native.c | 11 +++++++++++ arch/powerpc/sysdev/xive/xive-internal.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/sysdev/xive/common.c') diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 43f7f7df6407..1ca5564bda9d 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1847,7 +1847,9 @@ static void xive_core_debugfs_create(void) &xive_eq_debug_fops); } debugfs_create_bool("store-eoi", 0600, xive_dir, &xive_store_eoi); - debugfs_create_bool("save-restore", 0600, xive_dir, &xive_has_save_restore); + + if (xive_ops->debug_create) + xive_ops->debug_create(xive_dir); } #else static inline void xive_core_debugfs_create(void) { } diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index d6a091dc1bce..d4243dab230e 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -461,6 +461,14 @@ void xive_native_sync_queue(u32 hw_irq) } EXPORT_SYMBOL_GPL(xive_native_sync_queue); +#ifdef CONFIG_DEBUG_FS +static int xive_native_debug_create(struct dentry *xive_dir) +{ + debugfs_create_bool("save-restore", 0600, xive_dir, &xive_has_save_restore); + return 0; +} +#endif + static const struct xive_ops xive_native_ops = { .populate_irq_data = xive_native_populate_irq_data, .configure_irq = xive_native_configure_irq, @@ -478,6 +486,9 @@ static const struct xive_ops xive_native_ops = { .get_ipi = xive_native_get_ipi, .put_ipi = xive_native_put_ipi, #endif /* CONFIG_SMP */ +#ifdef CONFIG_DEBUG_FS + .debug_create = xive_native_debug_create, +#endif /* CONFIG_DEBUG_FS */ .name = "native", }; diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index e0941bc64430..fe6d95d54af9 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -58,6 +58,7 @@ struct xive_ops { void (*put_ipi)(unsigned int cpu, struct xive_cpu *xc); #endif int (*debug_show)(struct seq_file *m, void *private); + int (*debug_create)(struct dentry *xive_dir); const char *name; }; -- cgit v1.2.3