From bbe449f21806ea56a45a038bffdc04529ea1ac3a Mon Sep 17 00:00:00 2001 From: Ananya Gupta Date: Fri, 9 Oct 2020 22:03:58 +0530 Subject: [PATCH] qcacld-3.0: Call cdp function to deregister IPA handler from pdev A htt message arrived after ipa context is freed as part of deinitialization which was dereferenced by event handler assigned to pdev->ipa_uc_op_cb, resulting in crash. To fix this, cdp function is called during deinit to deregister pdev->ipa_uc_op_cb and assign it NULL. Also, adding NULL check in wlan_ipa_uc_op_cb. Also, registering ipa_uc_op_cb after work is created so as to not hit condition where work is scheduled before creation. Change-Id: Ib79136b1122625079d8173a401dba5516126c621 CRs-Fixed: 2794663 --- components/ipa/core/src/wlan_ipa_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 32c6aee8fd..a803ad26cc 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -3502,7 +3502,7 @@ static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg, struct op_msg_type *msg = op_msg; struct ipa_uc_fw_stats *uc_fw_stat; - if (!op_msg) { + if (!ipa_ctx || !op_msg) { ipa_err("INVALID ARG"); return; } @@ -3731,9 +3731,6 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx, ipa_err("Failed to init perf level"); } - cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, - wlan_ipa_uc_op_event_handler, (void *)ipa_ctx); - for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { ipa_ctx->uc_op_work[i].osdev = osdev; qdf_create_work(0, &ipa_ctx->uc_op_work[i].work, @@ -3742,6 +3739,8 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->uc_op_work[i].msg = NULL; } + cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, + wlan_ipa_uc_op_event_handler, (void *)ipa_ctx); fail_return: ipa_debug("exit: status=%d", status); return status; @@ -3790,6 +3789,8 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) wlan_ipa_cleanup_pending_event(ipa_ctx); qdf_mutex_release(&ipa_ctx->ipa_lock); + cdp_ipa_deregister_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); + for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { qdf_cancel_work(&ipa_ctx->uc_op_work[i].work); qdf_mem_free(ipa_ctx->uc_op_work[i].msg);