mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/xe: apply debug page-size allocation policy to user BOs
Apply the debug page-size allocation policy during user BO creation. When page-size allocation control is enabled, override the user BO page-size selection flags based on the selected debug mode and round the requested size up to the corresponding granularity: - 2M mode selects 2M handling - 1G mode selects 1G handling - mixed mode selects the page size from the current mixed-mode index This is intended for internal debug and validation flows. When the control mode is left at the default setting, the normal user BO creation path is unchanged. v2 - ensure debug page-size allocation does not affect the default path (sashiko) - rework synchronization for concurrent access (sashiko) - refactor commit message for readability v3 - update user BO size alignment based on debug policy mode - reword commit message - ensure normal user flow is unchanged when debug policy is disabled v4(sashiko) - limit debug page-size policy application to VRAM BOs - do not override preexisting page-size requirement flags - advance mixed-mode index only after successful BO create ioctl completion - add overflow checks before ALIGN() in debug page-size handling - ensure CONFIG_DRM_XE_DEBUG_PAGE_SIZE enabled and it is dgfx v5(Himal) v5: - Guard debug page-size policy paths with CONFIG_DRM_XE_DEBUG_PAGE_SIZE - Leave the normal BO creation path unchanged when no debug mode is selected v8(Himal) - Avoid current index increment for system BO's - Simplify mixed mode align logic by changing array to struct array - Have a inline check if it is on debug mode or not - Avoid condition compiled debug in function code blocks Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patch.msgid.link/20260729121843.1255891-5-naresh.kumar.g@intel.com Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
This commit is contained in:
parent
caf4fd4eb8
commit
2285c120e1
|
|
@ -2652,6 +2652,145 @@ static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *til
|
|||
return ret ? ERR_PTR(ret) : bo;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE
|
||||
static void xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe, struct xe_bo *bo)
|
||||
{
|
||||
if (!xe_debug_page_size_mode_is_mixed(xe))
|
||||
return;
|
||||
|
||||
if (!(bo->flags & XE_BO_FLAG_VRAM_MASK) ||
|
||||
!(bo->flags & XE_BO_FLAG_USER))
|
||||
return;
|
||||
|
||||
mutex_lock(&xe->page_size_alloc_ctrl.lock);
|
||||
if (xe->page_size_alloc_ctrl.mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED)
|
||||
xe->page_size_alloc_ctrl.cur_index++;
|
||||
mutex_unlock(&xe->page_size_alloc_ctrl.lock);
|
||||
}
|
||||
|
||||
static bool xe_size_align_overflows(size_t size, size_t align)
|
||||
{
|
||||
return size > SIZE_MAX - (align - 1);
|
||||
}
|
||||
|
||||
static u32 get_flag_from_cur_index_in_mixed_mode(struct xe_device *xe, size_t *align_size,
|
||||
int *err)
|
||||
{
|
||||
static const struct {
|
||||
u32 flag;
|
||||
size_t align;
|
||||
} map[] = {
|
||||
{ 0, SZ_4K }, /* default: 4K, no flag */
|
||||
{ XE_BO_FLAG_NEEDS_64K, SZ_64K },
|
||||
{ XE_BO_FLAG_NEEDS_2M, SZ_2M },
|
||||
{ XE_BO_FLAG_NEEDS_1G, SZ_1G },
|
||||
};
|
||||
u32 idx;
|
||||
const typeof(*map) *entry;
|
||||
|
||||
lockdep_assert_held(&xe->page_size_alloc_ctrl.lock);
|
||||
|
||||
*err = 0;
|
||||
idx = xe->page_size_alloc_ctrl.cur_index % ARRAY_SIZE(map);
|
||||
|
||||
entry = &map[idx];
|
||||
|
||||
if (!entry->flag)
|
||||
return 0;
|
||||
|
||||
if (xe_size_align_overflows(*align_size, entry->align)) {
|
||||
*err = -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
*align_size = ALIGN(*align_size, entry->align);
|
||||
|
||||
return entry->flag;
|
||||
}
|
||||
|
||||
static int xe_bo_apply_debug_page_size_policy(struct xe_device *xe,
|
||||
u32 *bo_flags,
|
||||
size_t *size)
|
||||
{
|
||||
enum xe_page_size_alloc_ctrl_mode mode;
|
||||
u32 want = 0;
|
||||
size_t align_size = *size;
|
||||
int err = 0;
|
||||
|
||||
/*
|
||||
* The debug page-size policy is only meaningful for BOs placed in
|
||||
* VRAM, where the downstream BO init path can
|
||||
* actually honor the corresponding minimum page-size requirement.
|
||||
*/
|
||||
if (!(*bo_flags & XE_BO_FLAG_VRAM_MASK))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Do not override existing page-size requirement flags, since they
|
||||
* may reflect functional requirements for specific BO types.
|
||||
*/
|
||||
if (*bo_flags & (XE_BO_FLAG_NEEDS_64K |
|
||||
XE_BO_FLAG_NEEDS_2M |
|
||||
XE_BO_FLAG_NEEDS_1G))
|
||||
return 0;
|
||||
|
||||
if (!READ_ONCE(xe->page_size_alloc_ctrl.mode))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&xe->page_size_alloc_ctrl.lock);
|
||||
|
||||
mode = xe->page_size_alloc_ctrl.mode;
|
||||
if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_NONE) {
|
||||
goto out_unlock;
|
||||
} else if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_2M) {
|
||||
if (xe_size_align_overflows(align_size, SZ_2M)) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
want = XE_BO_FLAG_NEEDS_2M;
|
||||
align_size = ALIGN(align_size, SZ_2M);
|
||||
} else if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_1G) {
|
||||
if (xe_size_align_overflows(align_size, SZ_1G)) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
want = XE_BO_FLAG_NEEDS_1G;
|
||||
align_size = ALIGN(align_size, SZ_1G);
|
||||
} else if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED) {
|
||||
want = get_flag_from_cur_index_in_mixed_mode(xe, &align_size, &err);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
} else {
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
mutex_unlock(&xe->page_size_alloc_ctrl.lock);
|
||||
|
||||
*bo_flags |= want;
|
||||
/*
|
||||
* Apply the debug page-size policy by rounding the user BO size up to
|
||||
* the selected granularity.
|
||||
*/
|
||||
*size = align_size;
|
||||
return err;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&xe->page_size_alloc_ctrl.lock);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static int xe_bo_apply_debug_page_size_policy(struct xe_device *xe,
|
||||
u32 *bo_flags,
|
||||
size_t *size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe,
|
||||
struct xe_bo *bo)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xe_bo_create_user() - Create a user BO
|
||||
* @xe: The xe device.
|
||||
|
|
@ -2672,9 +2811,16 @@ struct xe_bo *xe_bo_create_user(struct xe_device *xe,
|
|||
u32 flags, struct drm_exec *exec)
|
||||
{
|
||||
struct xe_bo *bo;
|
||||
int err = 0;
|
||||
|
||||
flags |= XE_BO_FLAG_USER;
|
||||
|
||||
if (xe_debug_page_size_mode_not_none(xe)) {
|
||||
err = xe_bo_apply_debug_page_size_policy(xe, &flags, &size);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
if (vm || exec) {
|
||||
xe_assert(xe, exec);
|
||||
bo = __xe_bo_create_locked(xe, NULL, vm, size, 0, ~0ULL,
|
||||
|
|
@ -3489,6 +3635,8 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
if (err)
|
||||
goto out_bulk;
|
||||
|
||||
xe_bo_debug_mixed_mode_cur_index_advance(xe, bo);
|
||||
|
||||
args->handle = handle;
|
||||
goto out_put;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user