qcacld-3.0: Fix vdev count leak in pre CAC

At present Pre CAC work queue callback pre_cac_handle_failure
doesn't release the vdev ref count. And the pre_cac_handle_radar_ind
doesn't take ref count before schedule work pre_cac_work.
To fix inconsistency by using psoc as work queue callback parameter
and get pre CAC vdev id from psoc context.

Change-Id: I65339ca9f3ac4b91faf31090978337d041320f99
CRs-Fixed: 3288125
这个提交包含在:
Liangwei Dong
2022-09-13 12:17:45 +08:00
提交者 Madan Koyyalamudi
父节点 f844af3bfc
当前提交 86a7824781
修改 6 个文件,包含 63 行新增35 行删除

查看文件

@@ -34,7 +34,7 @@ void pre_cac_stop(struct wlan_objmgr_psoc *psoc)
if (!psoc_priv)
return;
pre_cac_debug("cancel pre_cac_work");
if (psoc_priv->pre_cac_work.fn)
qdf_cancel_work(&psoc_priv->pre_cac_work);
}
@@ -146,19 +146,27 @@ bool pre_cac_complete_get(struct wlan_objmgr_vdev *vdev)
return vdev_priv->pre_cac_complete;
}
static void pre_cac_complete(struct wlan_objmgr_vdev *vdev,
static void pre_cac_complete(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
QDF_STATUS status)
{
if (glbl_pre_cac_ops &&
glbl_pre_cac_ops->pre_cac_complete_cb)
glbl_pre_cac_ops->pre_cac_complete_cb(vdev, status);
glbl_pre_cac_ops->pre_cac_complete_cb(psoc, vdev_id, status);
}
static void pre_cac_handle_success(void *data)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)data;
struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data;
struct pre_cac_psoc_priv *psoc_priv;
pre_cac_complete(vdev, QDF_STATUS_SUCCESS);
psoc_priv = pre_cac_psoc_get_priv(psoc);
if (!psoc_priv) {
pre_cac_err("Invalid psoc priv");
return;
}
pre_cac_debug("vdev id %d", psoc_priv->pre_cac_vdev_id);
pre_cac_complete(psoc, psoc_priv->pre_cac_vdev_id, QDF_STATUS_SUCCESS);
}
static void pre_cac_conditional_csa_ind(struct wlan_objmgr_psoc *psoc,
@@ -172,15 +180,22 @@ static void pre_cac_conditional_csa_ind(struct wlan_objmgr_psoc *psoc,
static void pre_cac_handle_failure(void *data)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)data;
struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data;
struct pre_cac_psoc_priv *psoc_priv;
pre_cac_complete(vdev, QDF_STATUS_E_FAILURE);
psoc_priv = pre_cac_psoc_get_priv(psoc);
if (!psoc_priv) {
pre_cac_err("Invalid psoc priv");
return;
}
pre_cac_debug("vdev id %d", psoc_priv->pre_cac_vdev_id);
pre_cac_complete(psoc, psoc_priv->pre_cac_vdev_id,
QDF_STATUS_E_FAILURE);
}
void pre_cac_clean_up(struct wlan_objmgr_psoc *psoc)
{
struct pre_cac_psoc_priv *psoc_priv = pre_cac_psoc_get_priv(psoc);
struct wlan_objmgr_vdev *vdev;
uint8_t vdev_id;
if (!psoc_priv) {
@@ -192,17 +207,11 @@ void pre_cac_clean_up(struct wlan_objmgr_psoc *psoc)
return;
pre_cac_get_vdev_id(psoc, &vdev_id);
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_PRE_CAC_ID);
if (!vdev) {
pre_cac_err("Invalid vdev");
return;
}
pre_cac_debug("schedue pre_cac_work vdev %d", vdev_id);
psoc_priv->pre_cac_vdev_id = vdev_id;
qdf_create_work(0, &psoc_priv->pre_cac_work,
pre_cac_handle_failure,
vdev);
psoc);
qdf_sched_work(0, &psoc_priv->pre_cac_work);
}
@@ -211,11 +220,13 @@ void pre_cac_handle_radar_ind(struct wlan_objmgr_vdev *vdev)
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
struct pre_cac_psoc_priv *psoc_priv = pre_cac_psoc_get_priv(psoc);
pre_cac_conditional_csa_ind(psoc, vdev->vdev_objmgr.vdev_id, false);
pre_cac_conditional_csa_ind(psoc, wlan_vdev_get_id(vdev), false);
pre_cac_debug("schedue pre_cac_work vdev %d", wlan_vdev_get_id(vdev));
psoc_priv->pre_cac_vdev_id = wlan_vdev_get_id(vdev);
qdf_create_work(0, &psoc_priv->pre_cac_work,
pre_cac_handle_failure,
vdev);
psoc);
qdf_sched_work(0, &psoc_priv->pre_cac_work);
}
@@ -224,11 +235,13 @@ void pre_cac_handle_cac_end(struct wlan_objmgr_vdev *vdev)
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
struct pre_cac_psoc_priv *psoc_priv = pre_cac_psoc_get_priv(psoc);
pre_cac_conditional_csa_ind(psoc, vdev->vdev_objmgr.vdev_id, true);
pre_cac_conditional_csa_ind(psoc, wlan_vdev_get_id(vdev), true);
pre_cac_debug("schedue pre_cac_work vdev %d", wlan_vdev_get_id(vdev));
psoc_priv->pre_cac_vdev_id = wlan_vdev_get_id(vdev);
qdf_create_work(0, &psoc_priv->pre_cac_work,
pre_cac_handle_success,
vdev);
psoc);
qdf_sched_work(0, &psoc_priv->pre_cac_work);
}

查看文件

@@ -77,9 +77,11 @@ struct pre_cac_vdev_priv {
/**
* struct pre_cac_psoc_priv - Private object to be stored in psoc
* @pre_cac_work: pre cac work handler
* @pre_cac_vdev_id: pre cac vdev id
*/
struct pre_cac_psoc_priv {
qdf_work_t pre_cac_work;
uint8_t pre_cac_vdev_id;
};
/**
@@ -158,8 +160,8 @@ pre_cac_psoc_get_priv_fl(struct wlan_objmgr_psoc *psoc,
*
* Return: pre_cac psoc private object
*/
#define pre_cac_psoc_get_priv(vdev) \
pre_cac_psoc_get_priv_fl(vdev, __func__, __LINE__)
#define pre_cac_psoc_get_priv(psoc) \
pre_cac_psoc_get_priv_fl(psoc, __func__, __LINE__)
/**
* pre_cac_init() - pre cac component initialization.

查看文件

@@ -29,7 +29,8 @@ struct pre_cac_ops {
void (*pre_cac_conditional_csa_ind_cb)(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
bool status);
void (*pre_cac_complete_cb)(struct wlan_objmgr_vdev *vdev,
QDF_STATUS status);
void (*pre_cac_complete_cb)(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
QDF_STATUS status);
};
#endif /* _WLAN_PRE_CAC_PUBLIC_STRUCT_H_ */