mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'drm-xe-next-fixes-2025-06-05' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
Driver Changes: - A couple of vm init fixes (Matt Auld) - Hwmon fixes (Karthik) - Drop reduntant conversion to bool (Raag) - Fix CONFIG_INTEL_VSEC dependency (Arnd) - Rework eviction rejection of bound external bos (Thomas) - Stop re-submitting signalled jobs (Matt Auld) - A couple of pxp fixes (Daniele) - Add back a fix that got lost in a merge (Matt Auld) - Create LRC bo without VM (Niranjana) - Fix for the above fix (Maciej) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com> Link: https://lore.kernel.org/r/aEHq44uIAZwfK-mG@fedora
This commit is contained in:
@@ -60,26 +60,26 @@ Description: RO. Package default power limit (default TDP setting).
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power2_crit
|
||||
Date: February 2024
|
||||
KernelVersion: 6.8
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_crit
|
||||
Date: May 2025
|
||||
KernelVersion: 6.15
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
Description: RW. Package reactive critical (I1) power limit in microwatts.
|
||||
Description: RW. Card reactive critical (I1) power limit in microwatts.
|
||||
|
||||
Package reactive critical (I1) power limit in microwatts is exposed
|
||||
Card reactive critical (I1) power limit in microwatts is exposed
|
||||
for client products. The power controller will throttle the
|
||||
operating frequency if the power averaged over a window exceeds
|
||||
this limit.
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/curr2_crit
|
||||
Date: February 2024
|
||||
KernelVersion: 6.8
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/curr1_crit
|
||||
Date: May 2025
|
||||
KernelVersion: 6.15
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
Description: RW. Package reactive critical (I1) power limit in milliamperes.
|
||||
Description: RW. Card reactive critical (I1) power limit in milliamperes.
|
||||
|
||||
Package reactive critical (I1) power limit in milliamperes is
|
||||
Card reactive critical (I1) power limit in milliamperes is
|
||||
exposed for server products. The power controller will throttle
|
||||
the operating frequency if the power averaged over a window
|
||||
exceeds this limit.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
config DRM_XE
|
||||
tristate "Intel Xe Graphics"
|
||||
depends on DRM && PCI && MMU && (m || (y && KUNIT=y))
|
||||
depends on INTEL_VSEC || !INTEL_VSEC
|
||||
depends on X86_PLATFORM_DEVICES || !(X86 && ACPI)
|
||||
select INTERVAL_TREE
|
||||
# we need shmfs for the swappable backing store, and in particular
|
||||
# the shmem_readpage() which depends upon tmpfs
|
||||
@@ -27,7 +29,6 @@ config DRM_XE
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if X86 && ACPI
|
||||
select X86_PLATFORM_DEVICES if X86 && ACPI
|
||||
select ACPI_WMI if X86 && ACPI
|
||||
select SYNC_FILE
|
||||
select IOSF_MBI
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
#define TEMP_MASK REG_GENMASK(7, 0)
|
||||
|
||||
#define PCU_CR_PACKAGE_RAPL_LIMIT XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x59a0)
|
||||
#define PKG_PWR_LIM_1 REG_GENMASK(14, 0)
|
||||
#define PKG_PWR_LIM_1_EN REG_BIT(15)
|
||||
#define PKG_PWR_LIM_1_TIME REG_GENMASK(23, 17)
|
||||
#define PKG_PWR_LIM_1_TIME_X REG_GENMASK(23, 22)
|
||||
#define PKG_PWR_LIM_1_TIME_Y REG_GENMASK(21, 17)
|
||||
#define PWR_LIM_VAL REG_GENMASK(14, 0)
|
||||
#define PWR_LIM_EN REG_BIT(15)
|
||||
#define PWR_LIM_TIME REG_GENMASK(23, 17)
|
||||
#define PWR_LIM_TIME_X REG_GENMASK(23, 22)
|
||||
#define PWR_LIM_TIME_Y REG_GENMASK(21, 17)
|
||||
|
||||
#endif /* _XE_MCHBAR_REGS_H_ */
|
||||
|
||||
@@ -18,16 +18,12 @@
|
||||
#define PVC_GT0_PLATFORM_ENERGY_STATUS XE_REG(0x28106c)
|
||||
#define PVC_GT0_PACKAGE_POWER_SKU XE_REG(0x281080)
|
||||
|
||||
#define BMG_PACKAGE_POWER_SKU XE_REG(0x138098)
|
||||
#define BMG_PACKAGE_POWER_SKU_UNIT XE_REG(0x1380dc)
|
||||
#define BMG_PACKAGE_ENERGY_STATUS XE_REG(0x138120)
|
||||
#define BMG_FAN_1_SPEED XE_REG(0x138140)
|
||||
#define BMG_FAN_2_SPEED XE_REG(0x138170)
|
||||
#define BMG_FAN_3_SPEED XE_REG(0x1381a0)
|
||||
#define BMG_VRAM_TEMPERATURE XE_REG(0x1382c0)
|
||||
#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)
|
||||
#define BMG_PACKAGE_RAPL_LIMIT XE_REG(0x138440)
|
||||
#define BMG_PLATFORM_ENERGY_STATUS XE_REG(0x138458)
|
||||
#define BMG_PLATFORM_POWER_LIMIT XE_REG(0x138460)
|
||||
|
||||
#endif /* _XE_PCODE_REGS_H_ */
|
||||
|
||||
+29
-19
@@ -841,21 +841,6 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reject BO eviction if BO is bound to current VM. */
|
||||
if (evict && ctx->resv) {
|
||||
struct drm_gpuvm_bo *vm_bo;
|
||||
|
||||
drm_gem_for_each_gpuvm_bo(vm_bo, &bo->ttm.base) {
|
||||
struct xe_vm *vm = gpuvm_to_vm(vm_bo->vm);
|
||||
|
||||
if (xe_vm_resv(vm) == ctx->resv &&
|
||||
xe_vm_in_preempt_fence_mode(vm)) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Failed multi-hop where the old_mem is still marked as
|
||||
* TTM_PL_FLAG_TEMPORARY, should just be a dummy move.
|
||||
@@ -1013,6 +998,25 @@ static long xe_bo_shrink_purge(struct ttm_operation_ctx *ctx,
|
||||
return lret;
|
||||
}
|
||||
|
||||
static bool
|
||||
xe_bo_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place)
|
||||
{
|
||||
struct drm_gpuvm_bo *vm_bo;
|
||||
|
||||
if (!ttm_bo_eviction_valuable(bo, place))
|
||||
return false;
|
||||
|
||||
if (!xe_bo_is_xe_bo(bo))
|
||||
return true;
|
||||
|
||||
drm_gem_for_each_gpuvm_bo(vm_bo, &bo->base) {
|
||||
if (xe_vm_is_validating(gpuvm_to_vm(vm_bo->vm)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_bo_shrink() - Try to shrink an xe bo.
|
||||
* @ctx: The struct ttm_operation_ctx used for shrinking.
|
||||
@@ -1047,7 +1051,7 @@ long xe_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
|
||||
(flags.purge && !xe_tt->purgeable))
|
||||
return -EBUSY;
|
||||
|
||||
if (!ttm_bo_eviction_valuable(bo, &place))
|
||||
if (!xe_bo_eviction_valuable(bo, &place))
|
||||
return -EBUSY;
|
||||
|
||||
if (!xe_bo_is_xe_bo(bo) || !xe_bo_get_unless_zero(xe_bo))
|
||||
@@ -1588,7 +1592,7 @@ const struct ttm_device_funcs xe_ttm_funcs = {
|
||||
.io_mem_pfn = xe_ttm_io_mem_pfn,
|
||||
.access_memory = xe_ttm_access_memory,
|
||||
.release_notify = xe_ttm_bo_release_notify,
|
||||
.eviction_valuable = ttm_bo_eviction_valuable,
|
||||
.eviction_valuable = xe_bo_eviction_valuable,
|
||||
.delete_mem_notify = xe_ttm_bo_delete_mem_notify,
|
||||
.swap_notify = xe_ttm_bo_swap_notify,
|
||||
};
|
||||
@@ -2431,6 +2435,8 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
|
||||
.no_wait_gpu = false,
|
||||
.gfp_retry_mayfail = true,
|
||||
};
|
||||
struct pin_cookie cookie;
|
||||
int ret;
|
||||
|
||||
if (vm) {
|
||||
lockdep_assert_held(&vm->lock);
|
||||
@@ -2440,8 +2446,12 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
|
||||
ctx.resv = xe_vm_resv(vm);
|
||||
}
|
||||
|
||||
cookie = xe_vm_set_validating(vm, allow_res_evict);
|
||||
trace_xe_bo_validate(bo);
|
||||
return ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
|
||||
ret = ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
|
||||
xe_vm_clear_validating(vm, allow_res_evict, cookie);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool xe_bo_is_xe_bo(struct ttm_buffer_object *bo)
|
||||
@@ -2557,7 +2567,7 @@ typedef int (*xe_gem_create_set_property_fn)(struct xe_device *xe,
|
||||
u64 value);
|
||||
|
||||
static const xe_gem_create_set_property_fn gem_create_set_property_funcs[] = {
|
||||
[DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY] = gem_create_set_pxp_type,
|
||||
[DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE] = gem_create_set_pxp_type,
|
||||
};
|
||||
|
||||
static int gem_create_user_ext_set_property(struct xe_device *xe,
|
||||
|
||||
@@ -115,7 +115,7 @@ auto_link_downgrade_capable_show(struct device *dev, struct device_attribute *at
|
||||
xe_pm_runtime_put(xe);
|
||||
|
||||
cap = REG_FIELD_GET(LINK_DOWNGRADE, val);
|
||||
return sysfs_emit(buf, "%u\n", cap == DOWNGRADE_CAPABLE ? true : false);
|
||||
return sysfs_emit(buf, "%u\n", cap == DOWNGRADE_CAPABLE);
|
||||
}
|
||||
static DEVICE_ATTR_ADMIN_RO(auto_link_downgrade_capable);
|
||||
|
||||
|
||||
@@ -325,6 +325,10 @@ struct xe_device {
|
||||
u8 has_heci_gscfi:1;
|
||||
/** @info.has_llc: Device has a shared CPU+GPU last level cache */
|
||||
u8 has_llc:1;
|
||||
/** @info.has_mbx_power_limits: Device has support to manage power limits using
|
||||
* pcode mailbox commands.
|
||||
*/
|
||||
u8 has_mbx_power_limits:1;
|
||||
/** @info.has_pxp: Device has PXP support */
|
||||
u8 has_pxp:1;
|
||||
/** @info.has_range_tlb_invalidation: Has range based TLB invalidations */
|
||||
|
||||
@@ -114,7 +114,6 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
|
||||
|
||||
static int __xe_exec_queue_init(struct xe_exec_queue *q)
|
||||
{
|
||||
struct xe_vm *vm = q->vm;
|
||||
int i, err;
|
||||
u32 flags = 0;
|
||||
|
||||
@@ -132,32 +131,20 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q)
|
||||
flags |= XE_LRC_CREATE_RUNALONE;
|
||||
}
|
||||
|
||||
if (vm) {
|
||||
err = xe_vm_lock(vm, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < q->width; ++i) {
|
||||
q->lrc[i] = xe_lrc_create(q->hwe, q->vm, SZ_16K, q->msix_vec, flags);
|
||||
if (IS_ERR(q->lrc[i])) {
|
||||
err = PTR_ERR(q->lrc[i]);
|
||||
goto err_unlock;
|
||||
goto err_lrc;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm)
|
||||
xe_vm_unlock(vm);
|
||||
|
||||
err = q->ops->init(q);
|
||||
if (err)
|
||||
goto err_lrc;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unlock:
|
||||
if (vm)
|
||||
xe_vm_unlock(vm);
|
||||
err_lrc:
|
||||
for (i = i - 1; i >= 0; --i)
|
||||
xe_lrc_put(q->lrc[i]);
|
||||
|
||||
@@ -51,7 +51,15 @@ static inline void xe_sched_tdr_queue_imm(struct xe_gpu_scheduler *sched)
|
||||
|
||||
static inline void xe_sched_resubmit_jobs(struct xe_gpu_scheduler *sched)
|
||||
{
|
||||
drm_sched_resubmit_jobs(&sched->base);
|
||||
struct drm_sched_job *s_job;
|
||||
|
||||
list_for_each_entry(s_job, &sched->base.pending_list, list) {
|
||||
struct drm_sched_fence *s_fence = s_job->s_fence;
|
||||
struct dma_fence *hw_fence = s_fence->parent;
|
||||
|
||||
if (hw_fence && !dma_fence_is_signaled(hw_fence))
|
||||
sched->base.ops->run_job(s_job);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
||||
@@ -229,6 +229,17 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
|
||||
static void guc_submit_fini(struct drm_device *drm, void *arg)
|
||||
{
|
||||
struct xe_guc *guc = arg;
|
||||
struct xe_device *xe = guc_to_xe(guc);
|
||||
struct xe_gt *gt = guc_to_gt(guc);
|
||||
int ret;
|
||||
|
||||
ret = wait_event_timeout(guc->submission_state.fini_wq,
|
||||
xa_empty(&guc->submission_state.exec_queue_lookup),
|
||||
HZ * 5);
|
||||
|
||||
drain_workqueue(xe->destroy_wq);
|
||||
|
||||
xe_gt_assert(gt, ret);
|
||||
|
||||
xa_destroy(&guc->submission_state.exec_queue_lookup);
|
||||
}
|
||||
|
||||
+287
-101
File diff suppressed because it is too large
Load Diff
@@ -876,10 +876,7 @@ static void xe_lrc_set_ppgtt(struct xe_lrc *lrc, struct xe_vm *vm)
|
||||
static void xe_lrc_finish(struct xe_lrc *lrc)
|
||||
{
|
||||
xe_hw_fence_ctx_finish(&lrc->fence_ctx);
|
||||
xe_bo_lock(lrc->bo, false);
|
||||
xe_bo_unpin(lrc->bo);
|
||||
xe_bo_unlock(lrc->bo);
|
||||
xe_bo_put(lrc->bo);
|
||||
xe_bo_unpin_map_no_vm(lrc->bo);
|
||||
}
|
||||
|
||||
#define PVC_CTX_ASID (0x2e + 1)
|
||||
@@ -914,7 +911,7 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
|
||||
* FIXME: Perma-pinning LRC as we don't yet support moving GGTT address
|
||||
* via VM bind calls.
|
||||
*/
|
||||
lrc->bo = xe_bo_create_pin_map(xe, tile, vm, lrc_size,
|
||||
lrc->bo = xe_bo_create_pin_map(xe, tile, NULL, lrc_size,
|
||||
ttm_bo_type_kernel,
|
||||
bo_flags);
|
||||
if (IS_ERR(lrc->bo))
|
||||
@@ -1676,9 +1673,6 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc)
|
||||
if (!snapshot)
|
||||
return NULL;
|
||||
|
||||
if (lrc->bo->vm)
|
||||
xe_vm_get(lrc->bo->vm);
|
||||
|
||||
snapshot->context_desc = xe_lrc_ggtt_addr(lrc);
|
||||
snapshot->ring_addr = __xe_lrc_ring_ggtt_addr(lrc);
|
||||
snapshot->indirect_context_desc = xe_lrc_indirect_ring_ggtt_addr(lrc);
|
||||
@@ -1700,14 +1694,12 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc)
|
||||
void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot)
|
||||
{
|
||||
struct xe_bo *bo;
|
||||
struct xe_vm *vm;
|
||||
struct iosys_map src;
|
||||
|
||||
if (!snapshot)
|
||||
return;
|
||||
|
||||
bo = snapshot->lrc_bo;
|
||||
vm = bo->vm;
|
||||
snapshot->lrc_bo = NULL;
|
||||
|
||||
snapshot->lrc_snapshot = kvmalloc(snapshot->lrc_size, GFP_KERNEL);
|
||||
@@ -1727,8 +1719,6 @@ void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot)
|
||||
xe_bo_unlock(bo);
|
||||
put_bo:
|
||||
xe_bo_put(bo);
|
||||
if (vm)
|
||||
xe_vm_put(vm);
|
||||
}
|
||||
|
||||
void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct drm_printer *p)
|
||||
@@ -1781,14 +1771,9 @@ void xe_lrc_snapshot_free(struct xe_lrc_snapshot *snapshot)
|
||||
return;
|
||||
|
||||
kvfree(snapshot->lrc_snapshot);
|
||||
if (snapshot->lrc_bo) {
|
||||
struct xe_vm *vm;
|
||||
|
||||
vm = snapshot->lrc_bo->vm;
|
||||
if (snapshot->lrc_bo)
|
||||
xe_bo_put(snapshot->lrc_bo);
|
||||
if (vm)
|
||||
xe_vm_put(vm);
|
||||
}
|
||||
|
||||
kfree(snapshot);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ struct xe_device_desc {
|
||||
u8 has_heci_gscfi:1;
|
||||
u8 has_heci_cscfi:1;
|
||||
u8 has_llc:1;
|
||||
u8 has_mbx_power_limits:1;
|
||||
u8 has_pxp:1;
|
||||
u8 has_sriov:1;
|
||||
u8 needs_scratch:1;
|
||||
@@ -305,6 +306,7 @@ static const struct xe_device_desc dg2_desc = {
|
||||
DG2_FEATURES,
|
||||
.has_display = true,
|
||||
.has_fan_control = true,
|
||||
.has_mbx_power_limits = false,
|
||||
};
|
||||
|
||||
static const __maybe_unused struct xe_device_desc pvc_desc = {
|
||||
@@ -316,6 +318,7 @@ static const __maybe_unused struct xe_device_desc pvc_desc = {
|
||||
.has_heci_gscfi = 1,
|
||||
.max_remote_tiles = 1,
|
||||
.require_force_probe = true,
|
||||
.has_mbx_power_limits = false,
|
||||
};
|
||||
|
||||
static const struct xe_device_desc mtl_desc = {
|
||||
@@ -341,6 +344,7 @@ static const struct xe_device_desc bmg_desc = {
|
||||
.dma_mask_size = 46,
|
||||
.has_display = true,
|
||||
.has_fan_control = true,
|
||||
.has_mbx_power_limits = true,
|
||||
.has_heci_cscfi = 1,
|
||||
.needs_scratch = true,
|
||||
};
|
||||
@@ -583,6 +587,7 @@ static int xe_info_init_early(struct xe_device *xe,
|
||||
xe->info.dma_mask_size = desc->dma_mask_size;
|
||||
xe->info.is_dgfx = desc->is_dgfx;
|
||||
xe->info.has_fan_control = desc->has_fan_control;
|
||||
xe->info.has_mbx_power_limits = desc->has_mbx_power_limits;
|
||||
xe->info.has_heci_gscfi = desc->has_heci_gscfi;
|
||||
xe->info.has_heci_cscfi = desc->has_heci_cscfi;
|
||||
xe->info.has_llc = desc->has_llc;
|
||||
|
||||
@@ -109,6 +109,17 @@ int xe_pcode_write_timeout(struct xe_tile *tile, u32 mbox, u32 data, int timeout
|
||||
return err;
|
||||
}
|
||||
|
||||
int xe_pcode_write64_timeout(struct xe_tile *tile, u32 mbox, u32 data0, u32 data1, int timeout)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&tile->pcode.lock);
|
||||
err = pcode_mailbox_rw(tile, mbox, &data0, &data1, timeout, false, false);
|
||||
mutex_unlock(&tile->pcode.lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int xe_pcode_read(struct xe_tile *tile, u32 mbox, u32 *val, u32 *val1)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -18,6 +18,9 @@ int xe_pcode_init_min_freq_table(struct xe_tile *tile, u32 min_gt_freq,
|
||||
int xe_pcode_read(struct xe_tile *tile, u32 mbox, u32 *val, u32 *val1);
|
||||
int xe_pcode_write_timeout(struct xe_tile *tile, u32 mbox, u32 val,
|
||||
int timeout_ms);
|
||||
int xe_pcode_write64_timeout(struct xe_tile *tile, u32 mbox, u32 data0,
|
||||
u32 data1, int timeout);
|
||||
|
||||
#define xe_pcode_write(tile, mbox, val) \
|
||||
xe_pcode_write_timeout(tile, mbox, val, 1)
|
||||
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
#define POWER_SETUP_I1_SHIFT 6 /* 10.6 fixed point format */
|
||||
#define POWER_SETUP_I1_DATA_MASK REG_GENMASK(15, 0)
|
||||
|
||||
#define READ_PSYSGPU_POWER_LIMIT 0x6
|
||||
#define WRITE_PSYSGPU_POWER_LIMIT 0x7
|
||||
#define READ_PACKAGE_POWER_LIMIT 0x8
|
||||
#define WRITE_PACKAGE_POWER_LIMIT 0x9
|
||||
#define READ_PL_FROM_FW 0x1
|
||||
#define READ_PL_FROM_PCODE 0x0
|
||||
|
||||
#define PCODE_FREQUENCY_CONFIG 0x6e
|
||||
/* Frequency Config Sub Commands (param1) */
|
||||
#define PCODE_MBOX_FC_SC_READ_FUSED_P0 0x0
|
||||
|
||||
@@ -541,10 +541,14 @@ int xe_pxp_exec_queue_add(struct xe_pxp *pxp, struct xe_exec_queue *q)
|
||||
*/
|
||||
xe_pm_runtime_get(pxp->xe);
|
||||
|
||||
if (!pxp_prerequisites_done(pxp)) {
|
||||
ret = -EBUSY;
|
||||
/* get_readiness_status() returns 0 for in-progress and 1 for done */
|
||||
ret = xe_pxp_get_readiness_status(pxp);
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
wait_for_idle:
|
||||
/*
|
||||
|
||||
+16
-11
@@ -1678,13 +1678,21 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
|
||||
* scheduler drops all the references of it, hence protecting the VM
|
||||
* for this case is necessary.
|
||||
*/
|
||||
if (flags & XE_VM_FLAG_LR_MODE)
|
||||
if (flags & XE_VM_FLAG_LR_MODE) {
|
||||
INIT_WORK(&vm->preempt.rebind_work, preempt_rebind_work_func);
|
||||
xe_pm_runtime_get_noresume(xe);
|
||||
}
|
||||
|
||||
if (flags & XE_VM_FLAG_FAULT_MODE) {
|
||||
err = xe_svm_init(vm);
|
||||
if (err)
|
||||
goto err_no_resv;
|
||||
}
|
||||
|
||||
vm_resv_obj = drm_gpuvm_resv_object_alloc(&xe->drm);
|
||||
if (!vm_resv_obj) {
|
||||
err = -ENOMEM;
|
||||
goto err_no_resv;
|
||||
goto err_svm_fini;
|
||||
}
|
||||
|
||||
drm_gpuvm_init(&vm->gpuvm, "Xe VM", DRM_GPUVM_RESV_PROTECTED, &xe->drm,
|
||||
@@ -1724,10 +1732,8 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
|
||||
vm->batch_invalidate_tlb = true;
|
||||
}
|
||||
|
||||
if (vm->flags & XE_VM_FLAG_LR_MODE) {
|
||||
INIT_WORK(&vm->preempt.rebind_work, preempt_rebind_work_func);
|
||||
if (vm->flags & XE_VM_FLAG_LR_MODE)
|
||||
vm->batch_invalidate_tlb = false;
|
||||
}
|
||||
|
||||
/* Fill pt_root after allocating scratch tables */
|
||||
for_each_tile(tile, xe, id) {
|
||||
@@ -1757,12 +1763,6 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & XE_VM_FLAG_FAULT_MODE) {
|
||||
err = xe_svm_init(vm);
|
||||
if (err)
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
if (number_tiles > 1)
|
||||
vm->composite_fence_ctx = dma_fence_context_alloc(1);
|
||||
|
||||
@@ -1776,6 +1776,11 @@ err_close:
|
||||
xe_vm_close_and_put(vm);
|
||||
return ERR_PTR(err);
|
||||
|
||||
err_svm_fini:
|
||||
if (flags & XE_VM_FLAG_FAULT_MODE) {
|
||||
vm->size = 0; /* close the vm */
|
||||
xe_svm_fini(vm);
|
||||
}
|
||||
err_no_resv:
|
||||
mutex_destroy(&vm->snap_mutex);
|
||||
for_each_tile(tile, xe, id)
|
||||
|
||||
@@ -301,6 +301,75 @@ void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap);
|
||||
void xe_vm_snapshot_print(struct xe_vm_snapshot *snap, struct drm_printer *p);
|
||||
void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
|
||||
|
||||
/**
|
||||
* xe_vm_set_validating() - Register this task as currently making bos resident
|
||||
* @allow_res_evict: Allow eviction of buffer objects bound to @vm when
|
||||
* validating.
|
||||
* @vm: Pointer to the vm or NULL.
|
||||
*
|
||||
* Register this task as currently making bos resident for the vm. Intended
|
||||
* to avoid eviction by the same task of shared bos bound to the vm.
|
||||
* Call with the vm's resv lock held.
|
||||
*
|
||||
* Return: A pin cookie that should be used for xe_vm_clear_validating().
|
||||
*/
|
||||
static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
|
||||
bool allow_res_evict)
|
||||
{
|
||||
struct pin_cookie cookie = {};
|
||||
|
||||
if (vm && !allow_res_evict) {
|
||||
xe_vm_assert_held(vm);
|
||||
cookie = lockdep_pin_lock(&xe_vm_resv(vm)->lock.base);
|
||||
/* Pairs with READ_ONCE in xe_vm_is_validating() */
|
||||
WRITE_ONCE(vm->validating, current);
|
||||
}
|
||||
|
||||
return cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_vm_clear_validating() - Unregister this task as currently making bos resident
|
||||
* @vm: Pointer to the vm or NULL
|
||||
* @allow_res_evict: Eviction from @vm was allowed. Must be set to the same
|
||||
* value as for xe_vm_set_validation().
|
||||
* @cookie: Cookie obtained from xe_vm_set_validating().
|
||||
*
|
||||
* Register this task as currently making bos resident for the vm. Intended
|
||||
* to avoid eviction by the same task of shared bos bound to the vm.
|
||||
* Call with the vm's resv lock held.
|
||||
*/
|
||||
static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict,
|
||||
struct pin_cookie cookie)
|
||||
{
|
||||
if (vm && !allow_res_evict) {
|
||||
lockdep_unpin_lock(&xe_vm_resv(vm)->lock.base, cookie);
|
||||
/* Pairs with READ_ONCE in xe_vm_is_validating() */
|
||||
WRITE_ONCE(vm->validating, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_vm_is_validating() - Whether bos bound to the vm are currently being made resident
|
||||
* by the current task.
|
||||
* @vm: Pointer to the vm.
|
||||
*
|
||||
* If this function returns %true, we should be in a vm resv locked region, since
|
||||
* the current process is the same task that called xe_vm_set_validating().
|
||||
* The function asserts that that's indeed the case.
|
||||
*
|
||||
* Return: %true if the task is currently making bos resident, %false otherwise.
|
||||
*/
|
||||
static inline bool xe_vm_is_validating(struct xe_vm *vm)
|
||||
{
|
||||
/* Pairs with WRITE_ONCE in xe_vm_is_validating() */
|
||||
if (READ_ONCE(vm->validating) == current) {
|
||||
xe_vm_assert_held(vm);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT)
|
||||
void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma);
|
||||
#else
|
||||
|
||||
@@ -310,6 +310,14 @@ struct xe_vm {
|
||||
* protected by the vm resv.
|
||||
*/
|
||||
u64 tlb_flush_seqno;
|
||||
/**
|
||||
* @validating: The task that is currently making bos resident for this vm.
|
||||
* Protected by the VM's resv for writing. Opportunistic reading can be done
|
||||
* using READ_ONCE. Note: This is a workaround for the
|
||||
* TTM eviction_valuable() callback not being passed a struct
|
||||
* ttm_operation_context(). Future work might want to address this.
|
||||
*/
|
||||
struct task_struct *validating;
|
||||
/** @batch_invalidate_tlb: Always invalidate TLB before batch start */
|
||||
bool batch_invalidate_tlb;
|
||||
/** @xef: XE file handle for tracking this VM's drm client */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user