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
This commit is contained in:
@@ -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 op_msg_type *msg = op_msg;
|
||||||
struct ipa_uc_fw_stats *uc_fw_stat;
|
struct ipa_uc_fw_stats *uc_fw_stat;
|
||||||
|
|
||||||
if (!op_msg) {
|
if (!ipa_ctx || !op_msg) {
|
||||||
ipa_err("INVALID ARG");
|
ipa_err("INVALID ARG");
|
||||||
return;
|
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");
|
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++) {
|
for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
|
||||||
ipa_ctx->uc_op_work[i].osdev = osdev;
|
ipa_ctx->uc_op_work[i].osdev = osdev;
|
||||||
qdf_create_work(0, &ipa_ctx->uc_op_work[i].work,
|
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;
|
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:
|
fail_return:
|
||||||
ipa_debug("exit: status=%d", status);
|
ipa_debug("exit: status=%d", status);
|
||||||
return 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);
|
wlan_ipa_cleanup_pending_event(ipa_ctx);
|
||||||
qdf_mutex_release(&ipa_ctx->ipa_lock);
|
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++) {
|
for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
|
||||||
qdf_cancel_work(&ipa_ctx->uc_op_work[i].work);
|
qdf_cancel_work(&ipa_ctx->uc_op_work[i].work);
|
||||||
qdf_mem_free(ipa_ctx->uc_op_work[i].msg);
|
qdf_mem_free(ipa_ctx->uc_op_work[i].msg);
|
||||||
|
Fai riferimento in un nuovo problema
Block a user