From: Mathieu Poirier <mathieu.poirier@linaro.org> To: ohad@wizery.com, bjorn.andersson@linaro.org, arnaud.pouliquen@st.com Cc: mcoquelin.stm32@gmail.com, alexandre.torgue@st.com, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v6 11/16] remoteproc: Properly deal with the resource table when attached Date: Tue, 23 Feb 2021 16:35:10 -0700 [thread overview] Message-ID: <20210223233515.3468677-12-mathieu.poirier@linaro.org> (raw) In-Reply-To: <20210223233515.3468677-1-mathieu.poirier@linaro.org> If it is possible to detach the remote processor, keep an untouched copy of the resource table. That way we can start from the same resource table without having to worry about original values or what elements the startup code has changed when re-attaching to the remote processor. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> --- New for V6: - Double free of the cached table has been fixed. - rproc_reset_loaded_rsc_table() has seen a complete re-write. - rproc_stop() now calls rproc_reset_loaded_rsc_table() rather than dealing with the cached. This allows to properly shutdown a remote processor that was attached to. --- drivers/remoteproc/remoteproc_core.c | 86 +++++++++++++++++++++++++++- include/linux/remoteproc.h | 3 + 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index fc01b29290a6..3a4692cc5220 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1556,6 +1556,21 @@ static int rproc_set_loaded_rsc_table(struct rproc *rproc) return ret; } + /* + * If it is possible to detach the remote processor, keep an untouched + * copy of the resource table. That way we can start fresh again when + * the remote processor is re-attached, that is: + * + * DETACHED -> ATTACHED -> DETACHED -> ATTACHED + * + * Free'd in rproc_reset_loaded_rsc_table(). + */ + if (rproc->ops->detach) { + rproc->clean_table = kmemdup(table_ptr, table_sz, GFP_KERNEL); + if (!rproc->clean_table) + return -ENOMEM; + } + rproc->cached_table = NULL; rproc->table_ptr = table_ptr; rproc->table_sz = table_sz; @@ -1563,6 +1578,65 @@ static int rproc_set_loaded_rsc_table(struct rproc *rproc) return 0; } +static int rproc_reset_loaded_rsc_table(struct rproc *rproc) +{ + struct resource_table *table_ptr; + + /* + * The cached table is already set if the remote processor was started + * by the remoteproc core. + */ + if (rproc->state == RPROC_RUNNING) { + rproc->table_ptr = rproc->cached_table; + return 0; + } + + /* A resource table was never retrieved, nothing to do here */ + if (!rproc->table_ptr) + return 0; + + /* + * If we made it to this point a cached_table _must_ have been + * allocated in rproc_set_loaded_rsc_table(). If one isn't present + * something went really wrong and we must complain. + */ + if (WARN_ON(!rproc->clean_table)) + return -EINVAL; + + /* Remember where the external entity installed the resource table */ + table_ptr = rproc->table_ptr; + + /* + * Make a copy of the resource table currently used by the remote + * processor. Free'd in rproc_detach() or rproc_shutdown(). + */ + rproc->cached_table = kmemdup(rproc->table_ptr, + rproc->table_sz, GFP_KERNEL); + if (!rproc->cached_table) + return -ENOMEM; + + /* + * Use a copy of the resource table for the remainder of the + * shutdown process. + */ + rproc->table_ptr = rproc->cached_table; + + /* + * Reset the memory area where the firmware loaded the resource table + * to its original value. That way when we re-attach the remote + * processor the resource table is clean and ready to be used again. + */ + memcpy(table_ptr, rproc->clean_table, rproc->table_sz); + + /* + * The clean resource table is no longer needed. Allocated in + * rproc_set_loaded_rsc_table(). + */ + kfree(rproc->clean_table); + + return 0; +} + /* * Attach to remote processor - similar to rproc_fw_boot() but without * the steps that deal with the firmware image. @@ -1688,7 +1762,11 @@ static int rproc_stop(struct rproc *rproc, bool crashed) rproc_stop_subdevices(rproc, crashed); /* the installed resource table is no longer accessible */ - rproc->table_ptr = rproc->cached_table; + ret = rproc_reset_loaded_rsc_table(rproc); + if (ret) { + dev_err(dev, "can't reset resource table: %d\n", ret); + return ret; + } /* power off the remote processor */ ret = rproc->ops->stop(rproc); @@ -1721,6 +1799,9 @@ static int __rproc_detach(struct rproc *rproc) /* Stop any subdevices for the remote processor */ rproc_stop_subdevices(rproc, false); + /* the installed resource table is no longer accessible */ + ret = rproc_reset_loaded_rsc_table(rproc); + /* Tell the remote processor the core isn't available anymore */ ret = rproc->ops->detach(rproc); if (ret) { @@ -1997,6 +2078,9 @@ int rproc_detach(struct rproc *rproc) rproc_disable_iommu(rproc); + /* Free the copy of the resource table */ + kfree(rproc->cached_table); + rproc->cached_table = NULL; rproc->table_ptr = NULL; out: mutex_unlock(&rproc->lock); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index e1c843c19cc6..e5f52a12a650 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -514,6 +514,8 @@ struct rproc_dump_segment { * @recovery_disabled: flag that state if recovery was disabled * @max_notifyid: largest allocated notify id. * @table_ptr: pointer to the resource table in effect + * @clean_table: copy of the resource table without modifications. Used + * when a remote processor is attached or detached from the core * @cached_table: copy of the resource table * @table_sz: size of @cached_table * @has_iommu: flag to indicate if remote processor is behind an MMU @@ -550,6 +552,7 @@ struct rproc { bool recovery_disabled; int max_notifyid; struct resource_table *table_ptr; + struct resource_table *clean_table; struct resource_table *cached_table; size_t table_sz; bool has_iommu; -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Mathieu Poirier <mathieu.poirier@linaro.org> To: ohad@wizery.com, bjorn.andersson@linaro.org, arnaud.pouliquen@st.com Cc: linux-arm-kernel@lists.infradead.org, linux-remoteproc@vger.kernel.org, alexandre.torgue@st.com, mcoquelin.stm32@gmail.com, linux-kernel@vger.kernel.org Subject: [PATCH v6 11/16] remoteproc: Properly deal with the resource table when attached Date: Tue, 23 Feb 2021 16:35:10 -0700 [thread overview] Message-ID: <20210223233515.3468677-12-mathieu.poirier@linaro.org> (raw) In-Reply-To: <20210223233515.3468677-1-mathieu.poirier@linaro.org> If it is possible to detach the remote processor, keep an untouched copy of the resource table. That way we can start from the same resource table without having to worry about original values or what elements the startup code has changed when re-attaching to the remote processor. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> --- New for V6: - Double free of the cached table has been fixed. - rproc_reset_loaded_rsc_table() has seen a complete re-write. - rproc_stop() now calls rproc_reset_loaded_rsc_table() rather than dealing with the cached. This allows to properly shutdown a remote processor that was attached to. --- drivers/remoteproc/remoteproc_core.c | 86 +++++++++++++++++++++++++++- include/linux/remoteproc.h | 3 + 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index fc01b29290a6..3a4692cc5220 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1556,6 +1556,21 @@ static int rproc_set_loaded_rsc_table(struct rproc *rproc) return ret; } + /* + * If it is possible to detach the remote processor, keep an untouched + * copy of the resource table. That way we can start fresh again when + * the remote processor is re-attached, that is: + * + * DETACHED -> ATTACHED -> DETACHED -> ATTACHED + * + * Free'd in rproc_reset_loaded_rsc_table(). + */ + if (rproc->ops->detach) { + rproc->clean_table = kmemdup(table_ptr, table_sz, GFP_KERNEL); + if (!rproc->clean_table) + return -ENOMEM; + } + rproc->cached_table = NULL; rproc->table_ptr = table_ptr; rproc->table_sz = table_sz; @@ -1563,6 +1578,65 @@ static int rproc_set_loaded_rsc_table(struct rproc *rproc) return 0; } +static int rproc_reset_loaded_rsc_table(struct rproc *rproc) +{ + struct resource_table *table_ptr; + + /* + * The cached table is already set if the remote processor was started + * by the remoteproc core. + */ + if (rproc->state == RPROC_RUNNING) { + rproc->table_ptr = rproc->cached_table; + return 0; + } + + /* A resource table was never retrieved, nothing to do here */ + if (!rproc->table_ptr) + return 0; + + /* + * If we made it to this point a cached_table _must_ have been + * allocated in rproc_set_loaded_rsc_table(). If one isn't present + * something went really wrong and we must complain. + */ + if (WARN_ON(!rproc->clean_table)) + return -EINVAL; + + /* Remember where the external entity installed the resource table */ + table_ptr = rproc->table_ptr; + + /* + * Make a copy of the resource table currently used by the remote + * processor. Free'd in rproc_detach() or rproc_shutdown(). + */ + rproc->cached_table = kmemdup(rproc->table_ptr, + rproc->table_sz, GFP_KERNEL); + if (!rproc->cached_table) + return -ENOMEM; + + /* + * Use a copy of the resource table for the remainder of the + * shutdown process. + */ + rproc->table_ptr = rproc->cached_table; + + /* + * Reset the memory area where the firmware loaded the resource table + * to its original value. That way when we re-attach the remote + * processor the resource table is clean and ready to be used again. + */ + memcpy(table_ptr, rproc->clean_table, rproc->table_sz); + + /* + * The clean resource table is no longer needed. Allocated in + * rproc_set_loaded_rsc_table(). + */ + kfree(rproc->clean_table); + + return 0; +} + /* * Attach to remote processor - similar to rproc_fw_boot() but without * the steps that deal with the firmware image. @@ -1688,7 +1762,11 @@ static int rproc_stop(struct rproc *rproc, bool crashed) rproc_stop_subdevices(rproc, crashed); /* the installed resource table is no longer accessible */ - rproc->table_ptr = rproc->cached_table; + ret = rproc_reset_loaded_rsc_table(rproc); + if (ret) { + dev_err(dev, "can't reset resource table: %d\n", ret); + return ret; + } /* power off the remote processor */ ret = rproc->ops->stop(rproc); @@ -1721,6 +1799,9 @@ static int __rproc_detach(struct rproc *rproc) /* Stop any subdevices for the remote processor */ rproc_stop_subdevices(rproc, false); + /* the installed resource table is no longer accessible */ + ret = rproc_reset_loaded_rsc_table(rproc); + /* Tell the remote processor the core isn't available anymore */ ret = rproc->ops->detach(rproc); if (ret) { @@ -1997,6 +2078,9 @@ int rproc_detach(struct rproc *rproc) rproc_disable_iommu(rproc); + /* Free the copy of the resource table */ + kfree(rproc->cached_table); + rproc->cached_table = NULL; rproc->table_ptr = NULL; out: mutex_unlock(&rproc->lock); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index e1c843c19cc6..e5f52a12a650 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -514,6 +514,8 @@ struct rproc_dump_segment { * @recovery_disabled: flag that state if recovery was disabled * @max_notifyid: largest allocated notify id. * @table_ptr: pointer to the resource table in effect + * @clean_table: copy of the resource table without modifications. Used + * when a remote processor is attached or detached from the core * @cached_table: copy of the resource table * @table_sz: size of @cached_table * @has_iommu: flag to indicate if remote processor is behind an MMU @@ -550,6 +552,7 @@ struct rproc { bool recovery_disabled; int max_notifyid; struct resource_table *table_ptr; + struct resource_table *clean_table; struct resource_table *cached_table; size_t table_sz; bool has_iommu; -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-02-23 23:46 UTC|newest] Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-02-23 23:34 [PATCH v6 00/16] remoteproc: Add support for detaching a remote processor Mathieu Poirier 2021-02-23 23:34 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 01/16] remoteproc: Remove useless check in rproc_del() Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 02/16] remoteproc: Rename function rproc_actuate() Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 03/16] remoteproc: Add new RPROC_ATTACHED state Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 04/16] remoteproc: Properly represent the attached state Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 05/16] remoteproc: Add new get_loaded_rsc_table() to rproc_ops Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:14 ` Arnaud POULIQUEN 2021-02-26 16:14 ` Arnaud POULIQUEN 2021-03-01 18:03 ` Mathieu Poirier 2021-03-01 18:03 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 06/16] remoteproc: stm32: Move resource table setup " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:14 ` Arnaud POULIQUEN 2021-02-26 16:14 ` Arnaud POULIQUEN 2021-02-23 23:35 ` [PATCH v6 07/16] remoteproc: stm32: Move memory parsing " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 08/16] remoteproc: Add new detach() remoteproc operation Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 09/16] remoteproc: Introduce function __rproc_detach() Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:15 ` Arnaud POULIQUEN 2021-02-26 16:15 ` Arnaud POULIQUEN 2021-02-23 23:35 ` [PATCH v6 10/16] remoteproc: Introduce function rproc_detach() Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:15 ` Arnaud POULIQUEN 2021-02-26 16:15 ` Arnaud POULIQUEN 2021-02-23 23:35 ` Mathieu Poirier [this message] 2021-02-23 23:35 ` [PATCH v6 11/16] remoteproc: Properly deal with the resource table when attached Mathieu Poirier 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-03-01 18:41 ` Mathieu Poirier 2021-03-01 18:41 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 12/16] remoteproc: Properly deal with a kernel panic " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 13/16] remoteproc: Properly deal with a start request " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-23 23:35 ` [PATCH v6 14/16] remoteproc: Properly deal with a stop " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-02-23 23:35 ` [PATCH v6 15/16] remoteproc: Properly deal with a detach " Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-02-26 16:21 ` Arnaud POULIQUEN 2021-02-23 23:35 ` [PATCH v6 16/16] remoteproc: Refactor rproc delete and cdev release path Mathieu Poirier 2021-02-23 23:35 ` Mathieu Poirier 2021-02-26 16:23 ` Arnaud POULIQUEN 2021-02-26 16:23 ` Arnaud POULIQUEN 2021-03-01 18:58 ` Mathieu Poirier 2021-03-01 18:58 ` Mathieu Poirier 2021-02-26 16:40 ` [PATCH v6 00/16] remoteproc: Add support for detaching a remote processor Arnaud POULIQUEN 2021-02-26 16:40 ` Arnaud POULIQUEN 2021-03-01 18:58 ` Mathieu Poirier 2021-03-01 18:58 ` Mathieu Poirier
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210223233515.3468677-12-mathieu.poirier@linaro.org \ --to=mathieu.poirier@linaro.org \ --cc=alexandre.torgue@st.com \ --cc=arnaud.pouliquen@st.com \ --cc=bjorn.andersson@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-remoteproc@vger.kernel.org \ --cc=mcoquelin.stm32@gmail.com \ --cc=ohad@wizery.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.