qcacmn: Check for tx desc leak or corruption

Tx descriptor is not being freed and put back in tx desc
pool for a long time. As a result, system is not going
into suspended state.
To find this descriptor, during dp_bus_suspend and
dp_runtime_suspend, parse through the descriptor pool to
check for any descriptors not freed for a long and trigger
self recovery when found.

Change-Id: Id97c5c8537c9bec922f4e254b5bf094505ee61ff
CRs-Fixed: 3109868
这个提交包含在:
Ananya Gupta
2022-01-14 08:20:37 +05:30
提交者 Madan Koyyalamudi
父节点 d3e9c9ca97
当前提交 940984c6a6
修改 8 个文件,包含 169 行新增6 行删除

查看文件

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -93,6 +93,19 @@ do { \
#endif /* !QCA_LL_TX_FLOW_CONTROL_V2 */
#define MAX_POOL_BUFF_COUNT 10000
#ifdef DP_TX_TRACKING
static inline void dp_tx_desc_set_magic(struct dp_tx_desc_s *tx_desc,
uint32_t magic_pattern)
{
tx_desc->magic = magic_pattern;
}
#else
static inline void dp_tx_desc_set_magic(struct dp_tx_desc_s *tx_desc,
uint32_t magic_pattern)
{
}
#endif
QDF_STATUS dp_tx_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
uint16_t num_elem);
QDF_STATUS dp_tx_desc_pool_init(struct dp_soc *soc, uint8_t pool_id,
@@ -301,7 +314,8 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id)
tx_desc = dp_tx_get_desc_flow_pool(pool);
tx_desc->pool_id = desc_pool_id;
tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED;
dp_tx_desc_set_magic(tx_desc,
DP_TX_MAGIC_PATTERN_INUSE);
is_pause = dp_tx_is_threshold_reached(pool,
pool->avail_desc);
@@ -391,6 +405,8 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc,
tx_desc->vdev_id = DP_INVALID_VDEV_ID;
tx_desc->nbuf = NULL;
tx_desc->flags = 0;
dp_tx_desc_set_magic(tx_desc, DP_TX_MAGIC_PATTERN_FREE);
tx_desc->timestamp = 0;
dp_tx_put_desc_flow_pool(pool, tx_desc);
switch (pool->status) {
case FLOW_POOL_ACTIVE_PAUSED:
@@ -503,6 +519,8 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id)
tx_desc = dp_tx_get_desc_flow_pool(pool);
tx_desc->pool_id = desc_pool_id;
tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED;
dp_tx_desc_set_magic(tx_desc,
DP_TX_MAGIC_PATTERN_INUSE);
if (qdf_unlikely(pool->avail_desc < pool->stop_th)) {
pool->status = FLOW_POOL_ACTIVE_PAUSED;
qdf_spin_unlock_bh(&pool->flow_pool_lock);
@@ -555,6 +573,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc,
tx_desc->vdev_id = DP_INVALID_VDEV_ID;
tx_desc->nbuf = NULL;
tx_desc->flags = 0;
dp_tx_desc_set_magic(tx_desc, DP_TX_MAGIC_PATTERN_FREE);
dp_tx_put_desc_flow_pool(pool, tx_desc);
switch (pool->status) {
case FLOW_POOL_ACTIVE_PAUSED: