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
This commit is contained in:
parent
f151174be6
commit
43fdd25d72
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1275,6 +1275,8 @@ static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
|
||||
tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
|
||||
tdls_cfg.tdls_rx_cb_data = psoc;
|
||||
tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
|
||||
tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
|
||||
tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
|
||||
|
||||
status = ucfg_tdls_update_config(psoc, &tdls_cfg);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
|
@ -60,19 +60,10 @@ hdd_init_vdev_os_priv(struct hdd_adapter *adapter)
|
||||
/* Initialize the vdev OS private structure*/
|
||||
os_priv->wdev = adapter->dev->ieee80211_ptr;
|
||||
os_priv->legacy_osif_priv = adapter;
|
||||
wlan_cfg80211_tdls_priv_init(os_priv);
|
||||
|
||||
return os_priv;
|
||||
}
|
||||
|
||||
static void hdd_deinit_vdev_os_priv(struct vdev_osif_priv *os_priv)
|
||||
{
|
||||
if (os_priv) {
|
||||
wlan_cfg80211_tdls_priv_deinit(os_priv);
|
||||
qdf_mem_free(os_priv);
|
||||
}
|
||||
}
|
||||
|
||||
static void hdd_init_psoc_qdf_ctx(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
qdf_device_t qdf_ctx;
|
||||
@ -239,7 +230,7 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
int errno = 0;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct vdev_osif_priv *osif_priv;
|
||||
struct wlan_vdev_create_params vdev_params = {0};
|
||||
@ -266,7 +257,8 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
|
||||
if (!vdev) {
|
||||
hdd_err("Failed to create vdev object");
|
||||
errno = -ENOMEM;
|
||||
goto osif_priv_free;
|
||||
qdf_mem_free(osif_priv);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -290,10 +282,6 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
|
||||
|
||||
vdev_destroy:
|
||||
wlan_objmgr_vdev_obj_delete(vdev);
|
||||
|
||||
osif_priv_free:
|
||||
hdd_deinit_vdev_os_priv(osif_priv);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
@ -301,7 +289,6 @@ int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct vdev_osif_priv *osif_priv;
|
||||
|
||||
qdf_spin_lock_bh(&adapter->vdev_lock);
|
||||
vdev = adapter->vdev;
|
||||
@ -313,12 +300,6 @@ int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter)
|
||||
if (!vdev)
|
||||
return -EINVAL;
|
||||
|
||||
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
wlan_vdev_reset_ospriv(vdev);
|
||||
|
||||
QDF_BUG(osif_priv);
|
||||
hdd_deinit_vdev_os_priv(osif_priv);
|
||||
|
||||
status = wlan_objmgr_vdev_obj_delete(vdev);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
|
||||
|
||||
|
@ -87,24 +87,24 @@ enum qca_wlan_vendor_tdls_trigger_mode_vdev_map {
|
||||
};
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_tdls_priv_init() - API to initialize tdls os private
|
||||
* @osif_priv: vdev os private
|
||||
* wlan_cfg80211_tdls_osif_priv_init() - API to initialize tdls os private
|
||||
* @vdev: vdev object
|
||||
*
|
||||
* API to initialize tdls os private
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv);
|
||||
QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_tdls_priv_deinit() - API to deinitialize tdls os private
|
||||
* @osif_priv: vdev os private
|
||||
* wlan_cfg80211_tdls_osif_priv_deinit() - API to deinitialize tdls os private
|
||||
* @vdev: vdev object
|
||||
*
|
||||
* API to deinitialize tdls os private
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv);
|
||||
void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_tdls_add_peer() - process cfg80211 add TDLS peer request
|
||||
@ -272,13 +272,13 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
#else /* FEATURE_WLAN_TDLS */
|
||||
static inline
|
||||
QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv)
|
||||
QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline
|
||||
void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv)
|
||||
void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,16 @@ static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv)
|
||||
QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct osif_tdls_vdev *tdls_priv;
|
||||
struct vdev_osif_priv *osif_priv;
|
||||
|
||||
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
if (!osif_priv) {
|
||||
cfg80211_err("osif_priv is NULL!");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
cfg80211_debug("initialize tdls os if layer private structure");
|
||||
tdls_priv = qdf_mem_malloc(sizeof(*tdls_priv));
|
||||
@ -78,13 +85,17 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv)
|
||||
void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
cfg80211_debug("deinitialize tdls os if layer private structure");
|
||||
struct vdev_osif_priv *osif_priv;
|
||||
|
||||
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
if (!osif_priv) {
|
||||
cfg80211_err("OS private structure of vdev is null ");
|
||||
cfg80211_err("osif_priv is NULL!");
|
||||
return;
|
||||
}
|
||||
|
||||
cfg80211_debug("deinitialize tdls os if layer private structure");
|
||||
if (osif_priv->osif_tdls)
|
||||
qdf_mem_free(osif_priv->osif_tdls);
|
||||
osif_priv->osif_tdls = NULL;
|
||||
@ -103,6 +114,8 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev)
|
||||
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
|
||||
tdls_priv = osif_priv->osif_tdls;
|
||||
if (!tdls_priv)
|
||||
return;
|
||||
|
||||
reinit_completion(&tdls_priv->tdls_teardown_comp);
|
||||
status = ucfg_tdls_teardown_links(vdev);
|
||||
|
Loading…
Reference in New Issue
Block a user