qcacmn: fix tx desc allocate from freed pool issue
The avail_desc is not set to 0 when the tx desc pool is freed, later if still try to allocate tx desc by judgement of avail_desc, panic happens. Change-Id: Ia4565da1caa6898c6d4293e2658cf4ccf89563fa CRs-Fixed: 2246328
This commit is contained in:
@@ -166,6 +166,7 @@ QDF_STATUS dp_tx_desc_pool_free(struct dp_soc *soc, uint8_t pool_id)
|
|||||||
qdf_mem_multi_pages_free(soc->osdev,
|
qdf_mem_multi_pages_free(soc->osdev,
|
||||||
&tx_desc_pool->desc_pages, 0, true);
|
&tx_desc_pool->desc_pages, 0, true);
|
||||||
TX_DESC_LOCK_DESTROY(&tx_desc_pool->lock);
|
TX_DESC_LOCK_DESTROY(&tx_desc_pool->lock);
|
||||||
|
TX_DESC_POOL_MEMBER_CLEAN(tx_desc_pool);
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,11 +56,29 @@
|
|||||||
#define TX_DESC_LOCK_DESTROY(lock)
|
#define TX_DESC_LOCK_DESTROY(lock)
|
||||||
#define TX_DESC_LOCK_LOCK(lock)
|
#define TX_DESC_LOCK_LOCK(lock)
|
||||||
#define TX_DESC_LOCK_UNLOCK(lock)
|
#define TX_DESC_LOCK_UNLOCK(lock)
|
||||||
|
#define TX_DESC_POOL_MEMBER_CLEAN(_tx_desc_pool) \
|
||||||
|
do { \
|
||||||
|
(_tx_desc_pool)->elem_size = 0; \
|
||||||
|
(_tx_desc_pool)->freelist = NULL; \
|
||||||
|
(_tx_desc_pool)->pool_size = 0; \
|
||||||
|
(_tx_desc_pool)->avail_desc = 0; \
|
||||||
|
(_tx_desc_pool)->start_th = 0; \
|
||||||
|
(_tx_desc_pool)->stop_th = 0; \
|
||||||
|
(_tx_desc_pool)->status = FLOW_POOL_INACTIVE; \
|
||||||
|
} while (0)
|
||||||
#else /* !QCA_LL_TX_FLOW_CONTROL_V2 */
|
#else /* !QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||||
#define TX_DESC_LOCK_CREATE(lock) qdf_spinlock_create(lock)
|
#define TX_DESC_LOCK_CREATE(lock) qdf_spinlock_create(lock)
|
||||||
#define TX_DESC_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
|
#define TX_DESC_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
|
||||||
#define TX_DESC_LOCK_LOCK(lock) qdf_spin_lock_bh(lock)
|
#define TX_DESC_LOCK_LOCK(lock) qdf_spin_lock_bh(lock)
|
||||||
#define TX_DESC_LOCK_UNLOCK(lock) qdf_spin_unlock_bh(lock)
|
#define TX_DESC_LOCK_UNLOCK(lock) qdf_spin_unlock_bh(lock)
|
||||||
|
#define TX_DESC_POOL_MEMBER_CLEAN(_tx_desc_pool) \
|
||||||
|
do { \
|
||||||
|
(_tx_desc_pool)->elem_size = 0; \
|
||||||
|
(_tx_desc_pool)->num_allocated = 0; \
|
||||||
|
(_tx_desc_pool)->freelist = NULL; \
|
||||||
|
(_tx_desc_pool)->elem_count = 0; \
|
||||||
|
(_tx_desc_pool)->num_free = 0; \
|
||||||
|
} while (0)
|
||||||
#endif /* !QCA_LL_TX_FLOW_CONTROL_V2 */
|
#endif /* !QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||||
#define MAX_POOL_BUFF_COUNT 10000
|
#define MAX_POOL_BUFF_COUNT 10000
|
||||||
|
|
||||||
@@ -149,7 +167,8 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id)
|
|||||||
|
|
||||||
if (pool) {
|
if (pool) {
|
||||||
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
||||||
if (pool->avail_desc) {
|
if (pool->status <= FLOW_POOL_ACTIVE_PAUSED &&
|
||||||
|
pool->avail_desc) {
|
||||||
tx_desc = dp_tx_get_desc_flow_pool(pool);
|
tx_desc = dp_tx_get_desc_flow_pool(pool);
|
||||||
tx_desc->pool_id = desc_pool_id;
|
tx_desc->pool_id = desc_pool_id;
|
||||||
tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED;
|
tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED;
|
||||||
@@ -205,7 +224,6 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc,
|
|||||||
case FLOW_POOL_INVALID:
|
case FLOW_POOL_INVALID:
|
||||||
if (pool->avail_desc == pool->pool_size) {
|
if (pool->avail_desc == pool->pool_size) {
|
||||||
dp_tx_desc_pool_free(soc, desc_pool_id);
|
dp_tx_desc_pool_free(soc, desc_pool_id);
|
||||||
pool->status = FLOW_POOL_INACTIVE;
|
|
||||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||||
qdf_print("%s %d pool is freed!!\n",
|
qdf_print("%s %d pool is freed!!\n",
|
||||||
__func__, __LINE__);
|
__func__, __LINE__);
|
||||||
|
Reference in New Issue
Block a user