mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
soc: qcom: glink_probe: Use ref count for holding ssr context
During ssr rpmsg ssr device will unregister, which can result in use of stale device pointer in ssr callback function. Now incrementing refcount inside ssr callback function to prevent release of rpmsg device. CRs-Fixed: 2551255 Change-Id: If3fc57c4635378dc6fdcb7df120c83dca0e83758 Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
This commit is contained in:
parent
cfcc5550df
commit
95d601bb7f
1 changed files with 19 additions and 2 deletions
|
|
@ -64,8 +64,21 @@ struct glink_ssr {
|
|||
u32 seq_num;
|
||||
struct completion completion;
|
||||
struct work_struct unreg_work;
|
||||
struct kref refcount;
|
||||
};
|
||||
|
||||
static void glink_ssr_release(struct kref *ref)
|
||||
{
|
||||
struct glink_ssr *ssr = container_of(ref, struct glink_ssr,
|
||||
refcount);
|
||||
struct glink_ssr_nb *nb, *tmp;
|
||||
|
||||
list_for_each_entry_safe(nb, tmp, &ssr->notify_list, list)
|
||||
kfree(nb);
|
||||
|
||||
kfree(ssr);
|
||||
}
|
||||
|
||||
static void glink_ssr_ssr_unreg_work(struct work_struct *work)
|
||||
{
|
||||
struct glink_ssr *ssr = container_of(work, struct glink_ssr,
|
||||
|
|
@ -75,9 +88,8 @@ static void glink_ssr_ssr_unreg_work(struct work_struct *work)
|
|||
list_for_each_entry_safe(nb, tmp, &ssr->notify_list, list) {
|
||||
subsys_notif_unregister_notifier(nb->ssr_register_handle,
|
||||
&nb->nb);
|
||||
kfree(nb);
|
||||
}
|
||||
kfree(ssr);
|
||||
kref_put(&ssr->refcount, glink_ssr_release);
|
||||
}
|
||||
|
||||
static int glink_ssr_ssr_cb(struct notifier_block *this,
|
||||
|
|
@ -92,6 +104,8 @@ static int glink_ssr_ssr_cb(struct notifier_block *this,
|
|||
if (!dev || !ssr->ept)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
kref_get(&ssr->refcount);
|
||||
|
||||
if (code == SUBSYS_AFTER_SHUTDOWN || code == SUBSYS_POWERUP_FAILURE) {
|
||||
ssr->seq_num++;
|
||||
reinit_completion(&ssr->completion);
|
||||
|
|
@ -110,6 +124,7 @@ static int glink_ssr_ssr_cb(struct notifier_block *this,
|
|||
if (ret) {
|
||||
MSM_SSR_ERR(dev, "fail to send do cleanup to %s %d\n",
|
||||
nb->ssr_label, ret);
|
||||
kref_put(&ssr->refcount, glink_ssr_release);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +132,7 @@ static int glink_ssr_ssr_cb(struct notifier_block *this,
|
|||
if (!ret)
|
||||
MSM_SSR_ERR(dev, "timeout waiting for cleanup resp\n");
|
||||
}
|
||||
kref_put(&ssr->refcount, glink_ssr_release);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
|
@ -217,6 +233,7 @@ static int glink_ssr_probe(struct rpmsg_device *rpdev)
|
|||
INIT_LIST_HEAD(&ssr->notify_list);
|
||||
init_completion(&ssr->completion);
|
||||
INIT_WORK(&ssr->unreg_work, glink_ssr_ssr_unreg_work);
|
||||
kref_init(&ssr->refcount);
|
||||
|
||||
ssr->dev = &rpdev->dev;
|
||||
ssr->ept = rpdev->ept;
|
||||
|
|
|
|||
Loading…
Reference in a new issue