summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/dp/txrx/ol_tx_desc.c8
-rw-r--r--core/dp/txrx/ol_tx_send.c2
-rw-r--r--core/dp/txrx/ol_txrx.c52
-rw-r--r--core/dp/txrx/ol_txrx_types.h4
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;