Skip to content

Commit

Permalink
drm/i915: Move fence register tracking from i915->mm to ggtt
Browse files Browse the repository at this point in the history
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@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190613073254.24048-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Jun 13, 2019
1 parent 70972f5 commit 0cf289b
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 137 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/gem/i915_gem_mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/gt/intel_reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions drivers/gpu/drm/i915/gvt/aperture_gm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)))
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/gvt/gvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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)
Expand Down
42 changes: 22 additions & 20 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,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),
Expand All @@ -160,17 +158,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,
Expand Down Expand Up @@ -221,9 +219,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)
Expand Down Expand Up @@ -698,28 +703,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();
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;
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
28 changes: 0 additions & 28 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,14 +757,6 @@ struct i915_gem_mm {
*/
struct list_head shrink_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.
*/
Expand Down Expand Up @@ -794,9 +786,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
Expand Down Expand Up @@ -1485,9 +1474,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;
Expand Down Expand Up @@ -2541,7 +2527,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);

Expand Down Expand Up @@ -2661,19 +2646,6 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags);

/* 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)
{
Expand Down
52 changes: 9 additions & 43 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,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;
Expand All @@ -897,17 +897,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,
Expand Down Expand Up @@ -1687,7 +1689,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);
Expand Down Expand Up @@ -1729,38 +1731,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);
Expand All @@ -1770,10 +1740,6 @@ static void i915_gem_init__mm(struct drm_i915_private *i915)

INIT_LIST_HEAD(&i915->mm.purge_list);
INIT_LIST_HEAD(&i915->mm.shrink_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);
}
Expand Down
Loading

0 comments on commit 0cf289b

Please sign in to comment.