qcacld-3.0: Add vdev lock to dp component
Add vdev lock to DP component to protect against vdev parallel delete while accessing vdev from DP interface, also introduce get and put APIs. Change-Id: I4ee838e1dea0caf9936ced13d6ddce6646333f6b CRs-Fixed: 3198876
This commit is contained in:

committed by
Madan Koyyalamudi

parent
cbb51199af
commit
b389b5b1bd
@@ -100,4 +100,56 @@ dp_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
|
||||
|
||||
return dp_ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_objmgr_get_vdev_by_user() - Get reference of vdev from dp_intf
|
||||
* with user id
|
||||
* @dp_intf: dp dp_intf
|
||||
* @dbgid: reference count dbg id
|
||||
*
|
||||
* Return: pointer to vdev object for success, NULL for failure
|
||||
*/
|
||||
#ifdef WLAN_OBJMGR_REF_ID_TRACE
|
||||
#define dp_objmgr_get_vdev_by_user(dp_intf, dbgid) \
|
||||
__dp_objmgr_get_vdev_by_user(dp_intf, dbgid, __func__, __LINE__)
|
||||
struct wlan_objmgr_vdev *
|
||||
__dp_objmgr_get_vdev_by_user(struct wlan_dp_intf *dp_intf,
|
||||
wlan_objmgr_ref_dbgid id,
|
||||
const char *func,
|
||||
int line);
|
||||
#else
|
||||
#define dp_objmgr_get_vdev_by_user(dp_intf, dbgid) \
|
||||
__dp_objmgr_get_vdev_by_user(dp_intf, dbgid, __func__)
|
||||
struct wlan_objmgr_vdev *
|
||||
__dp_objmgr_get_vdev_by_user(struct wlan_dp_intf *dp_intf,
|
||||
wlan_objmgr_ref_dbgid id,
|
||||
const char *func);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_objmgr_put_vdev_by_user() - Release reference of vdev object with
|
||||
* user id
|
||||
* @vdev: pointer to vdev object
|
||||
* @dbgid: reference count dbg id
|
||||
*
|
||||
* This API releases vdev object reference which was acquired using
|
||||
* dp_objmgr_get_vdev_by_user().
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
#ifdef WLAN_OBJMGR_REF_ID_TRACE
|
||||
#define dp_objmgr_put_vdev_by_user(vdev, dbgid) \
|
||||
__dp_objmgr_put_vdev_by_user(vdev, dbgid, __func__, __LINE__)
|
||||
void
|
||||
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
|
||||
wlan_objmgr_ref_dbgid id, const char *func,
|
||||
int line);
|
||||
#else
|
||||
#define dp_objmgr_put_vdev_by_user(vdev, dbgid) \
|
||||
__dp_objmgr_put_vdev_by_user(vdev, dbgid, __func__)
|
||||
void
|
||||
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
|
||||
wlan_objmgr_ref_dbgid id, const char *func);
|
||||
#endif
|
||||
|
||||
#endif /* __WLAN_DP_OBJMGR_H */
|
||||
|
@@ -286,6 +286,7 @@ struct wlan_dp_intf {
|
||||
qdf_list_node_t node;
|
||||
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
qdf_spinlock_t vdev_lock;
|
||||
qdf_netdev_t dev;
|
||||
/**Device TX/RX statistics*/
|
||||
struct dp_stats dp_stats;
|
||||
|
@@ -1690,17 +1690,14 @@ static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
|
||||
dp_ctx->bw_vote_time = curr_time_us;
|
||||
|
||||
dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
|
||||
vdev = dp_intf->vdev;
|
||||
vdev = dp_objmgr_get_vdev_by_user(dp_intf, WLAN_DP_ID);
|
||||
if (!vdev)
|
||||
continue;
|
||||
|
||||
if (dp_comp_vdev_get_ref(vdev))
|
||||
continue;
|
||||
|
||||
if ((dp_intf->device_mode == QDF_STA_MODE ||
|
||||
dp_intf->device_mode == QDF_P2P_CLIENT_MODE) &&
|
||||
!ucfg_cm_is_vdev_active(vdev)) {
|
||||
dp_comp_vdev_put_ref(vdev);
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1708,7 +1705,7 @@ static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
|
||||
dp_intf->device_mode == QDF_P2P_GO_MODE) &&
|
||||
!dp_ctx->dp_ops.dp_is_ap_active(ctx,
|
||||
dp_intf->intf_id)) {
|
||||
dp_comp_vdev_put_ref(vdev);
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1774,7 +1771,7 @@ static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
|
||||
QDF_NET_DEV_STATS_TX_BYTES(&dp_intf->stats);
|
||||
qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
|
||||
connected = true;
|
||||
dp_comp_vdev_put_ref(vdev);
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
|
@@ -638,15 +638,10 @@ static void
|
||||
__dp_process_mic_error(struct wlan_dp_intf *dp_intf)
|
||||
{
|
||||
struct wlan_dp_psoc_callbacks *ops = &dp_intf->dp_ctx->dp_ops;
|
||||
struct wlan_objmgr_vdev *vdev = dp_intf->vdev;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
vdev = dp_objmgr_get_vdev_by_user(dp_intf, WLAN_DP_ID);
|
||||
if (!vdev) {
|
||||
dp_err("vdev is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dp_comp_vdev_get_ref(vdev)) {
|
||||
dp_err("vdev ref get error");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -662,7 +657,7 @@ __dp_process_mic_error(struct wlan_dp_intf *dp_intf)
|
||||
else
|
||||
dp_err("Invalid interface type:%d", dp_intf->device_mode);
|
||||
|
||||
dp_comp_vdev_put_ref(vdev);
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -901,8 +896,10 @@ dp_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
||||
}
|
||||
|
||||
dp_intf->device_mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
qdf_spin_lock_bh(&dp_intf->vdev_lock);
|
||||
dp_intf->intf_id = vdev->vdev_objmgr.vdev_id;
|
||||
dp_intf->vdev = vdev;
|
||||
qdf_spin_unlock_bh(&dp_intf->vdev_lock);
|
||||
qdf_atomic_init(&dp_intf->num_active_task);
|
||||
|
||||
if (dp_intf->device_mode == QDF_SAP_MODE ||
|
||||
@@ -965,7 +962,9 @@ dp_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
|
||||
}
|
||||
qdf_mem_zero(&dp_intf->conn_info, sizeof(struct wlan_dp_conn_info));
|
||||
dp_intf->intf_id = WLAN_UMAC_VDEV_ID_MAX;
|
||||
qdf_spin_lock_bh(&dp_intf->vdev_lock);
|
||||
dp_intf->vdev = NULL;
|
||||
qdf_spin_unlock_bh(&dp_intf->vdev_lock);
|
||||
status = wlan_objmgr_vdev_component_obj_detach(vdev,
|
||||
WLAN_COMP_DP,
|
||||
(void *)dp_intf);
|
||||
@@ -1423,3 +1422,88 @@ QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef WLAN_OBJMGR_REF_ID_TRACE
|
||||
struct wlan_objmgr_vdev *
|
||||
__dp_objmgr_get_vdev_by_user(struct wlan_dp_intf *dp_intf,
|
||||
wlan_objmgr_ref_dbgid id,
|
||||
const char *func, int line)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!dp_intf) {
|
||||
dp_err("dp_intf is NULL (via %s, id %d)", func, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&dp_intf->vdev_lock);
|
||||
vdev = dp_intf->vdev;
|
||||
if (vdev) {
|
||||
status = wlan_objmgr_vdev_try_get_ref_debug(vdev, id, func,
|
||||
line);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
vdev = NULL;
|
||||
}
|
||||
qdf_spin_unlock_bh(&dp_intf->vdev_lock);
|
||||
|
||||
if (!vdev)
|
||||
dp_debug("VDEV is NULL (via %s, id %d)", func, id);
|
||||
|
||||
return vdev;
|
||||
}
|
||||
|
||||
void
|
||||
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
|
||||
wlan_objmgr_ref_dbgid id, const char *func,
|
||||
int line)
|
||||
{
|
||||
if (!vdev) {
|
||||
dp_err("VDEV is NULL (via %s, id %d)", func, id);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_objmgr_vdev_release_ref_debug(vdev, id, func, line);
|
||||
}
|
||||
#else
|
||||
struct wlan_objmgr_vdev *
|
||||
__dp_objmgr_get_vdev_by_user(struct wlan_dp_intf *dp_intf,
|
||||
wlan_objmgr_ref_dbgid id,
|
||||
const char *func)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!dp_intf) {
|
||||
dp_err("dp_intf is NULL (via %s, id %d)", func, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&dp_intf->vdev_lock);
|
||||
vdev = dp_intf->vdev;
|
||||
if (vdev) {
|
||||
status = wlan_objmgr_vdev_try_get_ref(vdev, id);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
vdev = NULL;
|
||||
}
|
||||
qdf_spin_unlock_bh(&dp_intf->vdev_lock);
|
||||
|
||||
if (!vdev)
|
||||
dp_debug("VDEV is NULL (via %s, id %d)", func, id);
|
||||
|
||||
return vdev;
|
||||
}
|
||||
|
||||
void
|
||||
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
|
||||
wlan_objmgr_ref_dbgid id, const char *func)
|
||||
{
|
||||
if (!vdev) {
|
||||
dp_err("VDEV is NULL (via %s, id %d)", func, id);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, id);
|
||||
}
|
||||
#endif /* WLAN_OBJMGR_REF_ID_TRACE */
|
||||
|
||||
|
@@ -136,19 +136,14 @@ void dp_nud_reset_tracking(struct wlan_dp_intf *dp_intf)
|
||||
*/
|
||||
static void dp_nud_stats_info(struct wlan_dp_intf *dp_intf)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev = dp_intf->vdev;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct dp_nud_tx_rx_stats *tx_rx_stats =
|
||||
&dp_intf->nud_tracking.tx_rx_stats;
|
||||
struct wlan_dp_psoc_callbacks *cb = &dp_intf->dp_ctx->dp_ops;
|
||||
uint32_t pause_map;
|
||||
|
||||
vdev = dp_objmgr_get_vdev_by_user(dp_intf, WLAN_DP_ID);
|
||||
if (!vdev) {
|
||||
dp_err("vdev is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dp_comp_vdev_get_ref(vdev)) {
|
||||
dp_err("vdev ref get error");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,12 +157,12 @@ static void dp_nud_stats_info(struct wlan_dp_intf *dp_intf)
|
||||
dp_info("NUD Gateway Rx : %d",
|
||||
qdf_atomic_read(&tx_rx_stats->gw_rx_packets));
|
||||
|
||||
cb->os_if_dp_nud_stats_info(dp_intf->vdev);
|
||||
cb->os_if_dp_nud_stats_info(vdev);
|
||||
|
||||
pause_map = cb->dp_get_pause_map(cb->callback_ctx,
|
||||
dp_intf->intf_id);
|
||||
dp_info("Current pause_map value %x", pause_map);
|
||||
dp_comp_vdev_put_ref(vdev);
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,6 +333,7 @@ static void dp_nud_filter_netevent(struct qdf_mac_addr *netdev_addr,
|
||||
int status;
|
||||
struct wlan_dp_intf *dp_intf;
|
||||
struct wlan_dp_psoc_context *dp_ctx;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
dp_ctx = dp_get_context();
|
||||
if (!dp_ctx)
|
||||
@@ -363,10 +359,16 @@ static void dp_nud_filter_netevent(struct qdf_mac_addr *netdev_addr,
|
||||
if (dp_intf->device_mode != QDF_STA_MODE)
|
||||
return;
|
||||
|
||||
if (!ucfg_cm_is_vdev_active(dp_intf->vdev)) {
|
||||
vdev = dp_objmgr_get_vdev_by_user(dp_intf, WLAN_DP_ID);
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
if (!ucfg_cm_is_vdev_active(vdev)) {
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
dp_info("Not in Connected State");
|
||||
return;
|
||||
}
|
||||
dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
|
||||
|
||||
if (!qdf_is_macaddr_equal(&dp_intf->nud_tracking.gw_mac_addr,
|
||||
gw_mac_addr))
|
||||
|
@@ -80,6 +80,7 @@ ucfg_dp_create_intf(struct wlan_objmgr_psoc *psoc,
|
||||
dp_intf->dev = ndev;
|
||||
dp_intf->intf_id = WLAN_UMAC_VDEV_ID_MAX;
|
||||
qdf_copy_macaddr(&dp_intf->mac_addr, intf_addr);
|
||||
qdf_spinlock_create(&dp_intf->vdev_lock);
|
||||
|
||||
qdf_spin_lock_bh(&dp_ctx->intf_list_lock);
|
||||
qdf_list_insert_front(&dp_ctx->intf_list, &dp_intf->node);
|
||||
@@ -116,6 +117,7 @@ ucfg_dp_destroy_intf(struct wlan_objmgr_psoc *psoc,
|
||||
dp_periodic_sta_stats_mutex_destroy(dp_intf);
|
||||
dp_nud_deinit_tracking(dp_intf);
|
||||
dp_mic_deinit_work(dp_intf);
|
||||
qdf_spinlock_destroy(&dp_intf->vdev_lock);
|
||||
|
||||
qdf_spin_lock_bh(&dp_ctx->intf_list_lock);
|
||||
qdf_list_remove_node(&dp_ctx->intf_list, &dp_intf->node);
|
||||
|
Reference in New Issue
Block a user