Forráskód Böngészése

qcacmn: Make access to serialization timers atomic

The serialization timers can be accessed from multiple contexts
when adding and removing commands to/from the serialization
queues. So the access to the serialization timers should be
atomic to protect the same timers being used for multiple
commands.

The serialization timers are maintained per psoc and are
protected with psoc timer locks.

Also the serialization lock APIs are updated to take the lock
object pointer as an argument

Change-Id: Ibdb41818fde9318fca6bbc92a536858364639365
CRs-Fixed: 2313039
Vivek 6 éve
szülő
commit
aa6303e509

+ 10 - 10
umac/cmn_services/serialization/src/wlan_serialization_api.c

@@ -617,7 +617,7 @@ wlan_serialization_non_scan_cmd_status(
 	/* Look in the pdev non scan active queue */
 	queue = &pdev_q->active_list;
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	node = wlan_serialization_find_cmd(
 			queue, WLAN_SER_MATCH_CMD_TYPE,
@@ -641,7 +641,7 @@ wlan_serialization_non_scan_cmd_status(
 	cmd_status = wlan_serialization_is_cmd_in_active_pending(
 			cmd_in_active, cmd_in_pending);
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 	ser_exit();
 	return cmd_status;
@@ -813,7 +813,7 @@ wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
 
 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	cmd_in_active =
 	wlan_serialization_is_cmd_in_vdev_list(
@@ -826,7 +826,7 @@ wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
 	status = wlan_serialization_is_cmd_in_active_pending(
 			cmd_in_active, cmd_in_pending);
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 	ser_exit();
 
 	return status;
@@ -857,7 +857,7 @@ wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
 
 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	cmd_in_active = !qdf_list_empty(&pdev_q->active_list);
 	cmd_in_pending = !qdf_list_empty(&pdev_q->pending_list);
@@ -865,7 +865,7 @@ wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
 	status = wlan_serialization_is_cmd_in_active_pending(
 			cmd_in_active, cmd_in_pending);
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 	return status;
 }
@@ -910,7 +910,7 @@ wlan_serialization_get_scan_cmd_using_scan_id(
 
 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	if (is_scan_cmd_from_active_queue)
 		queue = &pdev_q->active_list;
@@ -931,7 +931,7 @@ wlan_serialization_get_scan_cmd_using_scan_id(
 		}
 	}
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 release_vdev_ref:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
@@ -980,7 +980,7 @@ void *wlan_serialization_get_active_cmd(
 
 	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	queue = &pdev_q->active_list;
 
@@ -997,7 +997,7 @@ void *wlan_serialization_get_active_cmd(
 		umac_cmd = cmd_list->cmd.umac_cmd;
 	}
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 release_vdev_ref:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);

+ 29 - 14
umac/cmn_services/serialization/src/wlan_serialization_internal.c

@@ -164,12 +164,12 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
 		  cmd->is_high_priority,
 		  cmd->is_blocking);
 
-	wlan_serialization_acquire_lock(pdev_queue);
+	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
 
 	active_queue = wlan_serialization_is_active_cmd_allowed(cmd);
 
 	if (wlan_serialization_is_cmd_present_queue(cmd, active_queue)) {
-		wlan_serialization_release_lock(pdev_queue);
+		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
 		ser_err("duplicate command, can't enqueue");
 		goto error;
 	}
@@ -177,7 +177,7 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
 	if (wlan_serialization_remove_front(
 				&pdev_queue->cmd_pool_list,
 				&nnode) != QDF_STATUS_SUCCESS) {
-		wlan_serialization_release_lock(pdev_queue);
+		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
 		ser_err("Failed to get cmd buffer from global pool");
 		goto error;
 	}
@@ -216,7 +216,7 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
 				   &cmd_list->cmd_in_use);
 	}
 
-	wlan_serialization_release_lock(pdev_queue);
+	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
 
 	if (WLAN_SER_CMD_ACTIVE == status)
 		wlan_serialization_activate_cmd(cmd_list,
@@ -463,7 +463,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
 		  cmd->is_high_priority,
 		  cmd->is_blocking);
 
-	wlan_serialization_acquire_lock(pdev_queue);
+	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
 
 	if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN)
 		qdf_status = wlan_ser_remove_scan_cmd(
@@ -474,7 +474,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
 	}
 
 	if (qdf_status != QDF_STATUS_SUCCESS) {
-		wlan_serialization_release_lock(pdev_queue);
+		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
 		status = WLAN_SER_CMD_NOT_FOUND;
 		goto error;
 	}
@@ -520,7 +520,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
 			blocking_cmd_waiting);
 	}
 
-	wlan_serialization_release_lock(pdev_queue);
+	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
 
 	/* Call cmd cb for remove request*/
 	if (cmd_bkup.cmd_cb) {
@@ -674,6 +674,8 @@ wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc,
 	 * be unique and For non-scan command, there should be only one active
 	 * command per pdev
 	 */
+	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
+
 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
 		ser_timer = &psoc_ser_obj->timers[i];
 		if (!(ser_timer->cmd) ||
@@ -681,14 +683,21 @@ wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc,
 		    (ser_timer->cmd->cmd_type != cmd->cmd_type) ||
 		    (ser_timer->cmd->vdev != cmd->vdev))
 			continue;
+
+		status = QDF_STATUS_SUCCESS;
+		break;
+	}
+
+	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
 		status = wlan_serialization_stop_timer(ser_timer);
 		ser_debug("\n Stopping timer for cmd type:%d, id: %d",
 			  cmd->cmd_type, cmd->cmd_id);
-		break;
+	} else {
+		ser_err("Can't find timer for cmd_type[%d]", cmd->cmd_type);
 	}
 
-	if (QDF_STATUS_SUCCESS != status)
-		ser_err("Can't find timer for cmd_type[%d]", cmd->cmd_type);
 
 error:
 exit:
@@ -721,6 +730,8 @@ wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
 
 	psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc);
 
+	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
+
 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
 		/* Keep trying timer */
 		ser_timer = &psoc_ser_obj->timers[i];
@@ -729,22 +740,26 @@ wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
 
 		/* Remember timer is pointing to command */
 		ser_timer->cmd = cmd;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	}
+
+	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
 		qdf_timer_init(NULL,
 			       &ser_timer->timer,
 			       wlan_serialization_timer_handler,
 			       ser_timer,
 			       QDF_TIMER_TYPE_SW);
 			       qdf_timer_mod(&ser_timer->timer,
-					     cmd->cmd_timeout_duration);
+			       cmd->cmd_timeout_duration);
 
 		ser_debug("starting timer for cmd: type[%d] id[%d] high_priority[%d] blocking[%d]",
 			  cmd->cmd_type,
 			  cmd->cmd_id,
 			  cmd->is_high_priority,
 			  cmd->is_blocking);
-
-		status = QDF_STATUS_SUCCESS;
-		break;
 	}
 
 error:

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

@@ -520,6 +520,7 @@ QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc)
 	ser_soc_obj->timers = NULL;
 	ser_soc_obj->max_active_cmds = 0;
 
+	wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock);
 error:
 	ser_exit();
 	return status;
@@ -550,6 +551,7 @@ QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc)
 		goto error;
 	}
 
+	wlan_serialization_create_lock(&ser_soc_obj->timer_lock);
 	status = QDF_STATUS_SUCCESS;
 
 error:
@@ -708,7 +710,7 @@ static QDF_STATUS wlan_serialization_pdev_create_handler(
 	for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) {
 		pdev_queue = &ser_pdev_obj->pdev_q[index];
 
-		qdf_spinlock_create(&pdev_queue->pdev_queue_lock);
+		wlan_serialization_create_lock(&pdev_queue->pdev_queue_lock);
 
 		switch (index) {
 		case SER_PDEV_QUEUE_COMP_SCAN:
@@ -825,7 +827,7 @@ static QDF_STATUS wlan_serialization_pdev_destroy_handler(
 		wlan_serialization_destroy_pdev_list(pdev_queue);
 		wlan_serialization_destroy_cmd_pool(pdev_queue);
 
-		qdf_spinlock_destroy(&pdev_queue->pdev_queue_lock);
+		wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock);
 	}
 
 	qdf_mem_free(ser_pdev_obj);

+ 6 - 5
umac/cmn_services/serialization/src/wlan_serialization_non_scan.c

@@ -498,7 +498,7 @@ wlan_ser_cancel_non_scan_cmd(
 	else
 		ser_debug("Can't find psoc");
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	qsize = wlan_serialization_list_size(pdev_queue);
 	while (!wlan_serialization_list_empty(pdev_queue) && qsize--) {
@@ -554,7 +554,8 @@ wlan_ser_cancel_non_scan_cmd(
 			 */
 			if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
 						&cmd_list->cmd_in_use)) {
-				wlan_serialization_release_lock(pdev_q);
+				wlan_serialization_release_lock(
+						&pdev_q->pdev_queue_lock);
 				status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
 				goto error;
 			}
@@ -607,7 +608,7 @@ wlan_ser_cancel_non_scan_cmd(
 		}
 		nnode = pnode;
 
-		wlan_serialization_release_lock(pdev_q);
+		wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 		/*
 		 * call pending cmd's callback to notify that
 		 * it is being removed
@@ -626,7 +627,7 @@ wlan_ser_cancel_non_scan_cmd(
 					WLAN_SER_CB_RELEASE_MEM_CMD);
 		}
 
-		wlan_serialization_acquire_lock(pdev_q);
+		wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 		if (!is_active_queue)
 			status = WLAN_SER_CMD_IN_PENDING_LIST;
@@ -635,7 +636,7 @@ wlan_ser_cancel_non_scan_cmd(
 			break;
 	}
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 error:
 	ser_exit();

+ 6 - 5
umac/cmn_services/serialization/src/wlan_serialization_scan.c

@@ -186,7 +186,7 @@ wlan_ser_cancel_scan_cmd(
 	else
 		ser_debug("Can't find psoc");
 
-	wlan_serialization_acquire_lock(pdev_q);
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 	qsize = wlan_serialization_list_size(queue);
 	while (!wlan_serialization_list_empty(queue) && qsize--) {
@@ -242,7 +242,8 @@ wlan_ser_cancel_scan_cmd(
 			 */
 			if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
 						&cmd_list->cmd_in_use)) {
-				wlan_serialization_release_lock(pdev_q);
+				wlan_serialization_release_lock(
+						&pdev_q->pdev_queue_lock);
 				status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
 				goto error;
 			}
@@ -284,7 +285,7 @@ wlan_ser_cancel_scan_cmd(
 		}
 		nnode = pnode;
 
-		wlan_serialization_release_lock(pdev_q);
+		wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 		/*
 		 * call pending cmd's callback to notify that
 		 * it is being removed
@@ -303,13 +304,13 @@ wlan_ser_cancel_scan_cmd(
 					WLAN_SER_CB_RELEASE_MEM_CMD);
 		}
 
-		wlan_serialization_acquire_lock(pdev_q);
+		wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
 
 		if (!is_active_queue)
 			status = WLAN_SER_CMD_IN_PENDING_LIST;
 	}
 
-	wlan_serialization_release_lock(pdev_q);
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
 
 error:
 	ser_exit();

+ 11 - 28
umac/cmn_services/serialization/src/wlan_serialization_utils.c

@@ -1140,6 +1140,8 @@ QDF_STATUS wlan_serialization_cleanup_all_timers(
 		goto error;
 	}
 
+	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
+
 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
 		ser_timer = &psoc_ser_obj->timers[i];
 		if (!ser_timer->cmd)
@@ -1151,6 +1153,7 @@ QDF_STATUS wlan_serialization_cleanup_all_timers(
 		}
 	}
 
+	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
 error:
 	ser_exit();
 	return status;
@@ -1783,53 +1786,33 @@ error:
 }
 
 QDF_STATUS
-wlan_serialization_acquire_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue)
+wlan_serialization_acquire_lock(qdf_spinlock_t *lock)
 {
-	if (!pdev_queue) {
-		ser_err("invalid object");
-		return QDF_STATUS_E_FAILURE;
-	}
-	qdf_spin_lock_bh(&pdev_queue->pdev_queue_lock);
+	qdf_spin_lock_bh(lock);
 
 	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS
-wlan_serialization_release_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue)
+wlan_serialization_release_lock(qdf_spinlock_t *lock)
 {
-	if (!pdev_queue) {
-		ser_err("invalid object");
-		return QDF_STATUS_E_FAILURE;
-	}
-	qdf_spin_unlock_bh(&pdev_queue->pdev_queue_lock);
+	qdf_spin_unlock_bh(lock);
 
 	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS
-wlan_serialization_create_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue)
+wlan_serialization_create_lock(qdf_spinlock_t *lock)
 {
-	if (!pdev_queue) {
-		ser_err("invalid object");
-		return QDF_STATUS_E_FAILURE;
-	}
-	qdf_spinlock_create(&pdev_queue->pdev_queue_lock);
+	qdf_spinlock_create(lock);
 
 	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS
-wlan_serialization_destroy_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue)
+wlan_serialization_destroy_lock(qdf_spinlock_t *lock)
 {
-	if (!pdev_queue) {
-		ser_err("invalid object");
-		return QDF_STATUS_E_FAILURE;
-	}
-	qdf_spinlock_destroy(&pdev_queue->pdev_queue_lock);
+	qdf_spinlock_destroy(lock);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 9 - 12
umac/cmn_services/serialization/src/wlan_serialization_utils_i.h

@@ -784,6 +784,7 @@ struct wlan_ser_psoc_obj {
 	wlan_serialization_apply_rules_cb apply_rules_cb[WLAN_SER_CMD_MAX];
 	struct wlan_serialization_timer *timers;
 	uint8_t max_active_cmds;
+	qdf_spinlock_t timer_lock;
 };
 
 /**
@@ -1202,42 +1203,38 @@ QDF_STATUS wlan_serialization_peek_next(
 
 /**
  * wlan_serialization_acquire_lock() - Acquire lock to the given queue
- * @pdev_queue: Pointer to the pdev queue
+ * @lock: Pointer to the lock
  *
  * Return: QDF_STATUS success or failure
  */
 QDF_STATUS
-wlan_serialization_acquire_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue);
+wlan_serialization_acquire_lock(qdf_spinlock_t *lock);
 
 /**
  * wlan_serialization_release_lock() - Release lock to the given queue
- * @pdev_queue: Pointer to the pdev queue
+ * @lock: Pointer to the lock
  *
  * Return: QDF_STATUS success or failure
  */
 QDF_STATUS
-wlan_serialization_release_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue);
+wlan_serialization_release_lock(qdf_spinlock_t *lock);
 
 /**
  * wlan_serialization_create_lock() - Init the lock to the given queue
- * @pdev_queue: Pointer to the pdev queue
+ * @lock: Pointer to the lock
  *
  * Return: QDF_STATUS success or failure
  */
 QDF_STATUS
-wlan_serialization_create_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue);
+wlan_serialization_create_lock(qdf_spinlock_t *lock);
 
 /**
  * wlan_serialization_destroy_lock() - Deinit the lock to the given queue
- * @pdev_queue: Pointer to the pdev queue
+ * @lock: Pointer to the lock
  *
  * Return: QDF_STATUS success or failure
  */
 QDF_STATUS
-wlan_serialization_destroy_lock(
-		struct wlan_serialization_pdev_queue *pdev_queue);
+wlan_serialization_destroy_lock(qdf_spinlock_t *lock);
 #endif
 #endif