Commit 5bde069b authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2022-07-13' of...

Merge tag 'drm-intel-fixes-2022-07-13' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-fixes

- Selftest fix (Andrzej)
- TTM fix sg_table construction (Matt Auld)
- Error return fixes (Dan)
- Fix a performance regression related to waitboost (Chris)
- Fix GT resets (Chris)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Ys87yMujcG2sJC1R@intel.com
parents b1f4347f 333991c4
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -620,10 +620,15 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
			 struct ttm_resource *res)
{
	struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
	u64 page_alignment;

	if (!i915_ttm_gtt_binds_lmem(res))
		return i915_ttm_tt_get_st(bo->ttm);

	page_alignment = bo->page_alignment << PAGE_SHIFT;
	if (!page_alignment)
		page_alignment = obj->mm.region->min_page_size;

	/*
	 * If CPU mapping differs, we need to add the ttm_tt pages to
	 * the resulting st. Might make sense for GGTT.
@@ -634,7 +639,8 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
			struct i915_refct_sgt *rsgt;

			rsgt = intel_region_ttm_resource_to_rsgt(obj->mm.region,
								 res);
								 res,
								 page_alignment);
			if (IS_ERR(rsgt))
				return rsgt;

@@ -643,7 +649,8 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
		return i915_refct_sgt_get(obj->ttm.cached_io_rsgt);
	}

	return intel_region_ttm_resource_to_rsgt(obj->mm.region, res);
	return intel_region_ttm_resource_to_rsgt(obj->mm.region, res,
						 page_alignment);
}

static int i915_ttm_truncate(struct drm_i915_gem_object *obj)
+34 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/jiffies.h>

#include "gt/intel_engine.h"
#include "gt/intel_rps.h"

#include "i915_gem_ioctls.h"
#include "i915_gem_object.h"
@@ -31,6 +32,37 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
				      timeout);
}

static void
i915_gem_object_boost(struct dma_resv *resv, unsigned int flags)
{
	struct dma_resv_iter cursor;
	struct dma_fence *fence;

	/*
	 * Prescan all fences for potential boosting before we begin waiting.
	 *
	 * When we wait, we wait on outstanding fences serially. If the
	 * dma-resv contains a sequence such as 1:1, 1:2 instead of a reduced
	 * form 1:2, then as we look at each wait in turn we see that each
	 * request is currently executing and not worthy of boosting. But if
	 * we only happen to look at the final fence in the sequence (because
	 * of request coalescing or splitting between read/write arrays by
	 * the iterator), then we would boost. As such our decision to boost
	 * or not is delicately balanced on the order we wait on fences.
	 *
	 * So instead of looking for boosts sequentially, look for all boosts
	 * upfront and then wait on the outstanding fences.
	 */

	dma_resv_iter_begin(&cursor, resv,
			    dma_resv_usage_rw(flags & I915_WAIT_ALL));
	dma_resv_for_each_fence_unlocked(&cursor, fence)
		if (dma_fence_is_i915(fence) &&
		    !i915_request_started(to_request(fence)))
			intel_rps_boost(to_request(fence));
	dma_resv_iter_end(&cursor);
}

static long
i915_gem_object_wait_reservation(struct dma_resv *resv,
				 unsigned int flags,
@@ -40,6 +72,8 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
	struct dma_fence *fence;
	long ret = timeout ?: 1;

	i915_gem_object_boost(resv, flags);

	dma_resv_iter_begin(&cursor, resv,
			    dma_resv_usage_rw(flags & I915_WAIT_ALL));
	dma_resv_for_each_fence_unlocked(&cursor, fence) {
+14 −1
Original line number Diff line number Diff line
@@ -1209,6 +1209,20 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
	mutex_lock(&gt->tlb_invalidate_lock);
	intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);

	spin_lock_irq(&uncore->lock); /* serialise invalidate with GT reset */

	for_each_engine(engine, gt, id) {
		struct reg_and_bit rb;

		rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
		if (!i915_mmio_reg_offset(rb.reg))
			continue;

		intel_uncore_write_fw(uncore, rb.reg, rb.bit);
	}

	spin_unlock_irq(&uncore->lock);

	for_each_engine(engine, gt, id) {
		/*
		 * HW architecture suggest typical invalidation time at 40us,
@@ -1223,7 +1237,6 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
		if (!i915_mmio_reg_offset(rb.reg))
			continue;

		intel_uncore_write_fw(uncore, rb.reg, rb.bit);
		if (__intel_wait_for_register_fw(uncore,
						 rb.reg, rb.bit, 0,
						 timeout_us, timeout_ms,
+28 −9
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
	return err;
}

static int gen6_reset_engines(struct intel_gt *gt,
static int __gen6_reset_engines(struct intel_gt *gt,
				intel_engine_mask_t engine_mask,
				unsigned int retry)
{
@@ -321,6 +321,20 @@ static int gen6_reset_engines(struct intel_gt *gt,
	return gen6_hw_domain_reset(gt, hw_mask);
}

static int gen6_reset_engines(struct intel_gt *gt,
			      intel_engine_mask_t engine_mask,
			      unsigned int retry)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&gt->uncore->lock, flags);
	ret = __gen6_reset_engines(gt, engine_mask, retry);
	spin_unlock_irqrestore(&gt->uncore->lock, flags);

	return ret;
}

static struct intel_engine_cs *find_sfc_paired_vecs_engine(struct intel_engine_cs *engine)
{
	int vecs_id;
@@ -487,7 +501,7 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine)
	rmw_clear_fw(uncore, sfc_lock.lock_reg, sfc_lock.lock_bit);
}

static int gen11_reset_engines(struct intel_gt *gt,
static int __gen11_reset_engines(struct intel_gt *gt,
				 intel_engine_mask_t engine_mask,
				 unsigned int retry)
{
@@ -583,8 +597,11 @@ static int gen8_reset_engines(struct intel_gt *gt,
	struct intel_engine_cs *engine;
	const bool reset_non_ready = retry >= 1;
	intel_engine_mask_t tmp;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&gt->uncore->lock, flags);

	for_each_engine_masked(engine, gt, engine_mask, tmp) {
		ret = gen8_engine_reset_prepare(engine);
		if (ret && !reset_non_ready)
@@ -612,17 +629,19 @@ static int gen8_reset_engines(struct intel_gt *gt,
	 * This is best effort, so ignore any error from the initial reset.
	 */
	if (IS_DG2(gt->i915) && engine_mask == ALL_ENGINES)
		gen11_reset_engines(gt, gt->info.engine_mask, 0);
		__gen11_reset_engines(gt, gt->info.engine_mask, 0);

	if (GRAPHICS_VER(gt->i915) >= 11)
		ret = gen11_reset_engines(gt, engine_mask, retry);
		ret = __gen11_reset_engines(gt, engine_mask, retry);
	else
		ret = gen6_reset_engines(gt, engine_mask, retry);
		ret = __gen6_reset_engines(gt, engine_mask, retry);

skip_reset:
	for_each_engine_masked(engine, gt, engine_mask, tmp)
		gen8_engine_reset_cancel(engine);

	spin_unlock_irqrestore(&gt->uncore->lock, flags);

	return ret;
}

+4 −4
Original line number Diff line number Diff line
@@ -176,8 +176,8 @@ static int live_lrc_layout(void *arg)
			continue;

		hw = shmem_pin_map(engine->default_state);
		if (IS_ERR(hw)) {
			err = PTR_ERR(hw);
		if (!hw) {
			err = -ENOMEM;
			break;
		}
		hw += LRC_STATE_OFFSET / sizeof(*hw);
@@ -365,8 +365,8 @@ static int live_lrc_fixed(void *arg)
			continue;

		hw = shmem_pin_map(engine->default_state);
		if (IS_ERR(hw)) {
			err = PTR_ERR(hw);
		if (!hw) {
			err = -ENOMEM;
			break;
		}
		hw += LRC_STATE_OFFSET / sizeof(*hw);
Loading