qcacmn: Do RTPM put during cleanup in case of WMI Tx completion failure

For WMI messages RTPM get is done during HTC message send and the
corresponding put is done in Tx failure or in Tx completion handler
for Tx success case. In the case where Tx completion is not received
for WMI messages RTPM put is not done as part of the cleanup which
results in RTPM Get and PUT call out of sync issues.

To fix the issue as part of HTC cleanup do RTPM put for WMI messages
for which tx completion is not received.

Change-Id: If92f4bd8a6c104d7ccef1e33b31aa765ea6100bd
CRs-Fixed: 3315404
This commit is contained in:
Amit Mehta
2022-10-20 20:40:52 +05:30
committed by Madan Koyyalamudi
父節點 6487fc4371
當前提交 ea172ef154
共有 5 個文件被更改,包括 121 次插入27 次删除

查看文件

@@ -3400,7 +3400,7 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
* did not process this indication runtime_put happens * did not process this indication runtime_put happens
* properly in the cleanup path. * properly in the cleanup path.
*/ */
if (htc_dec_return_runtime_cnt(soc->htc_soc) >= 0) if (htc_dec_return_htt_runtime_cnt(soc->htc_soc) >= 0)
htc_pm_runtime_put(soc->htc_soc); htc_pm_runtime_put(soc->htc_soc);
else else
soc->stats.htt_ver_req_put_skip++; soc->stats.htt_ver_req_put_skip++;

查看文件

@@ -145,6 +145,42 @@ void htc_ce_tasklet_debug_dump(HTC_HANDLE htc_handle)
hif_display_stats(target->hif_dev); hif_display_stats(target->hif_dev);
} }
#ifdef FEATURE_RUNTIME_PM
/**
* htc_dec_return_wmi_runtime_cnt: Decrement htc wmi runtime count
* @target: HTC target
*
* Return: value of runtime count after decrement
*/
static inline
int32_t htc_dec_return_wmi_runtime_cnt(HTC_TARGET *target)
{
return qdf_atomic_dec_return(&target->htc_wmi_runtime_cnt);
}
/**
* htc_init_wmi_runtime_cnt: Initialize htc wmi runtime count
* @target: HTC target
*
* Return: None
*/
static inline
void htc_init_wmi_runtime_cnt(HTC_TARGET *target)
{
qdf_atomic_init(&target->htc_wmi_runtime_cnt);
}
#else
static inline
int32_t htc_dec_return_wmi_runtime_cnt(HTC_TARGET *target)
{
return -1;
}
static inline
void htc_init_wmi_runtime_cnt(HTC_TARGET *target)
{
}
#endif
/* cleanup the HTC instance */ /* cleanup the HTC instance */
static void htc_cleanup(HTC_TARGET *target) static void htc_cleanup(HTC_TARGET *target)
{ {
@@ -154,9 +190,12 @@ static void htc_cleanup(HTC_TARGET *target)
HTC_PACKET_QUEUE *pkt_queue; HTC_PACKET_QUEUE *pkt_queue;
qdf_nbuf_t netbuf; qdf_nbuf_t netbuf;
while (htc_dec_return_runtime_cnt((void *)target) >= 0) while (htc_dec_return_htt_runtime_cnt((void *)target) >= 0)
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, HIF_RTPM_ID_HTT); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, HIF_RTPM_ID_HTT);
while (htc_dec_return_wmi_runtime_cnt((void *)target) >= 0)
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, HIF_RTPM_ID_WMI);
if (target->hif_dev) { if (target->hif_dev) {
hif_detach_htc(target->hif_dev); hif_detach_htc(target->hif_dev);
hif_mask_interrupt_call(target->hif_dev); hif_mask_interrupt_call(target->hif_dev);
@@ -277,30 +316,30 @@ static void htc_runtime_pm_deinit(HTC_TARGET *target)
qdf_destroy_work(0, &target->queue_kicker); qdf_destroy_work(0, &target->queue_kicker);
} }
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc) int32_t htc_dec_return_htt_runtime_cnt(HTC_HANDLE htc)
{ {
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc); HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc);
return qdf_atomic_dec_return(&target->htc_runtime_cnt); return qdf_atomic_dec_return(&target->htc_htt_runtime_cnt);
} }
/** /**
* htc_init_runtime_cnt: Initialize htc runtime count * htc_init_htt_runtime_cnt: Initialize htc htt runtime count
* @htc: HTC handle * @target: HTC target
* *
* Return: None * Return: None
*/ */
static inline static inline
void htc_init_runtime_cnt(HTC_TARGET *target) void htc_init_htt_runtime_cnt(HTC_TARGET *target)
{ {
qdf_atomic_init(&target->htc_runtime_cnt); qdf_atomic_init(&target->htc_htt_runtime_cnt);
} }
#else #else
static inline void htc_runtime_pm_init(HTC_TARGET *target) { } static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { } static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { }
static inline static inline
void htc_init_runtime_cnt(HTC_TARGET *target) void htc_init_htt_runtime_cnt(HTC_TARGET *target)
{ {
} }
#endif #endif
@@ -479,7 +518,8 @@ HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo,
} while (false); } while (false);
htc_recv_init(target); htc_recv_init(target);
htc_init_runtime_cnt(target); htc_init_htt_runtime_cnt(target);
htc_init_wmi_runtime_cnt(target);
HTC_TRACE("-htc_create: (0x%pK)", target); HTC_TRACE("-htc_create: (0x%pK)", target);
@@ -503,10 +543,10 @@ void htc_destroy(HTC_HANDLE HTCHandle)
htc_hang_event_notifier_unregister(); htc_hang_event_notifier_unregister();
if (target) { if (target) {
hif_rtpm_deregister(HIF_RTPM_ID_HTT);
hif_rtpm_deregister(HIF_RTPM_ID_WMI);
hif_stop(htc_get_hif_device(HTCHandle)); hif_stop(htc_get_hif_device(HTCHandle));
htc_cleanup(target); htc_cleanup(target);
hif_rtpm_deregister(HIF_RTPM_ID_HTT);
hif_rtpm_deregister(HIF_RTPM_ID_WMI);
} }
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n")); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
htc_credit_history_deinit(); htc_credit_history_deinit();

查看文件

@@ -814,18 +814,18 @@ int htc_pm_runtime_get(HTC_HANDLE htc_handle);
int htc_pm_runtime_put(HTC_HANDLE htc_handle); int htc_pm_runtime_put(HTC_HANDLE htc_handle);
/** /**
* htc_dec_return_runtime_cnt: Decrement htc runtime count * htc_dec_return_htt_runtime_cnt: Decrement htc htt runtime count
* @htc: HTC handle * @htc: HTC handle
* *
* Return: value of runtime count after decrement * Return: value of runtime count after decrement
*/ */
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc); int32_t htc_dec_return_htt_runtime_cnt(HTC_HANDLE htc);
#else #else
static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; } static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; }
static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; } static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; }
static inline static inline
int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc) int32_t htc_dec_return_htt_runtime_cnt(HTC_HANDLE htc)
{ {
return -1; return -1;
} }

查看文件

@@ -263,8 +263,10 @@ typedef struct _HTC_TARGET {
bool htc_pkt_dbg; bool htc_pkt_dbg;
#ifdef FEATURE_RUNTIME_PM #ifdef FEATURE_RUNTIME_PM
/* Runtime count for H2T msg with response */ /* Runtime count for H2T HTT msg with response */
qdf_atomic_t htc_runtime_cnt; qdf_atomic_t htc_htt_runtime_cnt;
/* Runtime count for WMI msg*/
qdf_atomic_t htc_wmi_runtime_cnt;
#endif #endif
/* Non flow ctrl enabled endpoints nbuf map unmap count */ /* Non flow ctrl enabled endpoints nbuf map unmap count */
uint32_t nbuf_nfc_map_count; uint32_t nbuf_nfc_map_count;

查看文件

@@ -185,15 +185,15 @@ static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
} }
/** /**
* htc_inc_runtime_cnt: Increment htc runtime count * htc_inc_htt_runtime_cnt: Increment htc htt runtime count
* @target: handle of HTC context * @target: handle of HTC context
* *
* Return: None * Return: None
*/ */
static inline static inline
void htc_inc_runtime_cnt(HTC_TARGET *target) void htc_inc_htt_runtime_cnt(HTC_TARGET *target)
{ {
qdf_atomic_inc(&target->htc_runtime_cnt); qdf_atomic_inc(&target->htc_htt_runtime_cnt);
} }
#else #else
static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket) static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
@@ -201,7 +201,7 @@ static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket)
} }
static inline static inline
void htc_inc_runtime_cnt(HTC_TARGET *target) void htc_inc_htt_runtime_cnt(HTC_TARGET *target)
{ {
} }
#endif #endif
@@ -873,7 +873,7 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
} else if (pPacket->PktInfo.AsTx.Tag == } else if (pPacket->PktInfo.AsTx.Tag ==
HTC_TX_PACKET_TAG_RTPM_PUT_RC) { HTC_TX_PACKET_TAG_RTPM_PUT_RC) {
rt_put_in_resp = true; rt_put_in_resp = true;
htc_inc_runtime_cnt(target); htc_inc_htt_runtime_cnt(target);
} }
#if DEBUG_BUNDLE #if DEBUG_BUNDLE
@@ -895,7 +895,7 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
if (status != QDF_STATUS_SUCCESS) { if (status != QDF_STATUS_SUCCESS) {
if (rt_put_in_resp) if (rt_put_in_resp)
htc_dec_return_runtime_cnt((void *)target); htc_dec_return_htt_runtime_cnt((void *)target);
if (pPacket->PktInfo.AsTx.Tag == if (pPacket->PktInfo.AsTx.Tag ==
HTC_TX_PACKET_SYSTEM_SUSPEND) HTC_TX_PACKET_SYSTEM_SUSPEND)
@@ -1029,6 +1029,34 @@ static void queue_htc_pm_packets(HTC_ENDPOINT *endpoint,
HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&endpoint->TxQueue, queue); HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&endpoint->TxQueue, queue);
} }
/**
* htc_dec_wmi_runtime_cnt: Decrement htc wmi runtime count
* @target: HTC target
* @rtpm_code: RTPM code
*
* Return: None
*/
static inline
void htc_dec_wmi_runtime_cnt(HTC_TARGET *target, uint8_t rtpm_code)
{
if (rtpm_code == HIF_RTPM_ID_WMI)
qdf_atomic_dec(&target->htc_wmi_runtime_cnt);
}
/**
* htc_inc_wmi_runtime_cnt: Increment htc wmi runtime count
* @target: HTC target
* @rtpm_code: RTPM code
*
* Return: None
*/
static inline
void htc_inc_wmi_runtime_cnt(HTC_TARGET *target, uint8_t rtpm_code)
{
if (rtpm_code == HIF_RTPM_ID_WMI)
qdf_atomic_inc(&target->htc_wmi_runtime_cnt);
}
#else #else
static void extract_htc_pm_packets(HTC_ENDPOINT *endpoint, static void extract_htc_pm_packets(HTC_ENDPOINT *endpoint,
HTC_PACKET_QUEUE *queue) HTC_PACKET_QUEUE *queue)
@@ -1037,6 +1065,16 @@ static void extract_htc_pm_packets(HTC_ENDPOINT *endpoint,
static void queue_htc_pm_packets(HTC_ENDPOINT *endpoint, static void queue_htc_pm_packets(HTC_ENDPOINT *endpoint,
HTC_PACKET_QUEUE *queue) HTC_PACKET_QUEUE *queue)
{} {}
static inline
void htc_dec_wmi_runtime_cnt(HTC_TARGET *target, uint8_t rtpm_code)
{
}
static inline
void htc_inc_wmi_runtime_cnt(HTC_TARGET *target, uint8_t rtpm_code)
{
}
#endif #endif
/** /**
@@ -1168,21 +1206,26 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target,
log_packet_info(target, pPacket); log_packet_info(target, pPacket);
break; break;
} }
htc_inc_wmi_runtime_cnt(target, rtpm_code);
} }
sendFlags = 0; sendFlags = 0;
/* get packet at head, but don't remove it */ /* get packet at head, but don't remove it */
pPacket = htc_get_pkt_at_head(tx_queue); pPacket = htc_get_pkt_at_head(tx_queue);
if (!pPacket) { if (!pPacket) {
if (do_pm_get) if (do_pm_get) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code);
htc_dec_wmi_runtime_cnt(target, rtpm_code);
}
break; break;
} }
if (sys_pm_check && if (sys_pm_check &&
hif_system_pm_state_check(target->hif_dev)) { hif_system_pm_state_check(target->hif_dev)) {
if (do_pm_get) if (do_pm_get) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code);
htc_dec_wmi_runtime_cnt(target, rtpm_code);
}
break; break;
} }
@@ -1225,9 +1268,12 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target,
pEndpoint->TxCredits, pEndpoint->TxCredits,
creditsRequired)); creditsRequired));
#endif #endif
if (do_pm_get) if (do_pm_get) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, hif_rtpm_put(HIF_RTPM_PUT_ASYNC,
rtpm_code); rtpm_code);
htc_dec_wmi_runtime_cnt(target,
rtpm_code);
}
break; break;
} }
@@ -1324,6 +1370,7 @@ static void get_htc_send_packets(HTC_TARGET *target,
log_packet_info(target, pPacket); log_packet_info(target, pPacket);
break; break;
} }
htc_inc_wmi_runtime_cnt(target, rtpm_code);
} }
@@ -1331,6 +1378,7 @@ static void get_htc_send_packets(HTC_TARGET *target,
if (ret) { if (ret) {
if (do_pm_get) { if (do_pm_get) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code);
htc_dec_wmi_runtime_cnt(target, rtpm_code);
} }
break; break;
} }
@@ -1339,6 +1387,7 @@ static void get_htc_send_packets(HTC_TARGET *target,
if (!pPacket) { if (!pPacket) {
if (do_pm_get) { if (do_pm_get) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code);
htc_dec_wmi_runtime_cnt(target, rtpm_code);
} }
break; break;
} }
@@ -1697,6 +1746,7 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target,
pEndpoint->service_id); pEndpoint->service_id);
for (i = HTC_PACKET_QUEUE_DEPTH(&sendQueue); i > 0; i--) { for (i = HTC_PACKET_QUEUE_DEPTH(&sendQueue); i > 0; i--) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, rtpm_code);
htc_dec_wmi_runtime_cnt(target, rtpm_code);
} }
if (!pEndpoint->async_update) { if (!pEndpoint->async_update) {
@@ -2451,8 +2501,10 @@ QDF_STATUS htc_tx_completion_handler(void *Context,
} }
if (pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_AUTO_PM && if (pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_AUTO_PM &&
pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_RUNTIME_PUT && pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_RUNTIME_PUT &&
pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_RTPM_PUT_RC) pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_RTPM_PUT_RC) {
hif_rtpm_put(HIF_RTPM_PUT_ASYNC, HIF_RTPM_ID_WMI); hif_rtpm_put(HIF_RTPM_PUT_ASYNC, HIF_RTPM_ID_WMI);
htc_dec_wmi_runtime_cnt(target, HIF_RTPM_ID_WMI);
}
if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED) { if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED) {