qcacmn: Schedule CE tasklet when resource runs out
If there is no resourse to send packet via HTC, then check if interrupts are not processed from that CE for last 3 seconds. If so, schedule a tasklet to reap available entries. Also if Queue has reached 1024 entries within 3 seconds, then also schedule tasklet. This change is added because there is a case where intermittently completion interrupts are not received from CE3 and hence adding this WAR in host to come out of this issue scenario. Change-Id: I126cd5e678517127659237308f8f6b1313f8f422 CRs-Fixed: 3234943
This commit is contained in:

committed by
Madan Koyyalamudi

parent
053f59e4f0
commit
93bf7e1fb1
@@ -2855,6 +2855,39 @@ void hif_send_complete_check(struct hif_opaque_softc *hif_ctx, uint8_t pipe,
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CE_TASKLET_SCHEDULE_ON_FULL) && defined(CE_TASKLET_DEBUG_ENABLE)
|
||||
#define CE_RING_FULL_THRESHOLD_TIME 3000000
|
||||
#define CE_RING_FULL_THRESHOLD 1024
|
||||
/* Ths function is called from htc_send path. If there is no resourse to send
|
||||
* packet via HTC, then check if interrupts are not processed from that
|
||||
* CE for last 3 seconds. If so, schedule a tasklet to reap available entries.
|
||||
* Also if Queue has reached 1024 entries within 3 seconds, then also schedule
|
||||
* tasklet.
|
||||
*/
|
||||
void hif_schedule_ce_tasklet(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
|
||||
{
|
||||
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
|
||||
uint64_t diff_time = qdf_get_log_timestamp_usecs() -
|
||||
hif_state->stats.tasklet_sched_entry_ts[pipe];
|
||||
|
||||
hif_state->stats.ce_ring_full_count[pipe]++;
|
||||
|
||||
if (diff_time >= CE_RING_FULL_THRESHOLD_TIME ||
|
||||
hif_state->stats.ce_ring_full_count[pipe] >=
|
||||
CE_RING_FULL_THRESHOLD) {
|
||||
hif_state->stats.ce_ring_full_count[pipe] = 0;
|
||||
hif_state->stats.ce_manual_tasklet_schedule_count[pipe]++;
|
||||
hif_state->stats.ce_last_manual_tasklet_schedule_ts[pipe] =
|
||||
qdf_get_log_timestamp_usecs();
|
||||
ce_dispatch_interrupt(pipe, &hif_state->tasklets[pipe]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void hif_schedule_ce_tasklet(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t
|
||||
hif_get_free_queue_number(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
|
||||
{
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 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
|
||||
@@ -192,6 +193,11 @@ struct ce_stats {
|
||||
uint64_t ce_tasklet_sched_bucket[CE_COUNT_MAX][CE_BUCKET_MAX];
|
||||
uint64_t ce_tasklet_exec_last_update[CE_COUNT_MAX][CE_BUCKET_MAX];
|
||||
uint64_t ce_tasklet_sched_last_update[CE_COUNT_MAX][CE_BUCKET_MAX];
|
||||
#ifdef CE_TASKLET_SCHEDULE_ON_FULL
|
||||
uint32_t ce_ring_full_count[CE_COUNT_MAX];
|
||||
uint32_t ce_manual_tasklet_schedule_count[CE_COUNT_MAX];
|
||||
uint64_t ce_last_manual_tasklet_schedule_ts[CE_COUNT_MAX];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -340,6 +340,28 @@ hif_ce_latency_stats(struct hif_softc *hif_ctx)
|
||||
}
|
||||
#endif /*CE_TASKLET_DEBUG_ENABLE*/
|
||||
|
||||
#if defined(CE_TASKLET_DEBUG_ENABLE) && defined(CE_TASKLET_SCHEDULE_ON_FULL)
|
||||
/**
|
||||
* hif_reset_ce_full_count() - Reset ce full count
|
||||
* @scn: hif_softc
|
||||
* @ce_id: ce_id
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
hif_reset_ce_full_count(struct hif_softc *scn, uint8_t ce_id)
|
||||
{
|
||||
struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(scn);
|
||||
|
||||
hif_ce_state->stats.ce_ring_full_count[ce_id] = 0;
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
hif_reset_ce_full_count(struct hif_softc *scn, uint8_t ce_id)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HIF_DETECTION_LATENCY_ENABLE
|
||||
static inline
|
||||
void hif_latency_detect_tasklet_sched(
|
||||
@@ -429,6 +451,7 @@ static void ce_tasklet(unsigned long data)
|
||||
ce_tasklet_schedule(tasklet_entry);
|
||||
hif_latency_detect_tasklet_sched(scn, tasklet_entry);
|
||||
|
||||
hif_reset_ce_full_count(scn, tasklet_entry->ce_id);
|
||||
if (scn->ce_latency_stats) {
|
||||
ce_tasklet_update_bucket(hif_ce_state,
|
||||
tasklet_entry->ce_id);
|
||||
@@ -697,6 +720,7 @@ static inline bool hif_tasklet_schedule(struct hif_opaque_softc *hif_ctx,
|
||||
hif_latency_detect_tasklet_sched(scn, tasklet_entry);
|
||||
ce_tasklet_schedule(tasklet_entry);
|
||||
|
||||
hif_reset_ce_full_count(scn, tasklet_entry->ce_id);
|
||||
if (scn->ce_latency_stats)
|
||||
hif_record_tasklet_sched_entry_ts(scn, tasklet_entry->ce_id);
|
||||
|
||||
|
Reference in New Issue
Block a user