summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgbian <gbian@codeaurora.org>2016-12-07 11:12:29 +0800
committerqcabuildsw <qcabuildsw@localhost>2017-03-04 09:45:46 -0800
commit1b4f37d043d556e2af731da3c28078bcd15bff6d (patch)
tree98c6aea2b04de784c8d265ba4d4443e5958f91a8
parent99acdd8bb381370ead548a5fec89755b5b9b1f99 (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.c51
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
}
}