diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2018-05-10 20:20:05 +0300 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-06-03 13:40:30 +0300 |
commit | 56c0b48b1e443efa5d6f4d60513302c934e55b17 (patch) | |
tree | 95ae0d148361c2a1eac119173585d3475ddba936 /arch/powerpc/platforms/powernv/opal.c | |
parent | ee03b9b4479d1302d01cebedda3518dc967697b7 (diff) | |
download | linux-56c0b48b1e443efa5d6f4d60513302c934e55b17.tar.xz |
powerpc/powernv: process all OPAL event interrupts with kopald
Using irq_work for processing OPAL event interrupts is not necessary.
irq_work is typically used to schedule work from NMI context, a
softirq may be more appropriate. However OPAL events are not
particularly performance or latency critical, so they can all be
invoked by kopald.
This patch removes the irq_work queueing, and instead wakes up
kopald when there is an event to be processed. kopald processes
interrupts individually, enabling irqs and calling cond_resched
between each one to minimise latencies.
Event handlers themselves should still use threaded handlers,
workqueues, etc. as necessary to avoid high interrupts-off latencies
within any single interrupt.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv/opal.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 48fbb41af5d1..0d539c661748 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -540,21 +540,15 @@ int opal_hmi_exception_early(struct pt_regs *regs) /* HMI exception handler called in virtual mode during check_irq_replay. */ int opal_handle_hmi_exception(struct pt_regs *regs) { - s64 rc; - __be64 evt = 0; - /* * Check if HMI event is available. - * if Yes, then call opal_poll_events to pull opal messages and - * process them. + * if Yes, then wake kopald to process them. */ if (!local_paca->hmi_event_available) return 0; local_paca->hmi_event_available = 0; - rc = opal_poll_events(&evt); - if (rc == OPAL_SUCCESS && evt) - opal_handle_events(be64_to_cpu(evt)); + opal_wake_poller(); return 1; } @@ -757,14 +751,19 @@ static void __init opal_imc_init_dev(void) static int kopald(void *unused) { unsigned long timeout = msecs_to_jiffies(opal_heartbeat) + 1; - __be64 events; set_freezable(); do { try_to_freeze(); - opal_poll_events(&events); - opal_handle_events(be64_to_cpu(events)); - schedule_timeout_interruptible(timeout); + + opal_handle_events(); + + set_current_state(TASK_INTERRUPTIBLE); + if (opal_have_pending_events()) + __set_current_state(TASK_RUNNING); + else + schedule_timeout(timeout); + } while (!kthread_should_stop()); return 0; |