mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
soc: qcom: pdr: Add PDR notification timeout handler
This is a debug feature where a kernel panic is triggered when pdr notification to the APPS client is taking too long. This scenario can happen if the one of notifier gets stuck and due to which subsystem did not get ack back from APPS in time and trigger timeout panic. So, trigger a kernel panic in APPS if PDR notifications is taking too long. Change-Id: Ic58c421723a71ba87ba0306617eafc2ed39b6ee2 Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com> Signed-off-by: Gokul krishna Krishnakumar <quic_gokukris@quicinc.com> [quic_gurus@quicinc.com: Dropped kalama_GKI.config change] Signed-off-by: Guru Das Srinagesh <quic_gurus@quicinc.com>
This commit is contained in:
parent
e4dd10a51a
commit
33ad78c141
|
|
@ -134,6 +134,24 @@ config QCOM_PDR_HELPERS
|
|||
crash/recover without disrupting the other PDs running on
|
||||
the same Q6 ADSP.
|
||||
|
||||
config QCOM_PANIC_ON_PDR_NOTIF_TIMEOUT
|
||||
bool "Trigger kernel panic when PDR notification timeout expires"
|
||||
help
|
||||
This is a debug feature where a kernel panic is triggered when
|
||||
pdr notification to the APPS client is taking too long. This scneario
|
||||
can happen if the one of notifier gets stuck and due to which subsystem
|
||||
did not get ack back from APPS in time and trigger timeout panic.
|
||||
So, trigger a kernel panic in APPS if PDR notifications is taking
|
||||
too long.
|
||||
|
||||
config PDR_INDICATION_NOTIF_TIMEOUT
|
||||
int "Pdr notifications timeout in ms"
|
||||
default 3000
|
||||
help
|
||||
The amount of time, in milliseconds, that should elapse between
|
||||
the start and end of notifications, before a warning
|
||||
is emitted.
|
||||
|
||||
config QCOM_QMI_HELPERS
|
||||
tristate
|
||||
depends on NET
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -10,6 +11,9 @@
|
|||
#include <linux/workqueue.h>
|
||||
|
||||
#include "pdr_internal.h"
|
||||
#include "../../remoteproc/qcom_common.h"
|
||||
|
||||
#define PDR_IND_NOTIF_TIMEOUT CONFIG_PDR_INDICATION_NOTIF_TIMEOUT
|
||||
|
||||
struct pdr_service {
|
||||
char service_name[SERVREG_NAME_LENGTH + 1];
|
||||
|
|
@ -67,8 +71,12 @@ struct pdr_list_node {
|
|||
u16 transaction_id;
|
||||
struct pdr_service *pds;
|
||||
struct list_head node;
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
static const char * const ind_notif_timeout_msg =
|
||||
"PDR: Indication notifier %s, state: 0x%x, trans-id: %d\n taking too long";
|
||||
|
||||
static int pdr_locator_new_server(struct qmi_handle *qmi,
|
||||
struct qmi_service *svc)
|
||||
{
|
||||
|
|
@ -270,19 +278,38 @@ static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ind_notif_timeout_handler(struct timer_list *t)
|
||||
{
|
||||
struct pdr_list_node *ind = from_timer(ind, t, timer);
|
||||
struct pdr_service *pds = ind->pds;
|
||||
|
||||
if (IS_ENABLED(CONFIG_QCOM_PANIC_ON_PDR_NOTIF_TIMEOUT) &&
|
||||
system_state != SYSTEM_RESTART &&
|
||||
system_state != SYSTEM_POWER_OFF &&
|
||||
system_state != SYSTEM_HALT &&
|
||||
!qcom_device_shutdown_in_progress)
|
||||
panic(ind_notif_timeout_msg, pds->service_path, pds->state, ind->transaction_id);
|
||||
else
|
||||
WARN(1, ind_notif_timeout_msg, pds->service_path, pds->state, ind->transaction_id);
|
||||
}
|
||||
|
||||
static void pdr_indack_work(struct work_struct *work)
|
||||
{
|
||||
struct pdr_handle *pdr = container_of(work, struct pdr_handle,
|
||||
indack_work);
|
||||
struct pdr_list_node *ind, *tmp;
|
||||
struct pdr_service *pds;
|
||||
unsigned long timeout;
|
||||
|
||||
list_for_each_entry_safe(ind, tmp, &pdr->indack_list, node) {
|
||||
pds = ind->pds;
|
||||
|
||||
mutex_lock(&pdr->status_lock);
|
||||
pds->state = ind->curr_state;
|
||||
timeout = jiffies + msecs_to_jiffies(PDR_IND_NOTIF_TIMEOUT);
|
||||
mod_timer(&ind->timer, timeout);
|
||||
pdr->status(pds->state, pds->service_path, pdr->priv);
|
||||
del_timer_sync(&ind->timer);
|
||||
mutex_unlock(&pdr->status_lock);
|
||||
|
||||
/* Ack the indication after clients release the PD resources */
|
||||
|
|
@ -338,6 +365,7 @@ static void pdr_indication_cb(struct qmi_handle *qmi,
|
|||
ind->curr_state = ind_msg->curr_state;
|
||||
ind->pds = pds;
|
||||
|
||||
timer_setup(&ind->timer, ind_notif_timeout_handler, 0);
|
||||
mutex_lock(&pdr->list_lock);
|
||||
list_add_tail(&ind->node, &pdr->indack_list);
|
||||
mutex_unlock(&pdr->list_lock);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user