mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacld-3.0: Fix double free of SKB for TSO
In case of TSO, same skb results in multiple tx_desc after segmentation. To avoid multiple free of skb "skb->users" count is used. Currently, race condition is observed while incrementing "skb->users" count in ol_tx_ll_fast and before that, tx_completion is received for all the segments which are sent before. In this case, "skb->users" count will be 1 so, skb is removed from the skb debug node which leads double free of skb when tx completion is received for the last segment. To fix this, increment the "skb->users" count before sending first segment and decrement only iwhen the last segment. Change-Id: I26000fcda8715b737cac803ec8e64c0fb640dfe4 CRs-Fixed: 2582617
This commit is contained in:
parent
b5a79dfc0d
commit
69a11f24b1
1 changed files with 24 additions and 2 deletions
|
|
@ -382,6 +382,15 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
|
|||
* pointer before the ce_send call.
|
||||
*/
|
||||
next = qdf_nbuf_next(msdu);
|
||||
/*
|
||||
* Increment the skb->users count here, for this SKB, to make
|
||||
* sure it will be freed only after receiving Tx completion
|
||||
* of the last segment.
|
||||
* Decrement skb->users count before sending last segment
|
||||
*/
|
||||
if (qdf_nbuf_is_tso(msdu) && segments)
|
||||
qdf_nbuf_inc_users(msdu);
|
||||
|
||||
/* init the current segment to the 1st segment in the list */
|
||||
while (segments) {
|
||||
if (msdu_info.tso_info.curr_seg)
|
||||
|
|
@ -451,6 +460,13 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
|
|||
next_seg = NULL;
|
||||
}
|
||||
|
||||
/* Decrement the skb-users count if segment
|
||||
* is the last segment or the only segment
|
||||
*/
|
||||
if (tx_desc->pkt_type == OL_TX_FRM_TSO &&
|
||||
segments == 0)
|
||||
qdf_nbuf_tx_free(msdu, 0);
|
||||
|
||||
if ((ce_send_fast(pdev->ce_tx_hdl, msdu,
|
||||
ep_id,
|
||||
pkt_download_len) == 0)) {
|
||||
|
|
@ -465,6 +481,10 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
|
|||
tso_info->curr_seg = next_seg;
|
||||
ol_free_remaining_tso_segs(vdev,
|
||||
&msdu_info, true);
|
||||
if (segments)
|
||||
qdf_nbuf_tx_free(
|
||||
msdu,
|
||||
QDF_NBUF_PKT_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -491,10 +511,12 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
|
|||
* If TSO packet, free associated
|
||||
* remaining TSO segment descriptors
|
||||
*/
|
||||
if (qdf_nbuf_is_tso(msdu))
|
||||
if (qdf_nbuf_is_tso(msdu)) {
|
||||
ol_free_remaining_tso_segs(vdev,
|
||||
&msdu_info, true);
|
||||
|
||||
qdf_nbuf_tx_free(msdu,
|
||||
QDF_NBUF_PKT_ERROR);
|
||||
}
|
||||
TXRX_STATS_MSDU_LIST_INCR(
|
||||
pdev, tx.dropped.host_reject, msdu);
|
||||
/* the list of unaccepted MSDUs */
|
||||
|
|
|
|||
Loading…
Reference in a new issue