Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/intel-gfx _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx