diff options
| author | Mohit Khanna <mkhannaqca@codeaurora.org> | 2016-10-06 19:58:02 -0700 |
|---|---|---|
| committer | Mohit Khanna <mkhannaqca@codeaurora.org> | 2016-11-16 22:30:41 -0800 |
| commit | 4e5c84e3fb0ece3bb6f3e0f86c2a20ae61225366 (patch) | |
| tree | c9f28a4736d289988dc30367f18551eba56c2b21 /hif/src | |
| parent | 2df19cb29e089911ec0e0a42d5646522faa6df39 (diff) | |
qcacmn: Add NAPI statistics to dumpstats
Currently NAPI stats are retrieved as a part of iwpriv getStats command.
The buffer available for this command is limited and NAPI stats get
trucncated.
Add a new dumpStats parameter (9) to dump NAPI stats.
Change-Id: Iaf52a3dcecac2f7b24fde2f8220fbfddc767965b
CRs-Fixed: 1076563
Diffstat (limited to 'hif/src')
| -rw-r--r-- | hif/src/ce/ce_main.h | 4 | ||||
| -rw-r--r-- | hif/src/ce/ce_service.c | 18 | ||||
| -rw-r--r-- | hif/src/ce/ce_tasklet.c | 5 | ||||
| -rw-r--r-- | hif/src/hif_napi.c | 85 |
4 files changed, 94 insertions, 18 deletions
diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h index 3023be80fe4c..4a68618bd1bc 100644 --- a/hif/src/ce/ce_main.h +++ b/hif/src/ce/ce_main.h @@ -112,7 +112,7 @@ struct ce_tasklet_entry { void *hif_ce_state; }; -struct ce_intr_stats { +struct ce_stats { uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU]; }; @@ -140,7 +140,7 @@ struct HIF_CE_state { /* Copy Engine used for Diagnostic Accesses */ struct CE_handle *ce_diag; - struct ce_intr_stats stats; + struct ce_stats stats; }; /* diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 770f72c5126a..0cb54d6af9e8 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -35,6 +35,7 @@ #include "regtable.h" #include "hif_main.h" #include "hif_debug.h" +#include "hif_napi.h" #ifdef IPA_OFFLOAD #ifdef QCA_WIFI_3_0 @@ -199,9 +200,20 @@ inline void ce_init_ce_desc_event_log(int ce_id, int size) bool hif_ce_service_should_yield(struct hif_softc *scn, struct CE_state *ce_state) { - bool yield = qdf_system_time_after_eq(qdf_system_ticks(), - ce_state->ce_service_yield_time) || - hif_max_num_receives_reached(scn, ce_state->receive_count); + bool yield, time_limit_reached, rxpkt_thresh_reached = 0; + + time_limit_reached = qdf_system_time_after_eq(qdf_system_ticks(), + ce_state->ce_service_yield_time); + if (!time_limit_reached) + rxpkt_thresh_reached = hif_max_num_receives_reached + (scn, ce_state->receive_count); + + yield = time_limit_reached || rxpkt_thresh_reached; + + if (yield) + hif_napi_update_yield_stats(ce_state, + time_limit_reached, + rxpkt_thresh_reached); return yield; } diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c index c820d874f788..b604c30dc4d1 100644 --- a/hif/src/ce/ce_tasklet.c +++ b/hif/src/ce/ce_tasklet.c @@ -437,7 +437,6 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) for (i = 0; i < CE_COUNT_MAX; i++) { size = STR_SIZE; pos = 0; - qdf_print("CE id: %d", i); for (j = 0; j < QDF_MAX_AVAILABLE_CPU; j++) { ret = snprintf(str_buffer + pos, size, "[%d]: %d", j, hif_ce_state->stats.ce_per_cpu[i][j]); @@ -446,7 +445,7 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) size -= ret; pos += ret; } - qdf_print("%s", str_buffer); + qdf_print("CE id[%d] - %s", i, str_buffer); } #undef STR_SIZE } @@ -459,7 +458,7 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) */ void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state) { - qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_intr_stats)); + qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_stats)); } /** diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c index 90c04dec7365..9c08e21f8697 100644 --- a/hif/src/hif_napi.c +++ b/hif/src/hif_napi.c @@ -799,22 +799,78 @@ out: } #ifdef HELIUMPLUS -/* - * Local functions - * - no argument checks, all internal/trusted callers +/** + * + * hif_napi_update_yield_stats() - update NAPI yield related stats + * @cpu_id: CPU ID for which stats needs to be updates + * @ce_id: Copy Engine ID for which yield stats needs to be updates + * @time_limit_reached: indicates whether the time limit was reached + * @rxpkt_thresh_reached: indicates whether rx packet threshold was reached + * + * Return: None */ +void hif_napi_update_yield_stats(struct CE_state *ce_state, + bool time_limit_reached, + bool rxpkt_thresh_reached) +{ + struct hif_softc *hif; + struct qca_napi_data *napi_data = NULL; + int ce_id = 0; + int cpu_id = 0; + + if (unlikely(NULL == ce_state)) { + QDF_ASSERT(NULL != ce_state); + return; + } -#ifdef FEATURE_NAPI_DEBUG -static void hnc_dump_cpus(struct qca_napi_data *napid) + hif = ce_state->scn; + + if (unlikely(NULL == hif)) { + QDF_ASSERT(NULL != hif); + return; + } else { + napi_data = &(hif->napi_data); + if (unlikely(NULL == napi_data)) + QDF_ASSERT(NULL != napi_data); + return; + } + + ce_id = ce_state->id; + cpu_id = qdf_get_cpu(); + + if (time_limit_reached) + napi_data->napis[ce_id].stats[cpu_id].time_limit_reached++; + else + napi_data->napis[ce_id].stats[cpu_id].rxpkt_thresh_reached++; +} + +/** + * + * hif_napi_stats() - display NAPI CPU statistics + * @napid: pointer to qca_napi_data + * + * Description: + * Prints the various CPU cores on which the NAPI instances /CEs interrupts + * are being executed. Can be called from outside NAPI layer. + * + * Return: None + */ +void hif_napi_stats(struct qca_napi_data *napid) { int i; - struct qca_napi_cpu *cpu = napid->napi_cpu; + struct qca_napi_cpu *cpu; + + if (napid == NULL) { + qdf_print("%s: napiid struct is null", __func__); + return; + } - NAPI_DEBUG("%s: NAPI CPU TABLE", __func__); - NAPI_DEBUG("lilclhead=%d, bigclhead=%d", + cpu = napid->napi_cpu; + qdf_print("NAPI CPU TABLE"); + qdf_print("lilclhead=%d, bigclhead=%d", napid->lilcl_head, napid->bigcl_head); for (i = 0; i < NR_CPUS; i++) { - NAPI_DEBUG("CPU[%02d]: state:%d crid=%02d clid=%02d " + qdf_print("CPU[%02d]: state:%d crid=%02d clid=%02d " "crmk:0x%0lx thmk:0x%0lx frq:%d " "napi = 0x%08x lnk:%d", i, @@ -824,7 +880,16 @@ static void hnc_dump_cpus(struct qca_napi_data *napid) cpu[i].max_freq, cpu[i].napis, cpu[i].cluster_nxt); } - /* return; -- Linus does not like it, I do. */ +} + +#ifdef FEATURE_NAPI_DEBUG +/* + * Local functions + * - no argument checks, all internal/trusted callers + */ +static void hnc_dump_cpus(struct qca_napi_data *napid) +{ + hif_napi_stats(napid); } #else static void hnc_dump_cpus(struct qca_napi_data *napid) { /* no-op */ }; |
