mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 18:12:03 +02:00
Fixes in:
- CRI throttle reasons report (Sk) - TLB invalidation at wedge (Shuicheng) - SVM eviction and VM close (Brost) - Display corruption on LNL on Xen PV (Szymon) - W/a fix and addition (Tilak) -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmq1KCQACgkQ+mJfZA7r E8pjZAgAoGb4wVoZ9Qm1qCWRXiUJWoD63X9/s0cYe9qDoStsfJ3oppKuuy6A2lZQ SvaTLExbRLtYJiPU0RWQcphiay5lnjQzkjIrGMt8cMA/9fVPgdXfL13PXeJuJ4yM uQzv9+eWuptjyHxNbCuW0pEnxWZ8yyR/lMbyX68+hdJl7TgSDWHEllTkv8+xuNPn APyIizk69bI3VPzBcl0GcoW3VOtabgUzZiWkuuehuVf+Bl2vwZElRScjLq5gNZ3x IzNOQPE1z6d0v2drK/bk7SzfEt41o/J9RqKnoBguhW66XFbRU3/sVn924yCpThHQ 74e9Wa2DP2pdJZ6htJcnrNRl9ZNi9A== =cXRT -----END PGP SIGNATURE----- Merge tag 'drm-xe-fixes-2026-09-24' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes Fixes in: - CRI throttle reasons report (Sk) - TLB invalidation at wedge (Shuicheng) - SVM eviction and VM close (Brost) - Display corruption on LNL on Xen PV (Szymon) - W/a fix and addition (Tilak) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patch.msgid.link/arUoUf9LpsJpJouN@intel.com
This commit is contained in:
commit
c5d1690ff1
|
|
@ -651,6 +651,7 @@
|
|||
#define MEM_THERMAL_MASK REG_BIT(2)
|
||||
#define VR_THERMAL_MASK REG_BIT(3)
|
||||
#define ICCMAX_MASK REG_BIT(4)
|
||||
#define PWRBRK_MASK REG_BIT(5)
|
||||
#define SOC_AVG_THERMAL_MASK REG_BIT(6)
|
||||
#define FASTVMODE_MASK REG_BIT(7)
|
||||
#define PSYS_PL1_MASK REG_BIT(12)
|
||||
|
|
|
|||
|
|
@ -1037,6 +1037,13 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
|
|||
} else {
|
||||
drm_dbg(&xe->drm, "Evict system allocator BO failed=%pe\n",
|
||||
ERR_PTR(ret));
|
||||
/*
|
||||
* The semantic we want upon SVM eviction failure
|
||||
* because of racing access is keep walking for
|
||||
* eviction, which is -ENOSPC.
|
||||
*/
|
||||
if (ret == -EBUSY)
|
||||
ret = -ENOSPC;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <drm/drm_prime.h>
|
||||
#include <drm/ttm/ttm_tt.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
|
||||
#include "xe_bo_types.h"
|
||||
#include "xe_ggtt.h"
|
||||
#include "xe_macros.h"
|
||||
|
|
@ -575,6 +577,23 @@ static inline unsigned int xe_sg_segment_size(struct device *dev)
|
|||
struct scatterlist __maybe_unused sg;
|
||||
size_t max = BIT_ULL(sizeof(sg.length) * 8) - 1;
|
||||
|
||||
/*
|
||||
* For Xen PV guests pages aren't contiguous in DMA (machine) address
|
||||
* space. The DMA API takes care of that both in dma_alloc_* (by
|
||||
* calling into the hypervisor to make the pages contiguous) and in
|
||||
* dma_map_* (by bounce buffering). But xe (like i915, see commit
|
||||
* 78a07fe777c4) ignores the coherency aspects of the DMA API and thus
|
||||
* can't cope with bounce buffering actually happening, so add a hack
|
||||
* here to force small allocations and mappings when running in PV
|
||||
* mode on Xen.
|
||||
*
|
||||
* Note this will still break if bounce buffering is required for other
|
||||
* reasons, like confidential computing hypervisors or PCIe root ports
|
||||
* with addressing limitations.
|
||||
*/
|
||||
if (xen_pv_domain())
|
||||
return PAGE_SIZE;
|
||||
|
||||
max = min_t(size_t, max, dma_max_mapping_size(dev));
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
* - ``reason_mem_thermal``: Memory thermal
|
||||
* - ``reason_vr_thermal``: VR thermal
|
||||
* - ``reason_iccmax``: ICCMAX
|
||||
* - ``reason_ratl``: RATL thermal algorithm
|
||||
* - ``reason_pwrbrk``: Power brake
|
||||
* - ``reason_soc_avg_thermal``: SoC average temp
|
||||
* - ``reason_fastvmode``: VR is hitting FastVMode
|
||||
* - ``reason_psys_pl1``: PSYS PL1
|
||||
|
|
@ -200,6 +200,7 @@ static THROTTLE_ATTR_RO(reason_psys_pl1, PSYS_PL1_MASK);
|
|||
static THROTTLE_ATTR_RO(reason_psys_pl2, PSYS_PL2_MASK);
|
||||
static THROTTLE_ATTR_RO(reason_p0_freq, P0_FREQ_MASK);
|
||||
static THROTTLE_ATTR_RO(reason_psys_crit, PSYS_CRIT_MASK);
|
||||
static THROTTLE_ATTR_RO(reason_pwrbrk, PWRBRK_MASK);
|
||||
|
||||
static struct attribute *cri_throttle_attrs[] = {
|
||||
/* Common */
|
||||
|
|
@ -209,12 +210,12 @@ static struct attribute *cri_throttle_attrs[] = {
|
|||
&attr_reason_pl2.attr.attr,
|
||||
&attr_reason_pl4.attr.attr,
|
||||
&attr_reason_prochot.attr.attr,
|
||||
&attr_reason_ratl.attr.attr,
|
||||
/* CRI */
|
||||
&attr_reason_vr_thermal.attr.attr,
|
||||
&attr_reason_soc_thermal.attr.attr,
|
||||
&attr_reason_mem_thermal.attr.attr,
|
||||
&attr_reason_iccmax.attr.attr,
|
||||
&attr_reason_pwrbrk.attr.attr,
|
||||
&attr_reason_soc_avg_thermal.attr.attr,
|
||||
&attr_reason_fastvmode.attr.attr,
|
||||
&attr_reason_psys_pl1.attr.attr,
|
||||
|
|
|
|||
|
|
@ -864,7 +864,7 @@ static unsigned int guc_mmio_regset_write(struct xe_guc_ads *ads,
|
|||
}
|
||||
}
|
||||
|
||||
if (XE_GT_WA(hwe->gt, 16023105232))
|
||||
if (XE_GT_WA(hwe->gt, 16023105232) || XE_GT_WA(hwe->gt, 14025941587))
|
||||
guc_mmio_regset_write_one(ads, regset_map,
|
||||
RING_IDLEDLY(hwe->mmio_base),
|
||||
count++);
|
||||
|
|
|
|||
|
|
@ -585,28 +585,102 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe,
|
|||
xe_reg_whitelist_process_engine(hwe);
|
||||
}
|
||||
|
||||
static u32 idledly_floor_ticks(u32 idledly_ns, u32 idledly_units_ps)
|
||||
{
|
||||
return DIV_ROUND_DOWN_ULL((u64)idledly_ns * 1000, idledly_units_ps);
|
||||
}
|
||||
|
||||
static void adjust_idledly(struct xe_hw_engine *hwe)
|
||||
{
|
||||
struct xe_gt *gt = hwe->gt;
|
||||
u32 idledly, maxcnt;
|
||||
u32 idledly, idledly_hw, idledly_reg_val, maxcnt;
|
||||
u32 idledly_units_ps = 8 * gt->info.timestamp_base;
|
||||
u32 maxcnt_units_ns = 640;
|
||||
bool inhibit_switch = 0;
|
||||
bool inhibit_switch = false;
|
||||
bool wa_applied = false;
|
||||
bool clamped_below_maxcnt = false;
|
||||
|
||||
if (!IS_SRIOV_VF(gt_to_xe(hwe->gt)) && XE_GT_WA(gt, 16023105232)) {
|
||||
idledly = xe_mmio_read32(>->mmio, RING_IDLEDLY(hwe->mmio_base));
|
||||
if ((!IS_SRIOV_VF(gt_to_xe(gt)) && XE_GT_WA(gt, 16023105232)) ||
|
||||
XE_GT_WA(gt, 14025941587)) {
|
||||
u32 mincnt_idledly_ns = 5000;
|
||||
|
||||
/* xe_gt_clock_init() warns and zeroes timestamp_base on unknown crystal clock. */
|
||||
if (!idledly_units_ps)
|
||||
return;
|
||||
|
||||
idledly_reg_val = xe_mmio_read32(>->mmio, RING_IDLEDLY(hwe->mmio_base));
|
||||
maxcnt = xe_mmio_read32(>->mmio, RING_PWRCTX_MAXCNT(hwe->mmio_base));
|
||||
|
||||
inhibit_switch = idledly & INHIBIT_SWITCH_UNTIL_PREEMPTED;
|
||||
idledly = REG_FIELD_GET(IDLE_DELAY, idledly);
|
||||
idledly = DIV_ROUND_CLOSEST(idledly * idledly_units_ps, 1000);
|
||||
inhibit_switch = idledly_reg_val & INHIBIT_SWITCH_UNTIL_PREEMPTED;
|
||||
idledly = REG_FIELD_GET(IDLE_DELAY, idledly_reg_val);
|
||||
idledly = DIV_ROUND_CLOSEST_ULL((u64)idledly * idledly_units_ps, 1000);
|
||||
idledly_hw = idledly;
|
||||
maxcnt = REG_FIELD_GET(IDLE_WAIT_TIME, maxcnt);
|
||||
maxcnt *= maxcnt_units_ns;
|
||||
|
||||
if (xe_gt_WARN_ON(gt, idledly >= maxcnt || inhibit_switch)) {
|
||||
idledly = DIV_ROUND_CLOSEST(((maxcnt - 1) * 1000),
|
||||
idledly_units_ps);
|
||||
xe_mmio_write32(>->mmio, RING_IDLEDLY(hwe->mmio_base), idledly);
|
||||
/*
|
||||
* Wa_14025941587 is applied before Wa_16023105232, which takes
|
||||
* priority if the two ever conflict (not expected in practice).
|
||||
*/
|
||||
if (XE_GT_WA(gt, 14025941587) &&
|
||||
idledly < mincnt_idledly_ns) {
|
||||
idledly = mincnt_idledly_ns;
|
||||
wa_applied = true;
|
||||
}
|
||||
|
||||
if (XE_GT_WA(gt, 16023105232)) {
|
||||
/* Clear the inhibit switch without disturbing a valid delay. */
|
||||
if (inhibit_switch) {
|
||||
idledly_reg_val &= ~INHIBIT_SWITCH_UNTIL_PREEMPTED;
|
||||
wa_applied = true;
|
||||
}
|
||||
|
||||
/* Warn only on the value read from hardware. */
|
||||
xe_gt_WARN_ON(gt, idledly_hw >= maxcnt);
|
||||
|
||||
if (idledly >= maxcnt) {
|
||||
/* maxcnt may be 0 if IDLE_WAIT_TIME is unprogrammed. */
|
||||
idledly = maxcnt ? maxcnt - 1 : 0;
|
||||
clamped_below_maxcnt = true;
|
||||
wa_applied = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wa_applied) {
|
||||
u32 idledly_ticks;
|
||||
|
||||
/*
|
||||
* Wa_16023105232 requires idledly < maxcnt, so floor
|
||||
* that clamp; otherwise round up to guarantee the
|
||||
* Wa_14025941587 minimum survives tick quantization.
|
||||
*/
|
||||
if (clamped_below_maxcnt)
|
||||
idledly_ticks = idledly_floor_ticks(idledly, idledly_units_ps);
|
||||
else
|
||||
idledly_ticks = DIV_ROUND_UP_ULL((u64)idledly * 1000,
|
||||
idledly_units_ps);
|
||||
|
||||
/*
|
||||
* Tick quantization can still push the rounded-up value
|
||||
* to/above maxcnt; re-floor here so Wa_16023105232 keeps
|
||||
* priority even in that case.
|
||||
*/
|
||||
if (!clamped_below_maxcnt && XE_GT_WA(gt, 16023105232) &&
|
||||
(u64)idledly_ticks * idledly_units_ps >= (u64)maxcnt * 1000) {
|
||||
xe_gt_dbg(gt, "idledly %s: %u ticks would exceed maxcnt=%u, so flooring\n",
|
||||
hwe->name, idledly_ticks, maxcnt);
|
||||
idledly = maxcnt ? maxcnt - 1 : 0;
|
||||
idledly_ticks = idledly_floor_ticks(idledly, idledly_units_ps);
|
||||
}
|
||||
|
||||
idledly_reg_val &= ~IDLE_DELAY;
|
||||
idledly_reg_val |= REG_FIELD_PREP(IDLE_DELAY, idledly_ticks);
|
||||
xe_gt_dbg(gt, "idledly %s: set %u max=%u inh=%u ts=%u\n",
|
||||
hwe->name, idledly, maxcnt,
|
||||
!!inhibit_switch, gt->info.timestamp_base);
|
||||
xe_mmio_write32(>->mmio,
|
||||
RING_IDLEDLY(hwe->mmio_base),
|
||||
idledly_reg_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,8 @@ static void xe_tlb_inval_fence_prep(struct xe_tlb_inval_fence *fence)
|
|||
xe_tlb_inval_fence_signal_unlocked((__fence)); \
|
||||
mutex_unlock(&(__tlb_inval)->seqno_lock); \
|
||||
\
|
||||
__ret == -ECANCELED ? 0 : __ret; \
|
||||
/* Undelivered: fence already signalled, report done */ \
|
||||
(__ret == -ECANCELED || __ret == -ENOTRECOVERABLE) ? 0 : __ret; \
|
||||
})
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1947,21 +1947,13 @@ void xe_vm_close_and_put(struct xe_vm *vm)
|
|||
vma->gpuva.flags |= XE_VMA_DESTROYED;
|
||||
}
|
||||
|
||||
/*
|
||||
* All vm operations will add shared fences to resv.
|
||||
* The only exception is eviction for a shared object,
|
||||
* but even so, the unbind when evicted would still
|
||||
* install a fence to resv. Hence it's safe to
|
||||
* destroy the pagetables immediately.
|
||||
*/
|
||||
xe_vm_free_scratch(vm);
|
||||
xe_vm_pt_destroy(vm);
|
||||
xe_vm_unlock(vm);
|
||||
|
||||
/*
|
||||
* VM is now dead, cannot re-add nodes to vm->vmas if it's NULL
|
||||
* Since we hold a refcount to the bo, we can remove and free
|
||||
* the members safely without locking.
|
||||
* Unlink and destroy all contested external-BO VMAs before destroying
|
||||
* the page tables. Otherwise, concurrent eviction holding only bo->resv
|
||||
* can walk the BO's VMAs and attempt to invalidate/zap page tables that
|
||||
* have already been freed.
|
||||
*/
|
||||
list_for_each_entry_safe(vma, next_vma, &contested,
|
||||
combined_links.destroy) {
|
||||
|
|
@ -1969,6 +1961,11 @@ void xe_vm_close_and_put(struct xe_vm *vm)
|
|||
xe_vma_destroy_unlocked(vma);
|
||||
}
|
||||
|
||||
xe_vm_lock(vm, false);
|
||||
xe_vm_free_scratch(vm);
|
||||
xe_vm_pt_destroy(vm);
|
||||
xe_vm_unlock(vm);
|
||||
|
||||
xe_svm_fini(vm);
|
||||
|
||||
up_write(&vm->lock);
|
||||
|
|
|
|||
|
|
@ -72,3 +72,5 @@
|
|||
16029897822 MEDIA_VERSION(3500)
|
||||
GRAPHICS_VERSION(3510)
|
||||
14027054324 GRAPHICS_VERSION(3511)
|
||||
14025941587 GRAPHICS_VERSION_RANGE(2001, 3511), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
MEDIA_VERSION_RANGE(1301, 3503), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user