msm: eva: Send EVA session error to UMD

Through POLL SSR event, only notify the error session. Other
sessions will not be impacted. This is different than SSR
handling.

Change-Id: I5acb4e21c19909b16350816621ae085d54fe05ac
Signed-off-by: George Shen <quic_sqiao@quicinc.com>
This commit is contained in:
George Shen
2023-05-23 15:55:47 -07:00
committed by Gerrit - the friendly Code Review server
parent 4bd20f9c7c
commit 43c37a29e1
5 changed files with 69 additions and 161 deletions

View File

@@ -3305,10 +3305,8 @@ static void **get_session_id(struct msm_cvp_cb_info *info)
case HAL_SESSION_PROPERTY_INFO:
case HAL_SESSION_EVENT_CHANGE:
case HAL_SESSION_DUMP_NOTIFY:
session_id = &info->response.cmd.session_id;
break;
case HAL_SESSION_ERROR:
session_id = &info->response.data.session_id;
session_id = &info->response.cmd.session_id;
break;
case HAL_RESPONSE_UNUSED:
default:
@@ -3525,6 +3523,7 @@ err_no_work:
}
dprintk(CVP_HFI, "Processing response %d of %d, type %d\n",
(i + 1), num_responses, r->response_type);
/* callback = void cvp_handle_cmd_response() */
device->callback(r->response_type, rsp);
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/bitops.h>
@@ -93,8 +94,9 @@ static int hfi_process_session_error(u32 device_id,
cmd_done.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->event_data1);
cmd_done.size = pkt->event_data2;
info->response.cmd = cmd_done;
dprintk(CVP_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n",
dprintk(CVP_WARN, "Received: SESSION_ERROR with event data 1 2: %#x %#x\n",
pkt->event_data1, pkt->event_data2);
switch (pkt->event_data1) {
/* Ignore below errors */
@@ -108,7 +110,7 @@ static int hfi_process_session_error(u32 device_id,
"%s: session %x id %#x, data1 %#x, data2 %#x\n",
__func__, pkt->session_id, pkt->event_id,
pkt->event_data1, pkt->event_data2);
info->response_type = HAL_RESPONSE_UNUSED;
info->response_type = HAL_SESSION_ERROR;
break;
}
@@ -135,8 +137,6 @@ static int hfi_process_event_notify(u32 device_id,
return hfi_process_sys_error(device_id, pkt, info);
case HFI_EVENT_SESSION_ERROR:
dprintk(CVP_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n",
pkt->session_id);
return hfi_process_session_error(device_id, pkt, info);
default:

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "msm_cvp.h"
@@ -94,9 +95,8 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst,
if (wait_event_timeout(sq->wq,
cvp_msg_pending(sq, &msg, ktid), timeout) == 0) {
dprintk(CVP_WARN, "session queue wait timeout\n");
if(inst && inst->core && inst->core->device){
if (inst && inst->core && inst->core->device && inst->state != MSM_CVP_CORE_INVALID)
print_hfi_queue_info(inst->core->device);
}
rc = -ETIMEDOUT;
goto exit;
}
@@ -184,6 +184,11 @@ static int msm_cvp_session_process_hfi(
return -EINVAL;
}
if (inst->state == MSM_CVP_CORE_INVALID) {
dprintk(CVP_ERR, "sess %pK INVALIDim reject new HFIs\n", inst);
return -ECONNRESET;
}
s = cvp_get_inst_validate(inst->core, inst);
if (!s)
return -ECONNRESET;
@@ -474,121 +479,8 @@ exit:
static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
struct eva_kmd_arg *arg)
{
int rc = 0;
int idx;
struct eva_kmd_hfi_fence_packet *fence_pkt;
struct eva_kmd_hfi_synx_packet *synx_pkt;
struct eva_kmd_fence_ctrl *kfc;
struct cvp_hfi_cmd_session_hdr *pkt;
unsigned int offset = 0, buf_num = 0, in_offset, in_buf_num;
struct msm_cvp_inst *s;
struct cvp_fence_command *f;
struct cvp_fence_queue *q;
u32 *fence;
enum op_mode mode;
bool is_config_pkt;
if (!inst || !inst->core || !arg || !inst->core->device) {
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
dprintk(CVP_WARN, "Deprecated IOCTL command %s\n", __func__);
return -EINVAL;
}
s = cvp_get_inst_validate(inst->core, inst);
if (!s)
return -ECONNRESET;
q = &inst->fence_cmd_queue;
mutex_lock(&q->lock);
mode = q->mode;
mutex_unlock(&q->lock);
if (mode == OP_DRAINING) {
dprintk(CVP_SYNX, "%s: flush in progress\n", __func__);
rc = -EBUSY;
goto exit;
}
in_offset = arg->buf_offset;
in_buf_num = arg->buf_num;
fence_pkt = &arg->data.hfi_fence_pkt;
pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data;
idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt);
if (idx < 0 ||
(pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) {
dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__,
pkt->size, pkt->packet_type);
goto exit;
} else {
is_config_pkt = cvp_hfi_defs[idx].is_config_pkt;
}
if (in_offset && in_buf_num) {
offset = in_offset;
buf_num = in_buf_num;
}
if (!is_buf_param_valid(buf_num, offset)) {
dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n");
goto exit;
}
if (is_config_pkt)
pr_info(CVP_DBG_TAG "inst %pK config %s\n",
"pkt", inst, cvp_hfi_defs[idx].name);
rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset,
buf_num);
if (rc)
goto exit;
rc = cvp_alloc_fence_data(&f, pkt->size);
if (rc)
goto exit;
f->type = cvp_hfi_defs[idx].type;
f->mode = OP_NORMAL;
synx_pkt = &arg->data.hfi_synx_pkt;
if (synx_pkt->fence_data[0] != 0xFEEDFACE) {
dprintk(CVP_ERR, "%s deprecated synx path\n", __func__);
cvp_free_fence_data(f);
msm_cvp_unmap_frame(inst, pkt->client_data.kdata);
goto exit;
} else {
kfc = &synx_pkt->fc;
fence = (u32 *)&kfc->fences;
f->frame_id = kfc->frame_id;
f->signature = 0xFEEDFACE;
f->num_fences = kfc->num_fences;
f->output_index = kfc->output_index;
}
dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n",
__func__, f->frame_id, pkt->client_data.kdata);
memcpy(f->pkt, pkt, pkt->size);
f->pkt->client_data.kdata |= FENCE_BIT;
rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, fence);
if (rc) {
cvp_free_fence_data(f);
goto exit;
}
mutex_lock(&q->lock);
list_add_tail(&f->list, &inst->fence_cmd_queue.wait_list);
mutex_unlock(&q->lock);
wake_up(&inst->fence_cmd_queue.wq);
exit:
cvp_put_inst(s);
return rc;
}
@@ -1534,7 +1426,6 @@ check_sched:
int cvp_clean_session_queues(struct msm_cvp_inst *inst)
{
struct cvp_fence_queue *q;
struct cvp_session_queue *sq;
u32 count = 0, max_retries = 100;
q = &inst->fence_cmd_queue;
@@ -1563,11 +1454,6 @@ retry:
return -EBUSY;
goto retry;
sq = &inst->session_queue_fence;
spin_lock(&sq->lock);
sq->state = QUEUE_INVALID;
spin_unlock(&sq->lock);
}
static int cvp_flush_all(struct msm_cvp_inst *inst)

View File

@@ -2079,7 +2079,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst)
HAL_SESSION_RELEASE_BUFFER_DONE);
if (rc)
dprintk(CVP_WARN,
"%s: wait for signal failed, rc %d\n",
"%s: wait release_arp signal failed, rc %d\n",
__func__, rc);
mutex_lock(&inst->persistbufs.lock);
} else {

View File

@@ -384,6 +384,7 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst,
if (!rc) {
dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n",
SESSION_MSG_INDEX(cmd));
if (inst->state != MSM_CVP_CORE_INVALID)
print_hfi_queue_info(hdev);
rc = -ETIMEDOUT;
} else if (inst->state == MSM_CVP_CORE_INVALID) {
@@ -541,6 +542,8 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
struct msm_cvp_cb_cmd_done *response = data;
struct cvp_hfi_device *hdev = NULL;
struct msm_cvp_inst *inst = NULL;
unsigned long flags = 0;
int i;
if (!response) {
dprintk(CVP_ERR,
@@ -559,6 +562,19 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
hdev = inst->core->device;
dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n",
response->status, inst, hash32_ptr(inst->session));
cvp_print_inst(CVP_WARN, inst);
if (inst->state != MSM_CVP_CORE_INVALID) {
change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID);
if (cvp_clean_session_queues(inst))
dprintk(CVP_WARN, "Failed to clean sess queues\n");
for (i = 0; i < ARRAY_SIZE(inst->completions); i++)
complete(&inst->completions[i]);
spin_lock_irqsave(&inst->event_handler.lock, flags);
inst->event_handler.event = CVP_SSR_EVENT;
spin_unlock_irqrestore(
&inst->event_handler.lock, flags);
wake_up_all(&inst->event_handler.wq);
}
cvp_put_inst(inst);
}
@@ -994,13 +1010,6 @@ int msm_cvp_deinit_core(struct msm_cvp_inst *inst)
hdev = core->device;
mutex_lock(&core->lock);
if (core->state == CVP_CORE_UNINIT) {
dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n",
core->id, core->state);
goto core_already_uninited;
}
core_already_uninited:
change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT);
mutex_unlock(&core->lock);
return 0;
@@ -1113,38 +1122,48 @@ int msm_cvp_comm_suspend(int core_id)
static int get_flipped_state(int present_state, int desired_state)
{
int flipped_state = present_state;
int flipped_state;
if (present_state == MSM_CVP_CORE_INIT_DONE && desired_state > MSM_CVP_CLOSE)
flipped_state = MSM_CVP_CORE_UNINIT;
else if (present_state == MSM_CVP_CORE_INVALID)
flipped_state = MSM_CVP_CLOSE;
else
flipped_state = present_state;
if (flipped_state < MSM_CVP_CLOSE && desired_state > MSM_CVP_CLOSE) {
flipped_state = MSM_CVP_CLOSE + (MSM_CVP_CLOSE - flipped_state);
flipped_state &= 0xFFFE;
flipped_state = flipped_state - 1;
} else if (flipped_state > MSM_CVP_CLOSE
&& desired_state < MSM_CVP_CLOSE) {
flipped_state = MSM_CVP_CLOSE -
(flipped_state - MSM_CVP_CLOSE + 1);
flipped_state &= 0xFFFE;
flipped_state = flipped_state - 1;
}
return flipped_state;
}
static char state_names[MSM_CVP_CORE_INVALID + 1][32] = {
"Invlid entry",
"CORE_UNINIT_DONE",
"CORE_INIT",
"CORE_INIT_DONE",
"OPEN",
"OPEN_DONE",
"CLOSE",
"CLOSE_DONE",
"CORE_UNINIT",
"CORE_INVALID"
};
int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
{
int rc = 0;
int flipped_state;
struct msm_cvp_core *core;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
if (!inst) {
dprintk(CVP_ERR, "%s: invalid params %pK", __func__, inst);
return -EINVAL;
}
dprintk(CVP_SESS,
"Trying to move inst: %pK (%#x) from: %#x to %#x\n",
inst, hash32_ptr(inst->session), inst->state, state);
mutex_lock(&inst->sync_lock);
if (inst->state == MSM_CVP_CORE_INVALID) {
dprintk(CVP_ERR, "%s: inst %pK is in invalid\n",
if (inst->state == MSM_CVP_CORE_INVALID &&
core->state == CVP_CORE_UNINIT) {
dprintk(CVP_ERR, "%s: inst %pK & core are in invalid\n",
__func__, inst);
mutex_unlock(&inst->sync_lock);
return -EINVAL;
@@ -1152,8 +1171,10 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
flipped_state = get_flipped_state(inst->state, state);
dprintk(CVP_SESS,
"inst: %pK (%#x) flipped_state = %#x %x\n",
inst, hash32_ptr(inst->session), flipped_state, state);
"inst: %pK (%#x) cur_state %s dest_state %s flipped_state = %s\n",
inst, hash32_ptr(inst->session), state_names[inst->state],
state_names[state], state_names[flipped_state]);
switch (flipped_state) {
case MSM_CVP_CORE_UNINIT_DONE:
case MSM_CVP_CORE_INIT:
@@ -1208,8 +1229,10 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
if (rc == -ETIMEDOUT) {
dprintk(CVP_ERR,
"Timedout move from state: %d to %d\n",
inst->state, state);
"Timedout move from state: %s to %s\n",
state_names[inst->state],
state_names[state]);
if (inst->state != MSM_CVP_CORE_INVALID)
msm_cvp_comm_kill_session(inst);
}
return rc;