From e7d41574f3ef87463cbdc192a6a2dcd795c2e911 Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Fri, 27 Mar 2020 10:17:43 +0800 Subject: [PATCH] qcacmn: Add dbgid for each runtime put/get This is to enhance statics for runtime put/get, which is to detect if there is mismatch for usage_count. Change-Id: I24cddb9d10e4cb675c8375cbd0f589c7718bd680 CRs-Fixed: 2647972 --- dp/wifi3.0/dp_stats.c | 6 +- dp/wifi3.0/dp_tx.c | 6 +- dp/wifi3.0/dp_tx_desc.h | 7 +- hal/wifi3.0/hal_reo.c | 20 ++-- hif/inc/hif.h | 100 +++++++++++++++-- hif/src/ce/ce_service_legacy.c | 7 +- hif/src/pcie/if_pci.c | 194 +++++++++++++++++++++++---------- hif/src/pcie/if_pci.h | 32 +----- htc/htc.c | 6 +- htc/htc_send.c | 114 ++++++++++++------- qdf/linux/src/qdf_lock.c | 4 +- 11 files changed, 340 insertions(+), 156 deletions(-) diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index f70c0d899713..83f21ef7034a 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -4884,7 +4884,8 @@ dp_print_ring_stats(struct dp_pdev *pdev) int mac_id; int lmac_id; - if (hif_pm_runtime_get_sync(pdev->soc->hif_handle)) + if (hif_pm_runtime_get_sync(pdev->soc->hif_handle, + RTPM_ID_DP_PRINT_RING_STATS)) return; dp_print_ring_stat_from_hal(pdev->soc, @@ -4955,7 +4956,8 @@ dp_print_ring_stats(struct dp_pdev *pdev) [lmac_id], RXDMA_DST); } - hif_pm_runtime_put(pdev->soc->hif_handle); + hif_pm_runtime_put(pdev->soc->hif_handle, + RTPM_ID_DP_PRINT_RING_STATS); } /** diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 60081c95f25f..2dd0ea8e4c8b 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1237,9 +1237,11 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, status = QDF_STATUS_SUCCESS; ring_access_fail: - if (hif_pm_runtime_get(soc->hif_handle) == 0) { + if (hif_pm_runtime_get(soc->hif_handle, + RTPM_ID_DW_TX_HW_ENQUEUE) == 0) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); - hif_pm_runtime_put(soc->hif_handle); + hif_pm_runtime_put(soc->hif_handle, + RTPM_ID_DW_TX_HW_ENQUEUE); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); } diff --git a/dp/wifi3.0/dp_tx_desc.h b/dp/wifi3.0/dp_tx_desc.h index 720ec6ad15be..c281f8c96986 100644 --- a/dp/wifi3.0/dp_tx_desc.h +++ b/dp/wifi3.0/dp_tx_desc.h @@ -415,7 +415,9 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id) * success of allocating one descriptor. It will be * decremented after the packet has been sent. */ - hif_pm_runtime_get_noresume(soc->hif_handle); + hif_pm_runtime_get_noresume( + soc->hif_handle, + RTPM_ID_DP_TX_DESC_ALLOC_FREE); } else { pool->pkt_drop_no_desc++; qdf_spin_unlock_bh(&pool->flow_pool_lock); @@ -482,7 +484,8 @@ out: * Decrement PM usage count if the packet has been sent. This * should be tied with the success of freeing one descriptor. */ - hif_pm_runtime_put(soc->hif_handle); + hif_pm_runtime_put(soc->hif_handle, + RTPM_ID_DP_TX_DESC_ALLOC_FREE); } #endif /* QCA_AC_BASED_FLOW_CONTROL */ diff --git a/hal/wifi3.0/hal_reo.c b/hal/wifi3.0/hal_reo.c index 1a89f9d20c38..6f4f8c905fad 100644 --- a/hal/wifi3.0/hal_reo.c +++ b/hal/wifi3.0/hal_reo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. 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 @@ -454,9 +454,11 @@ inline int hal_reo_cmd_queue_stats(hal_ring_handle_t hal_ring_hdl, HAL_DESC_SET_FIELD(reo_desc, REO_GET_QUEUE_STATS_2, CLEAR_STATS, cmd->u.stats_params.clear); - if (hif_pm_runtime_get(hal_soc->hif_handle) == 0) { + if (hif_pm_runtime_get(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD) == 0) { hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); - hif_pm_runtime_put(hal_soc->hif_handle); + hif_pm_runtime_put(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD); } else { hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); @@ -590,9 +592,11 @@ inline int hal_reo_cmd_flush_cache(hal_ring_handle_t hal_ring_hdl, HAL_DESC_SET_FIELD(reo_desc, REO_FLUSH_CACHE_2, FLUSH_ENTIRE_CACHE, cp->flush_all); - if (hif_pm_runtime_get(hal_soc->hif_handle) == 0) { + if (hif_pm_runtime_get(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD) == 0) { hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); - hif_pm_runtime_put(hal_soc->hif_handle); + hif_pm_runtime_put(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD); } else { hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); @@ -913,9 +917,11 @@ inline int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl, HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_8, PN_127_96, p->pn_127_96); - if (hif_pm_runtime_get(hal_soc->hif_handle) == 0) { + if (hif_pm_runtime_get(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD) == 0) { hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); - hif_pm_runtime_put(hal_soc->hif_handle); + hif_pm_runtime_put(hal_soc->hif_handle, + RTPM_ID_HAL_REO_CMD); } else { hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); diff --git a/hif/inc/hif.h b/hif/inc/hif.h index d9fd995ac6b9..9dc11da52fa5 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -869,16 +869,83 @@ void hif_enable_ce_latency_stats(struct hif_opaque_softc *hif_ctx, #endif void hif_display_stats(struct hif_opaque_softc *hif_ctx); void hif_clear_stats(struct hif_opaque_softc *hif_ctx); + +/** + * enum wlan_rtpm_dbgid - runtime pm put/get debug id + * @RTPM_ID_RESVERD: Reserved + * @RTPM_ID_WMI: WMI sending msg, expect put happen at + * tx completion from CE level directly. + * @RTPM_ID_HTC: pkt sending by HTT_DATA_MSG_SVC, expect + * put from fw response or just in + * htc_issue_packets + * @RTPM_ID_QOS_NOTIFY: pm qos notifer + * @RTPM_ID_DP_TX_DESC_ALLOC_FREE: tx desc alloc/free + * @RTPM_ID_CE_SEND_FAST: operation in ce_send_fast, not include + * the pkt put happens outside this function + * @RTPM_ID_SUSPEND_RESUME: suspend/resume in hdd + * @RTPM_ID_DW_TX_HW_ENQUEUE: operation in functin dp_tx_hw_enqueue + * @RTPM_ID_HAL_REO_CMD: HAL_REO_CMD operation + * @RTPM_ID_DP_PRINT_RING_STATS: operation in dp_print_ring_stats + */ +/* New value added to the enum must also be reflected in function + * rtpm_string_from_dbgid() + */ +typedef enum { + RTPM_ID_RESVERD = 0, + RTPM_ID_WMI = 1, + RTPM_ID_HTC = 2, + RTPM_ID_QOS_NOTIFY = 3, + RTPM_ID_DP_TX_DESC_ALLOC_FREE = 4, + RTPM_ID_CE_SEND_FAST = 5, + RTPM_ID_SUSPEND_RESUME = 6, + RTPM_ID_DW_TX_HW_ENQUEUE = 7, + RTPM_ID_HAL_REO_CMD = 8, + RTPM_ID_DP_PRINT_RING_STATS = 9, + + RTPM_ID_MAX, +} wlan_rtpm_dbgid; + +/** + * rtpm_string_from_dbgid() - Convert dbgid to respective string + * @id - debug id + * + * Debug support function to convert dbgid to string. + * Please note to add new string in the array at index equal to + * its enum value in wlan_rtpm_dbgid. + */ +static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id) +{ + static const char *strings[] = { "RTPM_ID_RESVERD", + "RTPM_ID_WMI", + "RTPM_ID_HTC", + "RTPM_ID_QOS_NOTIFY", + "RTPM_ID_DP_TX_DESC_ALLOC_FREE", + "RTPM_ID_CE_SEND_FAST", + "RTPM_ID_SUSPEND_RESUME", + "RTPM_ID_DW_TX_HW_ENQUEUE", + "RTPM_ID_HAL_REO_CMD", + "RTPM_ID_DP_PRINT_RING_STATS", + "RTPM_ID_MAX"}; + + return (char *)strings[id]; +} + #ifdef FEATURE_RUNTIME_PM struct hif_pm_runtime_lock; void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx); -int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx); -int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx); +int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); +int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); int hif_pm_runtime_request_resume(struct hif_opaque_softc *hif_ctx); -int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx); -void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx); -int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx); -int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx); +int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); +void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); +int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); +int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid); void hif_pm_runtime_mark_last_busy(struct hif_opaque_softc *hif_ctx); int hif_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name); void hif_runtime_lock_deinit(struct hif_opaque_softc *hif_ctx, @@ -902,22 +969,31 @@ struct hif_pm_runtime_lock { const char *name; }; static inline void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx) {} -static inline int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) +static inline int +hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { return 0; } static inline int -hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx) +hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { return 0; } static inline int hif_pm_runtime_request_resume(struct hif_opaque_softc *hif_ctx) { return 0; } -static inline void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx) +static inline void +hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) {} -static inline int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx) +static inline int +hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx, wlan_rtpm_dbgid rtpm_dbgid) { return 0; } -static inline int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx) +static inline int +hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx, wlan_rtpm_dbgid rtpm_dbgid) { return 0; } -static inline int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx) +static inline int +hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { return 0; } static inline void hif_pm_runtime_mark_last_busy(struct hif_opaque_softc *hif_ctx) {}; diff --git a/hif/src/ce/ce_service_legacy.c b/hif/src/ce/ce_service_legacy.c index 5596d0d75ce9..0997fccce51a 100644 --- a/hif/src/ce/ce_service_legacy.c +++ b/hif/src/ce/ce_service_legacy.c @@ -147,7 +147,8 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, * Request runtime PM resume if it has already suspended and make * sure there is no PCIe link access. */ - if (hif_pm_runtime_get(hif_hdl) != 0) + if (hif_pm_runtime_get(hif_hdl, + RTPM_ID_CE_SEND_FAST) != 0) ok_to_send = false; if (ok_to_send) { @@ -190,7 +191,7 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, struct CE_src_desc *shadow_src_desc = CE_SRC_RING_TO_DESC(shadow_base, write_index); - hif_pm_runtime_get_noresume(hif_hdl); + hif_pm_runtime_get_noresume(hif_hdl, RTPM_ID_HTC); /* * First fill out the ring descriptor for the HTC HTT frame @@ -280,7 +281,7 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, } else { ce_state->state = CE_PENDING; } - hif_pm_runtime_put(hif_hdl); + hif_pm_runtime_put(hif_hdl, RTPM_ID_CE_SEND_FAST); } qdf_spin_unlock_bh(&ce_state->ce_index_lock); diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index ab8b5ada6906..bef104974c3f 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -933,48 +933,55 @@ static const char *hif_pm_runtime_state_to_string(uint32_t state) static void hif_pci_runtime_pm_warn(struct hif_pci_softc *sc, const char *msg) { struct hif_pm_runtime_lock *ctx; + int i; - HIF_DBG("%s: usage_count: %d, pm_state: %s, prevent_suspend_cnt: %d", - msg, atomic_read(&sc->dev->power.usage_count), - hif_pm_runtime_state_to_string( - atomic_read(&sc->pm_state)), - sc->prevent_suspend_cnt); + hif_debug("%s: usage_count: %d, pm_state: %s, prevent_suspend_cnt: %d", + msg, atomic_read(&sc->dev->power.usage_count), + hif_pm_runtime_state_to_string( + atomic_read(&sc->pm_state)), + sc->prevent_suspend_cnt); - HIF_DBG("runtime_status: %d, runtime_error: %d, disable_depth: %d autosuspend_delay: %d", - sc->dev->power.runtime_status, - sc->dev->power.runtime_error, - sc->dev->power.disable_depth, - sc->dev->power.autosuspend_delay); + hif_debug("runtime_status: %d, runtime_error: %d, disable_depth: %d autosuspend_delay: %d", + sc->dev->power.runtime_status, + sc->dev->power.runtime_error, + sc->dev->power.disable_depth, + sc->dev->power.autosuspend_delay); - HIF_DBG("runtime_get: %u, runtime_put: %u, request_resume: %u", - qdf_atomic_read(&sc->pm_stats.runtime_get), - qdf_atomic_read(&sc->pm_stats.runtime_put), - sc->pm_stats.request_resume); + hif_debug("runtime_get: %u, runtime_put: %u, request_resume: %u", + qdf_atomic_read(&sc->pm_stats.runtime_get), + qdf_atomic_read(&sc->pm_stats.runtime_put), + sc->pm_stats.request_resume); - HIF_DBG("runtime_get_caller_index: %u, runtime_put_caller_index: %u", - qdf_atomic_read(&sc->pm_stats.runtime_get_caller_index), - qdf_atomic_read(&sc->pm_stats.runtime_put_caller_index)); + hif_debug("get put get-timestamp put-timestamp :DBGID_NAME"); + for (i = 0; i < RTPM_ID_MAX; i++) { + hif_debug("%-10d %-10d 0x%-10llx 0x%-10llx :%-30s", + qdf_atomic_read(&sc->pm_stats.runtime_get_dbgid[i]), + qdf_atomic_read(&sc->pm_stats.runtime_put_dbgid[i]), + sc->pm_stats.runtime_get_timestamp_dbgid[i], + sc->pm_stats.runtime_put_timestamp_dbgid[i], + rtpm_string_from_dbgid(i)); + } - HIF_DBG("allow_suspend: %u, prevent_suspend: %u", - qdf_atomic_read(&sc->pm_stats.allow_suspend), - qdf_atomic_read(&sc->pm_stats.prevent_suspend)); + hif_debug("allow_suspend: %u, prevent_suspend: %u", + qdf_atomic_read(&sc->pm_stats.allow_suspend), + qdf_atomic_read(&sc->pm_stats.prevent_suspend)); - HIF_DBG("prevent_suspend_timeout: %u, allow_suspend_timeout: %u", - sc->pm_stats.prevent_suspend_timeout, - sc->pm_stats.allow_suspend_timeout); + hif_debug("prevent_suspend_timeout: %u, allow_suspend_timeout: %u", + sc->pm_stats.prevent_suspend_timeout, + sc->pm_stats.allow_suspend_timeout); - HIF_DBG("Suspended: %u, resumed: %u count", - sc->pm_stats.suspended, - sc->pm_stats.resumed); + hif_debug("Suspended: %u, resumed: %u count", + sc->pm_stats.suspended, + sc->pm_stats.resumed); - HIF_DBG("suspend_err: %u, runtime_get_err: %u", - sc->pm_stats.suspend_err, - sc->pm_stats.runtime_get_err); + hif_debug("suspend_err: %u, runtime_get_err: %u", + sc->pm_stats.suspend_err, + sc->pm_stats.runtime_get_err); - HIF_DBG("Active Wakeup Sources preventing Runtime Suspend: "); + hif_debug("Active Wakeup Sources preventing Runtime Suspend: "); list_for_each_entry(ctx, &sc->prevent_suspend_list, list) { - HIF_DBG("source %s; timeout %d ms", ctx->name, ctx->timeout); + hif_debug("source %s; timeout %d ms", ctx->name, ctx->timeout); } QDF_DEBUG_PANIC("hif_pci_runtime_pm_warn"); @@ -999,6 +1006,7 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data) int pm_state = atomic_read(&sc->pm_state); unsigned long timer_expires; struct hif_pm_runtime_lock *ctx; + int i; seq_printf(s, "%30s: %s\n", "Runtime PM state", autopm_state[pm_state]); @@ -1031,14 +1039,7 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data) HIF_PCI_RUNTIME_PM_STATS(s, sc, suspended); HIF_PCI_RUNTIME_PM_STATS(s, sc, suspend_err); HIF_PCI_RUNTIME_PM_STATS(s, sc, resumed); - seq_printf(s, "%30s: %u\n", "runtime_get", - qdf_atomic_read(&sc->pm_stats.runtime_get)); - seq_printf(s, "%30s: %u\n", "runtime_put", - qdf_atomic_read(&sc->pm_stats.runtime_put)); - seq_printf(s, "%30s: %u\n", "runtime_get_caller_index", - qdf_atomic_read(&sc->pm_stats.runtime_get_caller_index)); - seq_printf(s, "%30s: %u\n", "runtime_put_caller_index", - qdf_atomic_read(&sc->pm_stats.runtime_put_caller_index)); + HIF_PCI_RUNTIME_PM_STATS(s, sc, request_resume); seq_printf(s, "%30s: %u\n", "prevent_suspend", qdf_atomic_read(&sc->pm_stats.prevent_suspend)); @@ -1049,6 +1050,23 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data) HIF_PCI_RUNTIME_PM_STATS(s, sc, allow_suspend_timeout); HIF_PCI_RUNTIME_PM_STATS(s, sc, runtime_get_err); + seq_printf(s, "%30s: %u\n", "runtime_get", + qdf_atomic_read(&sc->pm_stats.runtime_get)); + seq_printf(s, "%30s: %u\n", "runtime_put", + qdf_atomic_read(&sc->pm_stats.runtime_put)); + seq_printf(s, "get put get-timestamp put-timestamp :DBGID_NAME\n"); + for (i = 0; i < RTPM_ID_MAX; i++) { + seq_printf(s, "%-10d ", + qdf_atomic_read(&sc->pm_stats.runtime_get_dbgid[i])); + seq_printf(s, "%-10d ", + qdf_atomic_read(&sc->pm_stats.runtime_put_dbgid[i])); + seq_printf(s, "0x%-10llx ", + sc->pm_stats.runtime_get_timestamp_dbgid[i]); + seq_printf(s, "0x%-10llx ", + sc->pm_stats.runtime_put_timestamp_dbgid[i]); + seq_printf(s, ":%-30s\n", rtpm_string_from_dbgid(i)); + } + timer_expires = sc->runtime_timer_expires; if (timer_expires > 0) { msecs_age = jiffies_to_msecs(timer_expires - jiffies); @@ -1212,17 +1230,20 @@ static void hif_pm_runtime_stop(struct hif_pci_softc *sc) */ static void hif_pm_runtime_open(struct hif_pci_softc *sc) { + int i; spin_lock_init(&sc->runtime_lock); qdf_atomic_init(&sc->pm_state); qdf_runtime_lock_init(&sc->prevent_linkdown_lock); qdf_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_NONE); - qdf_atomic_set(&sc->pm_stats.runtime_get, 0); - qdf_atomic_set(&sc->pm_stats.runtime_put, 0); - qdf_atomic_set(&sc->pm_stats.runtime_get_caller_index, 0); - qdf_atomic_set(&sc->pm_stats.runtime_put_caller_index, 0); - qdf_atomic_set(&sc->pm_stats.allow_suspend, 0); - qdf_atomic_set(&sc->pm_stats.prevent_suspend, 0); + qdf_atomic_init(&sc->pm_stats.runtime_get); + qdf_atomic_init(&sc->pm_stats.runtime_put); + qdf_atomic_init(&sc->pm_stats.allow_suspend); + qdf_atomic_init(&sc->pm_stats.prevent_suspend); + for (i = 0; i < RTPM_ID_MAX; i++) { + qdf_atomic_init(&sc->pm_stats.runtime_get_dbgid[i]); + qdf_atomic_init(&sc->pm_stats.runtime_put_dbgid[i]); + } INIT_LIST_HEAD(&sc->prevent_suspend_list); } @@ -3966,6 +3987,54 @@ void hif_pci_irq_disable(struct hif_softc *scn, int ce_id) } #ifdef FEATURE_RUNTIME_PM +/** + * hif_pm_stats_runtime_get_record() - record runtime get statics + * @sc: hif pci context + * @rtpm_dbgid: debug id to trace who use it + * + * + * Return: void + */ +static void hif_pm_stats_runtime_get_record(struct hif_pci_softc *sc, + wlan_rtpm_dbgid rtpm_dbgid) +{ + if (rtpm_dbgid >= RTPM_ID_MAX) { + QDF_BUG(0); + return; + } + qdf_atomic_inc(&sc->pm_stats.runtime_get); + qdf_atomic_inc(&sc->pm_stats.runtime_get_dbgid[rtpm_dbgid]); + sc->pm_stats.runtime_get_timestamp_dbgid[rtpm_dbgid] = + qdf_get_log_timestamp(); +} + +/** + * hif_pm_stats_runtime_put_record() - record runtime put statics + * @sc: hif pci context + * @rtpm_dbgid: dbg_id to trace who use it + * + * + * Return: void + */ +static void hif_pm_stats_runtime_put_record(struct hif_pci_softc *sc, + wlan_rtpm_dbgid rtpm_dbgid) +{ + if (rtpm_dbgid >= RTPM_ID_MAX) { + QDF_BUG(0); + return; + } + + if (atomic_read(&sc->dev->power.usage_count) <= 0) { + QDF_BUG(0); + return; + } + + qdf_atomic_inc(&sc->pm_stats.runtime_put); + qdf_atomic_inc(&sc->pm_stats.runtime_put_dbgid[rtpm_dbgid]); + sc->pm_stats.runtime_put_timestamp_dbgid[rtpm_dbgid] = + qdf_get_log_timestamp(); +} + /** * hif_pm_runtime_get_sync() - do a get operation with sync resume * @@ -3975,10 +4044,12 @@ void hif_pci_irq_disable(struct hif_softc *scn, int ce_id) * so it can only be called in non-atomic context. * * @hif_ctx: pointer of HIF context + * @rtpm_dbgid: dbgid to trace who use it * * Return: 0 if it is runtime PM resumed otherwise an error code. */ -int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) +int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); int pm_state; @@ -3996,7 +4067,7 @@ int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) hif_info_high("Runtime PM resume is requested by %ps", (void *)_RET_IP_); - HIF_PM_STATS_RUNTIME_GET_RECORD(sc); + hif_pm_stats_runtime_get_record(sc, rtpm_dbgid); ret = pm_runtime_get_sync(sc->dev); /* Get can return 1 if the device is already active, just return @@ -4009,7 +4080,7 @@ int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) sc->pm_stats.runtime_get_err++; hif_err("Runtime PM Get Sync error in pm_state: %d, ret: %d", qdf_atomic_read(&sc->pm_state), ret); - hif_pm_runtime_put(hif_ctx); + hif_pm_runtime_put(hif_ctx, rtpm_dbgid); } return ret; @@ -4025,7 +4096,8 @@ int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) * * Return: 0 for success otherwise an error code */ -int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx) +int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); int usage_count, pm_state; @@ -4051,7 +4123,7 @@ int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx) return -EINVAL; } - HIF_PM_STATS_RUNTIME_PUT_RECORD(sc); + hif_pm_stats_runtime_put_record(sc, rtpm_dbgid); return pm_runtime_put_sync_suspend(sc->dev); } @@ -4091,7 +4163,8 @@ void hif_pm_runtime_mark_last_busy(struct hif_opaque_softc *hif_ctx) return pm_runtime_mark_last_busy(sc->dev); } -void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx) +void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); @@ -4101,7 +4174,7 @@ void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx) if (!hif_pci_pm_runtime_enabled(sc)) return; - HIF_PM_STATS_RUNTIME_GET_RECORD(sc); + hif_pm_stats_runtime_get_record(sc, rtpm_dbgid); pm_runtime_get_noresume(sc->dev); } @@ -4118,7 +4191,8 @@ void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx) * return: success if the bus is up and a get has been issued * otherwise an error code. */ -int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx) +int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); @@ -4137,7 +4211,7 @@ int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx) if (pm_state == HIF_PM_RUNTIME_STATE_ON || pm_state == HIF_PM_RUNTIME_STATE_NONE) { - HIF_PM_STATS_RUNTIME_GET_RECORD(sc); + hif_pm_stats_runtime_get_record(sc, rtpm_dbgid); ret = __hif_pm_runtime_get(sc->dev); /* Get can return 1 if the device is already active, just return @@ -4147,7 +4221,7 @@ int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx) ret = 0; if (ret) - hif_pm_runtime_put(hif_ctx); + hif_pm_runtime_put(hif_ctx, rtpm_dbgid); if (ret && ret != -EINPROGRESS) { sc->pm_stats.runtime_get_err++; @@ -4185,7 +4259,8 @@ int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx) * * return: QDF_STATUS_SUCCESS if the put is performed */ -int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx) +int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); @@ -4218,7 +4293,7 @@ int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx) return -EINVAL; } - HIF_PM_STATS_RUNTIME_PUT_RECORD(sc); + hif_pm_stats_runtime_put_record(sc, rtpm_dbgid); hif_pm_runtime_mark_last_busy(hif_ctx); hif_pm_runtime_put_auto(sc->dev); @@ -4235,7 +4310,8 @@ int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx) * * Return: 0 for success otherwise an error code */ -int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx) +int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx, + wlan_rtpm_dbgid rtpm_dbgid) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); int usage_count, pm_state; @@ -4261,7 +4337,7 @@ int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx) return -EINVAL; } - HIF_PM_STATS_RUNTIME_PUT_RECORD(sc); + hif_pm_stats_runtime_put_record(sc, rtpm_dbgid); pm_runtime_put_noidle(sc->dev); return 0; diff --git a/hif/src/pcie/if_pci.h b/hif/src/pcie/if_pci.h index f3c02a83177f..76edc18d72c3 100644 --- a/hif/src/pcie/if_pci.h +++ b/hif/src/pcie/if_pci.h @@ -74,30 +74,6 @@ enum hif_pm_runtime_state { #ifdef FEATURE_RUNTIME_PM -#define PM_STATUS_RUNTIME_CALLER_MAX 128 - -#define HIF_PM_STATS_RUNTIME_GET_RECORD(sc) \ -{\ - typeof(sc) sc_ = (sc); \ - int32_t index = \ - qdf_atomic_read(&sc_->pm_stats.runtime_get_caller_index) % \ - PM_STATUS_RUNTIME_CALLER_MAX; \ - sc_->pm_stats.runtime_get_caller[index] = (void *)_RET_IP_; \ - qdf_atomic_inc(&sc_->pm_stats.runtime_get_caller_index); \ - qdf_atomic_inc(&sc_->pm_stats.runtime_get); \ -} - -#define HIF_PM_STATS_RUNTIME_PUT_RECORD(sc) \ -{\ - typeof(sc) sc_ = (sc); \ - int32_t index = \ - qdf_atomic_read(&sc_->pm_stats.runtime_put_caller_index) % \ - PM_STATUS_RUNTIME_CALLER_MAX; \ - sc_->pm_stats.runtime_put_caller[index] = (void *)_RET_IP_; \ - qdf_atomic_inc(&sc_->pm_stats.runtime_put_caller_index); \ - qdf_atomic_inc(&sc_->pm_stats.runtime_put); \ -} - /** * struct hif_pm_runtime_lock - data structure for preventing runtime suspend * @list - global list of runtime locks @@ -118,10 +94,10 @@ struct hif_pci_pm_stats { u32 resumed; atomic_t runtime_get; atomic_t runtime_put; - atomic_t runtime_get_caller_index; - atomic_t runtime_put_caller_index; - void *runtime_get_caller[PM_STATUS_RUNTIME_CALLER_MAX]; - void *runtime_put_caller[PM_STATUS_RUNTIME_CALLER_MAX]; + atomic_t runtime_get_dbgid[RTPM_ID_MAX]; + atomic_t runtime_put_dbgid[RTPM_ID_MAX]; + uint64_t runtime_get_timestamp_dbgid[RTPM_ID_MAX]; + uint64_t runtime_put_timestamp_dbgid[RTPM_ID_MAX]; u32 request_resume; atomic_t allow_suspend; atomic_t prevent_suspend; diff --git a/htc/htc.c b/htc/htc.c index 0bff8117fb12..fd7f9f9fbac5 100644 --- a/htc/htc.c +++ b/htc/htc.c @@ -1146,14 +1146,16 @@ int htc_pm_runtime_get(HTC_HANDLE htc_handle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); - return hif_pm_runtime_get(target->hif_dev); + return hif_pm_runtime_get(target->hif_dev, + RTPM_ID_HTC); } int htc_pm_runtime_put(HTC_HANDLE htc_handle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); - return hif_pm_runtime_put(target->hif_dev); + return hif_pm_runtime_put(target->hif_dev, + RTPM_ID_HTC); } #endif diff --git a/htc/htc_send.c b/htc/htc_send.c index 6a455e722a9e..c7034a24baee 100644 --- a/htc/htc_send.c +++ b/htc/htc_send.c @@ -913,7 +913,8 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, break; } if (rt_put) { - hif_pm_runtime_put(target->hif_dev); + hif_pm_runtime_put(target->hif_dev, + RTPM_ID_HTC); rt_put = false; } } @@ -987,6 +988,40 @@ static void queue_htc_pm_packets(HTC_ENDPOINT *endpoint, {} #endif +/** + * htc_send_pkts_rtpm_dbgid_get() - get runtime pm dbgid by service_id + * @service_id: service for endpoint + * + * For service_id HTT_DATA_MSG_SVC, HTT message donot have a tx complete + * from CE level, so they need runtime put which only can happen in fw + * response. runtime put will happens at 2 ways. + * 1 if packet tag HTC_TX_PACKET_TAG_RUNTIME_PUT, runtime put + * will be just in htc_issue_packets. as such pkt doesn't have + * a response from fw. + * 2 other pkt must have a response from fw, it will be handled + * by fw response using htc_pm_runtime_put. + * + * For other service_id, they have tx_completion from CE, so they will be + * handled in htc_tx_completion_handler, except packet tag as + * HTC_TX_PACKET_TAG_AUTO_PM, pm related wmi cmd don't need a runtime + * put/get. + * + * + * Return: rtpm_dbgid to trace who use it + */ +static wlan_rtpm_dbgid +htc_send_pkts_rtpm_dbgid_get(HTC_SERVICE_ID service_id) +{ + wlan_rtpm_dbgid rtpm_dbgid; + + if (service_id == HTT_DATA_MSG_SVC) + rtpm_dbgid = RTPM_ID_HTC; + else + rtpm_dbgid = RTPM_ID_WMI; + + return rtpm_dbgid; +} + /** * get_htc_send_packets_credit_based() - get packets based on available credits * @target: HTC target on which packets need to be sent @@ -1010,6 +1045,7 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, HTC_PACKET_QUEUE *tx_queue; HTC_PACKET_QUEUE pm_queue; bool do_pm_get = false; + wlan_rtpm_dbgid rtpm_dbgid = 0; int ret; /*** NOTE : the TX lock is held when this function is called ***/ @@ -1027,28 +1063,24 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, /* loop until we can grab as many packets out of the queue as we can */ while (true) { - if (do_pm_get) { - ret = hif_pm_runtime_get(target->hif_dev); - if (ret) { - /* bus suspended, runtime resume issued */ - QDF_ASSERT(HTC_PACKET_QUEUE_DEPTH(pQueue) == 0); - if (ret == -EAGAIN) { - pPacket = htc_get_pkt_at_head(tx_queue); - if (!pPacket) - break; - log_packet_info(target, pPacket); - } - break; - } - } - sendFlags = 0; /* get packet at head, but don't remove it */ pPacket = htc_get_pkt_at_head(tx_queue); - if (!pPacket) { - if (do_pm_get) - hif_pm_runtime_put(target->hif_dev); + if (!pPacket) break; + + if (do_pm_get) { + rtpm_dbgid = + htc_send_pkts_rtpm_dbgid_get( + pEndpoint->service_id); + ret = hif_pm_runtime_get(target->hif_dev, + rtpm_dbgid); + if (ret) { + /* bus suspended, runtime resume issued */ + if (ret == -EAGAIN) + log_packet_info(target, pPacket); + break; + } } AR_DEBUG_PRINTF(ATH_DEBUG_SEND, @@ -1091,7 +1123,8 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, creditsRequired)); #endif if (do_pm_get) - hif_pm_runtime_put(target->hif_dev); + hif_pm_runtime_put(target->hif_dev, + rtpm_dbgid); break; } @@ -1150,6 +1183,7 @@ static void get_htc_send_packets(HTC_TARGET *target, HTC_PACKET_QUEUE *tx_queue; HTC_PACKET_QUEUE pm_queue; bool do_pm_get = false; + wlan_rtpm_dbgid rtpm_dbgid; int ret; /*** NOTE : the TX lock is held when this function is called ***/ @@ -1169,27 +1203,23 @@ static void get_htc_send_packets(HTC_TARGET *target, while (Resources > 0) { int num_frags; + pPacket = htc_packet_dequeue(tx_queue); + if (!pPacket) + break; + if (do_pm_get) { - ret = hif_pm_runtime_get(target->hif_dev); + rtpm_dbgid = + htc_send_pkts_rtpm_dbgid_get( + pEndpoint->service_id); + ret = hif_pm_runtime_get(target->hif_dev, + rtpm_dbgid); if (ret) { /* bus suspended, runtime resume issued */ - QDF_ASSERT(HTC_PACKET_QUEUE_DEPTH(pQueue) == 0); - if (ret == -EAGAIN) { - pPacket = htc_get_pkt_at_head(tx_queue); - if (!pPacket) - break; + if (ret == -EAGAIN) log_packet_info(target, pPacket); - } break; } } - - pPacket = htc_packet_dequeue(tx_queue); - if (!pPacket) { - if (do_pm_get) - hif_pm_runtime_put(target->hif_dev); - break; - } AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Got packet:%pK , New Queue Depth: %d\n", pPacket, @@ -1507,6 +1537,7 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target, status = htc_issue_packets(target, pEndpoint, &sendQueue); if (status) { int i; + wlan_rtpm_dbgid rtpm_dbgid; result = HTC_SEND_QUEUE_DROP; @@ -1528,8 +1559,13 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target, break; } + rtpm_dbgid = + htc_send_pkts_rtpm_dbgid_get( + pEndpoint->service_id); for (i = HTC_PACKET_QUEUE_DEPTH(&sendQueue); i > 0; i--) - hif_pm_runtime_put(target->hif_dev); + hif_pm_runtime_put(target->hif_dev, + rtpm_dbgid); + if (!pEndpoint->async_update) { LOCK_HTC_TX(target); } @@ -1815,6 +1851,7 @@ QDF_STATUS htc_send_data_pkt(HTC_HANDLE htc_hdl, qdf_nbuf_t netbuf, int ep_id, int tx_resources; uint32_t data_attr = 0; int htc_payload_len = actual_length; + wlan_rtpm_dbgid rtpm_dbgid; pEndpoint = &target->endpoint[ep_id]; @@ -1833,7 +1870,9 @@ QDF_STATUS htc_send_data_pkt(HTC_HANDLE htc_hdl, qdf_nbuf_t netbuf, int ep_id, return QDF_STATUS_E_FAILURE; } - if (hif_pm_runtime_get(target->hif_dev)) + rtpm_dbgid = + htc_send_pkts_rtpm_dbgid_get(pEndpoint->service_id); + if (hif_pm_runtime_get(target->hif_dev, rtpm_dbgid)) return QDF_STATUS_E_FAILURE; p_htc_hdr = (HTC_FRAME_HDR *)qdf_nbuf_get_frag_vaddr(netbuf, 0); @@ -2276,7 +2315,8 @@ QDF_STATUS htc_tx_completion_handler(void *Context, break; } if (pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_AUTO_PM) - hif_pm_runtime_put(target->hif_dev); + hif_pm_runtime_put(target->hif_dev, + RTPM_ID_WMI); if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED) { HTC_PACKET *pPacketTemp; diff --git a/qdf/linux/src/qdf_lock.c b/qdf/linux/src/qdf_lock.c index 92cdc0316528..3ac5e960b704 100644 --- a/qdf/linux/src/qdf_lock.c +++ b/qdf/linux/src/qdf_lock.c @@ -448,7 +448,7 @@ QDF_STATUS qdf_runtime_pm_get(void) return QDF_STATUS_E_INVAL; } - ret = hif_pm_runtime_get(ol_sc); + ret = hif_pm_runtime_get(ol_sc, RTPM_ID_RESVERD); if (ret) return QDF_STATUS_E_FAILURE; @@ -481,7 +481,7 @@ QDF_STATUS qdf_runtime_pm_put(void) return QDF_STATUS_E_INVAL; } - ret = hif_pm_runtime_put(ol_sc); + ret = hif_pm_runtime_put(ol_sc, RTPM_ID_RESVERD); if (ret) return QDF_STATUS_E_FAILURE;