From: Vignesh Viswanathan <quic_viswanat@quicinc.com>
To: Mukesh Ojha <quic_mojha@quicinc.com>, <agross@kernel.org>,
<andersson@kernel.org>, <konrad.dybcio@linaro.org>,
<mathieu.poirier@linaro.org>, <linux-arm-msm@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
<linux-remoteproc@vger.kernel.org>
Cc: <quic_srichara@quicinc.com>, <quic_varada@quicinc.com>,
<quic_kathirav@quicinc.com>, <quic_devipriy@quicinc.com>,
<quic_sjaganat@quicinc.com>
Subject: Re: [PATCH] remoteproc: qcom: Add NOTIFY_FATAL event type to SSR subdevice
Date: Thu, 15 Jun 2023 16:10:13 +0530 [thread overview]
Message-ID: <d6b07470-983b-fd50-6b88-239ab0607e39@quicinc.com> (raw)
In-Reply-To: <3687b420-0993-7f76-7116-114b1784de05@quicinc.com>
On 5/29/2023 9:27 AM, Vignesh Viswanathan wrote:
> Gentle Reminder.
>
> On 5/22/2023 3:03 PM, Mukesh Ojha wrote:
>>
>>
>> On 5/3/2023 4:56 PM, Mukesh Ojha wrote:
>>>
>>>
>>> On 5/3/2023 11:51 AM, Vignesh Viswanathan wrote:
>>>> Currently the SSR subdevice notifies the client driver on crash of the
>>>> rproc from the recovery workqueue using the BEFORE_SHUTDOWN event.
>>>> However the client driver might be interested to know that the device
>>>> has crashed immediately to pause any further transactions with the
>>>> rproc. This calls for an event to be sent to the driver in the IRQ
>>>> context as soon as the rproc crashes.
>>>>
>>>> Add NOTIFY_FATAL event to SSR subdevice to atomically notify rproc has
>>>> crashed to the client driver.
>>>>
>>>> Validated the event in IPQ9574 and IPQ5332 by forcing the rproc to
>>>> crash
>>>> and ensuring the registered notifier function receives the notification
>>>> in IRQ context.
>>>
>>> This was one of valid use case we encounter in android, We have some
>>> other way of doing the same thing without core kernel change with
>>> something called early notifiers.
>>>
>>> https://git.codelinaro.org/clo/la/kernel/msm-5.15/-/commit/7583d24de337aa1bf7c375a7da706af9b995b9a1#a840754ebb0e24e88adbf48177e1abd0830b72d2
>>>
>>> https://git.codelinaro.org/clo/la/kernel/msm-5.15/-/commit/257de41c63a5a51a081cc7887cdaa4a46e4d1744
>>>
>>> But good to address this if possible.
>>
>> Ack the idea of early notifier;
>> But here, atomic does not guarantees it to be atomic.
>>
>> Acked-by: Mukesh Ojha <quic_mojha@quicinc.com>
>>
>> -- Mukesh
>>
Gentle Reminder!
Thanks,
Vignesh
>>
>>>
>>> -Mukesh
>>>>
>>>> Signed-off-by: Vignesh Viswanathan <quic_viswanat@quicinc.com>
>>>> ---
>>>> drivers/remoteproc/qcom_common.c | 60
>>>> +++++++++++++++++++++++++++
>>>> drivers/remoteproc/remoteproc_core.c | 12 ++++++
>>>> include/linux/remoteproc.h | 3 ++
>>>> include/linux/remoteproc/qcom_rproc.h | 17 ++++++++
>>>> 4 files changed, 92 insertions(+)
>>>>
>>>> diff --git a/drivers/remoteproc/qcom_common.c
>>>> b/drivers/remoteproc/qcom_common.c
>>>> index a0d4238492e9..76542229aeb6 100644
>>>> --- a/drivers/remoteproc/qcom_common.c
>>>> +++ b/drivers/remoteproc/qcom_common.c
>>>> @@ -84,6 +84,7 @@ struct minidump_global_toc {
>>>> struct qcom_ssr_subsystem {
>>>> const char *name;
>>>> struct srcu_notifier_head notifier_list;
>>>> + struct atomic_notifier_head atomic_notifier_list;
>>>> struct list_head list;
>>>> };
>>>> @@ -366,6 +367,7 @@ static struct qcom_ssr_subsystem
>>>> *qcom_ssr_get_subsys(const char *name)
>>>> }
>>>> info->name = kstrdup_const(name, GFP_KERNEL);
>>>> srcu_init_notifier_head(&info->notifier_list);
>>>> + ATOMIC_INIT_NOTIFIER_HEAD(&info->atomic_notifier_list);
>>>> /* Add to global notification list */
>>>> list_add_tail(&info->list, &qcom_ssr_subsystem_list);
>>>> @@ -417,6 +419,51 @@ int qcom_unregister_ssr_notifier(void *notify,
>>>> struct notifier_block *nb)
>>>> }
>>>> EXPORT_SYMBOL_GPL(qcom_unregister_ssr_notifier);
>>>> +/**
>>>> + * qcom_register_ssr_atomic_notifier() - register SSR Atomic
>>>> notification
>>>> + * handler
>>>> + * @name: Subsystem's SSR name
>>>> + * @nb: notifier_block to be invoked upon subsystem's state change
>>>> + *
>>>> + * This registers the @nb notifier block as part the atomic notifier
>>>> + * chain for a remoteproc associated with @name. The notifier
>>>> block's callback
>>>> + * will be invoked when the remote processor crashes in atomic
>>>> context before
>>>> + * the recovery process is queued.
>>>> + *
>>>> + * Return: a subsystem cookie on success, ERR_PTR on failure.
>>>> + */
>>>> +void *qcom_register_ssr_atomic_notifier(const char *name,
>>>> + struct notifier_block *nb)
>>>> +{
>>>> + struct qcom_ssr_subsystem *info;
>>>> +
>>>> + info = qcom_ssr_get_subsys(name);
>>>> + if (IS_ERR(info))
>>>> + return info;
>>>> +
>>>> + atomic_notifier_chain_register(&info->atomic_notifier_list, nb);
>>>> +
>>>> + return &info->atomic_notifier_list;
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(qcom_register_ssr_atomic_notifier);
>>>> +
>>>> +/**
>>>> + * qcom_unregister_ssr_atomic_notifier() - unregister SSR Atomic
>>>> notification
>>>> + * handler
>>>> + * @notify: subsystem cookie returned from
>>>> qcom_register_ssr_notifier
>>>> + * @nb: notifier_block to unregister
>>>> + *
>>>> + * This function will unregister the notifier from the atomic notifier
>>>> + * chain.
>>>> + *
>>>> + * Return: 0 on success, %ENOENT otherwise.
>>>> + */
>>>> +int qcom_unregister_ssr_atomic_notifier(void *notify, struct
>>>> notifier_block *nb)
>>>> +{
>>>> + return atomic_notifier_chain_unregister(notify, nb);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(qcom_unregister_ssr_atomic_notifier);
>>>> +
>>>> static int ssr_notify_prepare(struct rproc_subdev *subdev)
>>>> {
>>>> struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);
>>>> @@ -467,6 +514,18 @@ static void ssr_notify_unprepare(struct
>>>> rproc_subdev *subdev)
>>>> QCOM_SSR_AFTER_SHUTDOWN, &data);
>>>> }
>>>> +static void ssr_notify_crash(struct rproc_subdev *subdev)
>>>> +{
>>>> + struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);
>>>> + struct qcom_ssr_notify_data data = {
>>>> + .name = ssr->info->name,
>>>> + .crashed = true,
>>>> + };
>>>> +
>>>> + atomic_notifier_call_chain(&ssr->info->atomic_notifier_list,
>>>> + QCOM_SSR_NOTIFY_CRASH, &data);
>>>> +}
>>>> +
>>>> /**
>>>> * qcom_add_ssr_subdev() - register subdevice as restart
>>>> notification source
>>>> * @rproc: rproc handle
>>>> @@ -493,6 +552,7 @@ void qcom_add_ssr_subdev(struct rproc *rproc,
>>>> struct qcom_rproc_ssr *ssr,
>>>> ssr->subdev.start = ssr_notify_start;
>>>> ssr->subdev.stop = ssr_notify_stop;
>>>> ssr->subdev.unprepare = ssr_notify_unprepare;
>>>> + ssr->subdev.notify_crash = ssr_notify_crash;
>>>> rproc_add_subdev(rproc, &ssr->subdev);
>>>> }
>>>> diff --git a/drivers/remoteproc/remoteproc_core.c
>>>> b/drivers/remoteproc/remoteproc_core.c
>>>> index 695cce218e8c..3de0ece158ea 100644
>>>> --- a/drivers/remoteproc/remoteproc_core.c
>>>> +++ b/drivers/remoteproc/remoteproc_core.c
>>>> @@ -1139,6 +1139,16 @@ static void rproc_unprepare_subdevices(struct
>>>> rproc *rproc)
>>>> }
>>>> }
>>>> +static void rproc_notify_crash_subdevices(struct rproc *rproc)
>>>> +{
>>>> + struct rproc_subdev *subdev;
>>>> +
>>>> + list_for_each_entry_reverse(subdev, &rproc->subdevs, node) {
>>>> + if (subdev->notify_crash)
>>>> + subdev->notify_crash(subdev);
>>>> + }
>>>> +}
>>>> +
>>>> /**
>>>> * rproc_alloc_registered_carveouts() - allocate all carveouts
>>>> registered
>>>> * in the list
>>>> @@ -2687,6 +2697,8 @@ 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));
>>>> + rproc_notify_crash_subdevices(rproc);
>>>> +
>>>> queue_work(rproc_recovery_wq, &rproc->crash_handler);
>>>> }
>>>> EXPORT_SYMBOL(rproc_report_crash);
>>>> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
>>>> index fe8978eb69f1..f3c0e0103e81 100644
>>>> --- a/include/linux/remoteproc.h
>>>> +++ b/include/linux/remoteproc.h
>>>> @@ -596,6 +596,8 @@ struct rproc {
>>>> * @stop: stop function, called before the rproc is stopped; the
>>>> @crashed
>>>> * parameter indicates if this originates from a recovery
>>>> * @unprepare: unprepare function, called after the rproc has been
>>>> stopped
>>>> + * @notify_crash: notify_crash function, called in atomic context
>>>> to notify
>>>> + * rproc has crashed and recovery is about to start
>>>> */
>>>> struct rproc_subdev {
>>>> struct list_head node;
>>>> @@ -604,6 +606,7 @@ struct rproc_subdev {
>>>> int (*start)(struct rproc_subdev *subdev);
>>>> void (*stop)(struct rproc_subdev *subdev, bool crashed);
>>>> void (*unprepare)(struct rproc_subdev *subdev);
>>>> + void (*notify_crash)(struct rproc_subdev *subdev);
>>>> };
>>>> /* we currently support only two vrings per rvdev */
>>>> diff --git a/include/linux/remoteproc/qcom_rproc.h
>>>> b/include/linux/remoteproc/qcom_rproc.h
>>>> index 82b211518136..f3d06900f297 100644
>>>> --- a/include/linux/remoteproc/qcom_rproc.h
>>>> +++ b/include/linux/remoteproc/qcom_rproc.h
>>>> @@ -11,12 +11,14 @@ struct notifier_block;
>>>> * @QCOM_SSR_AFTER_POWERUP: Remoteproc is running (start stage)
>>>> * @QCOM_SSR_BEFORE_SHUTDOWN: Remoteproc crashed or shutting
>>>> down (stop stage)
>>>> * @QCOM_SSR_AFTER_SHUTDOWN: Remoteproc is down (unprepare stage)
>>>> + * @QCOM_SSR_NOTIFY_CRASH: Remoteproc crashed
>>>> */
>>>> enum qcom_ssr_notify_type {
>>>> QCOM_SSR_BEFORE_POWERUP,
>>>> QCOM_SSR_AFTER_POWERUP,
>>>> QCOM_SSR_BEFORE_SHUTDOWN,
>>>> QCOM_SSR_AFTER_SHUTDOWN,
>>>> + QCOM_SSR_NOTIFY_CRASH,
>>>> };
>>>> struct qcom_ssr_notify_data {
>>>> @@ -29,6 +31,10 @@ struct qcom_ssr_notify_data {
>>>> void *qcom_register_ssr_notifier(const char *name, struct
>>>> notifier_block *nb);
>>>> int qcom_unregister_ssr_notifier(void *notify, struct
>>>> notifier_block *nb);
>>>> +void *qcom_register_ssr_atomic_notifier(const char *name,
>>>> + struct notifier_block *nb);
>>>> +int qcom_unregister_ssr_atomic_notifier(void *notify,
>>>> + struct notifier_block *nb);
>>>> #else
>>>> static inline void *qcom_register_ssr_notifier(const char *name,
>>>> @@ -43,6 +49,17 @@ static inline int
>>>> qcom_unregister_ssr_notifier(void *notify,
>>>> return 0;
>>>> }
>>>> +static inline void *qcom_register_ssr_atomic_notifier(const char
>>>> *name,
>>>> + struct notifier_block *nb)
>>>> +{
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static inline int qcom_unregister_ssr_atomic_notifier(void *notify,
>>>> + struct notifier_block *nb)
>>>> +{
>>>> + return 0;
>>>> +}
>>>> #endif
>>>> #endif
>>>
next prev parent reply other threads:[~2023-06-15 10:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-03 6:21 Vignesh Viswanathan
2023-05-03 11:26 ` Mukesh Ojha
2023-05-22 9:33 ` Mukesh Ojha
2023-05-29 3:57 ` Vignesh Viswanathan
2023-06-15 10:40 ` Vignesh Viswanathan [this message]
2023-07-11 8:00 ` Vignesh Viswanathan
2023-07-15 20:20 ` Bjorn Andersson
2023-09-04 16:53 ` Vignesh Viswanathan
2023-11-24 18:54 ` Vignesh Viswanathan
2024-02-07 16:21 ` Vignesh Viswanathan
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=d6b07470-983b-fd50-6b88-239ab0607e39@quicinc.com \
--to=quic_viswanat@quicinc.com \
--cc=agross@kernel.org \
--cc=andersson@kernel.org \
--cc=konrad.dybcio@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
--cc=quic_devipriy@quicinc.com \
--cc=quic_kathirav@quicinc.com \
--cc=quic_mojha@quicinc.com \
--cc=quic_sjaganat@quicinc.com \
--cc=quic_srichara@quicinc.com \
--cc=quic_varada@quicinc.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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®