diff options
| -rw-r--r-- | core/dp/txrx/ol_tx_desc.c | 8 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_send.c | 2 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx.c | 52 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx_types.h | 4 |
4 files changed, 64 insertions, 2 deletions
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 1e2b48d5c605..519aaea94c67 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -156,6 +156,8 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, if (!tx_desc) return NULL; + tx_desc->vdev_id = vdev->vdev_id; + ol_tx_desc_vdev_update(tx_desc, vdev); ol_tx_desc_count_inc(vdev); qdf_atomic_inc(&tx_desc->ref_cnt); @@ -222,6 +224,8 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, pdev->pool_stats.pkt_drop_no_pool++; } + tx_desc->vdev_id = vdev->vdev_id; + return tx_desc; } @@ -366,6 +370,7 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) ol_tx_put_desc_global_pool(pdev, tx_desc); ol_tx_desc_vdev_rm(tx_desc); + tx_desc->vdev_id = OL_TXRX_INVALID_VDEV_ID; qdf_spin_unlock_bh(&pdev->tx_mutex); } @@ -416,6 +421,9 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) __func__, __LINE__); break; }; + + tx_desc->vdev_id = OL_TXRX_INVALID_VDEV_ID; + qdf_spin_unlock_bh(&pool->flow_pool_lock); } diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index ded02d24da03..6c0db9503186 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -643,7 +643,7 @@ void ol_tx_desc_update_group_credit(ol_txrx_pdev_handle pdev, OL_TXQ_GROUP_VDEV_ID_MASK_GET( pdev->txq_grps[i].membership); is_member = OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(vdev_id_mask, - tx_desc->vdev->vdev_id); + tx_desc->vdev_id); if (is_member) { ol_txrx_update_group_credit(&pdev->txq_grps[i], credit, absolute); diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 3fa99d33e600..8b7ee0e2cebb 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -2104,6 +2104,34 @@ void ol_txrx_set_drop_unenc(ol_txrx_vdev_handle vdev, uint32_t val) vdev->drop_unenc = val; } +#if defined(CONFIG_HL_SUPPORT) + +static void +ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int i; + struct ol_tx_desc_t *tx_desc; + + qdf_spin_lock_bh(&pdev->tx_mutex); + for (i = 0; i < pdev->tx_desc.pool_size; i++) { + tx_desc = ol_tx_desc_find(pdev, i); + if (tx_desc->vdev == vdev) + tx_desc->vdev = NULL; + } + qdf_spin_unlock_bh(&pdev->tx_mutex); +} + +#else + +static void +ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev) +{ + +} + +#endif + /** * ol_txrx_vdev_detach - Deallocate the specified data virtual * device object. @@ -2196,6 +2224,18 @@ ol_txrx_vdev_detach(ol_txrx_vdev_handle vdev, htt_vdev_detach(pdev->htt_pdev, vdev->vdev_id); /* + * The ol_tx_desc_free might access the invalid content of vdev referred + * by tx desc, since this vdev might be detached in another thread + * asynchronous. + * + * Go through tx desc pool to set corresponding tx desc's vdev to NULL + * when detach this vdev, and add vdev checking in the ol_tx_desc_free + * to avoid crash. + * + */ + ol_txrx_tx_desc_reset_vdev(vdev); + + /* * Doesn't matter if there are outstanding tx frames - * they will be freed once the target sends a tx completion * message for them. @@ -3082,13 +3122,23 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer, vdev->delete.callback; void *vdev_delete_context = vdev->delete.context; - /* * Now that there are no references to the peer, * we can release the peer reference lock. */ qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + /* + * The ol_tx_desc_free might access the invalid content of vdev + * referred by tx desc, since this vdev might be detached in + * another thread asynchronous. + * + * Go through tx desc pool to set corresponding tx desc's vdev + * to NULL when detach this vdev, and add vdev checking in the + * ol_tx_desc_free to avoid crash. + * + */ + ol_txrx_tx_desc_reset_vdev(vdev); TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "%s: deleting vdev object %p " "(%02x:%02x:%02x:%02x:%02x:%02x)" diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index ffafadc67562..5fb4784afeb1 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -89,6 +89,8 @@ #define TXRX_DATA_HISTROGRAM_GRANULARITY 1000 #define TXRX_DATA_HISTROGRAM_NUM_INTERVALS 100 +#define OL_TXRX_INVALID_VDEV_ID (-1) + struct ol_txrx_pdev_t; struct ol_txrx_vdev_t; struct ol_txrx_peer_t; @@ -189,6 +191,8 @@ struct ol_tx_desc_t { */ uint8_t pkt_type; + u_int8_t vdev_id; + struct ol_txrx_vdev_t *vdev; void *txq; |
