mirror of
https://github.com/torvalds/linux.git
synced 2026-01-25 15:03:52 +08:00
accel/ivpu: Abort jobs of faulty context
Abort all jobs that belong to contexts generating MMU faults in order to avoid flooding host with MMU IRQs. Jobs are cancelled with: - SSID_RELEASE command when OS scheduling is enabled - DESTROY_CMDQ command when HW scheduling is enabled Signed-off-by: Maciej Falkowski <maciej.falkowski@intel.com> Co-developed-by: Wachowski, Karol <karol.wachowski@intel.com> Signed-off-by: Wachowski, Karol <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240611120433.1012423-3-jacek.lawrynowicz@linux.intel.com
This commit is contained in:
committed by
Jacek Lawrynowicz
parent
d9dfc4eaa3
commit
b7ed87ffc7
@@ -446,6 +446,26 @@ static const struct drm_driver driver = {
|
||||
.minor = DRM_IVPU_DRIVER_MINOR,
|
||||
};
|
||||
|
||||
static void ivpu_context_abort_invalid(struct ivpu_device *vdev)
|
||||
{
|
||||
struct ivpu_file_priv *file_priv;
|
||||
unsigned long ctx_id;
|
||||
|
||||
mutex_lock(&vdev->context_list_lock);
|
||||
|
||||
xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
|
||||
if (!file_priv->has_mmu_faults || file_priv->aborted)
|
||||
continue;
|
||||
|
||||
mutex_lock(&file_priv->lock);
|
||||
ivpu_context_abort_locked(file_priv);
|
||||
file_priv->aborted = true;
|
||||
mutex_unlock(&file_priv->lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
}
|
||||
|
||||
static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
{
|
||||
struct ivpu_device *vdev = arg;
|
||||
@@ -459,6 +479,9 @@ static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
case IVPU_HW_IRQ_SRC_IPC:
|
||||
ivpu_ipc_irq_thread_handler(vdev);
|
||||
break;
|
||||
case IVPU_HW_IRQ_SRC_MMU_EVTQ:
|
||||
ivpu_context_abort_invalid(vdev);
|
||||
break;
|
||||
default:
|
||||
ivpu_err_ratelimited(vdev, "Unknown IRQ source: %u\n", irq_src);
|
||||
break;
|
||||
|
||||
@@ -169,6 +169,7 @@ struct ivpu_file_priv {
|
||||
struct ivpu_bo *ms_info_bo;
|
||||
bool has_mmu_faults;
|
||||
bool bound;
|
||||
bool aborted;
|
||||
};
|
||||
|
||||
extern int ivpu_dbg_mask;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020 - 2024 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_H__
|
||||
@@ -15,6 +15,7 @@
|
||||
#define IVPU_HW_IRQ_FIFO_LENGTH 1024
|
||||
|
||||
#define IVPU_HW_IRQ_SRC_IPC 1
|
||||
#define IVPU_HW_IRQ_SRC_MMU_EVTQ 2
|
||||
|
||||
struct ivpu_addr_range {
|
||||
resource_size_t start;
|
||||
|
||||
@@ -210,8 +210,7 @@ void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
|
||||
ivpu_ipc_tx_release(vdev, cons->tx_vpu_addr);
|
||||
}
|
||||
|
||||
static int
|
||||
ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
|
||||
int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
|
||||
{
|
||||
struct ivpu_ipc_info *ipc = vdev->ipc;
|
||||
int ret;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_IPC_H__
|
||||
@@ -96,6 +96,8 @@ void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
|
||||
u32 channel, ivpu_ipc_rx_callback_t callback);
|
||||
void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons);
|
||||
|
||||
int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
struct vpu_jsm_msg *req);
|
||||
int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg,
|
||||
unsigned long timeout_ms);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
@@ -312,6 +312,33 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev)
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
}
|
||||
|
||||
static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv)
|
||||
{
|
||||
u16 engine;
|
||||
u8 priority;
|
||||
|
||||
for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) {
|
||||
for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) {
|
||||
int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
|
||||
|
||||
if (file_priv->cmdq[cmdq_idx])
|
||||
ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv)
|
||||
{
|
||||
struct ivpu_device *vdev = file_priv->vdev;
|
||||
|
||||
lockdep_assert_held(&file_priv->lock);
|
||||
|
||||
ivpu_cmdq_fini_all(file_priv);
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS)
|
||||
ivpu_jsm_context_release(vdev, file_priv->ctx.id);
|
||||
}
|
||||
|
||||
static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
|
||||
{
|
||||
struct ivpu_device *vdev = job->vdev;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_JOB_H__
|
||||
@@ -57,6 +57,8 @@ struct ivpu_job {
|
||||
|
||||
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
|
||||
|
||||
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
|
||||
|
||||
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
|
||||
void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
|
||||
|
||||
|
||||
@@ -255,11 +255,16 @@ int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid)
|
||||
{
|
||||
struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE };
|
||||
struct vpu_jsm_msg resp;
|
||||
int ret;
|
||||
|
||||
req.payload.ssid_release.host_ssid = host_ssid;
|
||||
|
||||
return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
|
||||
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
|
||||
if (ret)
|
||||
ivpu_warn_ratelimited(vdev, "Failed to release context: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/circ_buf.h>
|
||||
@@ -878,8 +878,9 @@ static void ivpu_mmu_dump_event(struct ivpu_device *vdev, u32 *event)
|
||||
u64 in_addr = ((u64)event[5]) << 32 | event[4];
|
||||
u32 sid = event[1];
|
||||
|
||||
ivpu_err(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
|
||||
op, ivpu_mmu_event_to_str(op), ssid, sid, event[2], event[3], in_addr, fetch_addr);
|
||||
ivpu_err_ratelimited(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
|
||||
op, ivpu_mmu_event_to_str(op), ssid, sid,
|
||||
event[2], event[3], in_addr, fetch_addr);
|
||||
}
|
||||
|
||||
static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev)
|
||||
@@ -915,6 +916,9 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev)
|
||||
ivpu_mmu_user_context_mark_invalid(vdev, ssid);
|
||||
REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons);
|
||||
}
|
||||
|
||||
if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_MMU_EVTQ))
|
||||
ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
|
||||
}
|
||||
|
||||
void ivpu_mmu_evtq_dump(struct ivpu_device *vdev)
|
||||
|
||||
Reference in New Issue
Block a user