From 785b8450b5a983f27208ccf95a44845214556398 Mon Sep 17 00:00:00 2001 From: Rakshith Suresh Patkar Date: Mon, 18 Mar 2019 13:36:02 +0530 Subject: [PATCH] qcacld-3.0: Add flag for ipa pipes_down_in_progress ipa disable pipes request is honoured based on ipa_pipes_down flag. However, there is a possible synchronization issue if disable pipes request is initiated from different contexts, as there is no locking to protect this flag. Add pipes_down_in_progress flag in ipa_ctx and use this flag to ignore disable pipes requests if one request is already in progress. Change-Id: Iabf01249d4b6a551e03cea2ae96a0c6096f43ff8 CRs-Fixed: 2423155 --- components/ipa/core/inc/wlan_ipa_priv.h | 3 +++ components/ipa/core/src/wlan_ipa_core.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index 5e4824596153b..f36f4aa8c2f2b 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/components/ipa/core/inc/wlan_ipa_priv.h @@ -599,6 +599,9 @@ struct wlan_ipa_priv { qdf_spinlock_t q_lock; + qdf_spinlock_t pipes_down_lock; + bool pipes_down_in_progress; + qdf_list_node_t pend_desc_head; struct wlan_ipa_tx_desc *tx_desc_pool; qdf_list_t tx_desc_free_list; diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index c0277c815215f..56672492fc619 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -1052,6 +1052,15 @@ QDF_STATUS wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx) goto end; } + qdf_spin_lock_bh(&ipa_ctx->pipes_down_lock); + if (ipa_ctx->pipes_down_in_progress || ipa_ctx->ipa_pipes_down) { + ipa_warn("IPA WDI Pipes down already in progress"); + qdf_spin_unlock_bh(&ipa_ctx->pipes_down_lock); + return QDF_STATUS_E_ALREADY; + } + ipa_ctx->pipes_down_in_progress = true; + qdf_spin_unlock_bh(&ipa_ctx->pipes_down_lock); + cdp_ipa_disable_autonomy(ipa_ctx->dp_soc, ipa_ctx->dp_pdev); @@ -1059,10 +1068,12 @@ QDF_STATUS wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx) ipa_ctx->dp_pdev); if (result) { ipa_err("Disable IPA WDI PIPE failed: ret=%d", result); + ipa_ctx->pipes_down_in_progress = false; return QDF_STATUS_E_FAILURE; } ipa_ctx->ipa_pipes_down = true; + ipa_ctx->pipes_down_in_progress = false; end: ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down); @@ -2517,6 +2528,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, qdf_create_work(0, &ipa_ctx->pm_work, wlan_ipa_pm_flush, ipa_ctx); qdf_spinlock_create(&ipa_ctx->pm_lock); qdf_spinlock_create(&ipa_ctx->q_lock); + qdf_spinlock_create(&ipa_ctx->pipes_down_lock); qdf_nbuf_queue_init(&ipa_ctx->pm_queue_head); qdf_list_create(&ipa_ctx->pending_event, 1000); qdf_mutex_create(&ipa_ctx->event_lock); @@ -2541,6 +2553,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->resource_unloading = false; ipa_ctx->sta_connected = 0; ipa_ctx->ipa_pipes_down = true; + ipa_ctx->pipes_down_in_progress = false; ipa_ctx->wdi_enabled = false; /* Setup IPA system pipes */ if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { @@ -2577,6 +2590,7 @@ fail_create_sys_pipe: fail_setup_rm: qdf_spinlock_destroy(&ipa_ctx->pm_lock); qdf_spinlock_destroy(&ipa_ctx->q_lock); + qdf_spinlock_destroy(&ipa_ctx->pipes_down_lock); for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { iface_context = &ipa_ctx->iface_context[i]; qdf_spinlock_destroy(&iface_context->interface_lock); @@ -2640,6 +2654,7 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) qdf_spinlock_destroy(&ipa_ctx->pm_lock); qdf_spinlock_destroy(&ipa_ctx->q_lock); + qdf_spinlock_destroy(&ipa_ctx->pipes_down_lock); /* destroy the interface lock */ for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {