diff options
| author | Rajeev Kumar <rajekuma@qca.qualcomm.com> | 2015-08-28 13:07:21 -0700 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2015-08-31 14:14:11 +0530 |
| commit | fc0d5d08359b9849df2a9adb29c605c20b9bf10c (patch) | |
| tree | c32c702943774ae00f7e71330cdce0884212b881 | |
| parent | ff56c623774415815feb0ba3c45d94d318912838 (diff) | |
qcacld-2.0: Fix race condition in tx desc free count manipulation
- Protect TX descriptor free credits count under tx mutex
- Add debug log to dump total credit and free credit count if bus
suspend fails because of pending tx
Change-Id: I383e19b8c56edac487e3e0d8763e1212f03b7934
CRs-Fixed: 898742
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_send.c | 2 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx.c | 23 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 1 |
4 files changed, 28 insertions, 2 deletions
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c index 28b3b8a458de..320252a852e3 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -577,8 +577,8 @@ ol_tx_completion_handler( adf_os_spin_lock(&pdev->tx_mutex); tx_desc_last->next = pdev->tx_desc.freelist; pdev->tx_desc.freelist = lcl_freelist; - adf_os_spin_unlock(&pdev->tx_mutex); pdev->tx_desc.num_free += (u_int16_t) num_msdus; + adf_os_spin_unlock(&pdev->tx_mutex); } else { ol_tx_desc_frame_list_free(pdev, &tx_descs, status != htt_tx_status_ok); } diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index edbe624a2839..88f43de627cf 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -1756,6 +1756,29 @@ ol_txrx_peer_find_by_addr(struct ol_txrx_pdev_t *pdev, u_int8_t *peer_mac_addr) return peer; } +/** + * ol_txrx_dump_tx_desc() - dump tx desc info + * @pdev_handle: Pointer to pdev handle + * + * Return: none + */ +void ol_txrx_dump_tx_desc(ol_txrx_pdev_handle pdev_handle) +{ + struct ol_txrx_pdev_t *pdev = pdev_handle; + int total; + + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) + total = adf_os_atomic_read(&pdev->orig_target_tx_credit); + else + total = ol_cfg_target_tx_credit(pdev->ctrl_pdev); + + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "Total tx credits %d free_credits %d", + total, pdev->tx_desc.num_free); + + return; +} + int ol_txrx_get_tx_pending(ol_txrx_pdev_handle pdev_handle) { diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h index f1ac87dfb17f..ce59ca18ff6f 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -678,6 +678,8 @@ int ol_txrx_get_tx_pending( ol_txrx_pdev_handle pdev); +void ol_txrx_dump_tx_desc(ol_txrx_pdev_handle pdev); + /** * @brief Discard all tx frames that are pending in txrx. * @details diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 71cfd543e46e..f9ad96dff4ef 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -2220,6 +2220,7 @@ __hif_pci_suspend(struct pci_dev *pdev, pm_message_t state, bool runtime_pm) msleep(OL_ATH_TX_DRAIN_WAIT_DELAY); if (++tx_drain_wait_cnt > OL_ATH_TX_DRAIN_WAIT_CNT) { printk("%s: tx frames are pending\n", __func__); + ol_txrx_dump_tx_desc(txrx_pdev); goto out; } } |
