mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacmn: Fix peer ref counting leak while finding and deleting peer
There are two instances where peer ref counting leak has been observed 1) When DUT-STA is connected to AP1 and if it tries to roam to AP2 or to same AP1 then as part of roam sync indication, it needs to delete the old peer and create the new peer. Deletion of old peer is happening through force delete operation which is No-OP for some of the platforms. In such cases, do normal peer delete operation, so that peer ref count can be deleted properly. 2) When looking up peer by its associated vdev, driver goes one by one all peers and check their associated vdev and compare with given vdev. If it doesn't find the match then it returns without releasing the reference count. CRs-Fixed: 2263607 Change-Id: Ibcad72943258e531e29498961d3d7e692fd05b36
This commit is contained in:
parent
6b6b91db11
commit
304792abd8
3 changed files with 40 additions and 1 deletions
|
|
@ -721,4 +721,31 @@ static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_cdp_peer_detach_force_delete_supported() - To check if force delete
|
||||
* operation is supported
|
||||
* @soc: pointer to SOC handle
|
||||
*
|
||||
* Some of the platforms support force delete operation and some of them
|
||||
* don't. This API returns true if API which handles force delete operation
|
||||
* is registered and false otherwise.
|
||||
*
|
||||
* Return: true if API which handles force delete operation is registered
|
||||
* false in all other cases
|
||||
*/
|
||||
static inline bool
|
||||
is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_detach_force_delete)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* _CDP_TXRX_PEER_H_ */
|
||||
|
|
|
|||
|
|
@ -1984,8 +1984,10 @@ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle,
|
|||
if (!peer)
|
||||
return NULL;
|
||||
|
||||
if (peer->vdev != vdev)
|
||||
if (peer->vdev != vdev) {
|
||||
qdf_atomic_dec(&peer->ref_cnt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*local_id = peer->local_id;
|
||||
DP_TRACE(INFO, "peer %pK vdev %pK local id %d", peer, vdev, *local_id);
|
||||
|
|
|
|||
|
|
@ -1270,6 +1270,16 @@ void dp_rx_defrag_cleanup(struct dp_peer *peer, unsigned tid)
|
|||
struct dp_rx_reorder_array_elem *rx_reorder_array_elem =
|
||||
peer->rx_tid[tid].array;
|
||||
|
||||
if (!rx_reorder_array_elem) {
|
||||
/*
|
||||
* if this condition is hit then somebody
|
||||
* must have reset this pointer to NULL.
|
||||
* array pointer usually points to base variable
|
||||
* of TID queue structure: "struct dp_rx_tid"
|
||||
*/
|
||||
QDF_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
/* Free up nbufs */
|
||||
dp_rx_defrag_frames_free(rx_reorder_array_elem->head);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue