From 81cf264aaa81221e4eacad2d4ac9ca53af677c36 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 13 Nov 2018 12:20:20 -0800 Subject: [PATCH] qcacld-3.0: Print stack trace on DSC timeout DSC panics in debug builds in the event of various timeout events. In addition to these panics, print the stack trace of the invoking thread to assist in finding the exact reason for deadlocks. Change-Id: I69666cfc52fb7ca3638c32212bae3e3c3ddd8366 CRs-Fixed: 2349387 --- components/dsc/src/__wlan_dsc.c | 7 +++++++ components/dsc/src/__wlan_dsc.h | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/components/dsc/src/__wlan_dsc.c b/components/dsc/src/__wlan_dsc.c index 60032c26a040..10e16d82b2b5 100644 --- a/components/dsc/src/__wlan_dsc.c +++ b/components/dsc/src/__wlan_dsc.c @@ -20,6 +20,7 @@ #include "qdf_mem.h" #include "qdf_status.h" #include "qdf_str.h" +#include "qdf_threads.h" #include "qdf_timer.h" #include "__wlan_dsc.h" @@ -28,6 +29,7 @@ static void __dsc_dbg_op_timeout(void *opaque_op) { struct dsc_op *op = opaque_op; + qdf_print_thread_trace(op->thread); QDF_DEBUG_PANIC("Operation '%s' exceeded %ums", op->func, DSC_OP_TIMEOUT_MS); } @@ -70,6 +72,7 @@ static QDF_STATUS __dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func) if (!op) return QDF_STATUS_E_NOMEM; + op->thread = qdf_get_current_task(); status = qdf_timer_init(NULL, &op->timeout_timer, __dsc_dbg_op_timeout, op, QDF_TIMER_TYPE_SW); if (QDF_IS_STATUS_ERROR(status)) @@ -175,6 +178,7 @@ static void __dsc_dbg_trans_timeout(void *opaque_trans) { struct dsc_trans *trans = opaque_trans; + qdf_print_thread_trace(trans->thread); QDF_DEBUG_PANIC("Transition '%s' exceeded %ums", trans->active_desc, DSC_TRANS_TIMEOUT_MS); } @@ -189,6 +193,7 @@ static QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans) { QDF_STATUS status; + trans->thread = qdf_get_current_task(); status = qdf_timer_init(NULL, &trans->timeout_timer, __dsc_dbg_trans_timeout, trans, QDF_TIMER_TYPE_SW); @@ -216,6 +221,7 @@ static void __dsc_dbg_tran_wait_timeout(void *opaque_tran) { struct dsc_tran *tran = opaque_tran; + qdf_print_thread_trace(tran->thread); QDF_DEBUG_PANIC("Transition '%s' waited more than %ums", tran->desc, DSC_TRANS_WAIT_TIMEOUT_MS); } @@ -230,6 +236,7 @@ static QDF_STATUS __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran) { QDF_STATUS status; + tran->thread = qdf_get_current_task(); status = qdf_timer_init(NULL, &tran->timeout_timer, __dsc_dbg_tran_wait_timeout, tran, QDF_TIMER_TYPE_SW); diff --git a/components/dsc/src/__wlan_dsc.h b/components/dsc/src/__wlan_dsc.h index 721dbcde2602..5faa965492cf 100644 --- a/components/dsc/src/__wlan_dsc.h +++ b/components/dsc/src/__wlan_dsc.h @@ -25,8 +25,9 @@ #include "qdf_event.h" #include "qdf_list.h" -#include "qdf_trace.h" +#include "qdf_threads.h" #include "qdf_timer.h" +#include "qdf_trace.h" #include "qdf_types.h" #include "wlan_dsc.h" @@ -63,11 +64,13 @@ static inline bool __dsc_assert(const bool cond, const char *cond_str, * struct dsc_op - list node for operation tracking information * @node: list node * @timeout_timer: a timer used to detect operation timeouts + * @thread: the thread which started the operation * @func: name of the function the operation was started from */ struct dsc_op { qdf_list_node_t node; qdf_timer_t timeout_timer; + qdf_thread_t *thread; const char *func; }; #endif /* WLAN_DSC_DEBUG */ @@ -93,6 +96,7 @@ struct dsc_ops { * @node: list node * @event: event used to wait in *_start_trans_wait() APIs * @timeout_timer: a timer used to detect transition wait timeouts + * @thread: the thread which started the transition wait */ struct dsc_tran { bool abort; @@ -101,6 +105,7 @@ struct dsc_tran { qdf_event_t event; #ifdef WLAN_DSC_DEBUG qdf_timer_t timeout_timer; + qdf_thread_t *thread; #endif }; @@ -109,12 +114,14 @@ struct dsc_tran { * @active_desc: unique description of the current transition in progress * @queue: queue of pending transitions * @timeout_timer: a timer used to detect transition timeouts + * @thread: the thread which started the transition */ struct dsc_trans { const char *active_desc; qdf_list_t queue; #ifdef WLAN_DSC_DEBUG qdf_timer_t timeout_timer; + qdf_thread_t *thread; #endif };