aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/arch/powerpc/platforms/powernv/opal.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2018-05-11 03:20:05 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2018-06-03 20:40:30 +1000
commit56c0b48b1e443efa5d6f4d60513302c934e55b17 (patch)
tree95ae0d148361c2a1eac119173585d3475ddba936 /arch/powerpc/platforms/powernv/opal.c
parentpowerpc/powernv: call OPAL_QUIESCE before OPAL_SIGNAL_SYSTEM_RESET (diff)
downloadwireguard-linux-56c0b48b1e443efa5d6f4d60513302c934e55b17.tar.xz
wireguard-linux-56c0b48b1e443efa5d6f4d60513302c934e55b17.zip
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.c23
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;