diff options
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 4 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 69 |
2 files changed, 56 insertions, 17 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 2387be03a9fc..3a2756da823d 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1434,7 +1434,9 @@ struct hdd_context_s { #ifdef MSM_PLATFORM /* DDR bus bandwidth compute timer */ - qdf_mc_timer_t bus_bw_timer; + qdf_timer_t bus_bw_timer; + bool bus_bw_timer_started; + struct work_struct bus_bw_work; int cur_vote_level; spinlock_t bus_bw_lock; int cur_rx_level; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5a4b7595faa0..a53035f84264 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3384,6 +3384,8 @@ QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, } adapterNode = pCurrent; if (QDF_STATUS_SUCCESS == status) { + hdd_info("wait for bus bw work to flush"); + cancel_work_sync(&hdd_ctx->bus_bw_work); cds_clear_concurrency_mode(adapter->device_mode); hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held); @@ -5401,9 +5403,10 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, } #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) -static void hdd_bus_bw_compute_cbk(void *priv) +static void hdd_bus_bw_work_handler(struct work_struct *work) { - hdd_context_t *hdd_ctx = (hdd_context_t *) priv; + hdd_context_t *hdd_ctx = container_of(work, hdd_context_t, + bus_bw_work); hdd_adapter_t *adapter = NULL; uint64_t tx_packets = 0, rx_packets = 0; uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0; @@ -5500,28 +5503,62 @@ static void hdd_bus_bw_compute_cbk(void *priv) hdd_ipa_set_perf_level(hdd_ctx, tx_packets, rx_packets); hdd_ipa_uc_stat_request(adapter, 2); - qdf_mc_timer_start(&hdd_ctx->bus_bw_timer, + qdf_timer_start(&hdd_ctx->bus_bw_timer, hdd_ctx->config->busBandwidthComputeInterval); } +/** + * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback. + * @arg: Argument of timer function + * + * Schedule a workqueue in this function where all the processing is done. + * + * Return: None. + */ +static void __hdd_bus_bw_cbk(void *arg) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *) arg; + + if (wlan_hdd_validate_context(hdd_ctx)) + return; + + schedule_work(&hdd_ctx->bus_bw_work); +} + +/** + * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection. + * @arg: Argument of timer function + * + * Return: None. + */ +static void hdd_bus_bw_cbk(void *arg) +{ + cds_ssr_protect(__func__); + __hdd_bus_bw_cbk(arg); + cds_ssr_unprotect(__func__); +} + int hdd_bus_bandwidth_init(hdd_context_t *hdd_ctx) { spin_lock_init(&hdd_ctx->bus_bw_lock); - - qdf_mc_timer_init(&hdd_ctx->bus_bw_timer, - QDF_TIMER_TYPE_SW, - hdd_bus_bw_compute_cbk, (void *)hdd_ctx); + INIT_WORK(&hdd_ctx->bus_bw_work, + hdd_bus_bw_work_handler); + qdf_timer_init(NULL, + &hdd_ctx->bus_bw_timer, + hdd_bus_bw_cbk, (void *)hdd_ctx, + QDF_TIMER_TYPE_SW); return 0; } void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx) { - if (qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer) == - QDF_TIMER_STATE_RUNNING) + if (hdd_ctx->bus_bw_timer_started) hdd_reset_tcp_delack(hdd_ctx); - qdf_mc_timer_destroy(&hdd_ctx->bus_bw_timer); + hdd_info("wait for bus bw work to flush"); + cancel_work_sync(&hdd_ctx->bus_bw_work); + qdf_timer_free(&hdd_ctx->bus_bw_timer); } #endif @@ -8881,11 +8918,11 @@ void hdd_start_bus_bw_compute_timer(hdd_adapter_t *adapter) { hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (QDF_TIMER_STATE_RUNNING == - qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) + if (hdd_ctx->bus_bw_timer_started) return; - qdf_mc_timer_start(&hdd_ctx->bus_bw_timer, + hdd_ctx->bus_bw_timer_started = true; + qdf_timer_start(&hdd_ctx->bus_bw_timer, hdd_ctx->config->busBandwidthComputeInterval); } @@ -8896,8 +8933,7 @@ void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *adapter) bool can_stop = true; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (QDF_TIMER_STATE_RUNNING != - qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) { + if (!hdd_ctx->bus_bw_timer_started) { /* trying to stop timer, when not running is not good */ hdd_info("bus band width compute timer is not running"); return; @@ -8935,7 +8971,8 @@ void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *adapter) if (can_stop == true) { /* reset the ipa perf level */ hdd_ipa_set_perf_level(hdd_ctx, 0, 0); - qdf_mc_timer_stop(&hdd_ctx->bus_bw_timer); + qdf_timer_stop(&hdd_ctx->bus_bw_timer); + hdd_ctx->bus_bw_timer_started = false; hdd_reset_tcp_delack(hdd_ctx); } } |
