powerpc: Reduce footprint of irq_stat
PATCH 1/1 powerpc: Reduce footprint of irq_stat
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.
---
arch/powerpc/include/asm/hardirq.h +22 -1
@@ -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 */
arch/powerpc/kernel/irq.c +3 -0
@@ -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;
PATCH 1/1 powerpc: Reduce footprint of xics_ipi_struct
Right now we allocate a cacheline sized NR_CPUS array for xics IPI communication. Since irq_stat is now PowerPC specific and using DECLARE_PER_CPU_SHARED_ALIGNED (which should mean remote writes to this should not conflict with other per cpu data), we can put it in there.
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.
---
arch/powerpc/include/asm/hardirq.h +3 -0
@@ -6,6 +6,9 @@typedef struct {unsigned int __softirq_pending; +#if defined(CONFIG_XICS ) && defined(CONFIG_SMP ) +unsigned long xics_ipi; +#endif }____cacheline_aligned irq_cpustat_t ;DECLARE_PER_CPU_SHARED_ALIGNED (irq_cpustat_t, irq_stat);
arch/powerpc/platforms/pseries/xics.c +10 -15
@@ -514,15 +514,12 @@ 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 inline void smp_xics_do_message (int cpu,int msg) { -set_bit (msg, &xics_ipi_message[cpu].value); +unsigned long *tgt = &(per_cpu (irq_stat, cpu).xics_ipi); + +set_bit (msg, tgt);mb ();if (firmware_has_feature (FW_FEATURE_LPAR ))lpar_qirr_info (cpu,IPI_PRIORITY );
@@ -548,25 +545,23 @@ void smp_xics_message_pass(int target, istatic irqreturn_t xics_ipi_dispatch (int cpu) { +unsigned long *tgt = &(per_cpu (irq_stat, cpu).xics_ipi); +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
Re: [PATCH] powerpc: Reduce footprint of xics_ipi_struct
arch/powerpc/include/asm/hardirq.h line 12
Quoted 12 lines · Anton Blanchard
Index:
linux-cpumask/arch/powerpc/include/asm/hardirq.h
===================================================================arch/powerpc/include/asm/hardirq.h +3
-0@@ -6,6 +6,9 @@typedef struct {unsigned int __softirq_pending; +#if defined(CONFIG_XICS ) && defined(CONFIG_SMP ) +unsigned long xics_ipi; +#endif }____cacheline_aligned irq_cpustat_t ;
This is still a gross abuse of irq_cpustat_t ... Can't we do a separate DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi) inside xics.c instead ?
Cheers,
Ben.
Quoted 57 lines
arch/powerpc/include/asm/hardirq.h +0
-0DECLARE_PER_CPU_SHARED_ALIGNED (irq_cpustat_t, irq_stat);Index:
linux-cpumask/arch/powerpc/platforms/pseries/xics.c
===================================================================arch/powerpc/platforms/pseries/xics.c +10
-15@@ -514,15 +514,12 @@ 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 inline void smp_xics_do_message (int cpu,int msg) { -set_bit (msg, &xics_ipi_message[cpu].value); +unsigned long *tgt = &(per_cpu (irq_stat, cpu).xics_ipi); + +set_bit (msg, tgt);mb ();if (firmware_has_feature (FW_FEATURE_LPAR ))lpar_qirr_info (cpu,IPI_PRIORITY );@@ -548,25 +545,23 @@ void smp_xics_message_pass(int target, istatic irqreturn_t xics_ipi_dispatch (int cpu) { +unsigned long *tgt = &(per_cpu (irq_stat, cpu).xics_ipi); +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
Re: [PATCH] powerpc: Reduce footprint of xics_ipi_struct
Hi,
Quoted 8 lines
arch/powerpc/include/asm/hardirq.h line 12
Quoted 4 lines
arch/powerpc/include/asm/hardirq.h +3
-0+#if defined(CONFIG_XICS ) && defined(CONFIG_SMP ) +unsigned long xics_ipi; +#endif }____cacheline_aligned irq_cpustat_t;This is still a gross abuse of
irq_cpustat_t... Can't we do a separateDECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi)insidexics.cinstead ?
Yeah it was a bit tasteless :) Respinning...
Anton
Quoted 5 lines
arch/powerpc/include/asm/hardirq.h +4
-0+typedef struct { +unsigned int __softirq_pending; +}____cacheline_aligned irq_cpustat_t ; +
arch/powerpc/include/asm/hardirq.h line 20
Quoted 10 lines
arch/powerpc/include/asm/hardirq.h +10
-0+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); +}
Looks like some unrelated gunk slipped into this patch :-)
Cheers,
Ben.
Hi,
Quoted 6 lines
arch/powerpc/include/asm/hardirq.h line 20
Quoted 4 lines
arch/powerpc/include/asm/hardirq.h +4
-0+static inline void ack_bad_irq (unsigned int irq) +{ +printk (KERN_CRIT "unexpected IRQ trap at vector %02x\n" , irq); +}Looks like some unrelated gunk slipped into this patch :-)
We need that to link :)
kernel/irq/handle.c: In function ‘handle_bad_irq’:kernel/irq/handle.c:43: error: implicit declaration of function ‘ack_bad_irq’
It's basically a copy of the fallback handler in the asm-generic hardirq.h I'm happy to change it print "IRQ on fire" :)
Anton