[Intel-gfx] [PATCH 01/28] drm/i915: Move fence register tracking from i915->mm to ggtt

Mika Kuoppala mika.kuoppala at linux.intel.com
Mon Jun 10 09:46:43 UTC 2019


Chris Wilson <chris at chris-wilson.co.uk> writes:

> As the fence registers only apply to regions inside the GGTT is makes
> more sense that we track these as part of the i915_ggtt and not the
> general mm. In the next patch, we will then pull the register locking
> underneath the i915_ggtt.mutex.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  4 +-
>  drivers/gpu/drm/i915/gem/i915_gem_pm.c    |  2 +-
>  drivers/gpu/drm/i915/gt/intel_reset.c     |  6 +-
>  drivers/gpu/drm/i915/gvt/aperture_gm.c    |  7 +-
>  drivers/gpu/drm/i915/gvt/gvt.h            |  4 +-
>  drivers/gpu/drm/i915/i915_debugfs.c       | 42 +++++------
>  drivers/gpu/drm/i915/i915_drv.c           |  3 +-
>  drivers/gpu/drm/i915/i915_drv.h           | 28 --------
>  drivers/gpu/drm/i915/i915_gem.c           | 52 +++-----------
>  drivers/gpu/drm/i915/i915_gem_fence_reg.c | 85 +++++++++++++++++------
>  drivers/gpu/drm/i915/i915_gem_fence_reg.h | 19 ++++-
>  drivers/gpu/drm/i915/i915_gem_gtt.c       |  2 +
>  drivers/gpu/drm/i915/i915_gem_gtt.h       | 14 +++-
>  drivers/gpu/drm/i915/i915_gpu_error.c     |  6 +-
>  drivers/gpu/drm/i915/i915_vma.h           |  2 +-
>  15 files changed, 144 insertions(+), 132 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index c7b9b34de01b..a8b8b9c281f1 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -310,9 +310,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>  	/* Mark as being mmapped into userspace for later revocation */
>  	assert_rpm_wakelock_held(i915);
>  	if (!i915_vma_set_userfault(vma) && !obj->userfault_count++)
> -		list_add(&obj->userfault_link, &i915->mm.userfault_list);
> +		list_add(&obj->userfault_link, &i915->ggtt.userfault_list);
>  	if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
> -		intel_wakeref_auto(&i915->mm.userfault_wakeref,
> +		intel_wakeref_auto(&i915->ggtt.userfault_wakeref,
>  				   msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
>  	GEM_BUG_ON(!obj->userfault_count);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> index f40f13c0b8b7..6d6064fb2bf5 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> @@ -126,7 +126,7 @@ void i915_gem_suspend(struct drm_i915_private *i915)
>  {
>  	GEM_TRACE("\n");
>  
> -	intel_wakeref_auto(&i915->mm.userfault_wakeref, 0);
> +	intel_wakeref_auto(&i915->ggtt.userfault_wakeref, 0);
>  	flush_workqueue(i915->wq);
>  
>  	mutex_lock(&i915->drm.struct_mutex);
> diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
> index a6ecfdc735c4..1e93cf6eede4 100644
> --- a/drivers/gpu/drm/i915/gt/intel_reset.c
> +++ b/drivers/gpu/drm/i915/gt/intel_reset.c
> @@ -695,19 +695,19 @@ static void revoke_mmaps(struct drm_i915_private *i915)
>  {
>  	int i;
>  
> -	for (i = 0; i < i915->num_fence_regs; i++) {
> +	for (i = 0; i < i915->ggtt.num_fences; i++) {
>  		struct drm_vma_offset_node *node;
>  		struct i915_vma *vma;
>  		u64 vma_offset;
>  
> -		vma = READ_ONCE(i915->fence_regs[i].vma);
> +		vma = READ_ONCE(i915->ggtt.fence_regs[i].vma);
>  		if (!vma)
>  			continue;
>  
>  		if (!i915_vma_has_userfault(vma))
>  			continue;
>  
> -		GEM_BUG_ON(vma->fence != &i915->fence_regs[i]);
> +		GEM_BUG_ON(vma->fence != &i915->ggtt.fence_regs[i]);
>  		node = &vma->obj->base.vma_node;
>  		vma_offset = vma->ggtt_view.partial.offset << PAGE_SHIFT;
>  		unmap_mapping_range(i915->drm.anon_inode->i_mapping,
> diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
> index 1fa2f65c3cd1..4098902bfaeb 100644
> --- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
> +++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
> @@ -35,6 +35,7 @@
>   */
>  
>  #include "i915_drv.h"
> +#include "i915_gem_fence_reg.h"
>  #include "gvt.h"
>  
>  static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
> @@ -128,7 +129,7 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
>  {
>  	struct intel_gvt *gvt = vgpu->gvt;
>  	struct drm_i915_private *dev_priv = gvt->dev_priv;
> -	struct drm_i915_fence_reg *reg;
> +	struct i915_fence_reg *reg;
>  	i915_reg_t fence_reg_lo, fence_reg_hi;
>  
>  	assert_rpm_wakelock_held(dev_priv);
> @@ -163,7 +164,7 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
>  {
>  	struct intel_gvt *gvt = vgpu->gvt;
>  	struct drm_i915_private *dev_priv = gvt->dev_priv;
> -	struct drm_i915_fence_reg *reg;
> +	struct i915_fence_reg *reg;
>  	u32 i;
>  
>  	if (WARN_ON(!vgpu_fence_sz(vgpu)))
> @@ -187,7 +188,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
>  {
>  	struct intel_gvt *gvt = vgpu->gvt;
>  	struct drm_i915_private *dev_priv = gvt->dev_priv;
> -	struct drm_i915_fence_reg *reg;
> +	struct i915_fence_reg *reg;
>  	int i;
>  
>  	intel_runtime_pm_get(dev_priv);
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> index b54f2bdc13a4..dfd10cf82b65 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.h
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -87,7 +87,7 @@ struct intel_vgpu_gm {
>  
>  /* Fences owned by a vGPU */
>  struct intel_vgpu_fence {
> -	struct drm_i915_fence_reg *regs[INTEL_GVT_MAX_NUM_FENCES];
> +	struct i915_fence_reg *regs[INTEL_GVT_MAX_NUM_FENCES];
>  	u32 base;
>  	u32 size;
>  };
> @@ -390,7 +390,7 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt);
>  #define gvt_hidden_gmadr_end(gvt) (gvt_hidden_gmadr_base(gvt) \
>  				   + gvt_hidden_sz(gvt) - 1)
>  
> -#define gvt_fence_sz(gvt) (gvt->dev_priv->num_fence_regs)
> +#define gvt_fence_sz(gvt) ((gvt)->dev_priv->ggtt.num_fences)
>  
>  /* Aperture/GM space definitions for vGPU */
>  #define vgpu_aperture_offset(vgpu)	((vgpu)->gm.low_gm_node.start)
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index f212241a2758..331b2f478c48 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -156,8 +156,6 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>  	unsigned int frontbuffer_bits;
>  	int pin_count = 0;
>  
> -	lockdep_assert_held(&obj->base.dev->struct_mutex);
> -
>  	seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x %s%s%s",
>  		   &obj->base,
>  		   get_active_flag(obj),
> @@ -173,17 +171,17 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>  		   obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
>  	if (obj->base.name)
>  		seq_printf(m, " (name: %d)", obj->base.name);
> -	list_for_each_entry(vma, &obj->vma.list, obj_link) {
> -		if (i915_vma_is_pinned(vma))
> -			pin_count++;
> -	}
> -	seq_printf(m, " (pinned x %d)", pin_count);
> -	if (obj->pin_global)
> -		seq_printf(m, " (global)");
> +
> +	spin_lock(&obj->vma.lock);
>  	list_for_each_entry(vma, &obj->vma.list, obj_link) {
>  		if (!drm_mm_node_allocated(&vma->node))
>  			continue;
>  
> +		spin_unlock(&obj->vma.lock);
> +
> +		if (i915_vma_is_pinned(vma))
> +			pin_count++;
> +
>  		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx, pages: %s",
>  			   i915_vma_is_ggtt(vma) ? "g" : "pp",
>  			   vma->node.start, vma->node.size,
> @@ -234,9 +232,16 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>  				   vma->fence->id,
>  				   i915_active_request_isset(&vma->last_fence) ? "*" : "");
>  		seq_puts(m, ")");
> +
> +		spin_lock(&obj->vma.lock);
>  	}
> +	spin_unlock(&obj->vma.lock);
> +
> +	seq_printf(m, " (pinned x %d)", pin_count);
>  	if (obj->stolen)
>  		seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
> +	if (obj->pin_global)
> +		seq_printf(m, " (global)");
>  
>  	engine = i915_gem_object_last_write_engine(obj);
>  	if (engine)
> @@ -870,28 +875,25 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
>  
>  static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
>  {
> -	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> -	struct drm_device *dev = &dev_priv->drm;
> -	int i, ret;
> +	struct drm_i915_private *i915 = node_to_i915(m->private);
> +	unsigned int i;
>  
> -	ret = mutex_lock_interruptible(&dev->struct_mutex);
> -	if (ret)
> -		return ret;
> +	seq_printf(m, "Total fences = %d\n", i915->ggtt.num_fences);
>  
> -	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
> -	for (i = 0; i < dev_priv->num_fence_regs; i++) {
> -		struct i915_vma *vma = dev_priv->fence_regs[i].vma;
> +	rcu_read_lock();

This does not seem to be for reset. So it must be for keeping
the object alive.

What guarantees that the obj is kept alive over this rcu
lock?

-Mika

> +	for (i = 0; i < i915->ggtt.num_fences; i++) {
> +		struct i915_vma *vma = i915->ggtt.fence_regs[i].vma;
>  
>  		seq_printf(m, "Fence %d, pin count = %d, object = ",
> -			   i, dev_priv->fence_regs[i].pin_count);
> +			   i, i915->ggtt.fence_regs[i].pin_count);
>  		if (!vma)
>  			seq_puts(m, "unused");
>  		else
>  			describe_obj(m, vma->obj);
>  		seq_putc(m, '\n');
>  	}
> +	rcu_read_unlock();
>  
> -	mutex_unlock(&dev->struct_mutex);
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 1af6751e1b36..06a76d49ecd0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -350,7 +350,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
>  		value = pdev->revision;
>  		break;
>  	case I915_PARAM_NUM_FENCES_AVAIL:
> -		value = dev_priv->num_fence_regs;
> +		value = dev_priv->ggtt.num_fences;
>  		break;
>  	case I915_PARAM_HAS_OVERLAY:
>  		value = dev_priv->overlay ? 1 : 0;
> @@ -1625,7 +1625,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
>  	intel_uncore_sanitize(dev_priv);
>  
>  	intel_gt_init_workarounds(dev_priv);
> -	i915_gem_load_init_fences(dev_priv);
>  
>  	/* On the 945G/GM, the chipset reports the MSI capability on the
>  	 * integrated graphics even though the support isn't actually there
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 82e55c65289a..9e6eced477e7 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -761,14 +761,6 @@ struct i915_gem_mm {
>  	 */
>  	struct list_head purge_list;
>  
> -	/** List of all objects in gtt_space, currently mmaped by userspace.
> -	 * All objects within this list must also be on bound_list.
> -	 */
> -	struct list_head userfault_list;
> -
> -	/* Manual runtime pm autosuspend delay for user GGTT mmaps */
> -	struct intel_wakeref_auto userfault_wakeref;
> -
>  	/**
>  	 * List of objects which are pending destruction.
>  	 */
> @@ -798,9 +790,6 @@ struct i915_gem_mm {
>  	struct notifier_block vmap_notifier;
>  	struct shrinker shrinker;
>  
> -	/** LRU list of objects with fence regs on them. */
> -	struct list_head fence_list;
> -
>  	/**
>  	 * Workqueue to fault in userptr pages, flushed by the execbuf
>  	 * when required but otherwise left to userspace to try again
> @@ -1489,9 +1478,6 @@ struct drm_i915_private {
>  	/* protects panel power sequencer state */
>  	struct mutex pps_mutex;
>  
> -	struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
> -	int num_fence_regs; /* 8 on pre-965, 16 otherwise */
> -
>  	unsigned int fsb_freq, mem_freq, is_ddr3;
>  	unsigned int skl_preferred_vco_freq;
>  	unsigned int max_cdclk_freq;
> @@ -2542,7 +2528,6 @@ void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
>  void i915_gem_sanitize(struct drm_i915_private *i915);
>  int i915_gem_init_early(struct drm_i915_private *dev_priv);
>  void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
> -void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
>  int i915_gem_freeze(struct drm_i915_private *dev_priv);
>  int i915_gem_freeze_late(struct drm_i915_private *dev_priv);
>  
> @@ -2668,19 +2653,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
>  	return container_of(vm, struct i915_hw_ppgtt, vm);
>  }
>  
> -/* i915_gem_fence_reg.c */
> -struct drm_i915_fence_reg *
> -i915_reserve_fence(struct drm_i915_private *dev_priv);
> -void i915_unreserve_fence(struct drm_i915_fence_reg *fence);
> -
> -void i915_gem_restore_fences(struct drm_i915_private *dev_priv);
> -
> -void i915_gem_detect_bit_6_swizzle(struct drm_i915_private *dev_priv);
> -void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
> -				       struct sg_table *pages);
> -void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
> -					 struct sg_table *pages);
> -
>  static inline struct i915_gem_context *
>  __i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
>  {
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 9f2e213c6046..99427d8b9266 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -883,7 +883,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
>  	return 0;
>  }
>  
> -void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv)
> +void i915_gem_runtime_suspend(struct drm_i915_private *i915)
>  {
>  	struct drm_i915_gem_object *obj, *on;
>  	int i;
> @@ -896,17 +896,19 @@ void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv)
>  	 */
>  
>  	list_for_each_entry_safe(obj, on,
> -				 &dev_priv->mm.userfault_list, userfault_link)
> +				 &i915->ggtt.userfault_list, userfault_link)
>  		__i915_gem_object_release_mmap(obj);
>  
> -	/* The fence will be lost when the device powers down. If any were
> +	/*
> +	 * The fence will be lost when the device powers down. If any were
>  	 * in use by hardware (i.e. they are pinned), we should not be powering
>  	 * down! All other fences will be reacquired by the user upon waking.
>  	 */
> -	for (i = 0; i < dev_priv->num_fence_regs; i++) {
> -		struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
> +	for (i = 0; i < i915->ggtt.num_fences; i++) {
> +		struct i915_fence_reg *reg = &i915->ggtt.fence_regs[i];
>  
> -		/* Ideally we want to assert that the fence register is not
> +		/*
> +		 * Ideally we want to assert that the fence register is not
>  		 * live at this point (i.e. that no piece of code will be
>  		 * trying to write through fence + GTT, as that both violates
>  		 * our tracking of activity and associated locking/barriers,
> @@ -1684,7 +1686,7 @@ void i915_gem_fini_hw(struct drm_i915_private *dev_priv)
>  {
>  	GEM_BUG_ON(dev_priv->gt.awake);
>  
> -	intel_wakeref_auto_fini(&dev_priv->mm.userfault_wakeref);
> +	intel_wakeref_auto_fini(&dev_priv->ggtt.userfault_wakeref);
>  
>  	i915_gem_suspend_late(dev_priv);
>  	intel_disable_gt_powersave(dev_priv);
> @@ -1726,38 +1728,6 @@ void i915_gem_init_mmio(struct drm_i915_private *i915)
>  	i915_gem_sanitize(i915);
>  }
>  
> -void
> -i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
> -{
> -	int i;
> -
> -	if (INTEL_GEN(dev_priv) >= 7 && !IS_VALLEYVIEW(dev_priv) &&
> -	    !IS_CHERRYVIEW(dev_priv))
> -		dev_priv->num_fence_regs = 32;
> -	else if (INTEL_GEN(dev_priv) >= 4 ||
> -		 IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
> -		 IS_G33(dev_priv) || IS_PINEVIEW(dev_priv))
> -		dev_priv->num_fence_regs = 16;
> -	else
> -		dev_priv->num_fence_regs = 8;
> -
> -	if (intel_vgpu_active(dev_priv))
> -		dev_priv->num_fence_regs =
> -				I915_READ(vgtif_reg(avail_rs.fence_num));
> -
> -	/* Initialize fence registers to zero */
> -	for (i = 0; i < dev_priv->num_fence_regs; i++) {
> -		struct drm_i915_fence_reg *fence = &dev_priv->fence_regs[i];
> -
> -		fence->i915 = dev_priv;
> -		fence->id = i;
> -		list_add_tail(&fence->link, &dev_priv->mm.fence_list);
> -	}
> -	i915_gem_restore_fences(dev_priv);
> -
> -	i915_gem_detect_bit_6_swizzle(dev_priv);
> -}
> -
>  static void i915_gem_init__mm(struct drm_i915_private *i915)
>  {
>  	spin_lock_init(&i915->mm.obj_lock);
> @@ -1768,10 +1738,6 @@ static void i915_gem_init__mm(struct drm_i915_private *i915)
>  	INIT_LIST_HEAD(&i915->mm.purge_list);
>  	INIT_LIST_HEAD(&i915->mm.unbound_list);
>  	INIT_LIST_HEAD(&i915->mm.bound_list);
> -	INIT_LIST_HEAD(&i915->mm.fence_list);
> -
> -	INIT_LIST_HEAD(&i915->mm.userfault_list);
> -	intel_wakeref_auto_init(&i915->mm.userfault_wakeref, i915);
>  
>  	i915_gem_init__objects(i915);
>  }
> diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
> index 10aa6e350bfa..4ba3726556a4 100644
> --- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c
> +++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
> @@ -25,6 +25,7 @@
>  
>  #include "i915_drv.h"
>  #include "i915_scatterlist.h"
> +#include "i915_vgpu.h"
>  
>  /**
>   * DOC: fence register handling
> @@ -58,7 +59,7 @@
>  
>  #define pipelined 0
>  
> -static void i965_write_fence_reg(struct drm_i915_fence_reg *fence,
> +static void i965_write_fence_reg(struct i915_fence_reg *fence,
>  				 struct i915_vma *vma)
>  {
>  	i915_reg_t fence_reg_lo, fence_reg_hi;
> @@ -115,7 +116,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *fence,
>  	}
>  }
>  
> -static void i915_write_fence_reg(struct drm_i915_fence_reg *fence,
> +static void i915_write_fence_reg(struct i915_fence_reg *fence,
>  				 struct i915_vma *vma)
>  {
>  	u32 val;
> @@ -155,7 +156,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *fence,
>  	}
>  }
>  
> -static void i830_write_fence_reg(struct drm_i915_fence_reg *fence,
> +static void i830_write_fence_reg(struct i915_fence_reg *fence,
>  				 struct i915_vma *vma)
>  {
>  	u32 val;
> @@ -187,7 +188,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *fence,
>  	}
>  }
>  
> -static void fence_write(struct drm_i915_fence_reg *fence,
> +static void fence_write(struct i915_fence_reg *fence,
>  			struct i915_vma *vma)
>  {
>  	/*
> @@ -211,7 +212,7 @@ static void fence_write(struct drm_i915_fence_reg *fence,
>  	fence->dirty = false;
>  }
>  
> -static int fence_update(struct drm_i915_fence_reg *fence,
> +static int fence_update(struct i915_fence_reg *fence,
>  			struct i915_vma *vma)
>  {
>  	intel_wakeref_t wakeref;
> @@ -256,7 +257,7 @@ static int fence_update(struct drm_i915_fence_reg *fence,
>  			old->fence = NULL;
>  		}
>  
> -		list_move(&fence->link, &fence->i915->mm.fence_list);
> +		list_move(&fence->link, &fence->i915->ggtt.fence_list);
>  	}
>  
>  	/*
> @@ -280,7 +281,7 @@ static int fence_update(struct drm_i915_fence_reg *fence,
>  
>  	if (vma) {
>  		vma->fence = fence;
> -		list_move_tail(&fence->link, &fence->i915->mm.fence_list);
> +		list_move_tail(&fence->link, &fence->i915->ggtt.fence_list);
>  	}
>  
>  	intel_runtime_pm_put(fence->i915, wakeref);
> @@ -300,7 +301,7 @@ static int fence_update(struct drm_i915_fence_reg *fence,
>   */
>  int i915_vma_put_fence(struct i915_vma *vma)
>  {
> -	struct drm_i915_fence_reg *fence = vma->fence;
> +	struct i915_fence_reg *fence = vma->fence;
>  
>  	if (!fence)
>  		return 0;
> @@ -311,11 +312,11 @@ int i915_vma_put_fence(struct i915_vma *vma)
>  	return fence_update(fence, NULL);
>  }
>  
> -static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *i915)
> +static struct i915_fence_reg *fence_find(struct drm_i915_private *i915)
>  {
> -	struct drm_i915_fence_reg *fence;
> +	struct i915_fence_reg *fence;
>  
> -	list_for_each_entry(fence, &i915->mm.fence_list, link) {
> +	list_for_each_entry(fence, &i915->ggtt.fence_list, link) {
>  		GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
>  
>  		if (fence->pin_count)
> @@ -352,7 +353,7 @@ static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *i915)
>  int
>  i915_vma_pin_fence(struct i915_vma *vma)
>  {
> -	struct drm_i915_fence_reg *fence;
> +	struct i915_fence_reg *fence;
>  	struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL;
>  	int err;
>  
> @@ -369,7 +370,7 @@ i915_vma_pin_fence(struct i915_vma *vma)
>  		fence->pin_count++;
>  		if (!fence->dirty) {
>  			list_move_tail(&fence->link,
> -				       &fence->i915->mm.fence_list);
> +				       &fence->i915->ggtt.fence_list);
>  			return 0;
>  		}
>  	} else if (set) {
> @@ -404,10 +405,10 @@ i915_vma_pin_fence(struct i915_vma *vma)
>   * This function walks the fence regs looking for a free one and remove
>   * it from the fence_list. It is used to reserve fence for vGPU to use.
>   */
> -struct drm_i915_fence_reg *
> +struct i915_fence_reg *
>  i915_reserve_fence(struct drm_i915_private *i915)
>  {
> -	struct drm_i915_fence_reg *fence;
> +	struct i915_fence_reg *fence;
>  	int count;
>  	int ret;
>  
> @@ -415,7 +416,7 @@ i915_reserve_fence(struct drm_i915_private *i915)
>  
>  	/* Keep at least one fence available for the display engine. */
>  	count = 0;
> -	list_for_each_entry(fence, &i915->mm.fence_list, link)
> +	list_for_each_entry(fence, &i915->ggtt.fence_list, link)
>  		count += !fence->pin_count;
>  	if (count <= 1)
>  		return ERR_PTR(-ENOSPC);
> @@ -441,11 +442,11 @@ i915_reserve_fence(struct drm_i915_private *i915)
>   *
>   * This function add a reserved fence register from vGPU to the fence_list.
>   */
> -void i915_unreserve_fence(struct drm_i915_fence_reg *fence)
> +void i915_unreserve_fence(struct i915_fence_reg *fence)
>  {
>  	lockdep_assert_held(&fence->i915->drm.struct_mutex);
>  
> -	list_add(&fence->link, &fence->i915->mm.fence_list);
> +	list_add(&fence->link, &fence->i915->ggtt.fence_list);
>  }
>  
>  /**
> @@ -461,8 +462,8 @@ void i915_gem_restore_fences(struct drm_i915_private *i915)
>  	int i;
>  
>  	rcu_read_lock(); /* keep obj alive as we dereference */
> -	for (i = 0; i < i915->num_fence_regs; i++) {
> -		struct drm_i915_fence_reg *reg = &i915->fence_regs[i];
> +	for (i = 0; i < i915->ggtt.num_fences; i++) {
> +		struct i915_fence_reg *reg = &i915->ggtt.fence_regs[i];
>  		struct i915_vma *vma = READ_ONCE(reg->vma);
>  
>  		GEM_BUG_ON(vma && vma->fence != reg);
> @@ -534,8 +535,8 @@ void i915_gem_restore_fences(struct drm_i915_private *i915)
>   * Detects bit 6 swizzling of address lookup between IGD access and CPU
>   * access through main memory.
>   */
> -void
> -i915_gem_detect_bit_6_swizzle(struct drm_i915_private *i915)
> +static void
> +detect_bit_6_swizzle(struct drm_i915_private *i915)
>  {
>  	struct intel_uncore *uncore = &i915->uncore;
>  	u32 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
> @@ -798,3 +799,43 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
>  		i++;
>  	}
>  }
> +
> +void
> +i915_ggtt_init_fences(struct i915_ggtt *ggtt)
> +{
> +	struct drm_i915_private *i915 = ggtt->vm.i915;
> +	int num_fences;
> +	int i;
> +
> +	INIT_LIST_HEAD(&ggtt->fence_list);
> +	INIT_LIST_HEAD(&ggtt->userfault_list);
> +	intel_wakeref_auto_init(&ggtt->userfault_wakeref, i915);
> +
> +	detect_bit_6_swizzle(i915);
> +
> +	if (INTEL_GEN(i915) >= 7 &&
> +	    !(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
> +		num_fences = 32;
> +	else if (INTEL_GEN(i915) >= 4 ||
> +		 IS_I945G(i915) || IS_I945GM(i915) ||
> +		 IS_G33(i915) || IS_PINEVIEW(i915))
> +		num_fences = 16;
> +	else
> +		num_fences = 8;
> +
> +	if (intel_vgpu_active(i915))
> +		num_fences = intel_uncore_read(&i915->uncore,
> +					       vgtif_reg(avail_rs.fence_num));
> +
> +	/* Initialize fence registers to zero */
> +	for (i = 0; i < num_fences; i++) {
> +		struct i915_fence_reg *fence = &ggtt->fence_regs[i];
> +
> +		fence->i915 = i915;
> +		fence->id = i;
> +		list_add_tail(&fence->link, &ggtt->fence_list);
> +	}
> +	ggtt->num_fences = num_fences;
> +
> +	i915_gem_restore_fences(i915);
> +}
> diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.h b/drivers/gpu/drm/i915/i915_gem_fence_reg.h
> index 09dcaf14121b..d2da98828179 100644
> --- a/drivers/gpu/drm/i915/i915_gem_fence_reg.h
> +++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.h
> @@ -26,13 +26,17 @@
>  #define __I915_FENCE_REG_H__
>  
>  #include <linux/list.h>
> +#include <linux/types.h>
>  
> +struct drm_i915_gem_object;
>  struct drm_i915_private;
> +struct i915_ggtt;
>  struct i915_vma;
> +struct sg_table;
>  
>  #define I965_FENCE_PAGE 4096UL
>  
> -struct drm_i915_fence_reg {
> +struct i915_fence_reg {
>  	struct list_head link;
>  	struct drm_i915_private *i915;
>  	struct i915_vma *vma;
> @@ -49,4 +53,17 @@ struct drm_i915_fence_reg {
>  	bool dirty;
>  };
>  
> +/* i915_gem_fence_reg.c */
> +struct i915_fence_reg *i915_reserve_fence(struct drm_i915_private *i915);
> +void i915_unreserve_fence(struct i915_fence_reg *fence);
> +
> +void i915_gem_restore_fences(struct drm_i915_private *i915);
> +
> +void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
> +				       struct sg_table *pages);
> +void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
> +					 struct sg_table *pages);
> +
> +void i915_ggtt_init_fences(struct i915_ggtt *ggtt);
> +
>  #endif
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 87be9c1b6021..acc3cb7cb219 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3600,6 +3600,8 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
>  
>  	ggtt->mtrr = arch_phys_wc_add(ggtt->gmadr.start, ggtt->mappable_end);
>  
> +	i915_ggtt_init_fences(ggtt);
> +
>  	/*
>  	 * Initialise stolen early so that we may reserve preallocated
>  	 * objects for the BIOS to KMS transition.
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 12856f9dd1d1..ee396938de10 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -39,6 +39,7 @@
>  #include <linux/pagevec.h>
>  
>  #include "gt/intel_reset.h"
> +#include "i915_gem_fence_reg.h"
>  #include "i915_request.h"
>  #include "i915_scatterlist.h"
>  #include "i915_selftest.h"
> @@ -61,7 +62,6 @@
>  #define I915_MAX_NUM_FENCE_BITS 6
>  
>  struct drm_i915_file_private;
> -struct drm_i915_fence_reg;
>  struct drm_i915_gem_object;
>  struct i915_vma;
>  
> @@ -406,6 +406,18 @@ struct i915_ggtt {
>  
>  	u32 pin_bias;
>  
> +	unsigned int num_fences;
> +	struct i915_fence_reg fence_regs[I915_MAX_NUM_FENCES];
> +	struct list_head fence_list;
> +
> +	/** List of all objects in gtt_space, currently mmaped by userspace.
> +	 * All objects within this list must also be on bound_list.
> +	 */
> +	struct list_head userfault_list;
> +
> +	/* Manual runtime pm autosuspend delay for user GGTT mmaps */
> +	struct intel_wakeref_auto userfault_wakeref;
> +
>  	struct drm_mm_node error_capture;
>  	struct drm_mm_node uc_fw;
>  };
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 193a93857d99..8dc727cbfe68 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -1126,13 +1126,13 @@ static void gem_record_fences(struct i915_gpu_state *error)
>  	int i;
>  
>  	if (INTEL_GEN(dev_priv) >= 6) {
> -		for (i = 0; i < dev_priv->num_fence_regs; i++)
> +		for (i = 0; i < dev_priv->ggtt.num_fences; i++)
>  			error->fence[i] = I915_READ64(FENCE_REG_GEN6_LO(i));
>  	} else if (INTEL_GEN(dev_priv) >= 4) {
> -		for (i = 0; i < dev_priv->num_fence_regs; i++)
> +		for (i = 0; i < dev_priv->ggtt.num_fences; i++)
>  			error->fence[i] = I915_READ64(FENCE_REG_965_LO(i));
>  	} else {
> -		for (i = 0; i < dev_priv->num_fence_regs; i++)
> +		for (i = 0; i < dev_priv->ggtt.num_fences; i++)
>  			error->fence[i] = I915_READ(FENCE_REG(i));
>  	}
>  	error->nfence = i;
> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> index 0c57ab4fed5d..4b769db649bf 100644
> --- a/drivers/gpu/drm/i915/i915_vma.h
> +++ b/drivers/gpu/drm/i915/i915_vma.h
> @@ -54,7 +54,7 @@ struct i915_vma {
>  	struct drm_i915_gem_object *obj;
>  	struct i915_address_space *vm;
>  	const struct i915_vma_ops *ops;
> -	struct drm_i915_fence_reg *fence;
> +	struct i915_fence_reg *fence;
>  	struct reservation_object *resv; /** Alias of obj->resv */
>  	struct sg_table *pages;
>  	void __iomem *iomap;
> -- 
> 2.20.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list