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:
Arun Kumar Khandavalli 2019-04-24 18:34:18 +05:30 • committed by nshrivas
commit 43fdd25d72
8 changed files with 67 additions and 34 deletions

View file

@ -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)
{
}

View file

@ -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);