diff options
author | Anton Blanchard <anton@samba.org> | 2010-01-31 15:32:51 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-02-16 22:02:48 -0500 |
commit | fda9d86100e0b412d0c8a16abe0651c8c8e39e81 (patch) | |
tree | dccc2fce96c47f35e8f18c282a842fa8113a2e2d /arch/powerpc/platforms | |
parent | 8c007bfdf1bab536f824d91fccc76596c18aba78 (diff) |
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: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 63eaa8a220c0..41374e830eb1 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -510,15 +510,13 @@ static void __init xics_init_host(void) | |||
510 | /* | 510 | /* |
511 | * XICS only has a single IPI, so encode the messages per CPU | 511 | * XICS only has a single IPI, so encode the messages per CPU |
512 | */ | 512 | */ |
513 | struct xics_ipi_struct { | 513 | static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message); |
514 | unsigned long value; | ||
515 | } ____cacheline_aligned; | ||
516 | |||
517 | static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
518 | 514 | ||
519 | static inline void smp_xics_do_message(int cpu, int msg) | 515 | static inline void smp_xics_do_message(int cpu, int msg) |
520 | { | 516 | { |
521 | set_bit(msg, &xics_ipi_message[cpu].value); | 517 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); |
518 | |||
519 | set_bit(msg, tgt); | ||
522 | mb(); | 520 | mb(); |
523 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 521 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
524 | lpar_qirr_info(cpu, IPI_PRIORITY); | 522 | lpar_qirr_info(cpu, IPI_PRIORITY); |
@@ -544,25 +542,23 @@ void smp_xics_message_pass(int target, int msg) | |||
544 | 542 | ||
545 | static irqreturn_t xics_ipi_dispatch(int cpu) | 543 | static irqreturn_t xics_ipi_dispatch(int cpu) |
546 | { | 544 | { |
545 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); | ||
546 | |||
547 | WARN_ON(cpu_is_offline(cpu)); | 547 | WARN_ON(cpu_is_offline(cpu)); |
548 | 548 | ||
549 | mb(); /* order mmio clearing qirr */ | 549 | mb(); /* order mmio clearing qirr */ |
550 | while (xics_ipi_message[cpu].value) { | 550 | while (*tgt) { |
551 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, | 551 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { |
552 | &xics_ipi_message[cpu].value)) { | ||
553 | smp_message_recv(PPC_MSG_CALL_FUNCTION); | 552 | smp_message_recv(PPC_MSG_CALL_FUNCTION); |
554 | } | 553 | } |
555 | if (test_and_clear_bit(PPC_MSG_RESCHEDULE, | 554 | if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) { |
556 | &xics_ipi_message[cpu].value)) { | ||
557 | smp_message_recv(PPC_MSG_RESCHEDULE); | 555 | smp_message_recv(PPC_MSG_RESCHEDULE); |
558 | } | 556 | } |
559 | if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, | 557 | if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) { |
560 | &xics_ipi_message[cpu].value)) { | ||
561 | smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); | 558 | smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); |
562 | } | 559 | } |
563 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) | 560 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) |
564 | if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, | 561 | if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) { |
565 | &xics_ipi_message[cpu].value)) { | ||
566 | smp_message_recv(PPC_MSG_DEBUGGER_BREAK); | 562 | smp_message_recv(PPC_MSG_DEBUGGER_BREAK); |
567 | } | 563 | } |
568 | #endif | 564 | #endif |