* [PATCH] remoteproc: qcom: Add notification timeouts
@ 2020-10-30 0:10 Rishabh Bhatnagar
0 siblings, 0 replies; only message in thread
From: Rishabh Bhatnagar @ 2020-10-30 0:10 UTC (permalink / raw)
To: linux-remoteproc, linux-kernel, bjorn.andersson
Cc: tsoni, psodagud, sidgup, Rishabh Bhatnagar
Clients can register their callbacks for power-on/off notifications
of remote processors. While executing the notifier chain sometimes
these callbacks may get stuck or take a long time which is not desired.
To detect such cases this patch introduces a timeout and prints out a
warning indicating that notifier chain is taking a long time.
The timeout is set to 20secs by default and can be adjusted.
Signed-off-by: Rishabh Bhatnagar <rishabhb@codeaurora.org>
---
drivers/remoteproc/Kconfig | 16 ++++++++++++++++
drivers/remoteproc/qcom_common.c | 41 ++++++++++++++++++++++++++++++++--------
2 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index d99548f..e1e623e 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -234,6 +234,22 @@ config QCOM_WCNSS_PIL
Say y here to support the Peripheral Image Loader for the Qualcomm
Wireless Connectivity Subsystem.
+config QCOM_NOTIFY_TIMEOUT
+ int "Default timeout for ssr notifications to complete (in milliseconds)"
+ depends on QCOM_RPROC_COMMON
+ default 20000
+ help
+ As part of ssr notification clients can register their callbacks
+ to a notifier chain which is invoked whenever the remoteproc
+ powers-on/off. This option controls the timeout for ssr notifications
+ to complete.
+ This is a good to have debug feature as sometimes callbacks
+ can get stuck or take a long time. This feature helps in identifying
+ such scenarios.
+
+ The default value is kept as 20 secs and should be left as it is
+ in most cases.
+
config ST_REMOTEPROC
tristate "ST remoteproc support"
depends on ARCH_STI
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index 085fd73..d72c4f5 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -29,6 +29,8 @@ struct qcom_ssr_subsystem {
const char *name;
struct srcu_notifier_head notifier_list;
struct list_head list;
+ struct timer_list notify_timer;
+ const char *notify_type;
};
static LIST_HEAD(qcom_ssr_subsystem_list);
@@ -198,6 +200,14 @@ void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd)
}
EXPORT_SYMBOL_GPL(qcom_remove_smd_subdev);
+static void notify_timeout_handler(struct timer_list *t)
+{
+ struct qcom_ssr_subsystem *info = from_timer(info, t, notify_timer);
+
+ WARN(1, "srcu notifier chain for %s:%s taking too long", info->name,
+ info->notify_type);
+}
+
static struct qcom_ssr_subsystem *qcom_ssr_get_subsys(const char *name)
{
struct qcom_ssr_subsystem *info;
@@ -216,6 +226,9 @@ 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);
+ /* Setup the notification timer */
+ timer_setup(&info->notify_timer, notify_timeout_handler, 0);
+
/* Add to global notification list */
list_add_tail(&info->list, &qcom_ssr_subsystem_list);
@@ -266,6 +279,18 @@ int qcom_unregister_ssr_notifier(void *notify, struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(qcom_unregister_ssr_notifier);
+static inline void notify_ssr_clients(struct qcom_rproc_ssr *ssr,
+ enum qcom_ssr_notify_type type,
+ struct qcom_ssr_notify_data *data)
+{
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(CONFIG_QCOM_NOTIFY_TIMEOUT);
+ mod_timer(&ssr->info->notify_timer, timeout);
+ srcu_notifier_call_chain(&ssr->info->notifier_list, type, data);
+ del_timer_sync(&ssr->info->notify_timer);
+}
+
static int ssr_notify_prepare(struct rproc_subdev *subdev)
{
struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);
@@ -274,8 +299,8 @@ static int ssr_notify_prepare(struct rproc_subdev *subdev)
.crashed = false,
};
- srcu_notifier_call_chain(&ssr->info->notifier_list,
- QCOM_SSR_BEFORE_POWERUP, &data);
+ ssr->info->notify_type = "BEFORE_POWERUP";
+ notify_ssr_clients(ssr, QCOM_SSR_BEFORE_POWERUP, &data);
return 0;
}
@@ -287,8 +312,8 @@ static int ssr_notify_start(struct rproc_subdev *subdev)
.crashed = false,
};
- srcu_notifier_call_chain(&ssr->info->notifier_list,
- QCOM_SSR_AFTER_POWERUP, &data);
+ ssr->info->notify_type = "AFTER_POWERUP";
+ notify_ssr_clients(ssr, QCOM_SSR_AFTER_POWERUP, &data);
return 0;
}
@@ -300,8 +325,8 @@ static void ssr_notify_stop(struct rproc_subdev *subdev, bool crashed)
.crashed = crashed,
};
- srcu_notifier_call_chain(&ssr->info->notifier_list,
- QCOM_SSR_BEFORE_SHUTDOWN, &data);
+ ssr->info->notify_type = "BEFORE_SHUTDOWN";
+ notify_ssr_clients(ssr, QCOM_SSR_BEFORE_SHUTDOWN, &data);
}
static void ssr_notify_unprepare(struct rproc_subdev *subdev)
@@ -312,8 +337,8 @@ static void ssr_notify_unprepare(struct rproc_subdev *subdev)
.crashed = false,
};
- srcu_notifier_call_chain(&ssr->info->notifier_list,
- QCOM_SSR_AFTER_SHUTDOWN, &data);
+ ssr->info->notify_type = "AFTER_SHUTDOWN";
+ notify_ssr_clients(ssr, QCOM_SSR_AFTER_SHUTDOWN, &data);
}
/**
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-10-30 0:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-30 0:10 [PATCH] remoteproc: qcom: Add notification timeouts Rishabh Bhatnagar
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.