qcacmn: Include PID in SM history

Add PID name where SM events and transition
happened to help debug issues where the info
about which task started a certain event to
happen are crucial to rootcause the problem.

Change-Id: I208b46c6d0ec725ab0d9713bf2dd562c40719a24
CRs-Fixed: 3624811
This commit is contained in:
Vinod Kumar Pirla
2023-10-25 07:55:03 -07:00
committed by Ravindra Konda
parent 56e6df6383
commit 4bf1baaed2
11 changed files with 93 additions and 67 deletions

View File

@@ -1606,6 +1606,14 @@ enum qdf_suspend_type {
* of order packet counter values * of order packet counter values
* @QDF_MGMT_RX_REO_ZERO_DURATION_PKT: Reception of management packet with zero * @QDF_MGMT_RX_REO_ZERO_DURATION_PKT: Reception of management packet with zero
* packet duration * packet duration
* @QDF_VDEV_ACTIVE_SER_CONNECT_TIMEOUT: Active connect cmd in serialization
* timed out.
* @QDF_VDEV_ACTIVE_SER_DISCONNECT_TIMEOUT: Active disconnect cmd in
* serialization timed out.
* @QDF_VDEV_ACTIVE_SER_REASSOC_TIMEOUT: Active reassoc cmd in serialization
* timed out.
* @QDF_VDEV_ACTIVE_SER_LINK_SWITCH_TIMEOUT: Active link switch cmd in
* serialization timed out.
*/ */
enum qdf_hang_reason { enum qdf_hang_reason {
QDF_REASON_UNSPECIFIED, QDF_REASON_UNSPECIFIED,
@@ -1646,6 +1654,10 @@ enum qdf_hang_reason {
QDF_MGMT_RX_REO_INCONSISTENT_SNAPSHOT, QDF_MGMT_RX_REO_INCONSISTENT_SNAPSHOT,
QDF_MGMT_RX_REO_OUT_OF_ORDER_PKT, QDF_MGMT_RX_REO_OUT_OF_ORDER_PKT,
QDF_MGMT_RX_REO_ZERO_DURATION_PKT, QDF_MGMT_RX_REO_ZERO_DURATION_PKT,
QDF_VDEV_ACTIVE_SER_CONNECT_TIMEOUT,
QDF_VDEV_ACTIVE_SER_DISCONNECT_TIMEOUT,
QDF_VDEV_ACTIVE_SER_REASSOC_TIMEOUT,
QDF_VDEV_ACTIVE_SER_LINK_SWITCH_TIMEOUT,
}; };
/** /**

View File

@@ -51,7 +51,12 @@
#define sm_engine_nofl_debug(params...) \ #define sm_engine_nofl_debug(params...) \
QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_SM_ENGINE, params) QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_SM_ENGINE, params)
#ifdef CONN_MGR_ADV_FEATURE
#define WLAN_SM_ENGINE_HISTORY_SIZE 15
#else
#define WLAN_SM_ENGINE_HISTORY_SIZE 50 #define WLAN_SM_ENGINE_HISTORY_SIZE 50
#endif /* CONN_MGR_ADV_FEATURE */
struct wlan_sm; struct wlan_sm;
/** /**
* enum wlan_sm_trace_type - history element type * enum wlan_sm_trace_type - history element type
@@ -64,7 +69,7 @@ enum wlan_sm_trace_type {
}; };
#ifdef SM_ENG_HIST_ENABLE #ifdef SM_ENG_HIST_ENABLE
#define WLAN_SM_PID_MAX_LEN 7
/** /**
* struct wlan_sm_history_info - history element structure * struct wlan_sm_history_info - history element structure
* @trace_type: history element type * @trace_type: history element type
@@ -72,6 +77,7 @@ enum wlan_sm_trace_type {
* @initial_state: Current state (state/sub-state) * @initial_state: Current state (state/sub-state)
* @final_state: New state * @final_state: New state
* @time: Timestamp * @time: Timestamp
* @pid_name: Name of task (truncated to WLAN_SM_PID_MAX_LEN bytes)
*/ */
struct wlan_sm_history_info { struct wlan_sm_history_info {
enum wlan_sm_trace_type trace_type; enum wlan_sm_trace_type trace_type;
@@ -79,6 +85,7 @@ struct wlan_sm_history_info {
uint8_t initial_state; uint8_t initial_state;
uint8_t final_state; uint8_t final_state;
uint64_t time; uint64_t time;
char pid_name[WLAN_SM_PID_MAX_LEN];
}; };
/** /**

View File

@@ -18,6 +18,7 @@
/** /**
* DOC: Implements general SM debug framework * DOC: Implements general SM debug framework
*/ */
#include <qdf_threads.h>
#include <wlan_sm_engine.h> #include <wlan_sm_engine.h>
#include <wlan_sm_engine_dbg.h> #include <wlan_sm_engine_dbg.h>
@@ -47,6 +48,8 @@ void wlan_sm_save_history(struct wlan_sm *sm,
p_memento->final_state = final_state; p_memento->final_state = final_state;
p_memento->event_type = event_type; p_memento->event_type = event_type;
p_memento->time = qdf_get_log_timestamp(); p_memento->time = qdf_get_log_timestamp();
qdf_scnprintf(p_memento->pid_name, WLAN_SM_PID_MAX_LEN, "%.6s",
qdf_get_current_comm());
} }
void wlan_sm_history_init(struct wlan_sm *sm) void wlan_sm_history_init(struct wlan_sm *sm)
@@ -74,8 +77,8 @@ static void wlan_sm_print_history_entry(struct wlan_sm *sm,
return; return;
sm_engine_nofl_err( sm_engine_nofl_err(
"| 0x%016llx |%6d |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |", "| 0x%016llx |%6d |%6s |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |",
ent->time, i, ent->trace_type, ent->time, i, ent->pid_name, ent->trace_type,
event_name ? event_name : "UNKNOWN_EVENT", event_name ? event_name : "UNKNOWN_EVENT",
ent->event_type, ent->event_type,
sm->state_info[ent->initial_state].name, sm->state_info[ent->initial_state].name,
@@ -84,8 +87,8 @@ static void wlan_sm_print_history_entry(struct wlan_sm *sm,
ent->final_state); ent->final_state);
} else { } else {
sm_engine_nofl_err( sm_engine_nofl_err(
"| 0x%016llx |%6d |%11d |%28d |%19s[%2d] |%19s[%2d] |", "| 0x%016llx |%6d |%6s |%11d |%28d |%19s[%2d] |%19s[%2d] |",
ent->time, i, ent->trace_type, ent->time, i, ent->pid_name, ent->trace_type,
ent->event_type, ent->event_type,
sm->state_info[ent->initial_state].name, sm->state_info[ent->initial_state].name,
ent->initial_state, ent->initial_state,
@@ -106,8 +109,8 @@ void wlan_sm_print_history(struct wlan_sm *sm)
*/ */
qdf_spin_lock_bh(&p_sm_history->sm_history_lock); qdf_spin_lock_bh(&p_sm_history->sm_history_lock);
sm_engine_nofl_err("|%19s |%6s |%11s |%28s |%23s |%23s |", "Time", sm_engine_nofl_err("|%19s |%6s |%6s |%11s |%28s |%23s |%23s |", "Time",
"Index", "Trace Type", "Event", "Index", "PID", "Trace Type", "Event",
"Initial State", "Final State"); "Initial State", "Final State");
for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) { for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) {
@@ -134,8 +137,8 @@ static void wlan_sm_print_fs_history_entry(struct wlan_sm *sm,
return; return;
qdf_debugfs_printf( qdf_debugfs_printf(
m, "| 0x%016llx |%6d |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |\n", m, "| 0x%016llx |%6d |%6s |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |\n",
ent->time, i, ent->trace_type, ent->time, i, ent->pid_name, ent->trace_type,
event_name ? event_name : "UNKNOWN_EVENT", event_name ? event_name : "UNKNOWN_EVENT",
ent->event_type, ent->event_type,
sm->state_info[ent->initial_state].name, sm->state_info[ent->initial_state].name,
@@ -144,8 +147,8 @@ static void wlan_sm_print_fs_history_entry(struct wlan_sm *sm,
ent->final_state); ent->final_state);
} else { } else {
qdf_debugfs_printf( qdf_debugfs_printf(
m, "| 0x%016llx |%6d |%11d |%28d |%19s[%2d] |%19s[%2d] |\n", m, "| 0x%016llx |%6d |%6s |%11d |%28d |%19s[%2d] |%19s[%2d] |\n",
ent->time, i, ent->trace_type, ent->time, i, ent->pid_name, ent->trace_type,
ent->event_type, ent->event_type,
sm->state_info[ent->initial_state].name, sm->state_info[ent->initial_state].name,
ent->initial_state, ent->initial_state,
@@ -165,8 +168,8 @@ void wlan_sm_print_fs_history(struct wlan_sm *sm, qdf_debugfs_file_t m)
* Save a pointer to next write location and increment pointer. * Save a pointer to next write location and increment pointer.
*/ */
qdf_spin_lock_bh(&p_sm_history->sm_history_lock); qdf_spin_lock_bh(&p_sm_history->sm_history_lock);
qdf_debugfs_printf(m, "|%19s |%6s |%11s |%28s |%23s |%23s |\n", "Time", qdf_debugfs_printf(m, "|%19s |%6s |%6s |%11s |%28s |%23s |%23s |\n", "Time",
"Index", "Trace Type", "Event", "Index", "PID", "Trace Type", "Event",
"Initial State", "Final State"); "Initial State", "Final State");
for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) { for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) {

View File

@@ -175,6 +175,7 @@ cm_ser_connect_cb(struct wlan_serialization_command *cmd,
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
struct cnx_mgr *cm_ctx; struct cnx_mgr *cm_ctx;
enum qdf_hang_reason hang_reason = QDF_VDEV_ACTIVE_SER_CONNECT_TIMEOUT;
if (!cmd) { if (!cmd) {
mlme_err("cmd is NULL, reason: %d", reason); mlme_err("cmd is NULL, reason: %d", reason);
@@ -219,7 +220,7 @@ cm_ser_connect_cb(struct wlan_serialization_command *cmd,
case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
mlme_err(CM_PREFIX_FMT "Active command timeout", mlme_err(CM_PREFIX_FMT "Active command timeout",
CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id)); CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id));
cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev); cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev, hang_reason);
cm_connect_cmd_timeout(cm_ctx, cmd->cmd_id); cm_connect_cmd_timeout(cm_ctx, cmd->cmd_id);
break; break;
case WLAN_SER_CB_RELEASE_MEM_CMD: case WLAN_SER_CB_RELEASE_MEM_CMD:

View File

@@ -158,6 +158,8 @@ cm_ser_disconnect_cb(struct wlan_serialization_command *cmd,
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
struct cnx_mgr *cm_ctx; struct cnx_mgr *cm_ctx;
enum qdf_hang_reason hang_reason =
QDF_VDEV_ACTIVE_SER_DISCONNECT_TIMEOUT;
if (!cmd) { if (!cmd) {
mlme_err("cmd is NULL, reason: %d", reason); mlme_err("cmd is NULL, reason: %d", reason);
@@ -192,7 +194,7 @@ cm_ser_disconnect_cb(struct wlan_serialization_command *cmd,
case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
mlme_err(CM_PREFIX_FMT "Active command timeout", mlme_err(CM_PREFIX_FMT "Active command timeout",
CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id)); CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id));
cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev); cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev, hang_reason);
cm_send_disconnect_resp(cm_ctx, cmd->cmd_id); cm_send_disconnect_resp(cm_ctx, cmd->cmd_id);
break; break;
case WLAN_SER_CB_RELEASE_MEM_CMD: case WLAN_SER_CB_RELEASE_MEM_CMD:

View File

@@ -571,6 +571,8 @@ cm_ser_reassoc_cb(struct wlan_serialization_command *cmd,
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
struct cnx_mgr *cm_ctx; struct cnx_mgr *cm_ctx;
enum qdf_hang_reason hang_reason =
QDF_VDEV_ACTIVE_SER_REASSOC_TIMEOUT;
if (!cmd) { if (!cmd) {
mlme_err("cmd is NULL, reason: %d", reason); mlme_err("cmd is NULL, reason: %d", reason);
@@ -614,7 +616,7 @@ cm_ser_reassoc_cb(struct wlan_serialization_command *cmd,
case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
mlme_err(CM_PREFIX_FMT "Active command timeout", mlme_err(CM_PREFIX_FMT "Active command timeout",
CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id)); CM_PREFIX_REF(wlan_vdev_get_id(vdev), cmd->cmd_id));
cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev); cm_trigger_panic_on_cmd_timeout(cm_ctx->vdev, hang_reason);
cm_reassoc_cmd_timeout(cm_ctx, cmd->cmd_id); cm_reassoc_cmd_timeout(cm_ctx, cmd->cmd_id);
break; break;
case WLAN_SER_CB_RELEASE_MEM_CMD: case WLAN_SER_CB_RELEASE_MEM_CMD:

View File

@@ -1007,10 +1007,12 @@ void cm_set_max_connect_attempts(struct wlan_objmgr_vdev *vdev,
/** /**
* cm_trigger_panic_on_cmd_timeout() - trigger panic on active command timeout * cm_trigger_panic_on_cmd_timeout() - trigger panic on active command timeout
* @vdev: vdev pointer * @vdev: vdev pointer
* @reason: Hang reason code
* *
* Return: void * Return: void
*/ */
void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev); void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
enum qdf_hang_reason reason);
/** /**
* cm_set_max_connect_timeout() - Set max connect timeout * cm_set_max_connect_timeout() - Set max connect timeout

View File

@@ -197,6 +197,24 @@ QDF_STATUS cm_set_key(struct cnx_mgr *cm_ctx, bool unicast,
} }
#endif #endif
static void cm_dump_sm_history(struct wlan_objmgr_vdev *vdev)
{
struct vdev_mlme_obj *vdev_mlme;
struct wlan_sm *vdev_sm;
vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_MLME);
if (!vdev_mlme)
return;
vdev_sm = vdev_mlme->sm_hdl;
if (!vdev_sm)
return;
wlan_sm_print_history(vdev_sm);
cm_sm_history_print(vdev);
}
#ifdef CONN_MGR_ADV_FEATURE #ifdef CONN_MGR_ADV_FEATURE
void cm_store_wep_key(struct cnx_mgr *cm_ctx, void cm_store_wep_key(struct cnx_mgr *cm_ctx,
struct wlan_cm_connect_crypto_info *crypto, struct wlan_cm_connect_crypto_info *crypto,
@@ -255,7 +273,8 @@ void cm_store_wep_key(struct cnx_mgr *cm_ctx,
wep_keys->seq_len); wep_keys->seq_len);
} }
void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev) void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
enum qdf_hang_reason reason)
{ {
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
@@ -266,32 +285,15 @@ void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev)
if (qdf_is_recovering() || qdf_is_fw_down()) if (qdf_is_recovering() || qdf_is_fw_down())
return; return;
qdf_trigger_self_recovery(psoc, QDF_ACTIVE_LIST_TIMEOUT); cm_dump_sm_history(vdev);
qdf_trigger_self_recovery(psoc, reason);
} }
#else #else
void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev) void cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
enum qdf_hang_reason reason)
{ {
struct vdev_mlme_obj *vdev_mlme = NULL; cm_dump_sm_history(vdev);
struct wlan_sm *vdev_sm = NULL;
vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(
vdev,
WLAN_UMAC_COMP_MLME);
if (!vdev_mlme) {
mlme_err("VDEV MLME is null");
goto error;
}
vdev_sm = vdev_mlme->sm_hdl;
if (!vdev_sm) {
mlme_err("VDEV SM is null");
goto error;
}
wlan_sm_print_history(vdev_sm);
cm_sm_history_print(vdev);
error:
QDF_ASSERT(0); QDF_ASSERT(0);
} }
#endif #endif

View File

@@ -256,6 +256,16 @@ bool wlan_cm_is_link_switch_disconnect_resp(struct wlan_cm_discon_rsp *resp);
*/ */
bool wlan_cm_is_link_switch_connect_resp(struct wlan_cm_connect_resp *resp); bool wlan_cm_is_link_switch_connect_resp(struct wlan_cm_connect_resp *resp);
/**
* wlan_cm_trigger_panic_on_cmd_timeout() - Trigger recovery on CM command
* timeout.
* @vdev: VDEV object manager
* @reason: Hang reason code
*
* Return: void
*/
void wlan_cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
enum qdf_hang_reason reason);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD #ifdef WLAN_FEATURE_ROAM_OFFLOAD
/** /**
* wlan_cm_is_vdev_roam_started() - check if vdev is in roaming state and * wlan_cm_is_vdev_roam_started() - check if vdev is in roaming state and

View File

@@ -265,6 +265,12 @@ bool wlan_cm_is_link_switch_connect_resp(struct wlan_cm_connect_resp *resp)
return cm_is_link_switch_connect_resp(resp); return cm_is_link_switch_connect_resp(resp);
} }
void wlan_cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
enum qdf_hang_reason reason)
{
cm_trigger_panic_on_cmd_timeout(vdev, reason);
}
#ifdef WLAN_FEATURE_HOST_ROAM #ifdef WLAN_FEATURE_HOST_ROAM
bool wlan_cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev, bool wlan_cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_vdev_reassoc_req *req) struct wlan_cm_vdev_reassoc_req *req)

View File

@@ -892,38 +892,17 @@ mlo_mgr_start_link_switch(struct wlan_objmgr_vdev *vdev,
return status; return status;
} }
/**
* mlo_mgr_trigger_recovery_on_link_switch_timeout() - trigger panic on link
* switch timeout
* @vdev: vdev pointer
*
* Return: void
*/
static void
mlo_mgr_trigger_recovery_on_link_switch_timeout(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_psoc *psoc;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc)
return;
if (qdf_is_recovering() || qdf_is_fw_down())
return;
qdf_trigger_self_recovery(psoc, QDF_ACTIVE_LIST_TIMEOUT);
}
static QDF_STATUS static QDF_STATUS
mlo_mgr_ser_link_switch_cb(struct wlan_serialization_command *cmd, mlo_mgr_ser_link_switch_cb(struct wlan_serialization_command *cmd,
enum wlan_serialization_cb_reason reason) enum wlan_serialization_cb_reason cb_reason)
{ {
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_mlo_link_switch_req *req; struct wlan_mlo_link_switch_req *req;
enum qdf_hang_reason reason = QDF_VDEV_ACTIVE_SER_LINK_SWITCH_TIMEOUT;
if (!cmd) { if (!cmd) {
mlo_err("cmd is NULL, reason: %d", reason); mlo_err("cmd is NULL, reason: %d", cb_reason);
QDF_ASSERT(0); QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE; return QDF_STATUS_E_NULL_VALUE;
} }
@@ -931,7 +910,7 @@ mlo_mgr_ser_link_switch_cb(struct wlan_serialization_command *cmd,
vdev = cmd->vdev; vdev = cmd->vdev;
req = &vdev->mlo_dev_ctx->link_ctx->last_req; req = &vdev->mlo_dev_ctx->link_ctx->last_req;
switch (reason) { switch (cb_reason) {
case WLAN_SER_CB_ACTIVATE_CMD: case WLAN_SER_CB_ACTIVATE_CMD:
status = mlo_mgr_start_link_switch(vdev, cmd); status = mlo_mgr_start_link_switch(vdev, cmd);
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
@@ -947,7 +926,7 @@ mlo_mgr_ser_link_switch_cb(struct wlan_serialization_command *cmd,
break; break;
case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
mlo_err("Link switch active cmd timeout"); mlo_err("Link switch active cmd timeout");
mlo_mgr_trigger_recovery_on_link_switch_timeout(vdev); wlan_cm_trigger_panic_on_cmd_timeout(vdev, reason);
break; break;
default: default:
QDF_ASSERT(0); QDF_ASSERT(0);