qcacld-3.0: Check cbs->vdev after getting g_cbs_lock lock

Currently there is a corner case wlan_cbs_timer_handler is called
with cbs->vdev being NULL.

In wlan_cbs_iterate, cbs->vdev is checked before getting g_cbs_lock
lock, then wlan_son_cbs_disable is called which sets cbs->vdev as
NULL and sets cbs state as CBS_INIT, then in wlan_cbs_iterate, it
gets g_cbs_lock lock and set cbs state as CBS_WAIT and start timer.
Finally in timer callback, cbs->vdev is NULL and cbs state is CBS_WAIT.

Check cbs->vdev after getting g_cbs_lock lock in wlan_cbs_iterate.
g_cbs_lock should protect all fields in struct son_cbs.

Change-Id: I393db09ac29e19fd29e546035c37062c04da7f7d
CRs-Fixed: 3179382
This commit is contained in:
bings
2022-04-21 17:10:12 +08:00
committed by Madan Koyyalamudi
parent 45148112e6
commit 5c9765db81

View File

@@ -990,9 +990,11 @@ static int wlan_cbs_iterate(struct son_cbs *cbs)
int offset_array_idx; int offset_array_idx;
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
if (!cbs || !cbs->vdev)
return -EINVAL;
qdf_spin_lock_bh(&g_cbs_lock); qdf_spin_lock_bh(&g_cbs_lock);
if (!cbs || !cbs->vdev) {
qdf_spin_unlock_bh(&g_cbs_lock);
return -EINVAL;
}
son_debug("dwell_split_cnt: %d", cbs->dwell_split_cnt); son_debug("dwell_split_cnt: %d", cbs->dwell_split_cnt);
if (cbs->dwell_split_cnt < 0) { if (cbs->dwell_split_cnt < 0) {
psoc = wlan_vdev_get_psoc(cbs->vdev); psoc = wlan_vdev_get_psoc(cbs->vdev);