From 161b9f298a7657703e265a1091ff4ab56c6abce7 Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Mon, 24 Jul 2017 17:38:09 -0700 Subject: [PATCH] qcacld-3.0: Schedule work for cds_trigger_recovery() in atomic ctx Currently wherever cds_trigger_recovery() is called in atomic context, work is being scheduled. This change is to modify cds_trigger_recovery() itself detect that it is being called in atomic context and then itself schedule work to its own handler. Change-Id: Id37e97c9b838ad18c355234aa13f2b9c05503029 CRs-Fixed: 2081666 --- core/cds/inc/cds_sched.h | 2 ++ core/cds/src/cds_api.c | 57 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index e07edbb2b3e5..7075bda6e8b2 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -228,6 +228,8 @@ typedef struct _cds_context_type { struct cds_config_info *cds_cfg; struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM]; + qdf_work_t cds_recovery_work; + qdf_workqueue_t *cds_recovery_wq; } cds_context_type, *p_cds_contextType; /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 315789855658..201dc7ba01e9 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -85,6 +85,39 @@ static struct ol_if_ops dp_ol_if_ops = { }; void cds_sys_probe_thread_cback(void *pUserData); +static void cds_trigger_recovery_work(void *param); + +/** + * cds_recovery_work_init() - Initialize recovery work queue + * + * Return: none + */ +static QDF_STATUS cds_recovery_work_init(void) +{ + qdf_create_work(0, &gp_cds_context->cds_recovery_work, + cds_trigger_recovery_work, NULL); + gp_cds_context->cds_recovery_wq = + qdf_create_workqueue("cds_recovery_workqueue"); + if (NULL == gp_cds_context->cds_recovery_wq) { + cds_err("Failed to create cds_recovery_workqueue"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * cds_recovery_work_deinit() - Initialize recovery work queue + * + * Return: none + */ +static void cds_recovery_work_deinit(void) +{ + if (gp_cds_context->cds_recovery_wq) { + qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq); + qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq); + } +} /** cds_get_datapath_handles - Initialize pdev, vdev and soc * @soc - soc handle @@ -154,6 +187,8 @@ v_CONTEXT_t cds_init(void) cds_ssr_protect_init(); + cds_recovery_work_init(); + return gp_cds_context; } @@ -167,6 +202,7 @@ void cds_deinit(void) if (gp_cds_context == NULL) return; + cds_recovery_work_deinit(); qdf_mc_timer_manager_exit(); qdf_mem_exit(); qdf_lock_stats_deinit(); @@ -1794,11 +1830,11 @@ static QDF_STATUS cds_force_assert_target(qdf_device_t qdf) } /** - * cds_trigger_recovery() - trigger self recovery + * cds_trigger_recovery_work() - trigger self recovery work * * Return: none */ -void cds_trigger_recovery(void) +static void cds_trigger_recovery_work(void *param) { QDF_STATUS status; qdf_runtime_lock_t rtl; @@ -1823,7 +1859,7 @@ void cds_trigger_recovery(void) status = qdf_runtime_lock_init(&rtl); if (QDF_IS_STATUS_ERROR(status)) { - cds_err("Failed to initialize runtime pm lock"); + cds_err("qdf_runtime_lock_init failed, status: %d", status); return; } @@ -1843,6 +1879,21 @@ deinit_rtl: qdf_runtime_lock_deinit(&rtl); } +/** + * cds_trigger_recovery() - trigger self recovery + * + * Return: none + */ +void cds_trigger_recovery(void) +{ + if (in_atomic()) { + qdf_queue_work(0, gp_cds_context->cds_recovery_wq, + &gp_cds_context->cds_recovery_work); + return; + } + cds_trigger_recovery_work(NULL); +} + /** * cds_get_monotonic_boottime() - Get kernel boot time. *