diff --git a/qdf/inc/qdf_threads.h b/qdf/inc/qdf_threads.h index ff706dcdac..ae04cef871 100644 --- a/qdf/inc/qdf_threads.h +++ b/qdf/inc/qdf_threads.h @@ -81,4 +81,10 @@ int qdf_wake_up_process(qdf_thread_t *thread); */ void qdf_print_thread_trace(qdf_thread_t *thread); +/** + * qdf_get_current_task() - get current task struct + * + * Return: pointer to task struct + */ +qdf_thread_t *qdf_get_current_task(void); #endif /* __QDF_THREADS_H */ diff --git a/qdf/linux/src/qdf_threads.c b/qdf/linux/src/qdf_threads.c index 6a2994c3cc..a5f830d844 100644 --- a/qdf/linux/src/qdf_threads.c +++ b/qdf/linux/src/qdf_threads.c @@ -45,6 +45,7 @@ #include #include #include +#include /* Function declarations and documenation */ @@ -154,3 +155,8 @@ void qdf_print_thread_trace(qdf_thread_t *thread) { } #endif /* KERNEL_VERSION(4, 14, 0) */ EXPORT_SYMBOL(qdf_print_thread_trace); +qdf_thread_t *qdf_get_current_task(void) +{ + return current; +} +EXPORT_SYMBOL(qdf_get_current_task); diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index aba144934f..736f9df03f 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -48,6 +48,7 @@ #ifdef DFS_COMPONENT_ENABLE #include #endif +#include #define WMI_UNIFIED_MAX_EVENT 0x100 #define WMI_MAX_CMDS 1024 @@ -175,6 +176,18 @@ struct fwdebug { }; #endif /* WLAN_OPEN_SOURCE */ +/** + * struct wmi_wq_dbg_info - WMI WQ debug info + * @ wd_msg_type_id - wmi event id + * @ wmi_wq - WMI workqueue struct + * @ task - WMI workqueue task struct + */ +struct wmi_wq_dbg_info { + uint16_t wd_msg_type_id; + qdf_workqueue_t *wmi_wq; + qdf_thread_t *task; +}; + struct wmi_ops { QDF_STATUS (*send_vdev_create_cmd)(wmi_unified_t wmi_handle, uint8_t macaddr[IEEE80211_ADDR_LEN], diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c index 18f97d8677..bc0580c415 100644 --- a/wmi/src/wmi_unified.c +++ b/wmi/src/wmi_unified.c @@ -1883,7 +1883,11 @@ static inline void wmi_workqueue_watchdog_warn(uint16_t msg_type_id) #ifdef CONFIG_SLUB_DEBUG_ON static void wmi_workqueue_watchdog_bite(void *arg) { - wmi_workqueue_watchdog_warn(*(uint16_t *)arg); + struct wmi_wq_dbg_info *info = arg; + + wmi_workqueue_watchdog_warn(info->wd_msg_type_id); + qdf_print_thread_trace(info->task); + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, "%s: Going down for WMI WQ Watchdog Bite!", __func__); QDF_BUG(0); @@ -1891,7 +1895,9 @@ static void wmi_workqueue_watchdog_bite(void *arg) #else static inline void wmi_workqueue_watchdog_bite(void *arg) { - wmi_workqueue_watchdog_warn(*(uint16_t *)arg); + struct wmi_wq_dbg_info *info = arg; + + wmi_workqueue_watchdog_warn(info->wd_msg_type_id); } #endif @@ -1908,18 +1914,20 @@ static void wmi_rx_event_work(void *arg) wmi_buf_t buf; struct wmi_unified *wmi = arg; qdf_timer_t wd_timer; - uint16_t wd_msg_type_id; + struct wmi_wq_dbg_info info; /* initialize WMI workqueue watchdog timer */ qdf_timer_init(NULL, &wd_timer, &wmi_workqueue_watchdog_bite, - &wd_msg_type_id, QDF_TIMER_TYPE_SW); + &info, QDF_TIMER_TYPE_SW); qdf_spin_lock_bh(&wmi->eventq_lock); buf = qdf_nbuf_queue_remove(&wmi->event_queue); qdf_spin_unlock_bh(&wmi->eventq_lock); while (buf) { qdf_timer_start(&wd_timer, WMI_WQ_WD_TIMEOUT); - wd_msg_type_id = + info.wd_msg_type_id = WMI_GET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID); + info.wmi_wq = wmi->wmi_rx_work_queue; + info.task = qdf_get_current_task(); __wmi_control_rx(wmi, buf); qdf_timer_stop(&wd_timer); qdf_spin_lock_bh(&wmi->eventq_lock);