Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Anton Blanchard and committed by
Benjamin Herrenschmidt
fda9d861 8c007bfd

+11 -15
+11 -15
arch/powerpc/platforms/pseries/xics.c
··· 510 510 /* 511 511 * XICS only has a single IPI, so encode the messages per CPU 512 512 */ 513 - struct xics_ipi_struct { 514 - unsigned long value; 515 - } ____cacheline_aligned; 516 - 517 - static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; 513 + static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message); 518 514 519 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 520 mb(); 523 521 if (firmware_has_feature(FW_FEATURE_LPAR)) 524 522 lpar_qirr_info(cpu, IPI_PRIORITY); ··· 542 544 543 545 static irqreturn_t xics_ipi_dispatch(int cpu) 544 546 { 547 + unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); 548 + 545 549 WARN_ON(cpu_is_offline(cpu)); 546 550 547 551 mb(); /* order mmio clearing qirr */ 548 - while (xics_ipi_message[cpu].value) { 549 - if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, 550 - &xics_ipi_message[cpu].value)) { 552 + while (*tgt) { 553 + if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { 551 554 smp_message_recv(PPC_MSG_CALL_FUNCTION); 552 555 } 553 - if (test_and_clear_bit(PPC_MSG_RESCHEDULE, 554 - &xics_ipi_message[cpu].value)) { 556 + if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) { 555 557 smp_message_recv(PPC_MSG_RESCHEDULE); 556 558 } 557 - if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, 558 - &xics_ipi_message[cpu].value)) { 559 + if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) { 559 560 smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); 560 561 } 561 562 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 562 - if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, 563 - &xics_ipi_message[cpu].value)) { 563 + if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) { 564 564 smp_message_recv(PPC_MSG_DEBUGGER_BREAK); 565 565 } 566 566 #endif