From patchwork Thu Aug 30 18:26:13 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guzman Lugo, Fernando" X-Patchwork-Id: 1389201 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 24E623FDF5 for ; Thu, 30 Aug 2012 18:30:28 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1T79SE-0004Io-Qf; Thu, 30 Aug 2012 18:26:58 +0000 Received: from na3sys009aog131.obsmtp.com ([74.125.149.247]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1T79Rv-0004Hc-Oz for linux-arm-kernel@lists.infradead.org; Thu, 30 Aug 2012 18:26:42 +0000 Received: from mail-ob0-f177.google.com ([209.85.214.177]) (using TLSv1) by na3sys009aob131.postini.com ([74.125.148.12]) with SMTP ID DSNKUD+wXgvSpHQsLlrGrkGNoZtNzj0xeIjP@postini.com; Thu, 30 Aug 2012 11:26:39 PDT Received: by obbta17 with SMTP id ta17so4159396obb.36 for ; Thu, 30 Aug 2012 11:26:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=hezL94kQL6h4DAaI091/B8cVLCCC9yTysP1gL5SAGAc=; b=XAC/GTtKI+EwB8L80BvJd19oMNj+6EUTMoGhl65+I0Bb9q5CIKG+aslmnb6+2Xp/Ac x1npNZjeR4bg/uJ5AtUBmhZrdcLpqzUBkGA8cE+BTFQ473FyfCm7FydzLA/RcbicysRP 0I0Ar6Y9naKP3uV8weeFLsy8TFTvVFXF5WeeQktOYDA9UK4C1lfsHRXA+uY+thByl5Rw iCS6YxhGnsym0v2KDslbbBXv0a/QfRfpY0rvyYNXwk7pZvivkhDzPYky9ImqaJ5UW+PP pEsQSVHeq0uHaGp3YBFhj/XRNjm0tWOccX1etENGm3kuqQuOr6iZ/uywSwMEk+/TFFO5 Yw9w== Received: by 10.182.48.8 with SMTP id h8mr5588491obn.75.1346351197631; Thu, 30 Aug 2012 11:26:37 -0700 (PDT) Received: from localhost.localdomain (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id d6sm1950349obx.15.2012.08.30.11.26.36 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 30 Aug 2012 11:26:36 -0700 (PDT) From: Fernando Guzman Lugo To: , , , Subject: [PATCHv2 2/3] remoteproc: recover a remoteproc when it has crashed Date: Thu, 30 Aug 2012 13:26:13 -0500 Message-Id: <1346351174-28441-3-git-send-email-fernando.lugo@ti.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1346351174-28441-1-git-send-email-fernando.lugo@ti.com> References: <1346351174-28441-1-git-send-email-fernando.lugo@ti.com> X-Gm-Message-State: ALoCoQnW89zjS3tt5ueqiF9Q9UsVtlTluHbBTmY31vQ6Un21pBvwSTIaWUfQ/U7Ly+ceMUAtr4U3 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [74.125.149.247 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Fernando Guzman Lugo X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org This patch is introducing rproc_trigger_recover function which is in charge of recovering the rproc. One way to recover the rproc after a crash is resetting all its virtio devices. Doing that, all rpmsg drivers are restored along with the rpmsg devices and that also causes the reset of the remoteproc making the rpmsg communication with the remoteproc functional again. So far, rproc_trigger_recover function is only resetting all virtio devices, if in the future other rproc features are introduced and need to be reset too, rproc_trigger_recover function should take care of that. Signed-off-by: Fernando Guzman Lugo --- drivers/remoteproc/remoteproc_core.c | 37 +++++++++++++++++++++++++++++- drivers/remoteproc/remoteproc_internal.h | 1 + include/linux/remoteproc.h | 2 + 3 files changed, 39 insertions(+), 1 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3a6f1a1..9fbd364 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -882,6 +882,36 @@ out: } /** + * rproc_trigger_recover() - recover a remoteproc + * @rproc: the remote processor + * + * The recovery is done by reseting all the virtio devices, that way all the + * rpmsg drivers will be reseted along with the remote processor making the + * remoteproc functional again. + * + * This function can sleep, so that it cannot be called from atomic context. + */ +int rproc_trigger_recover(struct rproc *rproc) +{ + struct rproc_vdev *rvdev, *rvtmp; + + dev_err(&rproc->dev, "recovering %s\n", rproc->name); + + init_completion(&rproc->crash_comp); + /* clean up remote vdev entries */ + list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) + rproc_remove_virtio_dev(rvdev); + + /* wait until there is no more rproc users */ + wait_for_completion(&rproc->crash_comp); + + /* run rproc_fw_config_virtio to create vdevs again */ + return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + rproc->firmware, &rproc->dev, GFP_KERNEL, + rproc, rproc_fw_config_virtio); +} + +/** * rproc_crash_handler_work() - handle a crash * * This function needs to handle everything related to a crash, like cpu @@ -906,7 +936,7 @@ static void rproc_crash_handler_work(struct work_struct *work) ++rproc->crash_cnt, rproc->name); mutex_unlock(&rproc->lock); - /* TODO: handle crash */ + rproc_trigger_recover(rproc); } /** @@ -1030,6 +1060,10 @@ void rproc_shutdown(struct rproc *rproc) rproc_disable_iommu(rproc); + /* if in crash state, unlock crash handler */ + if (rproc->state == RPROC_CRASHED) + complete_all(&rproc->crash_comp); + rproc->state = RPROC_OFFLINE; dev_info(dev, "stopped remote processor %s\n", rproc->name); @@ -1204,6 +1238,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, INIT_LIST_HEAD(&rproc->rvdevs); INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work); + init_completion(&rproc->crash_comp); rproc->state = RPROC_OFFLINE; diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index a690ebe..d9c0730 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -63,6 +63,7 @@ void rproc_free_vring(struct rproc_vring *rvring); int rproc_alloc_vring(struct rproc_vdev *rvdev, int i); void *rproc_da_to_va(struct rproc *rproc, u64 da, int len); +int rproc_trigger_recover(struct rproc *rproc); static inline int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw) diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index a46ed27..0c1a2f9 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -398,6 +398,7 @@ enum rproc_crash_type { * @index: index of this rproc device * @crash_handler: workqueue for handling a crash * @crash_cnt: crash counter + * @crash_comp: completion used to sync crash handler and the rproc reload */ struct rproc { struct klist_node node; @@ -423,6 +424,7 @@ struct rproc { int index; struct work_struct crash_handler; unsigned crash_cnt; + struct completion crash_comp; }; /* we currently support only two vrings per rvdev */