From 81d5a33c5aa79a15d3e1ebca8c5f226bb68b954a Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Thu, 9 Mar 2017 20:35:20 -0600 Subject: [PATCH] remoteproc: fix multiple back-to-back error recoveries The remoteproc core uses a dedicated work item per remote processor to perform an error recovery of that processor. This work item is always scheduled upon notification of an error at the moment. The error recovery process itself is performed when the workqueue gets scheduled and executes the work function, but an error recovery needs to be performed only once if there are multiple notifications while an existing error recovery is in progress. Fix this by adding a check to make sure the remote processor error recovery work item is not already running or scheduled. This fixes an issue with error recovery upon MMU Faults on OMAP IPU remote processors. An MMU fault on OMAP IPU sends two error notifications - one a direct interrupt from the MMU, and the second a mailbox-based crash notification after the remote processor has collected some backtrace. The mailbox based interrupt mechanism, added in commit 7f275d21e240 ("remoteproc/omap: report device exceptions and trigger recovery"), is used for Attribute MMU (AMMU) faults and other internal exceptions on the IPU. The backtrace collection on the IPU remote processor is triggered by the same interrupt which cannot be differentiated between an MMU fault and an AMMU fault. The remoteproc core changes in 4.9 kernel around the boot sequences has now caused the second notification to trigger a secondary error recovery, which was avoided in previous kernels due to the event detection in the work-function itself. The newer code sequences changes the timing w.r.t previous kernels where the recovery process was performed a bit later due to the asynchronous firmware loading. Signed-off-by: Suman Anna --- drivers/remoteproc/remoteproc_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 30e02198bb30..9e33dbee6e20 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2037,8 +2037,9 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type) dev_err(&rproc->dev, "crash detected in %s: type %s\n", rproc->name, rproc_crash_to_string(type)); - /* create a new task to handle the error */ - schedule_work(&rproc->crash_handler); + /* create a new task to handle the error if not scheduled already */ + if (!work_busy(&rproc->crash_handler)) + schedule_work(&rproc->crash_handler); } EXPORT_SYMBOL(rproc_report_crash); -- 2.39.2