diff options
| author | gbian <gbian@codeaurora.org> | 2016-12-07 11:12:29 +0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2017-03-04 09:45:46 -0800 |
| commit | 1b4f37d043d556e2af731da3c28078bcd15bff6d (patch) | |
| tree | 98c6aea2b04de784c8d265ba4d4443e5958f91a8 | |
| parent | 99acdd8bb381370ead548a5fec89755b5b9b1f99 (diff) | |
qcacld-3.0: Reset tx desc type after calling msdu complete conditionally
qcacld-2.0 to qcacld-3.0 propagation
After calling ol_tx_msdu_complete, it will reset the tx desc's pakcet
type to ol_tx_frm_freed state. So there might be a race condition
if there is another thread try to allocate this tx description between
these two operations.
The ol_tx_msdu_complete doesn't always free the tx_desc according to the
tx desc type. So need to reset the tx desc's packet type only when the
ol_tx_msdu_complete hasn't freed it.
Change-Id: I0d96ef60d10048c524e93209469e8cdf20ce22c6
CRs-Fixed: 1087688
| -rw-r--r-- | core/dp/txrx/ol_tx_send.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index 6c0db9503186..447211ebf094 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -445,20 +445,25 @@ ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev, #ifdef QCA_TX_STD_PATH_ONLY #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, \ _netbuf, _lcl_freelist, \ - _tx_desc_last, _status) \ - ol_tx_msdu_complete_single((_pdev), (_tx_desc), \ - (_netbuf), (_lcl_freelist), \ - _tx_desc_last) + _tx_desc_last, _status, is_tx_desc_freed) \ + do { \ + is_tx_desc_freed = 0; \ + ol_tx_msdu_complete_single((_pdev), (_tx_desc), \ + (_netbuf), (_lcl_freelist), \ + _tx_desc_last) \ + } while (0) #else /* !QCA_TX_STD_PATH_ONLY */ #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, \ _netbuf, _lcl_freelist, \ - _tx_desc_last, _status) \ + _tx_desc_last, _status, is_tx_desc_freed) \ do { \ if (qdf_likely((_tx_desc)->pkt_type == OL_TX_FRM_STD)) { \ + is_tx_desc_freed = 0; \ ol_tx_msdu_complete_single((_pdev), (_tx_desc),\ (_netbuf), (_lcl_freelist), \ (_tx_desc_last)); \ } else { \ + is_tx_desc_freed = 1; \ ol_tx_desc_frame_free_nonstd( \ (_pdev), (_tx_desc), \ (_status) != htt_tx_status_ok); \ @@ -469,17 +474,23 @@ ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev, #ifdef QCA_TX_STD_PATH_ONLY #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, \ _netbuf, _lcl_freelist, \ - _tx_desc_last, _status) \ - ol_tx_msdus_complete_batch((_pdev), (_tx_desc), (_tx_descs), (_status)) + _tx_desc_last, _status, is_tx_desc_freed) \ + do { \ + is_tx_desc_freed = 0; \ + ol_tx_msdu_complete_batch((_pdev), (_tx_desc), \ + (_tx_descs), (_status)) \ + } while (0) #else /* !QCA_TX_STD_PATH_ONLY */ #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, \ _netbuf, _lcl_freelist, \ - _tx_desc_last, _status) \ + _tx_desc_last, _status, is_tx_desc_freed) \ do { \ if (qdf_likely((_tx_desc)->pkt_type == OL_TX_FRM_STD)) { \ + is_tx_desc_freed = 0; \ ol_tx_msdu_complete_batch((_pdev), (_tx_desc), \ (_tx_descs), (_status)); \ } else { \ + is_tx_desc_freed = 1; \ ol_tx_desc_frame_free_nonstd((_pdev), (_tx_desc), \ (_status) != \ htt_tx_status_ok); \ @@ -548,6 +559,7 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, uint32_t byte_cnt = 0; qdf_nbuf_t netbuf; tp_ol_packetdump_cb packetdump_cb; + uint32_t is_tx_desc_freed = 0; union ol_tx_desc_list_elem_t *lcl_freelist = NULL; union ol_tx_desc_list_elem_t *tx_desc_last = NULL; @@ -586,14 +598,18 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, htt_tx_desc))), status != htt_tx_status_ok); ol_tx_msdu_complete(pdev, tx_desc, tx_descs, netbuf, - lcl_freelist, tx_desc_last, status); - } + lcl_freelist, tx_desc_last, status, + is_tx_desc_freed); + #ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS - tx_desc->pkt_type = ol_tx_frm_freed; + if (!is_tx_desc_freed) { + tx_desc->pkt_type = ol_tx_frm_freed; #ifdef QCA_COMPUTE_TX_DELAY - tx_desc->entry_timestamp_ticks = 0xffffffff; + tx_desc->entry_timestamp_ticks = 0xffffffff; #endif + } #endif + } } /* One shot protected access to pdev freelist, when setup */ @@ -838,6 +854,8 @@ ol_tx_inspect_handler(ol_txrx_pdev_handle pdev, union ol_tx_desc_list_elem_t *tx_desc_last = NULL; qdf_nbuf_t netbuf; ol_tx_desc_list tx_descs; + uint32_t is_tx_desc_freed = 0; + TAILQ_INIT(&tx_descs); for (i = 0; i < num_msdus; i++) { @@ -866,13 +884,16 @@ ol_tx_inspect_handler(ol_txrx_pdev_handle pdev, */ ol_tx_msdu_complete(pdev, tx_desc, tx_descs, netbuf, lcl_freelist, tx_desc_last, - htt_tx_status_ok); + htt_tx_status_ok, + is_tx_desc_freed); #ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS - tx_desc->pkt_type = ol_tx_frm_freed; + if (!is_tx_desc_freed) { + tx_desc->pkt_type = ol_tx_frm_freed; #ifdef QCA_COMPUTE_TX_DELAY - tx_desc->entry_timestamp_ticks = 0xffffffff; + tx_desc->entry_timestamp_ticks = 0xffffffff; #endif + } #endif } } |
