ivpu_job.c (cd7272215c44676dba236491941c6c406701cc5e) ivpu_job.c (852be13f3bd32c1eab808840cfac41b1fea25991)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#include <drm/drm_file.h>
7
8#include <linux/bitfield.h>
9#include <linux/highmem.h>
10#include <linux/kthread.h>
11#include <linux/pci.h>
12#include <linux/module.h>
13#include <uapi/drm/ivpu_accel.h>
14
15#include "ivpu_drv.h"
16#include "ivpu_hw.h"
17#include "ivpu_ipc.h"
18#include "ivpu_job.h"
19#include "ivpu_jsm_msg.h"
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#include <drm/drm_file.h>
7
8#include <linux/bitfield.h>
9#include <linux/highmem.h>
10#include <linux/kthread.h>
11#include <linux/pci.h>
12#include <linux/module.h>
13#include <uapi/drm/ivpu_accel.h>
14
15#include "ivpu_drv.h"
16#include "ivpu_hw.h"
17#include "ivpu_ipc.h"
18#include "ivpu_job.h"
19#include "ivpu_jsm_msg.h"
20#include "ivpu_pm.h"
20
21#define CMD_BUF_IDX 0
22#define JOB_ID_JOB_MASK GENMASK(7, 0)
23#define JOB_ID_CONTEXT_MASK GENMASK(31, 8)
24#define JOB_MAX_BUFFER_COUNT 65535
25
26static unsigned int ivpu_tdr_timeout_ms;
27module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, uint, 0644);

--- 237 unchanged lines hidden (view full) ---

265 if (job->bos[i])
266 drm_gem_object_put(&job->bos[i]->base);
267
268 dma_fence_put(job->done_fence);
269 ivpu_file_priv_put(&job->file_priv);
270
271 ivpu_dbg(vdev, KREF, "Job released: id %u\n", job->job_id);
272 kfree(job);
21
22#define CMD_BUF_IDX 0
23#define JOB_ID_JOB_MASK GENMASK(7, 0)
24#define JOB_ID_CONTEXT_MASK GENMASK(31, 8)
25#define JOB_MAX_BUFFER_COUNT 65535
26
27static unsigned int ivpu_tdr_timeout_ms;
28module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, uint, 0644);

--- 237 unchanged lines hidden (view full) ---

266 if (job->bos[i])
267 drm_gem_object_put(&job->bos[i]->base);
268
269 dma_fence_put(job->done_fence);
270 ivpu_file_priv_put(&job->file_priv);
271
272 ivpu_dbg(vdev, KREF, "Job released: id %u\n", job->job_id);
273 kfree(job);
274
275 /* Allow the VPU to get suspended, must be called after ivpu_file_priv_put() */
276 ivpu_rpm_put(vdev);
273}
274
275static void job_put(struct ivpu_job *job)
276{
277 struct ivpu_device *vdev = job->vdev;
278
279 ivpu_dbg(vdev, KREF, "Job put: id %u refcount %u\n", job->job_id, kref_read(&job->ref));
280 kref_put(&job->ref, job_release);
281}
282
283static struct ivpu_job *
284ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count)
285{
286 struct ivpu_device *vdev = file_priv->vdev;
287 struct ivpu_job *job;
288 size_t buf_size;
277}
278
279static void job_put(struct ivpu_job *job)
280{
281 struct ivpu_device *vdev = job->vdev;
282
283 ivpu_dbg(vdev, KREF, "Job put: id %u refcount %u\n", job->job_id, kref_read(&job->ref));
284 kref_put(&job->ref, job_release);
285}
286
287static struct ivpu_job *
288ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count)
289{
290 struct ivpu_device *vdev = file_priv->vdev;
291 struct ivpu_job *job;
292 size_t buf_size;
293 int ret;
289
294
295 ret = ivpu_rpm_get(vdev);
296 if (ret < 0)
297 return NULL;
298
290 buf_size = sizeof(*job) + bo_count * sizeof(struct ivpu_bo *);
291 job = kzalloc(buf_size, GFP_KERNEL);
292 if (!job)
299 buf_size = sizeof(*job) + bo_count * sizeof(struct ivpu_bo *);
300 job = kzalloc(buf_size, GFP_KERNEL);
301 if (!job)
293 return NULL;
302 goto err_rpm_put;
294
295 kref_init(&job->ref);
296
297 job->vdev = vdev;
298 job->engine_idx = engine_idx;
299 job->bo_count = bo_count;
300 job->done_fence = ivpu_fence_create(vdev);
301 if (!job->done_fence) {

--- 4 unchanged lines hidden (view full) ---

306 job->file_priv = ivpu_file_priv_get(file_priv);
307
308 ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx);
309
310 return job;
311
312err_free_job:
313 kfree(job);
303
304 kref_init(&job->ref);
305
306 job->vdev = vdev;
307 job->engine_idx = engine_idx;
308 job->bo_count = bo_count;
309 job->done_fence = ivpu_fence_create(vdev);
310 if (!job->done_fence) {

--- 4 unchanged lines hidden (view full) ---

315 job->file_priv = ivpu_file_priv_get(file_priv);
316
317 ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx);
318
319 return job;
320
321err_free_job:
322 kfree(job);
323err_rpm_put:
324 ivpu_rpm_put(vdev);
314 return NULL;
315}
316
317static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status)
318{
319 struct ivpu_job *job;
320
321 job = xa_erase(&vdev->submitted_jobs_xa, job_id);

--- 238 unchanged lines hidden (view full) ---

560 jobs_submitted = !xa_empty(&vdev->submitted_jobs_xa);
561 ret = ivpu_ipc_receive(vdev, &cons, NULL, &jsm_msg, timeout);
562 if (!ret) {
563 ivpu_job_done_message(vdev, &jsm_msg);
564 } else if (ret == -ETIMEDOUT) {
565 if (jobs_submitted && !xa_empty(&vdev->submitted_jobs_xa)) {
566 ivpu_err(vdev, "TDR detected, timeout %d ms", timeout);
567 ivpu_hw_diagnose_failure(vdev);
325 return NULL;
326}
327
328static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status)
329{
330 struct ivpu_job *job;
331
332 job = xa_erase(&vdev->submitted_jobs_xa, job_id);

--- 238 unchanged lines hidden (view full) ---

571 jobs_submitted = !xa_empty(&vdev->submitted_jobs_xa);
572 ret = ivpu_ipc_receive(vdev, &cons, NULL, &jsm_msg, timeout);
573 if (!ret) {
574 ivpu_job_done_message(vdev, &jsm_msg);
575 } else if (ret == -ETIMEDOUT) {
576 if (jobs_submitted && !xa_empty(&vdev->submitted_jobs_xa)) {
577 ivpu_err(vdev, "TDR detected, timeout %d ms", timeout);
578 ivpu_hw_diagnose_failure(vdev);
579 ivpu_pm_schedule_recovery(vdev);
568 }
569 }
570 }
571
572 ivpu_ipc_consumer_del(vdev, &cons);
573
574 ivpu_jobs_abort_all(vdev);
575

--- 27 unchanged lines hidden ---
580 }
581 }
582 }
583
584 ivpu_ipc_consumer_del(vdev, &cons);
585
586 ivpu_jobs_abort_all(vdev);
587

--- 27 unchanged lines hidden ---