diff options
| author | Himanshu Agarwal <himanaga@codeaurora.org> | 2017-05-23 11:06:12 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-07-04 23:35:07 -0700 |
| commit | e59ad92715dd39a2443c80a7bc58d30810d95e71 (patch) | |
| tree | 8db5fdaca5ca9bf99b597e740c750efa9c8706d4 | |
| parent | 90cd8b4e9e48c6db7ff1699b5bcfd7070bfe5544 (diff) | |
qcacmn: Add APIs to set/get ce service max yield time
Add APIs to set/get ce service max yield time and update
max time taken in NAPI poll from the driver load time.
Change-Id: Idfd4a271ce13916f188c92ab3af32e1648f48c95
CRs-Fixed: 2055082
| -rw-r--r-- | hif/inc/hif.h | 25 | ||||
| -rw-r--r-- | hif/inc/hif_napi.h | 14 | ||||
| -rw-r--r-- | hif/src/ce/ce_internal.h | 2 | ||||
| -rw-r--r-- | hif/src/ce/ce_service.c | 16 | ||||
| -rw-r--r-- | hif/src/hif_main.c | 17 | ||||
| -rw-r--r-- | hif/src/hif_main.h | 2 | ||||
| -rw-r--r-- | hif/src/hif_napi.c | 24 |
7 files changed, 89 insertions, 11 deletions
diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 5ca4b353e99f..374a720b552d 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -126,6 +126,7 @@ struct qca_napi_stat { uint32_t napi_budget_uses[QCA_NAPI_NUM_BUCKETS]; uint32_t time_limit_reached; uint32_t rxpkt_thresh_reached; + unsigned long long napi_max_poll_time; }; /** @@ -755,4 +756,28 @@ hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx, } #endif +/** + * hif_set_ce_service_max_yield_time() - sets CE service max yield time + * @hif: hif context + * @ce_service_max_yield_time: CE service max yield time to set + * + * This API storess CE service max yield time in hif context based + * on ini value. + * + * Return: void + */ +void hif_set_ce_service_max_yield_time(struct hif_opaque_softc *hif, + uint8_t ce_service_max_yield_time); + +/** + * hif_get_ce_service_max_yield_time() - get CE service max yield time + * @hif: hif context + * + * This API returns CE service max yield time. + * + * Return: CE service max yield time + */ +unsigned long long +hif_get_ce_service_max_yield_time(struct hif_opaque_softc *hif); + #endif /* _HIF_H_ */ diff --git a/hif/inc/hif_napi.h b/hif/inc/hif_napi.h index f682ca0c6c8e..de511e0bb8c6 100644 --- a/hif/inc/hif_napi.h +++ b/hif/inc/hif_napi.h @@ -262,4 +262,18 @@ static inline void hif_napi_stats(struct qca_napi_data *napid) { } #endif /* FEATURE_NAPI */ +/** + * hif_update_napi_max_poll_time() - updates NAPI max poll time + * @ce_state: ce state + * @napi_info: pointer to napi info structure + * @cpu_id: cpu id + * + * This API updates NAPI max poll time per CE per SPU. + * + * Return: void + */ +void hif_update_napi_max_poll_time(struct CE_state *ce_state, + struct qca_napi_info *napi_info, + int cpu_id); + #endif /* __HIF_NAPI_H__ */ diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h index 4a9592e6481d..137e5f9a87ef 100644 --- a/hif/src/ce/ce_internal.h +++ b/hif/src/ce/ce_internal.h @@ -139,6 +139,8 @@ struct CE_state { /* time in nanoseconds to yield control of napi poll */ unsigned long long ce_service_yield_time; + /* CE service start time in nanoseconds */ + unsigned long long ce_service_start_time; /* Num Of Receive Buffers handled for one interrupt DPC routine */ unsigned int receive_count; /* epping */ diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index af4d8d7f8868..9a727c103ef9 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -1788,6 +1788,10 @@ more_data: more_comp_cnt = 0; goto more_data; } + + hif_update_napi_max_poll_time(ce_state, scn->napi_data.napis[ce_id], + qdf_get_cpu()); + qdf_atomic_set(&ce_state->rx_pending, 0); if (TARGET_REGISTER_ACCESS_ALLOW(scn)) { CE_ENGINE_INT_STATUS_CLEAR(scn, ctrl_addr, @@ -1815,11 +1819,6 @@ static void ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) } #endif /* WLAN_FEATURE_FASTPATH */ -/* Maximum amount of time in nano seconds before which the CE per engine service - * should yield. ~1 jiffie. - */ -#define CE_PER_ENGINE_SERVICE_MAX_YIELD_TIME_NS (10 * 1000 * 1000) - /* * Guts of interrupt handler for per-engine interrupts on a particular CE. * @@ -1856,10 +1855,11 @@ int ce_per_engine_service(struct hif_softc *scn, unsigned int CE_id) /* Clear force_break flag and re-initialize receive_count to 0 */ CE_state->receive_count = 0; CE_state->force_break = 0; + CE_state->ce_service_start_time = sched_clock(); CE_state->ce_service_yield_time = - sched_clock() + - (unsigned long long)CE_PER_ENGINE_SERVICE_MAX_YIELD_TIME_NS; - + CE_state->ce_service_start_time + + hif_get_ce_service_max_yield_time( + (struct hif_opaque_softc *)scn); qdf_spin_lock(&CE_state->ce_index_lock); /* diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index 39b403411cc4..e2a2426bfe94 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -1123,3 +1123,20 @@ void hif_ramdump_handler(struct hif_opaque_softc *scn) hif_usb_ramdump_handler(); } #endif + +void hif_set_ce_service_max_yield_time(struct hif_opaque_softc *hif, + uint8_t ce_service_max_yield_time) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif); + + hif_ctx->ce_service_max_yield_time = + ce_service_max_yield_time * 1000 * 1000; +} + +unsigned long long +hif_get_ce_service_max_yield_time(struct hif_opaque_softc *hif) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif); + + return hif_ctx->ce_service_max_yield_time; +} diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 8f49e4cbeeba..81963f47f06e 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -157,6 +157,8 @@ struct hif_softc { #ifdef FEATURE_NAPI struct qca_napi_data napi_data; #endif /* FEATURE_NAPI */ + /* stores ce_service_max_yield_time in ns */ + unsigned long long ce_service_max_yield_time; struct hif_driver_state_callbacks callbacks; uint32_t hif_con_param; #ifdef QCA_NSS_WIFI_OFFLOAD_SUPPORT diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c index 03699b625715..946699f6f9b7 100644 --- a/hif/src/hif_napi.c +++ b/hif/src/hif_napi.c @@ -917,6 +917,18 @@ out: return rc; } +void hif_update_napi_max_poll_time(struct CE_state *ce_state, + struct qca_napi_info *napi_info, + int cpu_id) +{ + unsigned long long napi_poll_time = sched_clock() - + ce_state->ce_service_start_time; + + if (napi_poll_time > + napi_info->stats[cpu_id].napi_max_poll_time) + napi_info->stats[cpu_id].napi_max_poll_time = napi_poll_time; +} + #ifdef HELIUMPLUS /** * @@ -954,16 +966,22 @@ void hif_napi_update_yield_stats(struct CE_state *ce_state, return; } - if (unlikely(NULL == napi_data->napis[ce_id])) - return; - ce_id = ce_state->id; cpu_id = qdf_get_cpu(); + if (unlikely(!napi_data->napis[ce_id])) { + HIF_INFO("%s: NAPI info is NULL for ce id: %d", + __func__, ce_id); + return; + } + 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_update_napi_max_poll_time(ce_state, napi_data->napis[ce_id], + cpu_id); } /** |
