diff --git a/components/dsc/src/__wlan_dsc.c b/components/dsc/src/__wlan_dsc.c index 25aad7846a..e71b499b75 100644 --- a/components/dsc/src/__wlan_dsc.c +++ b/components/dsc/src/__wlan_dsc.c @@ -20,9 +20,18 @@ #include "qdf_mem.h" #include "qdf_status.h" #include "qdf_str.h" +#include "qdf_timer.h" #include "__wlan_dsc.h" #ifdef WLAN_DSC_DEBUG +static void __dsc_dbg_op_timeout(void *opaque_op) +{ + struct dsc_op *op = opaque_op; + + QDF_DEBUG_PANIC("Operation '%s' exceeded %ums", + op->func, DSC_OP_TIMEOUT_MS); +} + /** * __dsc_dbg_ops_init() - initialize debug ops data structures * @ops: the ops container to initialize @@ -54,17 +63,29 @@ static inline void __dsc_dbg_ops_deinit(struct dsc_ops *ops) */ static QDF_STATUS __dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func) { + QDF_STATUS status; struct dsc_op *op; op = qdf_mem_malloc(sizeof(*op)); if (!op) return QDF_STATUS_E_NOMEM; + status = qdf_timer_init(NULL, &op->timeout_timer, __dsc_dbg_op_timeout, + op, QDF_TIMER_TYPE_SW); + if (QDF_IS_STATUS_ERROR(status)) + goto free_op; + op->func = func; + qdf_timer_start(&op->timeout_timer, DSC_OP_TIMEOUT_MS); qdf_list_insert_back(&ops->list, &op->node); return QDF_STATUS_SUCCESS; + +free_op: + qdf_mem_free(op); + + return status; } /** @@ -86,6 +107,8 @@ static void __dsc_dbg_ops_remove(struct dsc_ops *ops, const char *func) /* this is safe because we cease iteration */ qdf_list_remove_node(&ops->list, &op->node); + qdf_timer_stop(&op->timeout_timer); + qdf_timer_free(&op->timeout_timer); qdf_mem_free(op); return; diff --git a/components/dsc/src/__wlan_dsc.h b/components/dsc/src/__wlan_dsc.h index 103413d0d4..40ff29752e 100644 --- a/components/dsc/src/__wlan_dsc.h +++ b/components/dsc/src/__wlan_dsc.h @@ -26,6 +26,7 @@ #include "qdf_event.h" #include "qdf_list.h" #include "qdf_trace.h" +#include "qdf_timer.h" #include "qdf_types.h" #include "wlan_dsc.h" @@ -55,6 +56,7 @@ static inline bool __dsc_assert(const bool cond, const char *cond_str, #ifdef WLAN_DSC_DEBUG #define DSC_TRANS_TIMEOUT 120000 /* 2 minutes */ +#define DSC_OP_TIMEOUT_MS (1 * 60 * 1000) /* 1 minute */ #else #define DSC_TRANS_TIMEOUT 0 /* no timeout */ #endif @@ -63,10 +65,12 @@ 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 * @func: name of the function the operation was started from */ struct dsc_op { qdf_list_node_t node; + qdf_timer_t timeout_timer; const char *func; }; #endif /* WLAN_DSC_DEBUG */