Эх сурвалжийг харах

qcacmn: Refactor CM command timeouts and flush req list before deinit

Refactor connection manager command timeouts to handled unexpected
timeouts in VDEV/PEER SM.

Also flush the req list before deinit to avoid memleaks due to these
timout, if SM is not handled properly.

Change-Id: I6cd1857464691838c75b1ceda32f94ad4cda46a2
CRs-Fixed: 2971466
Abhishek Singh 4 жил өмнө
parent
commit
ce5d191d80

+ 59 - 13
umac/mlme/connection_mgr/core/src/wlan_cm_main.c

@@ -19,9 +19,9 @@
  */
 
 #include "wlan_cm_main.h"
-#include "wlan_cm_sm.h"
-#include "wlan_scan_api.h"
+#include "wlan_cm_roam.h"
 #include "wlan_cm_main_api.h"
+#include "wlan_scan_api.h"
 
 #ifdef WLAN_CM_USE_SPINLOCK
 /**
@@ -115,27 +115,73 @@ QDF_STATUS wlan_cm_init(struct vdev_mlme_obj *vdev_mlme)
 	return QDF_STATUS_SUCCESS;
 }
 
+static void cm_deinit_req_list(struct cnx_mgr *cm_ctx)
+{
+	uint32_t prefix;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	struct cm_req *cm_req = NULL;
+
+	/*
+	 * flush unhandled req from the list, this should not happen if SM is
+	 * handled properly, but in cases of active command timeout
+	 * (which needs be debugged and avoided anyway) if VDEV/PEER SM
+	 * is not able to handle the req it may send out of sync command and
+	 * thus resulting in a unhandled request. Thus to avoid memleak flush
+	 * all unhandled req before destroying the list.
+	 */
+	cm_req_lock_acquire(cm_ctx);
+	qdf_list_peek_front(&cm_ctx->req_list, &cur_node);
+	while (cur_node) {
+		qdf_list_peek_next(&cm_ctx->req_list, cur_node, &next_node);
+
+		cm_req = qdf_container_of(cur_node, struct cm_req, node);
+		prefix = CM_ID_GET_PREFIX(cm_req->cm_id);
+		qdf_list_remove_node(&cm_ctx->req_list, &cm_req->node);
+		mlme_info(CM_PREFIX_FMT "flush prefix %x",
+			  CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev),
+					cm_req->cm_id), prefix);
+		if (prefix == CONNECT_REQ_PREFIX) {
+			cm_ctx->connect_count--;
+			cm_free_connect_req_mem(&cm_req->connect_req);
+		} else if (prefix == ROAM_REQ_PREFIX) {
+			cm_free_roam_req_mem(&cm_req->roam_req);
+		} else if (prefix == DISCONNECT_REQ_PREFIX) {
+			cm_ctx->disconnect_count--;
+		}
+		qdf_mem_free(cm_req);
+
+		cur_node = next_node;
+		next_node = NULL;
+		cm_req = NULL;
+	}
+	cm_req_lock_release(cm_ctx);
+
+	cm_req_lock_destroy(cm_ctx);
+	qdf_list_destroy(&cm_ctx->req_list);
+}
+
 QDF_STATUS wlan_cm_deinit(struct vdev_mlme_obj *vdev_mlme)
 {
 	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
 	enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev);
 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
 	wlan_scan_requester scan_requester_id;
+	struct cnx_mgr *cm_ctx;
 
 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
 		return QDF_STATUS_SUCCESS;
 
-	cm_req_history_deinit(vdev_mlme->cnx_mgr_ctx);
-	qdf_event_destroy(&vdev_mlme->cnx_mgr_ctx->disconnect_complete);
-	scan_requester_id = vdev_mlme->cnx_mgr_ctx->scan_requester_id;
-	wlan_scan_unregister_requester(psoc,
-				       scan_requester_id);
-	cm_req_lock_destroy(vdev_mlme->cnx_mgr_ctx);
-	qdf_list_destroy(&vdev_mlme->cnx_mgr_ctx->req_list);
-	cm_sm_destroy(vdev_mlme->cnx_mgr_ctx);
-	mlme_cm_ext_hdl_destroy(vdev, vdev_mlme->cnx_mgr_ctx->ext_cm_ptr);
-	vdev_mlme->cnx_mgr_ctx->ext_cm_ptr = NULL;
-	qdf_mem_free(vdev_mlme->cnx_mgr_ctx);
+	cm_ctx = vdev_mlme->cnx_mgr_ctx;
+	cm_req_history_deinit(cm_ctx);
+	qdf_event_destroy(&cm_ctx->disconnect_complete);
+	scan_requester_id = cm_ctx->scan_requester_id;
+	wlan_scan_unregister_requester(psoc, scan_requester_id);
+
+	cm_deinit_req_list(cm_ctx);
+	cm_sm_destroy(cm_ctx);
+	mlme_cm_ext_hdl_destroy(vdev, cm_ctx->ext_cm_ptr);
+	cm_ctx->ext_cm_ptr = NULL;
+	qdf_mem_free(cm_ctx);
 	vdev_mlme->cnx_mgr_ctx = NULL;
 
 	return QDF_STATUS_SUCCESS;

+ 5 - 1
umac/mlme/connection_mgr/core/src/wlan_cm_main.h

@@ -31,7 +31,11 @@
 
 /* Max candidate/attempts to be tried to connect */
 #define CM_MAX_CONNECT_ATTEMPTS 5
-#define CM_MAX_CONNECT_TIMEOUT 10000
+/*
+ * Default connect timeout to consider 3 sec join timeout + 5 sec auth timeout +
+ * 2 sec assoc timeout + 5 sec buffer for vdev related timeouts.
+ */
+#define CM_MAX_CONNECT_TIMEOUT 15000
 
 /*
  * Default max retry attempts to be tried for a candidate.

+ 5 - 2
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h

@@ -34,8 +34,11 @@ typedef uint32_t wlan_cm_id;
 /* Diconnect active timeout */
 #define DISCONNECT_TIMEOUT   STOP_RESPONSE_TIMER + DELETE_RESPONSE_TIMER + 1000
 
-/* Diconnect command wait timeout */
-#define CM_DISCONNECT_CMD_TIMEOUT DISCONNECT_TIMEOUT + 2000
+/*
+ * Disconnect command wait timeout VDEV timeouts + 5 sec buff for current active
+ * command to complete
+ */
+#define CM_DISCONNECT_CMD_TIMEOUT DISCONNECT_TIMEOUT + 5000
 
 /**
  * struct wlan_cm_wep_key_params - store wep key info