diff options
| -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 |
