qcacld-3.0: Fix uc_op_work->msg leak from uC ready callback
Do not schedule uc_op_work inside uC ready callback, when the uc_op_work is not initialized. So, if the uC ready callback is invoked before hdd_ipa_ol_init(), just set uc_loaded flag and return, without scheduling uc_op_work. Change-Id: I9c813047ab4b1b129e4fb057d8aacbef5cc9efea CRs-Fixed: 2169668
This commit is contained in:
@@ -577,6 +577,14 @@ static void hdd_ipa_uc_loaded_uc_cb(void *priv_ctxt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdd_ipa = (struct hdd_ipa_priv *)priv_ctxt;
|
hdd_ipa = (struct hdd_ipa_priv *)priv_ctxt;
|
||||||
|
hdd_ipa->uc_loaded = true;
|
||||||
|
|
||||||
|
uc_op_work = &hdd_ipa->uc_op_work[HDD_IPA_UC_OPCODE_UC_READY];
|
||||||
|
|
||||||
|
if (!list_empty(&uc_op_work->work.entry))
|
||||||
|
/* uc_op_work is not initialized yet */
|
||||||
|
return;
|
||||||
|
|
||||||
msg = (struct op_msg_type *)qdf_mem_malloc(sizeof(*msg));
|
msg = (struct op_msg_type *)qdf_mem_malloc(sizeof(*msg));
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "op_msg allocation fails");
|
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "op_msg allocation fails");
|
||||||
@@ -585,8 +593,6 @@ static void hdd_ipa_uc_loaded_uc_cb(void *priv_ctxt)
|
|||||||
|
|
||||||
msg->op_code = HDD_IPA_UC_OPCODE_UC_READY;
|
msg->op_code = HDD_IPA_UC_OPCODE_UC_READY;
|
||||||
|
|
||||||
uc_op_work = &hdd_ipa->uc_op_work[msg->op_code];
|
|
||||||
|
|
||||||
/* When the same uC OPCODE is already pended, just return */
|
/* When the same uC OPCODE is already pended, just return */
|
||||||
if (uc_op_work->msg)
|
if (uc_op_work->msg)
|
||||||
goto done;
|
goto done;
|
||||||
@@ -2141,7 +2147,6 @@ static void hdd_ipa_uc_loaded_handler(struct hdd_ipa_priv *hdd_ipa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdd_ctx = hdd_ipa->hdd_ctx;
|
hdd_ctx = hdd_ipa->hdd_ctx;
|
||||||
hdd_ipa->uc_loaded = true;
|
|
||||||
|
|
||||||
/* Connect pipe */
|
/* Connect pipe */
|
||||||
status = cdp_ipa_setup(soc, (struct cdp_pdev *)pdev,
|
status = cdp_ipa_setup(soc, (struct cdp_pdev *)pdev,
|
||||||
@@ -3194,7 +3199,7 @@ static void hdd_ipa_cleanup_pending_event(struct hdd_ipa_priv *hdd_ipa)
|
|||||||
int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx)
|
int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx)
|
||||||
{
|
{
|
||||||
struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa;
|
struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa;
|
||||||
int ret = 0;
|
int i, ret = 0;
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
|
|
||||||
HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "enter");
|
HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "enter");
|
||||||
@@ -3213,7 +3218,7 @@ int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx)
|
|||||||
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
|
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||||
"Failure to cleanup IPA pipes (status=%d)",
|
"Failure to cleanup IPA pipes (status=%d)",
|
||||||
status);
|
status);
|
||||||
return -EFAULT;
|
ret = -EFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3221,6 +3226,12 @@ int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx)
|
|||||||
hdd_ipa_cleanup_pending_event(hdd_ipa);
|
hdd_ipa_cleanup_pending_event(hdd_ipa);
|
||||||
qdf_mutex_release(&hdd_ipa->ipa_lock);
|
qdf_mutex_release(&hdd_ipa->ipa_lock);
|
||||||
|
|
||||||
|
for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) {
|
||||||
|
cancel_work_sync(&hdd_ipa->uc_op_work[i].work);
|
||||||
|
qdf_mem_free(hdd_ipa->uc_op_work[i].msg);
|
||||||
|
hdd_ipa->uc_op_work[i].msg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "exit: ret=%d", ret);
|
HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "exit: ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -6091,6 +6102,7 @@ static QDF_STATUS __hdd_ipa_cleanup(struct hdd_context *hdd_ctx)
|
|||||||
|
|
||||||
for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) {
|
for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) {
|
||||||
cancel_work_sync(&hdd_ipa->uc_op_work[i].work);
|
cancel_work_sync(&hdd_ipa->uc_op_work[i].work);
|
||||||
|
qdf_mem_free(hdd_ipa->uc_op_work[i].msg);
|
||||||
hdd_ipa->uc_op_work[i].msg = NULL;
|
hdd_ipa->uc_op_work[i].msg = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user