diff --git a/components/dp/core/inc/wlan_dp_objmgr.h b/components/dp/core/inc/wlan_dp_objmgr.h index c95d47d5b5..713ed5f706 100644 --- a/components/dp/core/inc/wlan_dp_objmgr.h +++ b/components/dp/core/inc/wlan_dp_objmgr.h @@ -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 */ diff --git a/components/dp/core/inc/wlan_dp_priv.h b/components/dp/core/inc/wlan_dp_priv.h index 423660c753..fdf52ae3d5 100644 --- a/components/dp/core/inc/wlan_dp_priv.h +++ b/components/dp/core/inc/wlan_dp_priv.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; diff --git a/components/dp/core/src/wlan_dp_bus_bandwidth.c b/components/dp/core/src/wlan_dp_bus_bandwidth.c index 585a64134f..62eeed40d5 100644 --- a/components/dp/core/src/wlan_dp_bus_bandwidth.c +++ b/components/dp/core/src/wlan_dp_bus_bandwidth.c @@ -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) { diff --git a/components/dp/core/src/wlan_dp_main.c b/components/dp/core/src/wlan_dp_main.c index 0a650bb7b4..e32ed9e7c9 100644 --- a/components/dp/core/src/wlan_dp_main.c +++ b/components/dp/core/src/wlan_dp_main.c @@ -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 */ + diff --git a/components/dp/core/src/wlan_dp_nud_tracking.c b/components/dp/core/src/wlan_dp_nud_tracking.c index fdaf668c7a..95eb317f6b 100644 --- a/components/dp/core/src/wlan_dp_nud_tracking.c +++ b/components/dp/core/src/wlan_dp_nud_tracking.c @@ -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)) diff --git a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c index 3f5415dd8d..e4db9eb9fe 100644 --- a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c +++ b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c @@ -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);