From 7e322d9e0988eab549e922c979519159dce6bf72 Mon Sep 17 00:00:00 2001 From: Abdul Muqtadeer Ahmed Date: Fri, 17 Dec 2021 17:21:58 +0530 Subject: [PATCH] qcacld-3.0: Move the sar req-resp event to work context In the process of sar req-resp event the timer callback will wait for the userspace response due to which time scheduler thread is paused and can't process any other message. Because of this there is delay and some command may fail. To address above issue, move the process of sar req-resp event to work context as we are waiting in the timer handler. Change-Id: Idadd99ff28dcb6f5ec2d925cb381f223124300e6 CRs-fixed: 3091293 --- core/hdd/inc/wlan_hdd_main.h | 2 +- core/hdd/src/wlan_hdd_sar_limits.c | 63 ++++++++++++++++-------------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index a129d5903766..e3ff6165781e 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2169,7 +2169,7 @@ struct hdd_context { struct sar_limit_cmd_params *sar_cmd_params; #ifdef SAR_SAFETY_FEATURE qdf_mc_timer_t sar_safety_timer; - qdf_mc_timer_t sar_safety_unsolicited_timer; + struct qdf_delayed_work sar_safety_unsolicited_work; qdf_event_t sar_safety_req_resp_event; qdf_atomic_t sar_safety_req_resp_event_in_progress; #endif diff --git a/core/hdd/src/wlan_hdd_sar_limits.c b/core/hdd/src/wlan_hdd_sar_limits.c index 5d6735db7b9c..e51ae8ac56ea 100644 --- a/core/hdd/src/wlan_hdd_sar_limits.c +++ b/core/hdd/src/wlan_hdd_sar_limits.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 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 @@ -993,14 +994,29 @@ static void hdd_send_sar_unsolicited_event(struct hdd_context *hdd_ctx) cfg80211_vendor_event(vendor_event, GFP_KERNEL); } -static void hdd_sar_unsolicited_timer_cb(void *user_data) +static void hdd_sar_unsolicited_work_cb(void *user_data) { struct hdd_context *hdd_ctx = (struct hdd_context *)user_data; uint8_t i = 0; QDF_STATUS status; + int errno; + struct osif_psoc_sync *psoc_sync; hdd_nofl_debug("Sar unsolicited timer expired"); + errno = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + + if (errno == -EAGAIN) { + hdd_nofl_debug("rescheduling sar unsolicited work"); + qdf_delayed_work_start(&hdd_ctx->sar_safety_unsolicited_work, + hdd_ctx->config->sar_safety_unsolicited_timeout); + + return; + } else if (errno) { + hdd_err("cannot handle sar unsolicited work"); + return; + } + qdf_atomic_set(&hdd_ctx->sar_safety_req_resp_event_in_progress, 1); for (i = 0; i < hdd_ctx->config->sar_safety_req_resp_retry; i++) { @@ -1017,6 +1033,8 @@ static void hdd_sar_unsolicited_timer_cb(void *user_data) if (i >= hdd_ctx->config->sar_safety_req_resp_retry) hdd_configure_sar_index(hdd_ctx, hdd_ctx->config->sar_safety_index); + + osif_psoc_sync_op_stop(psoc_sync); } static void hdd_sar_safety_timer_cb(void *user_data) @@ -1029,8 +1047,6 @@ static void hdd_sar_safety_timer_cb(void *user_data) void wlan_hdd_sar_unsolicited_timer_start(struct hdd_context *hdd_ctx) { - QDF_STATUS status; - if (!hdd_ctx->config->enable_sar_safety) return; @@ -1038,16 +1054,10 @@ void wlan_hdd_sar_unsolicited_timer_start(struct hdd_context *hdd_ctx) &hdd_ctx->sar_safety_req_resp_event_in_progress) > 0) return; - if (QDF_TIMER_STATE_RUNNING != - qdf_mc_timer_get_current_state( - &hdd_ctx->sar_safety_unsolicited_timer)) { - status = qdf_mc_timer_start( - &hdd_ctx->sar_safety_unsolicited_timer, - hdd_ctx->config->sar_safety_unsolicited_timeout); + qdf_delayed_work_start(&hdd_ctx->sar_safety_unsolicited_work, + hdd_ctx->config->sar_safety_unsolicited_timeout); - if (QDF_IS_STATUS_SUCCESS(status)) - hdd_nofl_debug("sar unsolicited timer started"); - } + hdd_nofl_debug("sar safety unsolicited work started"); } void wlan_hdd_sar_timers_reset(struct hdd_context *hdd_ctx) @@ -1072,20 +1082,16 @@ void wlan_hdd_sar_timers_reset(struct hdd_context *hdd_ctx) if (QDF_IS_STATUS_SUCCESS(status)) hdd_nofl_debug("sar safety timer started"); - if (QDF_TIMER_STATE_RUNNING == - qdf_mc_timer_get_current_state( - &hdd_ctx->sar_safety_unsolicited_timer)) { - status = qdf_mc_timer_stop( - &hdd_ctx->sar_safety_unsolicited_timer); - if (QDF_IS_STATUS_SUCCESS(status)) - hdd_nofl_debug("sar unsolicited timer stopped"); - } + qdf_delayed_work_stop_sync(&hdd_ctx->sar_safety_unsolicited_work); + hdd_nofl_debug("sar safety unsolicited work stopped"); qdf_event_set(&hdd_ctx->sar_safety_req_resp_event); } void wlan_hdd_sar_timers_init(struct hdd_context *hdd_ctx) { + QDF_STATUS status; + if (!hdd_ctx->config->enable_sar_safety) return; @@ -1094,9 +1100,13 @@ void wlan_hdd_sar_timers_init(struct hdd_context *hdd_ctx) qdf_mc_timer_init(&hdd_ctx->sar_safety_timer, QDF_TIMER_TYPE_SW, hdd_sar_safety_timer_cb, hdd_ctx); - qdf_mc_timer_init(&hdd_ctx->sar_safety_unsolicited_timer, - QDF_TIMER_TYPE_SW, - hdd_sar_unsolicited_timer_cb, hdd_ctx); + status = qdf_delayed_work_create(&hdd_ctx->sar_safety_unsolicited_work, + hdd_sar_unsolicited_work_cb, + hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("failed to create sar safety unsolicited work"); + return; + } qdf_atomic_init(&hdd_ctx->sar_safety_req_resp_event_in_progress); qdf_event_create(&hdd_ctx->sar_safety_req_resp_event); @@ -1117,12 +1127,7 @@ void wlan_hdd_sar_timers_deinit(struct hdd_context *hdd_ctx) qdf_mc_timer_destroy(&hdd_ctx->sar_safety_timer); - if (QDF_TIMER_STATE_RUNNING == - qdf_mc_timer_get_current_state( - &hdd_ctx->sar_safety_unsolicited_timer)) - qdf_mc_timer_stop(&hdd_ctx->sar_safety_unsolicited_timer); - - qdf_mc_timer_destroy(&hdd_ctx->sar_safety_unsolicited_timer); + qdf_delayed_work_destroy(&hdd_ctx->sar_safety_unsolicited_work); qdf_event_destroy(&hdd_ctx->sar_safety_req_resp_event);