Commit fda9d861 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt

powerpc: Reduce footprint of xics_ipi_struct

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: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 8c007bfd
...@@ -510,15 +510,13 @@ static void __init xics_init_host(void) ...@@ -510,15 +510,13 @@ static void __init xics_init_host(void)
/* /*
* XICS only has a single IPI, so encode the messages per CPU * XICS only has a single IPI, so encode the messages per CPU
*/ */
struct xics_ipi_struct { static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
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) 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(); mb();
if (firmware_has_feature(FW_FEATURE_LPAR)) if (firmware_has_feature(FW_FEATURE_LPAR))
lpar_qirr_info(cpu, IPI_PRIORITY); lpar_qirr_info(cpu, IPI_PRIORITY);
...@@ -544,25 +542,23 @@ void smp_xics_message_pass(int target, int msg) ...@@ -544,25 +542,23 @@ void smp_xics_message_pass(int target, int msg)
static irqreturn_t xics_ipi_dispatch(int cpu) static irqreturn_t xics_ipi_dispatch(int cpu)
{ {
unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
WARN_ON(cpu_is_offline(cpu)); WARN_ON(cpu_is_offline(cpu));
mb(); /* order mmio clearing qirr */ mb(); /* order mmio clearing qirr */
while (xics_ipi_message[cpu].value) { while (*tgt) {
if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) {
&xics_ipi_message[cpu].value)) {
smp_message_recv(PPC_MSG_CALL_FUNCTION); smp_message_recv(PPC_MSG_CALL_FUNCTION);
} }
if (test_and_clear_bit(PPC_MSG_RESCHEDULE, if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) {
&xics_ipi_message[cpu].value)) {
smp_message_recv(PPC_MSG_RESCHEDULE); smp_message_recv(PPC_MSG_RESCHEDULE);
} }
if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) {
&xics_ipi_message[cpu].value)) {
smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
} }
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) {
&xics_ipi_message[cpu].value)) {
smp_message_recv(PPC_MSG_DEBUGGER_BREAK); smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment