Jelajahi Sumber

qcacld-3.0: Add mutex to protect rssi_disallow_bssid list

rssi_disallow_bssid could be accessed from different thread,
mutex protection is added to avoid node invalid access when
node has been deleted or updated.

Change-Id: I2b19d48f19a3da55030384f26c501aee283801c7
CRs-Fixed: 2405157
Jingxiang Ge 6 tahun lalu
induk
melakukan
f95dc4df29

+ 7 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -6350,6 +6350,8 @@ void lim_add_roam_blacklist_ap(struct mac_context *mac_ctx,
 		entry->time_during_rejection = blacklist->received_time;
 		/* set 0dbm as expected rssi for btm blaclisted entries */
 		entry->expected_rssi = LIM_MIN_RSSI;
+
+		qdf_mutex_acquire(&mac_ctx->roam.rssi_disallow_bssid_lock);
 		lim_remove_duplicate_bssid_node(
 					entry,
 					&mac_ctx->roam.rssi_disallow_bssid);
@@ -6359,6 +6361,8 @@ void lim_add_roam_blacklist_ap(struct mac_context *mac_ctx,
 			status = lim_rem_blacklist_entry_with_lowest_delta(
 					&mac_ctx->roam.rssi_disallow_bssid);
 			if (QDF_IS_STATUS_ERROR(status)) {
+				qdf_mutex_release(&mac_ctx->roam.
+					rssi_disallow_bssid_lock);
 				pe_err("Failed to remove entry with lowest delta");
 				qdf_mem_free(entry);
 				return;
@@ -6370,6 +6374,8 @@ void lim_add_roam_blacklist_ap(struct mac_context *mac_ctx,
 					&mac_ctx->roam.rssi_disallow_bssid,
 					&entry->node);
 			if (QDF_IS_STATUS_ERROR(status)) {
+				qdf_mutex_release(&mac_ctx->roam.
+					rssi_disallow_bssid_lock);
 				pe_err("Failed to enqueue bssid: %pM",
 				       entry->bssid.bytes);
 				qdf_mem_free(entry);
@@ -6378,6 +6384,7 @@ void lim_add_roam_blacklist_ap(struct mac_context *mac_ctx,
 			pe_debug("Added BTM blacklisted bssid: %pM",
 				 entry->bssid.bytes);
 		}
+		qdf_mutex_release(&mac_ctx->roam.rssi_disallow_bssid_lock);
 		blacklist++;
 	}
 }

+ 2 - 0
core/mac/src/pe/lim/lim_utils.c

@@ -7629,6 +7629,7 @@ void lim_assoc_rej_add_to_rssi_based_reject_list(struct mac_context *mac_ctx,
 		qdf_do_div(qdf_get_monotonic_boottime(),
 		QDF_MC_TIMER_TO_MS_UNIT);
 
+	qdf_mutex_acquire(&mac_ctx->roam.rssi_disallow_bssid_lock);
 	if (qdf_list_size(&mac_ctx->roam.rssi_disallow_bssid) >=
 		MAX_RSSI_AVOID_BSSID_LIST) {
 		status = lim_rem_blacklist_entry_with_lowest_delta(
@@ -7641,6 +7642,7 @@ void lim_assoc_rej_add_to_rssi_based_reject_list(struct mac_context *mac_ctx,
 		status = qdf_list_insert_back(
 				&mac_ctx->roam.rssi_disallow_bssid,
 				&entry->node);
+	qdf_mutex_release(&mac_ctx->roam.rssi_disallow_bssid_lock);
 
 	if (QDF_IS_STATUS_ERROR(status)) {
 		pe_err("Failed to enqueue bssid entry");

+ 1 - 0
core/sme/inc/csr_internal.h

@@ -735,6 +735,7 @@ struct csr_roamstruct {
 	uint16_t reassocRespLen;        /* length of reassociation response */
 	qdf_mc_timer_t packetdump_timer;
 	qdf_list_t rssi_disallow_bssid;
+	qdf_mutex_t rssi_disallow_bssid_lock;
 	spinlock_t roam_state_lock;
 };
 

+ 68 - 31
core/sme/src/csr/csr_api_roam.c

@@ -591,6 +591,68 @@ static void csr_close_stats_ll(struct mac_context *mac_ctx)
 }
 #endif
 
+/**
+ * csr_assoc_rej_free_rssi_disallow_list() - Free the rssi disallowed
+ * BSSID entries and destroy the list
+ * @mac_ctx: MAC context
+ *
+ * Return: void
+ */
+static void csr_assoc_rej_free_rssi_disallow_list(struct mac_context *mac)
+{
+	QDF_STATUS status;
+	struct sir_rssi_disallow_lst *cur_node;
+	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
+	qdf_list_t *list = &mac->roam.rssi_disallow_bssid;
+
+	qdf_mutex_acquire(&mac->roam.rssi_disallow_bssid_lock);
+	qdf_list_peek_front(list, &cur_lst);
+	while (cur_lst) {
+		qdf_list_peek_next(list, cur_lst, &next_lst);
+		cur_node = qdf_container_of(cur_lst,
+					    struct sir_rssi_disallow_lst, node);
+		status = qdf_list_remove_node(list, cur_lst);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			qdf_mem_free(cur_node);
+		cur_lst = next_lst;
+		next_lst = NULL;
+	}
+	qdf_list_destroy(list);
+	qdf_mutex_release(&mac->roam.rssi_disallow_bssid_lock);
+}
+
+/**
+ * csr_roam_rssi_disallow_bssid_init() - Init the rssi disallowed
+ * list and mutex
+ * @mac_ctx: MAC context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS csr_roam_rssi_disallow_bssid_init(
+					     struct mac_context *mac_ctx)
+{
+	qdf_list_create(&mac_ctx->roam.rssi_disallow_bssid,
+			MAX_RSSI_AVOID_BSSID_LIST);
+	qdf_mutex_create(&mac_ctx->roam.rssi_disallow_bssid_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_roam_rssi_disallow_bssid_deinit() - Free the rssi diallowed
+ * BSSID entries and destroy the list&mutex
+ * @mac_ctx: MAC context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS csr_roam_rssi_disallow_bssid_deinit(
+					     struct mac_context *mac_ctx)
+{
+	csr_assoc_rej_free_rssi_disallow_list(mac_ctx);
+	qdf_mutex_destroy(&mac_ctx->roam.rssi_disallow_bssid_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS csr_open(struct mac_context *mac)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -622,8 +684,8 @@ QDF_STATUS csr_open(struct mac_context *mac)
 			csr_roam_free_globals();
 			break;
 		}
-		qdf_list_create(&mac->roam.rssi_disallow_bssid,
-			MAX_RSSI_AVOID_BSSID_LIST);
+
+		csr_roam_rssi_disallow_bssid_init(mac);
 	} while (0);
 
 	return status;
@@ -674,40 +736,12 @@ QDF_STATUS csr_set_channels(struct mac_context *mac, tCsrConfigParam *pParam)
 	return status;
 }
 
-/**
- * csr_assoc_rej_free_rssi_disallow_list() - Free the rssi diallowed
- * BSSID entries and destroy the list
- * @list: rssi based disallowed list entry
- *
- * Return: void
- */
-static void csr_assoc_rej_free_rssi_disallow_list(qdf_list_t *list)
-{
-	QDF_STATUS status;
-	struct sir_rssi_disallow_lst *cur_node;
-	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
-
-	qdf_list_peek_front(list, &cur_lst);
-	while (cur_lst) {
-		qdf_list_peek_next(list, cur_lst, &next_lst);
-		cur_node = qdf_container_of(cur_lst,
-			struct sir_rssi_disallow_lst, node);
-		status = qdf_list_remove_node(list, cur_lst);
-		if (QDF_IS_STATUS_SUCCESS(status))
-			qdf_mem_free(cur_node);
-		cur_lst = next_lst;
-		next_lst = NULL;
-	}
-	qdf_list_destroy(list);
-}
-
 QDF_STATUS csr_close(struct mac_context *mac)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	csr_roam_close(mac);
-	csr_assoc_rej_free_rssi_disallow_list(
-		&mac->roam.rssi_disallow_bssid);
+	csr_roam_rssi_disallow_bssid_deinit(mac);
 	csr_scan_close(mac);
 	csr_close_stats_ll(mac);
 	/* DeInit Globals */
@@ -18268,6 +18302,7 @@ static void csr_add_rssi_reject_ap_list(struct mac_context *mac_ctx,
 	if (roam_params->num_rssi_rejection_ap > MAX_RSSI_AVOID_BSSID_LIST)
 		roam_params->num_rssi_rejection_ap = MAX_RSSI_AVOID_BSSID_LIST;
 
+	qdf_mutex_acquire(&mac_ctx->roam.rssi_disallow_bssid_lock);
 	qdf_list_peek_front(list, &cur_list);
 	while (cur_list) {
 		int32_t rem_time;
@@ -18293,6 +18328,8 @@ static void csr_add_rssi_reject_ap_list(struct mac_context *mac_ctx,
 		if (i >= MAX_RSSI_AVOID_BSSID_LIST)
 			break;
 	}
+	qdf_mutex_release(&mac_ctx->roam.rssi_disallow_bssid_lock);
+
 	for (i = 0; i < roam_params->num_rssi_rejection_ap; i++) {
 		sme_debug("BSSID %pM expected rssi %d remaining duration %d",
 			roam_params->rssi_rejection_ap[i].bssid.bytes,

+ 4 - 0
core/sme/src/csr/csr_api_scan.c

@@ -2809,9 +2809,13 @@ static void csr_filter_ap_due_to_rssi_reject(struct mac_context *mac_ctx,
 					Link);
 		next_entry = csr_ll_next(&scan_list->List,
 						cur_entry, LL_ACCESS_NOLOCK);
+
+		qdf_mutex_acquire(&mac_ctx->roam.rssi_disallow_bssid_lock);
 		remove = csr_remove_ap_due_to_rssi(
 			&mac_ctx->roam.rssi_disallow_bssid,
 			&scan_res->Result.BssDescriptor);
+		qdf_mutex_release(&mac_ctx->roam.rssi_disallow_bssid_lock);
+
 		if (remove) {
 			csr_ll_remove_entry(&scan_list->List,
 				cur_entry, LL_ACCESS_NOLOCK);