Kaynağa Gözat

Merge "qcacmn: Fix stability caused by unwanted recursive calls in serialization"

Linux Build Service Account 7 yıl önce
ebeveyn
işleme
458de35c6d

+ 20 - 1
umac/cmn_services/serialization/src/wlan_serialization_api.c

@@ -203,9 +203,12 @@ wlan_serialization_request(struct wlan_serialization_command *cmd)
 {
 	bool is_active_cmd_allowed;
 	QDF_STATUS status;
+	enum wlan_serialization_status serialization_status;
 	uint8_t comp_id;
 	struct wlan_serialization_psoc_priv_obj *ser_soc_obj;
 	union wlan_serialization_rules_info info;
+	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj = NULL;
+	struct wlan_objmgr_pdev *pdev = NULL;
 
 	serialization_enter();
 	if (!cmd) {
@@ -224,6 +227,18 @@ wlan_serialization_request(struct wlan_serialization_command *cmd)
 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
 	}
 
+	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
+	if (!pdev) {
+		serialization_err("pdev is invalid");
+		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
+	}
+
+	ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
+			WLAN_UMAC_COMP_SERIALIZATION);
+	if (!ser_pdev_obj) {
+		serialization_err("Invalid ser_pdev_obj");
+		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
+	}
 	/*
 	 * Get Component Info callback by calling
 	 * each registered module
@@ -240,7 +255,11 @@ wlan_serialization_request(struct wlan_serialization_command *cmd)
 	}
 
 	is_active_cmd_allowed = wlan_serialization_is_active_cmd_allowed(cmd);
-	return wlan_serialization_enqueue_cmd(cmd, is_active_cmd_allowed);
+	serialization_status = wlan_serialization_enqueue_cmd(
+				cmd, is_active_cmd_allowed);
+	if (WLAN_SER_CMD_ACTIVE == serialization_status)
+		wlan_serialization_activate_cmd(cmd->cmd_type, ser_pdev_obj);
+	return serialization_status;
 }
 
 enum wlan_serialization_cmd_status

+ 4 - 2
umac/cmn_services/serialization/src/wlan_serialization_dequeue.c

@@ -73,9 +73,11 @@ void wlan_serialization_move_pending_to_active(
 		serialization_err("Can't move cmd to activeQ id-%d type-%d",
 				cmd_list->cmd.cmd_id, cmd_list->cmd.cmd_type);
 		return;
-	}
-	wlan_serialization_put_back_to_global_list(pending_queue,
+	} else {
+		wlan_serialization_put_back_to_global_list(pending_queue,
 				ser_pdev_obj, cmd_list);
+		wlan_serialization_activate_cmd(cmd_type, ser_pdev_obj);
+	}
 
 	return;
 }

+ 68 - 31
umac/cmn_services/serialization/src/wlan_serialization_enqueue.c

@@ -77,43 +77,80 @@ wlan_serialization_add_cmd_to_given_queue(qdf_list_t *queue,
 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
 	}
 
-	if (is_cmd_for_active_queue) {
-		/*
-		 * command is already pushed to active queue above
-		 * now start the timer and notify requestor
-		 */
-		wlan_serialization_find_and_start_timer(psoc,
-							&cmd_list->cmd);
-		if (cmd_list->cmd.cmd_cb) {
-			/*
-			 * Remember that serialization module may send
-			 * this callback in same context through which it
-			 * received the serialization request. Due to which
-			 * it is caller's responsibility to ensure acquiring
-			 * and releasing its own lock appropriately.
-			 */
-			qdf_status = cmd_list->cmd.cmd_cb(&cmd_list->cmd,
-						WLAN_SER_CB_ACTIVATE_CMD);
-			if (qdf_status != QDF_STATUS_SUCCESS) {
-				wlan_serialization_find_and_stop_timer(psoc,
-								&cmd_list->cmd);
-				cmd_list->cmd.cmd_cb(&cmd_list->cmd,
-						WLAN_SER_CB_RELEASE_MEM_CMD);
-				wlan_serialization_put_back_to_global_list(
-						queue, ser_pdev_obj, cmd_list);
-				wlan_serialization_move_pending_to_active(
-						cmd_list->cmd.cmd_type,
-						ser_pdev_obj);
-			}
-		}
+	if (is_cmd_for_active_queue)
 		status = WLAN_SER_CMD_ACTIVE;
-	} else {
+	else
 		status = WLAN_SER_CMD_PENDING;
-	}
 
 	return status;
 }
 
+void wlan_serialization_activate_cmd(enum wlan_serialization_cmd_type cmd_type,
+			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	qdf_list_t *queue = NULL;
+	qdf_list_node_t *nnode = NULL;
+	struct wlan_serialization_command_list *cmd_list = NULL;
+	struct wlan_objmgr_psoc *psoc = NULL;
+
+	if (cmd_type < WLAN_SER_CMD_NONSCAN)
+		queue = &ser_pdev_obj->active_scan_list;
+	else
+		queue = &ser_pdev_obj->active_list;
+	if (qdf_list_empty(queue)) {
+		serialization_err("nothing in active queue");
+		QDF_ASSERT(0);
+		return;
+	}
+	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(queue, &nnode)) {
+		serialization_err("can't read from active queue");
+		serialization_debug("cmd_type - %d", cmd_type);
+		return;
+	}
+	cmd_list = qdf_container_of(nnode,
+			struct wlan_serialization_command_list, node);
+
+	/*
+	 * command is already pushed to active queue above
+	 * now start the timer and notify requestor
+	 */
+	wlan_serialization_find_and_start_timer(psoc,
+							&cmd_list->cmd);
+	if (cmd_list && cmd_list->cmd.cmd_cb) {
+		if (cmd_list->cmd.vdev) {
+			psoc = wlan_vdev_get_psoc(cmd_list->cmd.vdev);
+			if (psoc == NULL) {
+				serialization_err("invalid psoc");
+				return;
+			}
+		} else {
+			serialization_err("invalid cmd.vdev");
+			return;
+		}
+		/*
+		 * Remember that serialization module may send
+		 * this callback in same context through which it
+		 * received the serialization request. Due to which
+		 * it is caller's responsibility to ensure acquiring
+		 * and releasing its own lock appropriately.
+		 */
+		qdf_status = cmd_list->cmd.cmd_cb(&cmd_list->cmd,
+				WLAN_SER_CB_ACTIVATE_CMD);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			wlan_serialization_find_and_stop_timer(psoc,
+					&cmd_list->cmd);
+			cmd_list->cmd.cmd_cb(&cmd_list->cmd,
+					WLAN_SER_CB_RELEASE_MEM_CMD);
+			wlan_serialization_put_back_to_global_list(
+					queue, ser_pdev_obj, cmd_list);
+			wlan_serialization_move_pending_to_active(
+					cmd_list->cmd.cmd_type,
+					ser_pdev_obj);
+		}
+	}
+}
+
 enum wlan_serialization_status
 wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd,
 			       uint8_t is_cmd_for_active_queue)

+ 10 - 0
umac/cmn_services/serialization/src/wlan_serialization_utils_i.h

@@ -398,4 +398,14 @@ wlan_serialization_remove_all_cmd_from_queue(qdf_list_t *queue,
 bool wlan_serialization_is_cmd_present_queue(
 			struct wlan_serialization_command *cmd,
 			uint8_t is_active_queue);
+
+/**
+ * wlan_serialization_activate_cmd() - activate first cmd in active queue
+ * @cmd_type: Command Type
+ * @ser_pdev_obj: Serialization private pdev object
+ *
+ * Return: None
+ */
+void wlan_serialization_activate_cmd(enum wlan_serialization_cmd_type cmd_type,
+			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj);
 #endif