* [PATCH 1/7] powerpc: Reduce footprint of irq_stat
@ 2010-02-01 6:30 Anton Blanchard
2010-02-01 6:32 ` [PATCH 2/7] powerpc: Reduce footprint of xics_ipi_struct Anton Blanchard
2010-02-01 21:55 ` [PATCH 1/7] powerpc: Reduce footprint of irq_stat Christoph Hellwig
0 siblings, 2 replies; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:30 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
PowerPC is currently using asm-generic/hardirq.h which statically allocates an
NR_CPUS irq_stat array. Switch to an arch specific implementation which uses
per cpu data:
On a kernel with NR_CPUS=1024, this saves quite a lot of memory:
text data bss dec hex filename
8767938 2944132 1636796 13348866 cbb002 vmlinux.baseline
8767779 2944260 1505724 13217763 c9afe3 vmlinux.irq_cpustat
A saving of around 128kB.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-cpumask/arch/powerpc/include/asm/hardirq.h
===================================================================
--- linux-cpumask.orig/arch/powerpc/include/asm/hardirq.h 2010-01-31 22:07:21.037211728 +1100
+++ linux-cpumask/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:28:56.990963256 +1100
@@ -1 +1,22 @@
-#include <asm-generic/hardirq.h>
+#ifndef _ASM_POWERPC_HARDIRQ_H
+#define _ASM_POWERPC_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+
+#define __ARCH_IRQ_STAT
+
+#define local_softirq_pending() __get_cpu_var(irq_stat).__softirq_pending
+
+static inline void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+#endif /* _ASM_POWERPC_HARDIRQ_H */
Index: linux-cpumask/arch/powerpc/kernel/irq.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/irq.c 2010-01-31 22:07:21.027213106 +1100
+++ linux-cpumask/arch/powerpc/kernel/irq.c 2010-02-01 17:28:56.880963661 +1100
@@ -73,6 +73,9 @@
#define CREATE_TRACE_POINTS
#include <asm/trace.h>
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
int __irq_offset_value;
static int ppc_spurious_interrupts;
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/7] powerpc: Reduce footprint of xics_ipi_struct
2010-02-01 6:30 [PATCH 1/7] powerpc: Reduce footprint of irq_stat Anton Blanchard
@ 2010-02-01 6:32 ` Anton Blanchard
2010-02-01 6:33 ` [PATCH 3/7] powerpc: Rework /proc/interrupts Anton Blanchard
2010-02-01 21:55 ` [PATCH 1/7] powerpc: Reduce footprint of irq_stat Christoph Hellwig
1 sibling, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:32 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Right now we allocate a cacheline sized NR_CPUS array for xics IPI
communication. Use DECLARE_PER_CPU_SHARED_ALIGNED to put it in percpu
data in its own cacheline since it is written to by other cpus.
On a kernel with NR_CPUS=1024, this saves quite a lot of memory:
text data bss dec hex filename
8767779 2944260 1505724 13217763 c9afe3 vmlinux.irq_cpustat
8767555 2813444 1505724 13086723 c7b003 vmlinux.xics
A saving of around 128kB.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-cpumask/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/pseries/xics.c 2010-02-01 17:28:56.980961887 +1100
+++ linux-cpumask/arch/powerpc/platforms/pseries/xics.c 2010-02-01 17:29:00.980963118 +1100
@@ -514,15 +514,13 @@ static void __init xics_init_host(void)
/*
* XICS only has a single IPI, so encode the messages per CPU
*/
-struct xics_ipi_struct {
- unsigned long value;
- } ____cacheline_aligned;
-
-static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
static inline void smp_xics_do_message(int cpu, int msg)
{
- set_bit(msg, &xics_ipi_message[cpu].value);
+ unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
+ set_bit(msg, tgt);
mb();
if (firmware_has_feature(FW_FEATURE_LPAR))
lpar_qirr_info(cpu, IPI_PRIORITY);
@@ -548,25 +546,23 @@ void smp_xics_message_pass(int target, i
static irqreturn_t xics_ipi_dispatch(int cpu)
{
+ unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
WARN_ON(cpu_is_offline(cpu));
mb(); /* order mmio clearing qirr */
- while (xics_ipi_message[cpu].value) {
- if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
- &xics_ipi_message[cpu].value)) {
+ while (*tgt) {
+ if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) {
smp_message_recv(PPC_MSG_CALL_FUNCTION);
}
- if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) {
smp_message_recv(PPC_MSG_RESCHEDULE);
}
- if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) {
smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
}
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
- if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) {
smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
}
#endif
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/7] powerpc: Rework /proc/interrupts
2010-02-01 6:32 ` [PATCH 2/7] powerpc: Reduce footprint of xics_ipi_struct Anton Blanchard
@ 2010-02-01 6:33 ` Anton Blanchard
2010-02-01 6:33 ` [PATCH 4/7] powerpc: Remove whitespace in irq chip name fields Anton Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:33 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
On a large machine I noticed the columns of /proc/interrupts failed to line up
with the header after CPU9. At sufficiently large numbers of CPUs it becomes
impossible to line up the CPU number with the counts.
While fixing this I noticed x86 has a number of updates that we may as well
pull in. On PowerPC we currently omit an interrupt completely if there is no
active handler, whereas on x86 it is printed if there is a non zero count.
The x86 code also spaces the first column correctly based on nr_irqs.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-cpumask/arch/powerpc/kernel/irq.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/irq.c 2010-02-01 17:28:56.880963661 +1100
+++ linux-cpumask/arch/powerpc/kernel/irq.c 2010-02-01 17:29:02.007212291 +1100
@@ -183,30 +183,46 @@ notrace void raw_local_irq_restore(unsig
EXPORT_SYMBOL(raw_local_irq_restore);
#endif /* CONFIG_PPC64 */
+static int show_other_interrupts(struct seq_file *p, int prec)
+{
+ int j;
+
+#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
+ if (tau_initialized) {
+ seq_printf(p, "%*s: ", prec, "TAU");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", tau_interrupts(j));
+ seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
+ }
+#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
+
+ seq_printf(p, "%*s: %10u\n", prec, "BAD", ppc_spurious_interrupts);
+
+ return 0;
+}
+
int show_interrupts(struct seq_file *p, void *v)
{
- int i = *(loff_t *)v, j;
+ unsigned long flags, any_count = 0;
+ int i = *(loff_t *) v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
+ if (i > nr_irqs)
+ return 0;
+
+ for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
+ j *= 10;
+
+ if (i == nr_irqs)
+ return show_other_interrupts(p, prec);
+
+ /* print header */
if (i == 0) {
- seq_puts(p, " ");
+ seq_printf(p, "%*s", prec + 8, "");
for_each_online_cpu(j)
- seq_printf(p, "CPU%d ", j);
+ seq_printf(p, "CPU%-8d", j);
seq_putc(p, '\n');
- } else if (i == nr_irqs) {
-#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
- if (tau_initialized){
- seq_puts(p, "TAU: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", tau_interrupts(j));
- seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
- }
-#endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/
- seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
-
- return 0;
}
desc = irq_to_desc(i);
@@ -214,34 +230,31 @@ int show_interrupts(struct seq_file *p,
return 0;
raw_spin_lock_irqsave(&desc->lock, flags);
-
+ for_each_online_cpu(j)
+ any_count |= kstat_irqs_cpu(i, j);
action = desc->action;
- if (!action || !action->handler)
- goto skip;
+ if (!action && !any_count)
+ goto out;
- seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
+ seq_printf(p, "%*d: ", prec, i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#else
- seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
if (desc->chip)
- seq_printf(p, " %s ", desc->chip->name);
+ seq_printf(p, " %-16s", desc->chip->name);
else
- seq_puts(p, " None ");
+ seq_printf(p, " %-16s", "None");
+ seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
- seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
- seq_printf(p, " %s", action->name);
+ if (action) {
+ seq_printf(p, " %s", action->name);
+ while ((action = action->next) != NULL)
+ seq_printf(p, ", %s", action->name);
+ }
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
-
-skip:
+out:
raw_spin_unlock_irqrestore(&desc->lock, flags);
-
return 0;
}
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/7] powerpc: Remove whitespace in irq chip name fields
2010-02-01 6:33 ` [PATCH 3/7] powerpc: Rework /proc/interrupts Anton Blanchard
@ 2010-02-01 6:33 ` Anton Blanchard
2010-02-01 6:34 ` [PATCH 5/7] powerpc: Add timer, performance monitor and machine check counts to /proc/interrupts Anton Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:33 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Now we use printf style alignment there is no need to manually space
these fields.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-cpumask/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c 2010-02-01 17:28:56.700961947 +1100
+++ linux-cpumask/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c 2010-02-01 17:29:02.987211921 +1100
@@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq)
}
static struct irq_chip cpld_pic = {
- .name = " CPLD PIC ",
+ .name = "CPLD PIC",
.mask = cpld_mask_irq,
.ack = cpld_mask_irq,
.unmask = cpld_unmask_irq,
Index: linux-cpumask/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/85xx/socrates_fpga_pic.c 2010-02-01 17:28:56.750962488 +1100
+++ linux-cpumask/arch/powerpc/platforms/85xx/socrates_fpga_pic.c 2010-02-01 17:29:02.997212166 +1100
@@ -232,7 +232,7 @@ static int socrates_fpga_pic_set_type(un
}
static struct irq_chip socrates_fpga_pic_chip = {
- .name = " FPGA-PIC ",
+ .name = "FPGA-PIC",
.ack = socrates_fpga_pic_ack,
.mask = socrates_fpga_pic_mask,
.mask_ack = socrates_fpga_pic_mask_ack,
Index: linux-cpumask/arch/powerpc/platforms/cell/beat_interrupt.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/cell/beat_interrupt.c 2010-02-01 17:28:56.720961496 +1100
+++ linux-cpumask/arch/powerpc/platforms/cell/beat_interrupt.c 2010-02-01 17:29:02.997212166 +1100
@@ -110,7 +110,7 @@ static void beatic_end_irq(unsigned int
}
static struct irq_chip beatic_pic = {
- .name = " CELL-BEAT ",
+ .name = "CELL-BEAT",
.unmask = beatic_unmask_irq,
.mask = beatic_mask_irq,
.eoi = beatic_end_irq,
Index: linux-cpumask/arch/powerpc/platforms/cell/interrupt.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/cell/interrupt.c 2010-02-01 17:28:56.730973203 +1100
+++ linux-cpumask/arch/powerpc/platforms/cell/interrupt.c 2010-02-01 17:29:02.997212166 +1100
@@ -88,7 +88,7 @@ static void iic_eoi(unsigned int irq)
}
static struct irq_chip iic_chip = {
- .name = " CELL-IIC ",
+ .name = "CELL-IIC",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_eoi,
@@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned i
static struct irq_chip iic_ioexc_chip = {
- .name = " CELL-IOEX",
+ .name = "CELL-IOEX",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_ioexc_eoi,
Index: linux-cpumask/arch/powerpc/platforms/cell/spider-pic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/cell/spider-pic.c 2010-02-01 17:28:56.720961496 +1100
+++ linux-cpumask/arch/powerpc/platforms/cell/spider-pic.c 2010-02-01 17:29:02.997212166 +1100
@@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned
}
static struct irq_chip spider_pic = {
- .name = " SPIDER ",
+ .name = "SPIDER",
.unmask = spider_unmask_irq,
.mask = spider_mask_irq,
.ack = spider_ack_irq,
Index: linux-cpumask/arch/powerpc/platforms/iseries/irq.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/iseries/irq.c 2010-02-01 17:28:56.690961770 +1100
+++ linux-cpumask/arch/powerpc/platforms/iseries/irq.c 2010-02-01 17:29:02.997212166 +1100
@@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int
}
static struct irq_chip iseries_pic = {
- .name = "iSeries irq controller",
+ .name = "iSeries",
.startup = iseries_startup_IRQ,
.shutdown = iseries_shutdown_IRQ,
.unmask = iseries_enable_IRQ,
Index: linux-cpumask/arch/powerpc/platforms/powermac/pic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/powermac/pic.c 2010-02-01 17:28:56.710961247 +1100
+++ linux-cpumask/arch/powerpc/platforms/powermac/pic.c 2010-02-01 17:29:02.997212166 +1100
@@ -195,7 +195,7 @@ static int pmac_retrigger(unsigned int v
}
static struct irq_chip pmac_pic = {
- .name = " PMAC-PIC ",
+ .name = "PMAC-PIC",
.startup = pmac_startup_irq,
.mask = pmac_mask_irq,
.ack = pmac_ack_irq,
Index: linux-cpumask/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/platforms/pseries/xics.c 2010-02-01 17:29:00.980963118 +1100
+++ linux-cpumask/arch/powerpc/platforms/pseries/xics.c 2010-02-01 17:29:02.997212166 +1100
@@ -428,7 +428,7 @@ static int xics_set_affinity(unsigned in
}
static struct irq_chip xics_pic_direct = {
- .name = " XICS ",
+ .name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
@@ -437,7 +437,7 @@ static struct irq_chip xics_pic_direct =
};
static struct irq_chip xics_pic_lpar = {
- .name = " XICS ",
+ .name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
Index: linux-cpumask/arch/powerpc/sysdev/cpm1.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/cpm1.c 2010-02-01 17:28:56.810962592 +1100
+++ linux-cpumask/arch/powerpc/sysdev/cpm1.c 2010-02-01 17:29:02.997212166 +1100
@@ -77,7 +77,7 @@ static void cpm_end_irq(unsigned int irq
}
static struct irq_chip cpm_pic = {
- .name = " CPM PIC ",
+ .name = "CPM PIC",
.mask = cpm_mask_irq,
.unmask = cpm_unmask_irq,
.eoi = cpm_end_irq,
Index: linux-cpumask/arch/powerpc/sysdev/cpm2_pic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/cpm2_pic.c 2010-02-01 17:28:56.830961830 +1100
+++ linux-cpumask/arch/powerpc/sysdev/cpm2_pic.c 2010-02-01 17:29:02.997212166 +1100
@@ -198,7 +198,7 @@ err_sense:
}
static struct irq_chip cpm2_pic = {
- .name = " CPM2 SIU ",
+ .name = "CPM2 SIU",
.mask = cpm2_mask_irq,
.unmask = cpm2_unmask_irq,
.ack = cpm2_ack,
Index: linux-cpumask/arch/powerpc/sysdev/fsl_msi.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/fsl_msi.c 2010-02-01 17:28:56.790962373 +1100
+++ linux-cpumask/arch/powerpc/sysdev/fsl_msi.c 2010-02-01 17:29:02.997212166 +1100
@@ -47,7 +47,7 @@ static struct irq_chip fsl_msi_chip = {
.mask = mask_msi_irq,
.unmask = unmask_msi_irq,
.ack = fsl_msi_end_irq,
- .name = " FSL-MSI ",
+ .name = "FSL-MSI",
};
static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
Index: linux-cpumask/arch/powerpc/sysdev/i8259.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/i8259.c 2010-02-01 17:28:56.800961602 +1100
+++ linux-cpumask/arch/powerpc/sysdev/i8259.c 2010-02-01 17:29:02.997212166 +1100
@@ -135,7 +135,7 @@ static void i8259_unmask_irq(unsigned in
}
static struct irq_chip i8259_pic = {
- .name = " i8259 ",
+ .name = "i8259",
.mask = i8259_mask_irq,
.disable = i8259_mask_irq,
.unmask = i8259_unmask_irq,
Index: linux-cpumask/arch/powerpc/sysdev/ipic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/ipic.c 2010-02-01 17:28:56.770971720 +1100
+++ linux-cpumask/arch/powerpc/sysdev/ipic.c 2010-02-01 17:29:02.997212166 +1100
@@ -660,7 +660,7 @@ static int ipic_set_irq_type(unsigned in
/* level interrupts and edge interrupts have different ack operations */
static struct irq_chip ipic_level_irq_chip = {
- .name = " IPIC ",
+ .name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq,
@@ -668,7 +668,7 @@ static struct irq_chip ipic_level_irq_ch
};
static struct irq_chip ipic_edge_irq_chip = {
- .name = " IPIC ",
+ .name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq_and_ack,
Index: linux-cpumask/arch/powerpc/sysdev/mpc8xx_pic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/mpc8xx_pic.c 2010-02-01 17:28:56.780962529 +1100
+++ linux-cpumask/arch/powerpc/sysdev/mpc8xx_pic.c 2010-02-01 17:29:02.997212166 +1100
@@ -94,7 +94,7 @@ static int mpc8xx_set_irq_type(unsigned
}
static struct irq_chip mpc8xx_pic = {
- .name = " MPC8XX SIU ",
+ .name = "MPC8XX SIU",
.unmask = mpc8xx_unmask_irq,
.mask = mpc8xx_mask_irq,
.ack = mpc8xx_ack,
Index: linux-cpumask/arch/powerpc/sysdev/mpic_pasemi_msi.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/mpic_pasemi_msi.c 2010-02-01 17:28:56.820964610 +1100
+++ linux-cpumask/arch/powerpc/sysdev/mpic_pasemi_msi.c 2010-02-01 17:29:02.997212166 +1100
@@ -60,7 +60,7 @@ static struct irq_chip mpic_pasemi_msi_c
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
- .name = "PASEMI-MSI ",
+ .name = "PASEMI-MSI",
};
static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
Index: linux-cpumask/arch/powerpc/sysdev/qe_lib/qe_ic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/qe_lib/qe_ic.c 2010-02-01 17:28:56.780962529 +1100
+++ linux-cpumask/arch/powerpc/sysdev/qe_lib/qe_ic.c 2010-02-01 17:29:02.997212166 +1100
@@ -237,7 +237,7 @@ static void qe_ic_mask_irq(unsigned int
}
static struct irq_chip qe_ic_irq_chip = {
- .name = " QEIC ",
+ .name = "QEIC",
.unmask = qe_ic_unmask_irq,
.mask = qe_ic_mask_irq,
.mask_ack = qe_ic_mask_irq,
Index: linux-cpumask/arch/powerpc/sysdev/uic.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/sysdev/uic.c 2010-02-01 17:28:56.760964179 +1100
+++ linux-cpumask/arch/powerpc/sysdev/uic.c 2010-02-01 17:29:02.997212166 +1100
@@ -177,7 +177,7 @@ static int uic_set_irq_type(unsigned int
}
static struct irq_chip uic_irq_chip = {
- .name = " UIC ",
+ .name = "UIC",
.unmask = uic_unmask_irq,
.mask = uic_mask_irq,
.mask_ack = uic_mask_ack_irq,
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 5/7] powerpc: Add timer, performance monitor and machine check counts to /proc/interrupts
2010-02-01 6:33 ` [PATCH 4/7] powerpc: Remove whitespace in irq chip name fields Anton Blanchard
@ 2010-02-01 6:34 ` Anton Blanchard
2010-02-01 6:34 ` [PATCH 6/7] powerpc: Convert global "BAD" interrupt to per cpu spurious Anton Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:34 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
With NO_HZ it is useful to know how often the decrementer is going off. The
patch below adds an entry for it and also adds it into the /proc/stat
summaries.
While here, I added performance monitoring and machine check exceptions.
I found it useful to keep an eye on the PMU exception rate
when using the perf tool. Since it's possible to take a completely
handled machine check on a System p box it also sounds like a good idea to
keep a machine check summary.
The event naming matches x86 to keep gratuitous differences to a minimum.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
If people really don't like the x86 short names, we can think up something
else.
Index: linux-cpumask/arch/powerpc/include/asm/hardirq.h
===================================================================
--- linux-cpumask.orig/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:28:56.990963256 +1100
+++ linux-cpumask/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:29:03.887211643 +1100
@@ -6,6 +6,9 @@
typedef struct {
unsigned int __softirq_pending;
+ unsigned int timer_irqs;
+ unsigned int pmu_irqs;
+ unsigned int mce_exceptions;
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
@@ -19,4 +22,10 @@ static inline void ack_bad_irq(unsigned
printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
}
+extern u64 arch_irq_stat_cpu(unsigned int cpu);
+#define arch_irq_stat_cpu arch_irq_stat_cpu
+
+extern u64 arch_irq_stat(void);
+#define arch_irq_stat arch_irq_stat
+
#endif /* _ASM_POWERPC_HARDIRQ_H */
Index: linux-cpumask/arch/powerpc/kernel/time.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/time.c 2010-02-01 17:28:56.590961781 +1100
+++ linux-cpumask/arch/powerpc/kernel/time.c 2010-02-01 17:29:03.887211643 +1100
@@ -575,6 +575,8 @@ void timer_interrupt(struct pt_regs * re
trace_timer_interrupt_entry(regs);
+ __get_cpu_var(irq_stat).timer_irqs++;
+
/* Ensure a positive value is written to the decrementer, or else
* some CPUs will continuue to take decrementer exceptions */
set_dec(DECREMENTER_MAX);
Index: linux-cpumask/arch/powerpc/kernel/irq.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/irq.c 2010-02-01 17:29:02.007212291 +1100
+++ linux-cpumask/arch/powerpc/kernel/irq.c 2010-02-01 17:29:03.887211643 +1100
@@ -196,6 +196,21 @@ static int show_other_interrupts(struct
}
#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
+ seq_printf(p, "%*s: ", prec, "LOC");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs);
+ seq_printf(p, " Local timer interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "CNT");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
+ seq_printf(p, " Performance monitoring interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "MCE");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
+ seq_printf(p, " Machine check exceptions\n");
+
seq_printf(p, "%*s: %10u\n", prec, "BAD", ppc_spurious_interrupts);
return 0;
@@ -258,6 +273,26 @@ out:
return 0;
}
+/*
+ * /proc/stat helpers
+ */
+u64 arch_irq_stat_cpu(unsigned int cpu)
+{
+ u64 sum = per_cpu(irq_stat, cpu).timer_irqs;
+
+ sum += per_cpu(irq_stat, cpu).pmu_irqs;
+ sum += per_cpu(irq_stat, cpu).mce_exceptions;
+
+ return sum;
+}
+
+u64 arch_irq_stat(void)
+{
+ u64 sum = ppc_spurious_interrupts;
+
+ return sum;
+}
+
#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(cpumask_t map)
{
Index: linux-cpumask/arch/powerpc/kernel/traps.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/traps.c 2010-02-01 17:28:56.570961322 +1100
+++ linux-cpumask/arch/powerpc/kernel/traps.c 2010-02-01 17:29:03.897211396 +1100
@@ -478,6 +478,8 @@ void machine_check_exception(struct pt_r
{
int recover = 0;
+ __get_cpu_var(irq_stat).mce_exceptions++;
+
/* See if any machine dependent calls. In theory, we would want
* to call the CPU first, and call the ppc_md. one if the CPU
* one returns a positive number. However there is existing code
@@ -960,6 +962,8 @@ void vsx_unavailable_exception(struct pt
void performance_monitor_exception(struct pt_regs *regs)
{
+ __get_cpu_var(irq_stat).pmu_irqs++;
+
perf_irq(regs);
}
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6/7] powerpc: Convert global "BAD" interrupt to per cpu spurious
2010-02-01 6:34 ` [PATCH 5/7] powerpc: Add timer, performance monitor and machine check counts to /proc/interrupts Anton Blanchard
@ 2010-02-01 6:34 ` Anton Blanchard
2010-02-01 6:34 ` [PATCH 7/7] powerpc: Increase NR_IRQS Kconfig maximum to 32768 Anton Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:34 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
I often get asked if BAD interrupts are really bad. On some boxes (eg
IBM machines running a hypervisor) there are valid cases where are
presented with an interrupt that is not for us. These cases are common
enough to show up as thousands of BAD interrupts a day.
Tone them down by calling them spurious. Since they can be a significant cause
of OS jitter, we may as well log them per cpu so we know where they are
occurring.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Again, the short name matches x86 but if people are sufficiently confused by
it ("SPU"), then we can think up something else.
Index: linux-cpumask/arch/powerpc/include/asm/hardirq.h
===================================================================
--- linux-cpumask.orig/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:29:03.887211643 +1100
+++ linux-cpumask/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:29:04.738461552 +1100
@@ -9,6 +9,7 @@ typedef struct {
unsigned int timer_irqs;
unsigned int pmu_irqs;
unsigned int mce_exceptions;
+ unsigned int spurious_irqs;
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
@@ -25,7 +26,4 @@ static inline void ack_bad_irq(unsigned
extern u64 arch_irq_stat_cpu(unsigned int cpu);
#define arch_irq_stat_cpu arch_irq_stat_cpu
-extern u64 arch_irq_stat(void);
-#define arch_irq_stat arch_irq_stat
-
#endif /* _ASM_POWERPC_HARDIRQ_H */
Index: linux-cpumask/arch/powerpc/kernel/irq.c
===================================================================
--- linux-cpumask.orig/arch/powerpc/kernel/irq.c 2010-02-01 17:29:03.887211643 +1100
+++ linux-cpumask/arch/powerpc/kernel/irq.c 2010-02-01 17:29:04.738461552 +1100
@@ -77,7 +77,6 @@ DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpusta
EXPORT_PER_CPU_SYMBOL(irq_stat);
int __irq_offset_value;
-static int ppc_spurious_interrupts;
#ifdef CONFIG_PPC32
EXPORT_SYMBOL(__irq_offset_value);
@@ -201,6 +200,11 @@ static int show_other_interrupts(struct
seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs);
seq_printf(p, " Local timer interrupts\n");
+ seq_printf(p, "%*s: ", prec, "SPU");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs);
+ seq_printf(p, " Spurious interrupts\n");
+
seq_printf(p, "%*s: ", prec, "CNT");
for_each_online_cpu(j)
seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
@@ -211,8 +215,6 @@ static int show_other_interrupts(struct
seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
seq_printf(p, " Machine check exceptions\n");
- seq_printf(p, "%*s: %10u\n", prec, "BAD", ppc_spurious_interrupts);
-
return 0;
}
@@ -282,13 +284,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
sum += per_cpu(irq_stat, cpu).pmu_irqs;
sum += per_cpu(irq_stat, cpu).mce_exceptions;
-
- return sum;
-}
-
-u64 arch_irq_stat(void)
-{
- u64 sum = ppc_spurious_interrupts;
+ sum += per_cpu(irq_stat, cpu).spurious_irqs;
return sum;
}
@@ -404,8 +400,7 @@ void do_IRQ(struct pt_regs *regs)
if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)
handle_one_irq(irq);
else if (irq != NO_IRQ_IGNORE)
- /* That's not SMP safe ... but who cares ? */
- ppc_spurious_interrupts++;
+ __get_cpu_var(irq_stat).spurious_irqs++;
irq_exit();
set_irq_regs(old_regs);
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 7/7] powerpc: Increase NR_IRQS Kconfig maximum to 32768
2010-02-01 6:34 ` [PATCH 6/7] powerpc: Convert global "BAD" interrupt to per cpu spurious Anton Blanchard
@ 2010-02-01 6:34 ` Anton Blanchard
0 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2010-02-01 6:34 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
With dynamic irq descriptors the overhead of a large NR_IRQS is much lower
than it used to be. With more MSI-X capable adapters and drivers exploiting
multiple vectors we may as well allow the user to increase it beyond the
current maximum of 512.
32768 seems large enough that we'd never have to bump it again (although I bet
my prediction is horribly wrong). It boot tests OK and the vmlinux footprint
increase is only around 500kB due to:
struct irq_map_entry irq_map[NR_IRQS];
We format /proc/interrupts correctly with the previous changes:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
286: 0 0 0 0 0 0
516: 0 0 0 0 0 0
16689: 1833 0 0 0 0 0
17157: 0 0 0 0 0 0
17158: 319 0 0 0 0 0
25092: 0 0 0 0 0 0
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-cpumask/arch/powerpc/Kconfig
===================================================================
--- linux-cpumask.orig/arch/powerpc/Kconfig 2010-02-01 17:28:56.400961742 +1100
+++ linux-cpumask/arch/powerpc/Kconfig 2010-02-01 17:29:05.609711618 +1100
@@ -58,7 +58,7 @@ config IRQ_PER_CPU
config NR_IRQS
int "Number of virtual interrupt numbers"
- range 32 512
+ range 32 32768
default "512"
help
This defines the number of virtual interrupt numbers the kernel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/7] powerpc: Reduce footprint of irq_stat
2010-02-01 6:30 [PATCH 1/7] powerpc: Reduce footprint of irq_stat Anton Blanchard
2010-02-01 6:32 ` [PATCH 2/7] powerpc: Reduce footprint of xics_ipi_struct Anton Blanchard
@ 2010-02-01 21:55 ` Christoph Hellwig
2010-02-01 23:07 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2010-02-01 21:55 UTC (permalink / raw)
To: Anton Blanchard; +Cc: linuxppc-dev
On Mon, Feb 01, 2010 at 05:30:23PM +1100, Anton Blanchard wrote:
>
> PowerPC is currently using asm-generic/hardirq.h which statically allocates an
> NR_CPUS irq_stat array. Switch to an arch specific implementation which uses
> per cpu data:
>
> On a kernel with NR_CPUS=1024, this saves quite a lot of memory:
>
> text data bss dec hex filename
> 8767938 2944132 1636796 13348866 cbb002 vmlinux.baseline
> 8767779 2944260 1505724 13217763 c9afe3 vmlinux.irq_cpustat
>
> A saving of around 128kB.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>
> Index: linux-cpumask/arch/powerpc/include/asm/hardirq.h
> ===================================================================
> --- linux-cpumask.orig/arch/powerpc/include/asm/hardirq.h 2010-01-31 22:07:21.037211728 +1100
> +++ linux-cpumask/arch/powerpc/include/asm/hardirq.h 2010-02-01 17:28:56.990963256 +1100
> @@ -1 +1,22 @@
> -#include <asm-generic/hardirq.h>
> +#ifndef _ASM_POWERPC_HARDIRQ_H
> +#define _ASM_POWERPC_HARDIRQ_H
> +
> +#include <linux/threads.h>
> +#include <linux/irq.h>
> +
> +typedef struct {
> + unsigned int __softirq_pending;
> +} ____cacheline_aligned irq_cpustat_t;
No need to bother with an irq_cpustat_t type at all in this case, just
declare a softirq_pending per-cpu variable.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/7] powerpc: Reduce footprint of irq_stat
2010-02-01 21:55 ` [PATCH 1/7] powerpc: Reduce footprint of irq_stat Christoph Hellwig
@ 2010-02-01 23:07 ` Benjamin Herrenschmidt
2010-02-02 8:19 ` Christoph Hellwig
0 siblings, 1 reply; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2010-02-01 23:07 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev, Anton Blanchard
On Mon, 2010-02-01 at 22:55 +0100, Christoph Hellwig wrote:
> > +typedef struct {
> > + unsigned int __softirq_pending;
> > +} ____cacheline_aligned irq_cpustat_t;
>
> No need to bother with an irq_cpustat_t type at all in this case, just
> declare a softirq_pending per-cpu variable.
I think his subsequent patches add members to that struct for
CE, MCE etc... stats.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/7] powerpc: Reduce footprint of irq_stat
2010-02-01 23:07 ` Benjamin Herrenschmidt
@ 2010-02-02 8:19 ` Christoph Hellwig
0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2010-02-02 8:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Christoph Hellwig, Anton Blanchard
On Tue, Feb 02, 2010 at 10:07:10AM +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2010-02-01 at 22:55 +0100, Christoph Hellwig wrote:
>
> > > +typedef struct {
> > > + unsigned int __softirq_pending;
> > > +} ____cacheline_aligned irq_cpustat_t;
> >
> > No need to bother with an irq_cpustat_t type at all in this case, just
> > declare a softirq_pending per-cpu variable.
>
> I think his subsequent patches add members to that struct for
> CE, MCE etc... stats.
Well, if you want those in a structure for arch-local reasons please
give them an arch-local name. I really want to get rid of the current
concept of a generic irq_cpustat_t - it doens't make much sense in
it's current form. Instead the API will be the local_softirq_pending()
function/macro with arch specific or a generic implementation.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-02-02 8:19 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-01 6:30 [PATCH 1/7] powerpc: Reduce footprint of irq_stat Anton Blanchard
2010-02-01 6:32 ` [PATCH 2/7] powerpc: Reduce footprint of xics_ipi_struct Anton Blanchard
2010-02-01 6:33 ` [PATCH 3/7] powerpc: Rework /proc/interrupts Anton Blanchard
2010-02-01 6:33 ` [PATCH 4/7] powerpc: Remove whitespace in irq chip name fields Anton Blanchard
2010-02-01 6:34 ` [PATCH 5/7] powerpc: Add timer, performance monitor and machine check counts to /proc/interrupts Anton Blanchard
2010-02-01 6:34 ` [PATCH 6/7] powerpc: Convert global "BAD" interrupt to per cpu spurious Anton Blanchard
2010-02-01 6:34 ` [PATCH 7/7] powerpc: Increase NR_IRQS Kconfig maximum to 32768 Anton Blanchard
2010-02-01 21:55 ` [PATCH 1/7] powerpc: Reduce footprint of irq_stat Christoph Hellwig
2010-02-01 23:07 ` Benjamin Herrenschmidt
2010-02-02 8:19 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).