mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-08-21 16:31:14 +02:00

By default xe_bb_create_job() appends a MI_BATCH_BUFFER_END to batch
buffer, this is not a problem if batch buffer is only used once but
oa reuses the batch buffer for the same metric and at each call
it appends a MI_BATCH_BUFFER_END, printing the warning below and then
overflowing.
[ 381.072016] ------------[ cut here ]------------
[ 381.072019] xe 0000:00:02.0: [drm] Assertion `bb->len * 4 + bb_prefetch(q->gt) <= size` failed!
platform: LUNARLAKE subplatform: 1
graphics: Xe2_LPG / Xe2_HPG 20.04 step B0
media: Xe2_LPM / Xe2_HPM 20.00 step B0
tile: 0 VRAM 0 B
GT: 0 type 1
So here checking if batch buffer already have MI_BATCH_BUFFER_END if
not append it.
v2:
- simply fix, suggestion from Ashutosh
Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240912153842.35813-1-jose.souza@intel.com
(cherry picked from commit 9ba0e0f30c
)
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
114 lines
2.5 KiB
C
114 lines
2.5 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright © 2022 Intel Corporation
|
|
*/
|
|
|
|
#include "xe_bb.h"
|
|
|
|
#include "instructions/xe_mi_commands.h"
|
|
#include "xe_assert.h"
|
|
#include "xe_device.h"
|
|
#include "xe_exec_queue_types.h"
|
|
#include "xe_gt.h"
|
|
#include "xe_hw_fence.h"
|
|
#include "xe_sa.h"
|
|
#include "xe_sched_job.h"
|
|
#include "xe_vm_types.h"
|
|
|
|
static int bb_prefetch(struct xe_gt *gt)
|
|
{
|
|
struct xe_device *xe = gt_to_xe(gt);
|
|
|
|
if (GRAPHICS_VERx100(xe) >= 1250 && !xe_gt_is_media_type(gt))
|
|
/*
|
|
* RCS and CCS require 1K, although other engines would be
|
|
* okay with 512.
|
|
*/
|
|
return SZ_1K;
|
|
else
|
|
return SZ_512;
|
|
}
|
|
|
|
struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm)
|
|
{
|
|
struct xe_tile *tile = gt_to_tile(gt);
|
|
struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL);
|
|
int err;
|
|
|
|
if (!bb)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
/*
|
|
* We need to allocate space for the requested number of dwords,
|
|
* one additional MI_BATCH_BUFFER_END dword, and additional buffer
|
|
* space to accomodate the platform-specific hardware prefetch
|
|
* requirements.
|
|
*/
|
|
bb->bo = xe_sa_bo_new(!usm ? tile->mem.kernel_bb_pool : gt->usm.bb_pool,
|
|
4 * (dwords + 1) + bb_prefetch(gt));
|
|
if (IS_ERR(bb->bo)) {
|
|
err = PTR_ERR(bb->bo);
|
|
goto err;
|
|
}
|
|
|
|
bb->cs = xe_sa_bo_cpu_addr(bb->bo);
|
|
bb->len = 0;
|
|
|
|
return bb;
|
|
err:
|
|
kfree(bb);
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
static struct xe_sched_job *
|
|
__xe_bb_create_job(struct xe_exec_queue *q, struct xe_bb *bb, u64 *addr)
|
|
{
|
|
u32 size = drm_suballoc_size(bb->bo);
|
|
|
|
if (bb->len == 0 || bb->cs[bb->len - 1] != MI_BATCH_BUFFER_END)
|
|
bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
|
|
|
|
xe_gt_assert(q->gt, bb->len * 4 + bb_prefetch(q->gt) <= size);
|
|
|
|
xe_sa_bo_flush_write(bb->bo);
|
|
|
|
return xe_sched_job_create(q, addr);
|
|
}
|
|
|
|
struct xe_sched_job *xe_bb_create_migration_job(struct xe_exec_queue *q,
|
|
struct xe_bb *bb,
|
|
u64 batch_base_ofs,
|
|
u32 second_idx)
|
|
{
|
|
u64 addr[2] = {
|
|
batch_base_ofs + drm_suballoc_soffset(bb->bo),
|
|
batch_base_ofs + drm_suballoc_soffset(bb->bo) +
|
|
4 * second_idx,
|
|
};
|
|
|
|
xe_gt_assert(q->gt, second_idx <= bb->len);
|
|
xe_gt_assert(q->gt, xe_sched_job_is_migration(q));
|
|
xe_gt_assert(q->gt, q->width == 1);
|
|
|
|
return __xe_bb_create_job(q, bb, addr);
|
|
}
|
|
|
|
struct xe_sched_job *xe_bb_create_job(struct xe_exec_queue *q,
|
|
struct xe_bb *bb)
|
|
{
|
|
u64 addr = xe_sa_bo_gpu_addr(bb->bo);
|
|
|
|
xe_gt_assert(q->gt, !xe_sched_job_is_migration(q));
|
|
xe_gt_assert(q->gt, q->width == 1);
|
|
return __xe_bb_create_job(q, bb, &addr);
|
|
}
|
|
|
|
void xe_bb_free(struct xe_bb *bb, struct dma_fence *fence)
|
|
{
|
|
if (!bb)
|
|
return;
|
|
|
|
xe_sa_bo_free(bb->bo, fence);
|
|
kfree(bb);
|
|
}
|