Browse Source

qcacld-3.0: Add lock for multicast list update

Currently, kernel provides the multicast address list to the driver
and driver appends this list with new peer multicast address which
are not included in the list. This is done in irq thread.
But with recent changes, for NDI, driver will update this list on
the peer addition and deletion which is executed in scheduler thread.
This may lead to issue when request to update the multicast
list comes from scheduler thread while irq thread request is in
progress and vice-versa.
So, to handle such situation, add spin lock which will protect the
multicast address list.

Change-Id: I9093a92d3714abd875dcd02743f711a5bed26090
CRs-Fixed: 3518989
Rahul Gusain 1 year ago
parent
commit
def3833179
2 changed files with 7 additions and 1 deletions
  1. 3 1
      core/hdd/inc/wlan_hdd_main.h
  2. 4 0
      core/hdd/src/wlan_hdd_main.c

+ 3 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -1115,7 +1115,8 @@ struct wlan_hdd_tx_power {
  * @wapi_info:
  * @sap_stop_bss_work:
  * @tsf: structure containing tsf related information
- * @mc_addr_list:
+ * @mc_addr_list: multicast address list
+ * @mc_list_lock: spin lock for multicast list
  * @addr_filter_pattern:
  * @scan_info:
  * @psb_changed: Flag to ensure PSB is configured through framework
@@ -1263,6 +1264,7 @@ struct hdd_adapter {
 	struct hdd_vdev_tsf tsf;
 #endif
 	struct hdd_multicast_addr_list mc_addr_list;
+	qdf_spinlock_t mc_list_lock;
 	uint8_t addr_filter_pattern;
 
 	struct hdd_scan_info scan_info;

+ 4 - 0
core/hdd/src/wlan_hdd_main.c

@@ -5966,6 +5966,7 @@ static void __hdd_set_multicast_list(struct net_device *dev)
 	if (!mc_list_request)
 		return;
 
+	qdf_spin_lock_bh(&adapter->mc_list_lock);
 	/* Delete already configured multicast address list */
 	if (adapter->mc_addr_list.mc_cnt > 0)
 		hdd_disable_and_flush_mc_addr_list(adapter,
@@ -6018,6 +6019,7 @@ static void __hdd_set_multicast_list(struct net_device *dev)
 	hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
 
 free_req:
+	qdf_spin_unlock_bh(&adapter->mc_list_lock);
 	qdf_mem_free(mc_list_request);
 }
 
@@ -7458,6 +7460,7 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
 	}
 
 	hdd_apf_context_destroy(adapter);
+	qdf_spinlock_destroy(&adapter->mc_list_lock);
 	hdd_adapter_for_each_link_entry(adapter, link_idx) {
 		link_info = hdd_adapter_get_link_info_ptr(adapter, link_idx);
 		if (!link_info)
@@ -8270,6 +8273,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
 	qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
 	qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
 	qdf_event_create(&adapter->deflink->acs_complete_event);
+	qdf_spinlock_create(&adapter->mc_list_lock);
 	qdf_event_create(&adapter->peer_cleanup_done);
 	hdd_sta_info_init(&adapter->sta_info_list);
 	hdd_sta_info_init(&adapter->cache_sta_info_list);