Browse Source

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
Dustin Brown 6 years ago
parent
commit
81cf264aaa
2 changed files with 15 additions and 1 deletions
  1. 7 0
      components/dsc/src/__wlan_dsc.c
  2. 8 1
      components/dsc/src/__wlan_dsc.h

+ 7 - 0
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);

+ 8 - 1
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
 };