Răsfoiți Sursa

qcacld-3.0: Move allocation of tdls private to tdls component

Presently osif tdls memory is freed as part of the osif_priv
when the vdev is logically destroyed. There is case seen
wherein the  tdls is holding vdev reference and in the other
thread the  interface down is received and the osif_priv is
freed resulting in the tdls osif priv also, if the other thread
tries to dereference the tdls os priv it will result
null pointer exception.

Move the tdls osif priv memory creation/deletion to the tdls component.

Change-Id: I3782f6304bee5a6eaab4d9122a569ba56fd29947
CRs-Fixed: 2436379
Arun Kumar Khandavalli 6 ani în urmă
părinte
comite
bae951f1ce

+ 7 - 0
tdls/core/src/wlan_tdls_main.c

@@ -256,6 +256,11 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
 		return QDF_STATUS_E_NOMEM;
 	}
 
+	if (tdls_soc_obj->tdls_osif_init_cb) {
+		status = tdls_soc_obj->tdls_osif_init_cb(vdev);
+		if (QDF_IS_STATUS_ERROR(status))
+			return status;
+	}
 	tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags;
 	if (!TDLS_IS_ENABLED(tdls_feature_flags)) {
 		tdls_debug("disabled in ini");
@@ -342,6 +347,8 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev,
 
 	tdls_vdev_deinit(tdls_vdev_obj);
 	qdf_mem_free(tdls_vdev_obj);
+	if (tdls_soc_obj->tdls_osif_deinit_cb)
+		tdls_soc_obj->tdls_osif_deinit_cb(vdev);
 
 	return status;
 }

+ 4 - 0
tdls/core/src/wlan_tdls_main.h

@@ -183,6 +183,8 @@ struct tdls_set_state_info {
  * @tdls_update_dp_vdev_flags store CDP_UPDATE_TDLS_FLAGS
  * @tdls_idle_peer_data: provide information about idle peer
  * @tdls_ct_spinlock: connection tracker spin lock
+ * @tdls_osif_init_cb: Callback to initialize the tdls private
+ * @tdls_osif_deinit_cb: Callback to deinitialize the tdls private
  */
 struct tdls_soc_priv_obj {
 	struct wlan_objmgr_psoc *soc;
@@ -224,6 +226,8 @@ struct tdls_soc_priv_obj {
 	uint16_t tdls_del_all_peers;
 	uint32_t tdls_update_dp_vdev_flags;
 	qdf_spinlock_t tdls_ct_spinlock;
+	tdls_vdev_init_cb tdls_osif_init_cb;
+	tdls_vdev_deinit_cb tdls_osif_deinit_cb;
 };
 
 /**

+ 24 - 0
tdls/dispatcher/inc/wlan_tdls_public_structs.h

@@ -609,6 +609,26 @@ typedef QDF_STATUS
 /* This callback is to release vdev ref for tdls offchan param related msg */
 typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * tdls_vdev_init_cb() - Callback for initializing the tdls private structure
+ * @vdev: vdev object
+ *
+ * This callback will be used to create the vdev private object and store
+ * in os_priv.
+ *
+ * Return: QDF_STATUS
+ */
+typedef QDF_STATUS (*tdls_vdev_init_cb)(struct wlan_objmgr_vdev *vdev);
+/**
+ * tdls_vdev_deinit_cb() - Callback for deinitializing the tdls private struct
+ * @vdev: vdev object
+ *
+ * This callback will be used to destroy the vdev private object.
+ *
+ * Return: None
+ */
+typedef void (*tdls_vdev_deinit_cb)(struct wlan_objmgr_vdev *vdev);
+
 /**
  * struct tdls_start_params - tdls start params
  * @config: tdls user config
@@ -624,6 +644,8 @@ typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev);
  * @tdls_reg_peer: register tdls peer with datapath
  * @tdls_dereg_peer: deregister tdls peer from datapath
  * @tdls_dp_vdev_update: update vdev flags in datapath
+ * @tdls_osif_init_cb: callback to initialize the tdls priv
+ * @tdls_osif_deinit_cb: callback to deinitialize the tdls priv
  */
 struct tdls_start_params {
 	struct tdls_user_config config;
@@ -643,6 +665,8 @@ struct tdls_start_params {
 	tdls_register_peer_callback tdls_reg_peer;
 	tdls_deregister_peer_callback tdls_dereg_peer;
 	tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update;
+	tdls_vdev_init_cb tdls_osif_init_cb;
+	tdls_vdev_deinit_cb tdls_osif_deinit_cb;
 };
 
 /**

+ 2 - 0
tdls/dispatcher/src/wlan_tdls_ucfg_api.c

@@ -307,6 +307,8 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
 	soc_obj->tdls_del_all_peers = req->tdls_del_all_peers;
 	soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags;
 	soc_obj->tdls_dp_vdev_update = req->tdls_dp_vdev_update;
+	soc_obj->tdls_osif_init_cb = req->tdls_osif_init_cb;
+	soc_obj->tdls_osif_deinit_cb = req->tdls_osif_deinit_cb;
 	tdls_pm_call_backs.tdls_notify_increment_session =
 			tdls_notify_increment_session;