mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
Merge "msm: npu: fix network and misc commands race condition problem"
This commit is contained in:
commit
7fbe930d38
2 changed files with 50 additions and 22 deletions
|
|
@ -292,9 +292,8 @@ int npu_host_init(struct npu_device *npu_dev)
|
|||
struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
|
||||
|
||||
memset(host_ctx, 0, sizeof(*host_ctx));
|
||||
init_completion(&host_ctx->loopback_done);
|
||||
init_completion(&host_ctx->misc_done);
|
||||
init_completion(&host_ctx->fw_deinit_done);
|
||||
init_completion(&host_ctx->property_done);
|
||||
mutex_init(&host_ctx->lock);
|
||||
atomic_set(&host_ctx->ipc_trans_id, 1);
|
||||
host_ctx->npu_dev = npu_dev;
|
||||
|
|
@ -308,6 +307,8 @@ int npu_host_init(struct npu_device *npu_dev)
|
|||
if (!host_ctx->prop_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
host_ctx->misc_pending = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -368,6 +369,7 @@ static int host_error_hdlr(struct npu_device *npu_dev, bool force)
|
|||
network = &host_ctx->networks[i];
|
||||
if (network->is_valid && network->cmd_pending &&
|
||||
network->fw_error) {
|
||||
network->cmd_pending = false;
|
||||
if (network->cmd_async) {
|
||||
pr_debug("async cmd, queue ssr event\n");
|
||||
kevt.evt.type = MSM_NPU_EVENT_TYPE_SSR;
|
||||
|
|
@ -382,7 +384,8 @@ static int host_error_hdlr(struct npu_device *npu_dev, bool force)
|
|||
}
|
||||
}
|
||||
}
|
||||
complete_all(&host_ctx->loopback_done);
|
||||
host_ctx->misc_pending = false;
|
||||
complete_all(&host_ctx->misc_done);
|
||||
mutex_unlock(&host_ctx->lock);
|
||||
|
||||
return 1;
|
||||
|
|
@ -927,7 +930,9 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg)
|
|||
|
||||
pr_debug("NPU_IPC_MSG_LOOPBACK_DONE loopbackParams: 0x%x\n",
|
||||
lb_rsp_pkt->loopbackParams);
|
||||
complete_all(&host_ctx->loopback_done);
|
||||
host_ctx->misc_pending = false;
|
||||
|
||||
complete_all(&host_ctx->misc_done);
|
||||
break;
|
||||
}
|
||||
case NPU_IPC_MSG_SET_PROPERTY_DONE:
|
||||
|
|
@ -942,8 +947,9 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg)
|
|||
param[0]);
|
||||
|
||||
host_ctx->cmd_ret_status = prop_rsp_pkt->header.status;
|
||||
host_ctx->misc_pending = false;
|
||||
|
||||
complete_all(&host_ctx->property_done);
|
||||
complete_all(&host_ctx->misc_done);
|
||||
break;
|
||||
}
|
||||
case NPU_IPC_MSG_GET_PROPERTY_DONE:
|
||||
|
|
@ -968,8 +974,9 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg)
|
|||
sizeof(struct ipc_msg_header_pkt);
|
||||
memcpy(host_ctx->prop_buf, prop_data, prop_size);
|
||||
}
|
||||
host_ctx->misc_pending = false;
|
||||
|
||||
complete_all(&host_ctx->property_done);
|
||||
complete_all(&host_ctx->misc_done);
|
||||
break;
|
||||
}
|
||||
case NPU_IPC_MSG_GENERAL_NOTIFY:
|
||||
|
|
@ -1143,7 +1150,7 @@ static int npu_send_network_cmd(struct npu_device *npu_dev,
|
|||
network->cmd_async = async;
|
||||
network->cmd_ret_status = 0;
|
||||
network->cmd_pending = true;
|
||||
network->trans_id = atomic_read(&host_ctx->ipc_trans_id);
|
||||
network->trans_id = ((struct ipc_cmd_header_pkt *)cmd_ptr)->trans_id;
|
||||
ret = npu_host_ipc_send_cmd(npu_dev,
|
||||
IPC_QUEUE_APPS_EXEC, cmd_ptr);
|
||||
if (ret)
|
||||
|
|
@ -1163,11 +1170,18 @@ static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx,
|
|||
if (host_ctx->fw_error || (host_ctx->fw_state == FW_DISABLED)) {
|
||||
pr_err("fw is in error state or disabled, can't send misc cmd\n");
|
||||
ret = -EIO;
|
||||
} else if (host_ctx->misc_pending) {
|
||||
pr_err("Another misc cmd is pending\n");
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
pr_debug("Send cmd %d\n",
|
||||
((struct ipc_cmd_header_pkt *)cmd_ptr)->cmd_type);
|
||||
host_ctx->cmd_ret_status = 0;
|
||||
reinit_completion(&host_ctx->misc_done);
|
||||
host_ctx->misc_pending = true;
|
||||
ret = npu_host_ipc_send_cmd(npu_dev, q_idx, cmd_ptr);
|
||||
if (ret)
|
||||
host_ctx->misc_pending = false;
|
||||
}
|
||||
mutex_unlock(&host_ctx->lock);
|
||||
|
||||
|
|
@ -1306,6 +1320,12 @@ int32_t npu_host_set_fw_property(struct npu_device *npu_dev,
|
|||
goto set_prop_exit;
|
||||
}
|
||||
|
||||
ret = fw_init(npu_dev);
|
||||
if (ret) {
|
||||
pr_err("fw_init fail\n");
|
||||
goto set_prop_exit;
|
||||
}
|
||||
|
||||
prop_packet->header.cmd_type = NPU_IPC_CMD_SET_PROPERTY;
|
||||
prop_packet->header.size = pkt_size;
|
||||
prop_packet->header.trans_id =
|
||||
|
|
@ -1318,34 +1338,36 @@ int32_t npu_host_set_fw_property(struct npu_device *npu_dev,
|
|||
for (i = 0; i < num_of_params; i++)
|
||||
prop_packet->prop_param[i] = property->prop_param[i];
|
||||
|
||||
reinit_completion(&host_ctx->property_done);
|
||||
ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC,
|
||||
prop_packet);
|
||||
|
||||
pr_debug("NPU_IPC_CMD_SET_PROPERTY sent status: %d\n", ret);
|
||||
|
||||
if (ret) {
|
||||
pr_err("NPU_IPC_CMD_SET_PROPERTY failed\n");
|
||||
goto set_prop_exit;
|
||||
goto deinit_fw;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(
|
||||
&host_ctx->property_done,
|
||||
&host_ctx->misc_done,
|
||||
(host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ?
|
||||
NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT);
|
||||
|
||||
if (!ret) {
|
||||
pr_err_ratelimited("npu: NPU_IPC_CMD_SET_PROPERTY time out\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto set_prop_exit;
|
||||
goto deinit_fw;
|
||||
} else if (ret < 0) {
|
||||
pr_err("Wait for set_property done interrupted by signal\n");
|
||||
goto set_prop_exit;
|
||||
goto deinit_fw;
|
||||
}
|
||||
|
||||
ret = host_ctx->cmd_ret_status;
|
||||
if (ret)
|
||||
pr_err("set fw property failed %d\n", ret);
|
||||
|
||||
deinit_fw:
|
||||
fw_deinit(npu_dev, false, true);
|
||||
set_prop_exit:
|
||||
kfree(prop_packet);
|
||||
return ret;
|
||||
|
|
@ -1368,6 +1390,12 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
|
|||
if (!prop_packet)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = fw_init(npu_dev);
|
||||
if (ret) {
|
||||
pr_err("fw_init fail\n");
|
||||
goto get_prop_exit;
|
||||
}
|
||||
|
||||
prop_packet->header.cmd_type = NPU_IPC_CMD_GET_PROPERTY;
|
||||
prop_packet->header.size = pkt_size;
|
||||
prop_packet->header.trans_id =
|
||||
|
|
@ -1380,28 +1408,27 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
|
|||
for (i = 0; i < num_of_params; i++)
|
||||
prop_packet->prop_param[i] = property->prop_param[i];
|
||||
|
||||
reinit_completion(&host_ctx->property_done);
|
||||
ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC,
|
||||
prop_packet);
|
||||
pr_debug("NPU_IPC_CMD_GET_PROPERTY sent status: %d\n", ret);
|
||||
|
||||
if (ret) {
|
||||
pr_err("NPU_IPC_CMD_GET_PROPERTY failed\n");
|
||||
goto get_prop_exit;
|
||||
goto deinit_fw;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(
|
||||
&host_ctx->property_done,
|
||||
&host_ctx->misc_done,
|
||||
(host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ?
|
||||
NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT);
|
||||
|
||||
if (!ret) {
|
||||
pr_err_ratelimited("npu: NPU_IPC_CMD_GET_PROPERTY time out\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto get_prop_exit;
|
||||
goto deinit_fw;
|
||||
} else if (ret < 0) {
|
||||
pr_err("Wait for get_property done interrupted by signal\n");
|
||||
goto get_prop_exit;
|
||||
goto deinit_fw;
|
||||
}
|
||||
|
||||
ret = host_ctx->cmd_ret_status;
|
||||
|
|
@ -1419,6 +1446,8 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
|
|||
pr_err("get fw property failed %d\n", ret);
|
||||
}
|
||||
|
||||
deinit_fw:
|
||||
fw_deinit(npu_dev, false, true);
|
||||
get_prop_exit:
|
||||
kfree(prop_packet);
|
||||
return ret;
|
||||
|
|
@ -1609,7 +1638,7 @@ int32_t npu_host_load_network_v2(struct npu_client *client,
|
|||
mutex_lock(&host_ctx->lock);
|
||||
|
||||
if (!ret) {
|
||||
pr_err_ratelimited("npu: NPU_IPC_CMD_LOAD time out\n");
|
||||
pr_err_ratelimited("npu: NPU_IPC_CMD_LOAD_V2 time out\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto error_free_network;
|
||||
}
|
||||
|
|
@ -2052,7 +2081,6 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev)
|
|||
loopback_packet.header.flags = 0;
|
||||
loopback_packet.loopbackParams = 15;
|
||||
|
||||
reinit_completion(&host_ctx->loopback_done);
|
||||
ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &loopback_packet);
|
||||
|
||||
if (ret) {
|
||||
|
|
@ -2061,7 +2089,7 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev)
|
|||
}
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(
|
||||
&host_ctx->loopback_done,
|
||||
&host_ctx->misc_done,
|
||||
(host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ?
|
||||
NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,9 +77,9 @@ struct npu_host_ctx {
|
|||
struct delayed_work fw_deinit_work;
|
||||
atomic_t fw_deinit_work_cnt;
|
||||
struct workqueue_struct *wq;
|
||||
struct completion loopback_done;
|
||||
struct completion misc_done;
|
||||
struct completion fw_deinit_done;
|
||||
struct completion property_done;
|
||||
bool misc_pending;
|
||||
void *prop_buf;
|
||||
int32_t network_num;
|
||||
struct npu_network networks[MAX_LOADED_NETWORK];
|
||||
|
|
|
|||
Loading…
Reference in a new issue