Browse Source

qcacld-3.0: Use the global lock instead of the ipa init_deinit_lock

Use the global lock instead of the init_deinit_lock in the ipa_obj to
avoid access the invalid memory with ipa_obj->init_deinit_lock since
the ipa_obj will be freed after driver shutdown.

Change-Id: I98a844456873f60213fae19c237bb08b76b4846c
CRs-Fixed: 2887487
Tiger Yu 4 years ago
parent
commit
9845857014

+ 14 - 0
components/ipa/core/inc/wlan_ipa_main.h

@@ -525,6 +525,20 @@ void ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
  */
 bool ipa_cb_is_ready(void);
 
+/**
+ * ipa_init_deinit_lock() - lock ipa init deinit lock
+ *
+ * Return: None
+ */
+void ipa_init_deinit_lock(void);
+
+/**
+ * ipa_init_deinit_unlock() - unlock ipa init deinit lock
+ *
+ * Return: None
+ */
+void ipa_init_deinit_unlock(void);
+
 #else /* Not IPA_OFFLOAD */
 typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
 typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev);

+ 0 - 1
components/ipa/core/inc/wlan_ipa_priv.h

@@ -686,7 +686,6 @@ struct wlan_ipa_priv {
 	qdf_mc_timer_t rt_debug_fill_timer;
 	qdf_mutex_t rt_debug_lock;
 	qdf_mutex_t ipa_lock;
-	qdf_mutex_t init_deinit_lock;
 
 	uint8_t vdev_to_iface[WLAN_IPA_MAX_SESSION];
 	bool vdev_offload_enabled[WLAN_IPA_MAX_SESSION];

+ 2 - 2
components/ipa/core/src/wlan_ipa_main.c

@@ -581,7 +581,7 @@ QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	qdf_mutex_acquire(&ipa_obj->init_deinit_lock);
+	ipa_init_deinit_lock();
 
 	if (!ipa_config_is_enabled()) {
 		ipa_debug("ipa is disabled");
@@ -598,7 +598,7 @@ QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
 	status = wlan_ipa_uc_ol_deinit(ipa_obj);
 
 out:
-	qdf_mutex_release(&ipa_obj->init_deinit_lock);
+	ipa_init_deinit_unlock();
 	return status;
 }
 

+ 18 - 4
components/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c

@@ -27,6 +27,7 @@
 #include "qdf_platform.h"
 
 static bool g_ipa_is_ready;
+static qdf_mutex_t g_init_deinit_lock;
 bool ipa_cb_is_ready(void)
 {
 	return g_ipa_is_ready;
@@ -38,6 +39,16 @@ void ipa_disable_register_cb(void)
 	g_ipa_is_ready = false;
 }
 
+void ipa_init_deinit_lock(void)
+{
+	qdf_mutex_acquire(&g_init_deinit_lock);
+}
+
+void ipa_init_deinit_unlock(void)
+{
+	qdf_mutex_release(&g_init_deinit_lock);
+}
+
 /**
  * ipa_pdev_obj_destroy_notification() - IPA pdev object destroy notification
  * @pdev: pdev handle
@@ -71,7 +82,6 @@ ipa_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
 		ipa_err("Failed to detatch ipa pdev object");
 
 	ipa_obj_cleanup(ipa_obj);
-	qdf_mutex_destroy(&ipa_obj->init_deinit_lock);
 	qdf_mem_free(ipa_obj);
 	ipa_disable_register_cb();
 
@@ -103,7 +113,6 @@ ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
 	if (!ipa_obj)
 		return QDF_STATUS_E_NOMEM;
 
-	qdf_mutex_create(&ipa_obj->init_deinit_lock);
 	status = wlan_objmgr_pdev_component_obj_attach(pdev,
 						       WLAN_UMAC_COMP_IPA,
 						       (void *)ipa_obj,
@@ -146,7 +155,8 @@ static void ipa_register_ready_cb(void *user_data)
 		return;
 	}
 
-	qdf_mutex_acquire(&ipa_obj->init_deinit_lock);
+	ipa_init_deinit_lock();
+
 	/*
 	 * Meanwhile acquiring lock, driver stop modules can happen in parallel,
 	 * validate driver state once again to proceed with IPA init.
@@ -180,7 +190,7 @@ static void ipa_register_ready_cb(void *user_data)
 	}
 
 out:
-	qdf_mutex_release(&ipa_obj->init_deinit_lock);
+	ipa_init_deinit_unlock();
 }
 
 QDF_STATUS ipa_register_is_ipa_ready(struct wlan_objmgr_pdev *pdev)
@@ -239,6 +249,8 @@ QDF_STATUS ipa_init(void)
 		goto fail_delete_pdev;
 	}
 
+	qdf_mutex_create(&g_init_deinit_lock);
+
 	return status;
 
 fail_delete_pdev:
@@ -264,6 +276,8 @@ QDF_STATUS ipa_deinit(void)
 		return status;
 	}
 
+	qdf_mutex_destroy(&g_init_deinit_lock);
+
 	status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_IPA,
 				ipa_pdev_obj_destroy_notification, NULL);
 	if (QDF_IS_STATUS_ERROR(status))