[Intel-gfx] [PATCH 37/38] drm/i915: Track pinned VMA
Daniel Vetter
daniel at ffwll.ch
Wed Jun 8 10:08:40 UTC 2016
On Fri, Jun 03, 2016 at 05:55:52PM +0100, Chris Wilson wrote:
> Treat the VMA as the primary struct responsible for tracking bindings
> into the GPU's VM. That is we want to treat the VMA returned after we
> pin an object into the VM as the cookie we hold and eventually release
> when unpinning. Doing so eliminates the ambiguity in pinning the object
> and then searching for the relevant pin later.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Imo would be good to split this up a bit more, like you already extracted
the overlay parts. I know there's probably a few chicken&eggs in here, but
still imo needed.
-Daniel
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 75 +++++-----
> drivers/gpu/drm/i915/i915_drv.h | 64 +++------
> drivers/gpu/drm/i915/i915_gem.c | 200 ++++++---------------------
> drivers/gpu/drm/i915/i915_gem_context.c | 43 +++---
> drivers/gpu/drm/i915/i915_gem_execbuffer.c | 60 ++++----
> drivers/gpu/drm/i915/i915_gem_fence.c | 64 ++++-----
> drivers/gpu/drm/i915/i915_gem_gtt.c | 58 +++++---
> drivers/gpu/drm/i915/i915_gem_gtt.h | 14 --
> drivers/gpu/drm/i915/i915_gem_render_state.c | 31 ++---
> drivers/gpu/drm/i915/i915_gem_render_state.h | 2 +-
> drivers/gpu/drm/i915/i915_gem_request.c | 10 +-
> drivers/gpu/drm/i915/i915_gem_request.h | 2 +-
> drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +-
> drivers/gpu/drm/i915/i915_gem_tiling.c | 42 +++---
> drivers/gpu/drm/i915/i915_gpu_error.c | 55 +++-----
> drivers/gpu/drm/i915/i915_guc_submission.c | 28 ++--
> drivers/gpu/drm/i915/intel_display.c | 57 +++++---
> drivers/gpu/drm/i915/intel_drv.h | 5 +-
> drivers/gpu/drm/i915/intel_fbc.c | 2 +-
> drivers/gpu/drm/i915/intel_fbdev.c | 19 ++-
> drivers/gpu/drm/i915/intel_guc_loader.c | 29 ++--
> drivers/gpu/drm/i915/intel_lrc.c | 113 ++++++++-------
> drivers/gpu/drm/i915/intel_overlay.c | 44 +++---
> drivers/gpu/drm/i915/intel_ringbuffer.c | 194 ++++++++++++++------------
> drivers/gpu/drm/i915/intel_ringbuffer.h | 20 +--
> drivers/gpu/drm/i915/intel_sprite.c | 8 +-
> 26 files changed, 549 insertions(+), 692 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 485fc23893d6..938a95df8a11 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -111,7 +111,7 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj)
>
> static char get_global_flag(struct drm_i915_gem_object *obj)
> {
> - return i915_gem_obj_to_ggtt(obj) ? 'g' : ' ';
> + return i915_gem_object_to_ggtt(obj, NULL) ? 'g' : ' ';
> }
>
> static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
> @@ -278,7 +278,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
> struct drm_device *dev = node->minor->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct drm_i915_gem_object *obj;
> - u64 total_obj_size, total_gtt_size;
> + u64 total_obj_size;
> LIST_HEAD(stolen);
> int count, ret;
>
> @@ -286,7 +286,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
> if (ret)
> return ret;
>
> - total_obj_size = total_gtt_size = count = 0;
> + total_obj_size = count = 0;
> list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
> if (obj->stolen == NULL)
> continue;
> @@ -294,7 +294,6 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
> list_add(&obj->obj_exec_link, &stolen);
>
> total_obj_size += obj->base.size;
> - total_gtt_size += i915_gem_obj_total_ggtt_size(obj);
> count++;
> }
> list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
> @@ -317,8 +316,8 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
> }
> mutex_unlock(&dev->struct_mutex);
>
> - seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
> - count, total_obj_size, total_gtt_size);
> + seq_printf(m, "Total %d objects, %llu bytes\n",
> + count, total_obj_size);
> return 0;
> }
>
> @@ -327,7 +326,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
> size += i915_gem_obj_total_ggtt_size(obj); \
> ++count; \
> if (obj->map_and_fenceable) { \
> - mappable_size += i915_gem_obj_ggtt_size(obj); \
> + mappable_size += obj->base.size; \
> ++mappable_count; \
> } \
> } \
> @@ -451,10 +450,10 @@ static void print_context_stats(struct seq_file *m,
>
> #define count_vmas(list, member) do { \
> list_for_each_entry(vma, list, member) { \
> - size += i915_gem_obj_total_ggtt_size(vma->obj); \
> + size += vma->size; \
> ++count; \
> if (vma->obj->map_and_fenceable) { \
> - mappable_size += i915_gem_obj_ggtt_size(vma->obj); \
> + mappable_size += vma->size; \
> ++mappable_count; \
> } \
> } \
> @@ -517,11 +516,11 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
> size = count = mappable_size = mappable_count = 0;
> list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
> if (obj->fault_mappable) {
> - size += i915_gem_obj_ggtt_size(obj);
> + size += obj->base.size;
> ++count;
> }
> if (obj->pin_display) {
> - mappable_size += i915_gem_obj_ggtt_size(obj);
> + mappable_size += obj->base.size;
> ++mappable_count;
> }
> if (obj->madv == I915_MADV_DONTNEED) {
> @@ -589,30 +588,29 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data)
> uintptr_t list = (uintptr_t) node->info_ent->data;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct drm_i915_gem_object *obj;
> - u64 total_obj_size, total_gtt_size;
> + u64 total_obj_size;
> int count, ret;
>
> ret = mutex_lock_interruptible(&dev->struct_mutex);
> if (ret)
> return ret;
>
> - total_obj_size = total_gtt_size = count = 0;
> + total_obj_size = count = 0;
> list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
> - if (list == PINNED_LIST && !i915_gem_obj_is_pinned(obj))
> + if (list == PINNED_LIST && !obj->pin_display)
> continue;
>
> seq_puts(m, " ");
> describe_obj(m, obj);
> seq_putc(m, '\n');
> total_obj_size += obj->base.size;
> - total_gtt_size += i915_gem_obj_total_ggtt_size(obj);
> count++;
> }
>
> mutex_unlock(&dev->struct_mutex);
>
> - seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
> - count, total_obj_size, total_gtt_size);
> + seq_printf(m, "Total %d objects, %llu bytes\n",
> + count, total_obj_size);
>
> return 0;
> }
> @@ -2075,38 +2073,35 @@ static void i915_dump_lrc_obj(struct seq_file *m,
> struct i915_gem_context *ctx,
> struct intel_engine_cs *engine)
> {
> - struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
> + struct drm_i915_gem_object *obj = ctx->engine[engine->id].state;
> + struct i915_vma *vma = ctx->engine[engine->id].vma;
> struct page *page;
> - uint32_t *reg_state;
> int j;
> - unsigned long ggtt_offset = 0;
>
> seq_printf(m, "CONTEXT: %s %u\n", engine->name, ctx->hw_id);
> -
> - if (ctx_obj == NULL) {
> - seq_puts(m, "\tNot allocated\n");
> - return;
> - }
> -
> - if (!i915_gem_obj_ggtt_bound(ctx_obj))
> + if (vma == NULL) {
> seq_puts(m, "\tNot bound in GGTT\n");
> - else
> - ggtt_offset = i915_gem_obj_ggtt_offset(ctx_obj);
> + } else {
> + seq_printf(m, "\tBound in GGTT at %x\n",
> + lower_32_bits(vma->node.start));
> + }
>
> - if (i915_gem_object_get_pages(ctx_obj)) {
> - seq_puts(m, "\tFailed to get pages for context object\n");
> + if (i915_gem_object_get_pages(obj)) {
> + seq_puts(m, "\tFailed to get pages for context object\n\n");
> return;
> }
>
> - page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
> - if (!WARN_ON(page == NULL)) {
> - reg_state = kmap_atomic(page);
> -
> + page = i915_gem_object_get_page(obj, LRC_STATE_PN);
> + if (page != NULL) {
> + uint32_t *reg_state = kmap_atomic(page);
> for (j = 0; j < 0x600 / sizeof(u32) / 4; j += 4) {
> - seq_printf(m, "\t[0x%08lx] 0x%08x 0x%08x 0x%08x 0x%08x\n",
> - ggtt_offset + 4096 + (j * 4),
> - reg_state[j], reg_state[j + 1],
> - reg_state[j + 2], reg_state[j + 3]);
> + seq_printf(m,
> + "\t[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
> + j * 4,
> + reg_state[j],
> + reg_state[j + 1],
> + reg_state[j + 2],
> + reg_state[j + 3]);
> }
> kunmap_atomic(reg_state);
> }
> @@ -3210,7 +3205,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
> struct page *page;
> uint64_t *seqno;
>
> - page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
> + page = i915_gem_object_get_page(dev_priv->semaphore_vma->obj, 0);
>
> seqno = (uint64_t *)kmap_atomic(page);
> for_each_engine_id(engine, dev_priv, id) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 77564f378771..ed968deb36aa 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -880,8 +880,8 @@ struct i915_gem_context {
>
> struct intel_context {
> struct drm_i915_gem_object *state;
> + struct i915_vma *vma;
> struct intel_ring *ring;
> - struct i915_vma *lrc_vma;
> uint32_t *lrc_reg_state;
> u64 lrc_desc;
> int pin_count;
> @@ -1736,7 +1736,7 @@ struct drm_i915_private {
> struct pci_dev *bridge_dev;
> struct i915_gem_context *kernel_context;
> struct intel_engine_cs engine[I915_NUM_ENGINES];
> - struct drm_i915_gem_object *semaphore_obj;
> + struct i915_vma *semaphore_vma;
> uint32_t next_seqno;
>
> struct drm_dma_handle *status_page_dmah;
> @@ -2996,7 +2996,7 @@ static inline void i915_vma_unpin(struct i915_vma *vma)
> __i915_vma_unpin(vma);
> }
>
> -int __must_check
> +struct i915_vma * __must_check
> i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
> const struct i915_ggtt_view *view,
> uint64_t size,
> @@ -3174,12 +3174,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
> bool write);
> int __must_check
> i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
> -int __must_check
> +struct i915_vma * __must_check
> i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
> u32 alignment,
> const struct i915_ggtt_view *view);
> -void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view);
> +void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
> int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
> int align);
> int i915_gem_open(struct drm_device *dev, struct drm_file *file);
> @@ -3200,63 +3199,34 @@ 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);
>
> -u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
> - const struct i915_ggtt_view *view);
> -u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
> - struct i915_address_space *vm);
> -static inline u64
> -i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
> -{
> - return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
> -}
> -
> -bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
> - const struct i915_ggtt_view *view);
> -bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
> - struct i915_address_space *vm);
> -
> struct i915_vma *
> i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
> - struct i915_address_space *vm);
> -struct i915_vma *
> -i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view);
> + struct i915_address_space *vm,
> + const struct i915_ggtt_view *view);
>
> struct i915_vma *
> i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
> - struct i915_address_space *vm);
> -struct i915_vma *
> -i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view);
> -
> -static inline struct i915_vma *
> -i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
> -{
> - return i915_gem_obj_to_ggtt_view(obj, &i915_ggtt_view_normal);
> -}
> -bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
> + struct i915_address_space *vm,
> + const struct i915_ggtt_view *view);
>
> -/* Some GGTT VM helpers */
> static inline struct i915_hw_ppgtt *
> i915_vm_to_ppgtt(struct i915_address_space *vm)
> {
> return container_of(vm, struct i915_hw_ppgtt, base);
> }
>
> -static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
> +static inline struct i915_vma *
> +i915_gem_object_to_ggtt(struct drm_i915_gem_object *obj,
> + const struct i915_ggtt_view *view)
> {
> - return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal);
> + return i915_gem_obj_to_vma(obj, &to_i915(obj->base.dev)->ggtt.base, view);
> }
>
> -unsigned long
> -i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj);
> -
> -void i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view);
> -static inline void
> -i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
> +static inline unsigned long
> +i915_gem_object_ggtt_offset(struct drm_i915_gem_object *o,
> + const struct i915_ggtt_view *view)
> {
> - i915_gem_object_ggtt_unpin_view(obj, &i915_ggtt_view_normal);
> + return i915_gem_object_to_ggtt(o, view)->node.start;
> }
>
> /* i915_gem_fence.c */
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index dad00800aeef..e0db9b02ee04 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -848,16 +848,18 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
> {
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct i915_ggtt *ggtt = &dev_priv->ggtt;
> + struct i915_vma *vma;
> ssize_t remain;
> loff_t offset, page_base;
> char __user *user_data;
> int page_offset, page_length, ret;
>
> - ret = i915_gem_object_ggtt_pin(obj, NULL,
> - 0, 0,
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
> PIN_MAPPABLE | PIN_NONBLOCK);
> - if (ret)
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto out;
> + }
>
> ret = i915_gem_object_set_to_gtt_domain(obj, true);
> if (ret)
> @@ -870,7 +872,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
> user_data = u64_to_user_ptr(args->data_ptr);
> remain = args->size;
>
> - offset = i915_gem_obj_ggtt_offset(obj) + args->offset;
> + offset = vma->node.start + args->offset;
>
> intel_fb_obj_invalidate(obj, ORIGIN_GTT);
>
> @@ -905,7 +907,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
> out_flush:
> intel_fb_obj_flush(obj, false, ORIGIN_GTT);
> out_unpin:
> - i915_gem_object_ggtt_unpin(obj);
> + i915_vma_unpin(vma);
> out:
> return ret;
> }
> @@ -1382,8 +1384,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data);
> struct drm_device *dev = obj->base.dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> - struct i915_ggtt *ggtt = &dev_priv->ggtt;
> struct i915_ggtt_view view = i915_ggtt_view_normal;
> + struct i915_vma *ggtt;
> pgoff_t page_offset;
> unsigned long pfn;
> int ret = 0;
> @@ -1417,7 +1419,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> }
>
> /* Use a partial view if the object is bigger than the aperture. */
> - if (obj->base.size >= ggtt->mappable_end &&
> + if (obj->base.size >= dev_priv->ggtt.mappable_end &&
> obj->tiling_mode == I915_TILING_NONE) {
> static const unsigned int chunk_size = 256; // 1 MiB
>
> @@ -1432,9 +1434,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> }
>
> /* Now pin it into the GTT if needed */
> - ret = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
> - if (ret)
> + ggtt = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
> + if (IS_ERR(ggtt)) {
> + ret = PTR_ERR(ggtt);
> goto err_unlock;
> + }
>
> ret = i915_gem_object_set_to_gtt_domain(obj, write);
> if (ret)
> @@ -1445,8 +1449,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> goto err_unpin;
>
> /* Finally, remap it using the new GTT offset */
> - pfn = ggtt->mappable_base +
> - i915_gem_obj_ggtt_offset_view(obj, &view);
> + pfn = dev_priv->ggtt.mappable_base + ggtt->node.start;
> pfn >>= PAGE_SHIFT;
>
> if (unlikely(view.type == I915_GGTT_VIEW_PARTIAL)) {
> @@ -1488,7 +1491,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> pfn + page_offset);
> }
> err_unpin:
> - i915_gem_object_ggtt_unpin_view(obj, &view);
> + __i915_vma_unpin(ggtt);
> err_unlock:
> mutex_unlock(&dev->struct_mutex);
> err_rpm:
> @@ -2925,7 +2928,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
> old_write_domain);
>
> /* And bump the LRU for this access */
> - vma = i915_gem_obj_to_ggtt(obj);
> + vma = i915_gem_object_to_ggtt(obj, NULL);
> if (vma &&
> drm_mm_node_allocated(&vma->node) &&
> !i915_vma_is_active(vma))
> @@ -3149,11 +3152,12 @@ rpm_put:
> * Can be called from an uninterruptible phase (modesetting) and allows
> * any flushes to be pipelined (for pageflips).
> */
> -int
> +struct i915_vma *
> i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
> u32 alignment,
> const struct i915_ggtt_view *view)
> {
> + struct i915_vma *vma;
> u32 old_read_domains, old_write_domain;
> int ret;
>
> @@ -3173,19 +3177,23 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
> */
> ret = i915_gem_object_set_cache_level(obj,
> HAS_WT(obj->base.dev) ? I915_CACHE_WT : I915_CACHE_NONE);
> - if (ret)
> + if (ret) {
> + vma = ERR_PTR(ret);
> goto err_unpin_display;
> + }
>
> /* As the user may map the buffer once pinned in the display plane
> * (e.g. libkms for the bootup splash), we have to ensure that we
> * always use map_and_fenceable for all scanout buffers.
> */
> - ret = i915_gem_object_ggtt_pin(obj, view, 0, alignment,
> + vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment,
> view->type == I915_GGTT_VIEW_NORMAL ?
> PIN_MAPPABLE : 0);
> - if (ret)
> + if (IS_ERR(vma))
> goto err_unpin_display;
>
> + WARN_ON(obj->pin_display > vma->pin_count);
> +
> i915_gem_object_flush_cpu_write_domain(obj);
>
> old_write_domain = obj->base.write_domain;
> @@ -3204,24 +3212,24 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
> /* Increment the pages_pin_count to guard against the shrinker */
> obj->pages_pin_count++;
>
> - return 0;
> + return vma;
>
> err_unpin_display:
> obj->pin_display--;
> - return ret;
> + return vma;
> }
>
> void
> -i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view)
> +i915_gem_object_unpin_from_display_plane(struct i915_vma *vma)
> {
> - if (WARN_ON(obj->pin_display == 0))
> + if (WARN_ON(vma->obj->pin_display == 0))
> return;
>
> - i915_gem_object_ggtt_unpin_view(obj, view);
> + vma->obj->pin_display--;
> + vma->obj->pages_pin_count--;
>
> - obj->pages_pin_count--;
> - obj->pin_display--;
> + i915_vma_unpin(vma);
> + WARN_ON(vma->obj->pin_display > vma->pin_count);
> }
>
> /**
> @@ -3421,26 +3429,24 @@ err:
> return ret;
> }
>
> -int
> +struct i915_vma *
> i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view,
> + const struct i915_ggtt_view *ggtt_view,
> uint64_t size,
> uint64_t alignment,
> uint64_t flags)
> {
> + struct i915_address_space *vm = &to_i915(obj->base.dev)->ggtt.base;
> struct i915_vma *vma;
> int ret;
>
> - if (view == NULL)
> - view = &i915_ggtt_view_normal;
> -
> - vma = i915_gem_obj_lookup_or_create_ggtt_vma(obj, view);
> + vma = i915_gem_obj_lookup_or_create_vma(obj, vm, ggtt_view);
> if (IS_ERR(vma))
> - return PTR_ERR(vma);
> + return vma;
>
> if (i915_vma_misplaced(vma, size, alignment, flags)) {
> if (flags & PIN_NONBLOCK && (vma->pin_count | vma->active))
> - return -ENOSPC;
> + return ERR_PTR(-ENOSPC);
>
> WARN(vma->pin_count,
> "bo is already pinned in ggtt with incorrect alignment:"
> @@ -3453,17 +3459,14 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
> obj->map_and_fenceable);
> ret = i915_vma_unbind(vma);
> if (ret)
> - return ret;
> + return ERR_PTR(ret);
> }
>
> - return i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
> -}
> + ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
> + if (ret)
> + return ERR_PTR(ret);
>
> -void
> -i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view)
> -{
> - i915_vma_unpin(i915_gem_obj_to_ggtt_view(obj, view));
> + return vma;
> }
>
> static __always_inline unsigned
> @@ -3799,31 +3802,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
> intel_runtime_pm_put(dev_priv);
> }
>
> -struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
> - struct i915_address_space *vm)
> -{
> - struct i915_vma *vma;
> - list_for_each_entry(vma, &obj->vma_list, obj_link) {
> - if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL &&
> - vma->vm == vm)
> - return vma;
> - }
> - return NULL;
> -}
> -
> -struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view)
> -{
> - struct i915_vma *vma;
> -
> - GEM_BUG_ON(!view);
> -
> - list_for_each_entry(vma, &obj->vma_list, obj_link)
> - if (vma->is_ggtt && i915_ggtt_view_equal(&vma->ggtt_view, view))
> - return vma;
> - return NULL;
> -}
> -
> int
> i915_gem_suspend(struct drm_device *dev)
> {
> @@ -4321,96 +4299,6 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
> }
> }
>
> -/* All the new VM stuff */
> -u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
> - struct i915_address_space *vm)
> -{
> - struct drm_i915_private *dev_priv = o->base.dev->dev_private;
> - struct i915_vma *vma;
> -
> - WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
> -
> - list_for_each_entry(vma, &o->vma_list, obj_link) {
> - if (vma->is_ggtt &&
> - vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
> - continue;
> - if (vma->vm == vm)
> - return vma->node.start;
> - }
> -
> - WARN(1, "%s vma for this object not found.\n",
> - i915_is_ggtt(vm) ? "global" : "ppgtt");
> - return -1;
> -}
> -
> -u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
> - const struct i915_ggtt_view *view)
> -{
> - struct i915_vma *vma;
> -
> - list_for_each_entry(vma, &o->vma_list, obj_link)
> - if (vma->is_ggtt && i915_ggtt_view_equal(&vma->ggtt_view, view))
> - return vma->node.start;
> -
> - WARN(1, "global vma for this object not found. (view=%u)\n", view->type);
> - return -1;
> -}
> -
> -bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
> - struct i915_address_space *vm)
> -{
> - struct i915_vma *vma;
> -
> - list_for_each_entry(vma, &o->vma_list, obj_link) {
> - if (vma->is_ggtt &&
> - vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
> - continue;
> - if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
> - return true;
> - }
> -
> - return false;
> -}
> -
> -bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
> - const struct i915_ggtt_view *view)
> -{
> - struct i915_vma *vma;
> -
> - list_for_each_entry(vma, &o->vma_list, obj_link)
> - if (vma->is_ggtt &&
> - i915_ggtt_view_equal(&vma->ggtt_view, view) &&
> - drm_mm_node_allocated(&vma->node))
> - return true;
> -
> - return false;
> -}
> -
> -unsigned long i915_gem_obj_ggtt_size(struct drm_i915_gem_object *o)
> -{
> - struct i915_vma *vma;
> -
> - GEM_BUG_ON(list_empty(&o->vma_list));
> -
> - list_for_each_entry(vma, &o->vma_list, obj_link) {
> - if (vma->is_ggtt &&
> - vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
> - return vma->node.size;
> - }
> -
> - return 0;
> -}
> -
> -bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
> -{
> - struct i915_vma *vma;
> - list_for_each_entry(vma, &obj->vma_list, obj_link)
> - if (i915_vma_is_pinned(vma))
> - return true;
> -
> - return false;
> -}
> -
> /* Like i915_gem_object_get_page(), but mark the returned page dirty */
> struct page *
> i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n)
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index c9b8c2c62828..0ed8a4a7321a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -360,8 +360,8 @@ static void i915_gem_context_unpin(struct i915_gem_context *ctx,
> } else {
> struct intel_context *ce = &ctx->engine[engine->id];
>
> - if (ce->state)
> - i915_gem_object_ggtt_unpin(ce->state);
> + if (ce->vma)
> + i915_vma_unpin(ce->vma);
>
> i915_gem_context_put(ctx);
> }
> @@ -580,9 +580,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
>
> intel_ring_emit(ring, MI_NOOP);
> intel_ring_emit(ring, MI_SET_CONTEXT);
> - intel_ring_emit(ring,
> - i915_gem_obj_ggtt_offset(req->ctx->engine[RCS].state) |
> - flags);
> + intel_ring_emit(ring, req->ctx->engine[RCS].vma->node.start | flags);
> /*
> * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
> * WaMiSetContext_Hang:snb,ivb,vlv
> @@ -610,7 +608,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
> MI_STORE_REGISTER_MEM |
> MI_SRM_LRM_GLOBAL_GTT);
> intel_ring_emit_reg(ring, last_reg);
> - intel_ring_emit(ring, req->engine->scratch.gtt_offset);
> + intel_ring_emit(ring, req->engine->scratch->node.start);
> intel_ring_emit(ring, MI_NOOP);
> }
> intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE);
> @@ -715,6 +713,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> struct intel_engine_cs *engine = req->engine;
> struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> struct i915_gem_context *from;
> + struct i915_vma *vma;
> u32 hw_flags;
> int ret, i;
>
> @@ -722,10 +721,17 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> return 0;
>
> /* Trying to pin first makes error handling easier. */
> - ret = i915_gem_object_ggtt_pin(to->engine[RCS].state, NULL, 0,
> + vma = i915_gem_object_ggtt_pin(to->engine[RCS].state, NULL, 0,
> to->ggtt_alignment, 0);
> - if (ret)
> - return ret;
> + if (IS_ERR(vma))
> + return PTR_ERR(vma);
> +
> + to->engine[RCS].vma = vma;
> +
> + if (WARN_ON(!(vma->bound & GLOBAL_BIND))) {
> + ret = -ENODEV;
> + goto unpin_vma;
> + }
>
> /*
> * Pin can switch back to the default context if we end up calling into
> @@ -746,7 +752,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> */
> ret = i915_gem_object_set_to_gtt_domain(to->engine[RCS].state, false);
> if (ret)
> - goto unpin_out;
> + goto unpin_vma;
>
> if (needs_pd_load_pre(ppgtt, engine, to)) {
> /* Older GENs and non render rings still want the load first,
> @@ -756,7 +762,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> trace_switch_mm(engine, to);
> ret = ppgtt->switch_mm(ppgtt, req);
> if (ret)
> - goto unpin_out;
> + goto unpin_vma;
> }
>
> if (!to->engine[RCS].initialised || i915_gem_context_is_default(to))
> @@ -773,7 +779,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> if (to != from || (hw_flags & MI_FORCE_RESTORE)) {
> ret = mi_set_context(req, hw_flags);
> if (ret)
> - goto unpin_out;
> + goto unpin_vma;
> }
>
> /* The backing object for the context is done after switching to the
> @@ -783,8 +789,6 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> * MI_SET_CONTEXT instead of when the next seqno has completed.
> */
> if (from != NULL) {
> - struct drm_i915_gem_object *obj = from->engine[RCS].state;
> -
> /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
> * whole damn pipeline, we don't need to explicitly mark the
> * object dirty. The only exception is that the context must be
> @@ -792,11 +796,10 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
> * able to defer doing this until we know the object would be
> * swapped, but there is no way to do that yet.
> */
> - obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> - i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), req, 0);
> -
> + i915_vma_move_to_active(from->engine[RCS].vma, req, 0);
> /* obj is kept alive until the next request by its active ref */
> - i915_gem_object_ggtt_unpin(obj);
> + i915_vma_unpin(from->engine[RCS].vma);
> +
> i915_gem_context_put(from);
> }
> engine->last_context = i915_gem_context_get(to);
> @@ -841,8 +844,8 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
>
> return 0;
>
> -unpin_out:
> - i915_gem_object_ggtt_unpin(to->engine[RCS].state);
> +unpin_vma:
> + i915_vma_unpin(vma);
> return ret;
> }
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index b89e9d2b33c4..a29c4b6fea28 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -174,8 +174,8 @@ eb_lookup_vmas(struct eb_vmas *eb,
> * from the (obj, vm) we don't run the risk of creating
> * duplicated vmas for the same vm.
> */
> - vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
> - if (IS_ERR(vma)) {
> + vma = i915_gem_obj_lookup_or_create_vma(obj, vm, NULL);
> + if (unlikely(IS_ERR(vma))) {
> DRM_DEBUG("Failed to lookup VMA\n");
> ret = PTR_ERR(vma);
> goto err;
> @@ -343,30 +343,34 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
> struct drm_i915_gem_relocation_entry *reloc,
> uint64_t target_offset)
> {
> - struct drm_device *dev = obj->base.dev;
> - struct drm_i915_private *dev_priv = to_i915(dev);
> + struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
> struct i915_ggtt *ggtt = &dev_priv->ggtt;
> + struct i915_vma *vma;
> uint64_t delta = relocation_target(reloc, target_offset);
> uint64_t offset;
> void __iomem *reloc_page;
> int ret;
>
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
> + if (IS_ERR(vma))
> + return PTR_ERR(vma);
> +
> ret = i915_gem_object_set_to_gtt_domain(obj, true);
> if (ret)
> - return ret;
> + goto unpin;
>
> ret = i915_gem_object_put_fence(obj);
> if (ret)
> - return ret;
> + goto unpin;
>
> /* Map the page containing the relocation we're going to perform. */
> - offset = i915_gem_obj_ggtt_offset(obj);
> + offset = vma->node.start;
> offset += reloc->offset;
> reloc_page = io_mapping_map_atomic_wc(ggtt->mappable,
> offset & PAGE_MASK);
> iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset));
>
> - if (INTEL_INFO(dev)->gen >= 8) {
> + if (INTEL_GEN(dev_priv) >= 8) {
> offset += sizeof(uint32_t);
>
> if (offset_in_page(offset) == 0) {
> @@ -382,7 +386,9 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
>
> io_mapping_unmap_atomic(reloc_page);
>
> - return 0;
> +unpin:
> + i915_vma_unpin(vma);
> + return ret;
> }
>
> static void
> @@ -1236,7 +1242,7 @@ i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req)
> return 0;
> }
>
> -static struct i915_vma*
> +static struct i915_vma *
> i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
> struct drm_i915_gem_exec_object2 *shadow_exec_entry,
> struct drm_i915_gem_object *batch_obj,
> @@ -1260,31 +1266,30 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
> batch_start_offset,
> batch_len,
> is_master);
> - if (ret)
> + if (ret) {
> + if (ret == -EACCES) /* unhandled chained batch */
> + vma = NULL;
> + else
> + vma = ERR_PTR(ret);
> goto err;
> + }
>
> - ret = i915_gem_object_ggtt_pin(shadow_batch_obj, NULL, 0, 0, 0);
> - if (ret)
> + vma = i915_gem_object_ggtt_pin(shadow_batch_obj, NULL, 0, 0, 0);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto err;
> -
> - i915_gem_object_unpin_pages(shadow_batch_obj);
> + }
>
> memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry));
>
> - vma = i915_gem_obj_to_ggtt(shadow_batch_obj);
> vma->exec_entry = shadow_exec_entry;
> vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN;
> i915_gem_object_get(shadow_batch_obj);
> list_add_tail(&vma->exec_list, &eb->vmas);
>
> - return vma;
> -
> err:
> i915_gem_object_unpin_pages(shadow_batch_obj);
> - if (ret == -EACCES) /* unhandled chained batch */
> - return NULL;
> - else
> - return ERR_PTR(ret);
> + return vma;
> }
>
> static int
> @@ -1631,6 +1636,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
> * hsw should have this fixed, but bdw mucks it up again. */
> if (dispatch_flags & I915_DISPATCH_SECURE) {
> struct drm_i915_gem_object *obj = params->batch_vma->obj;
> + struct i915_vma *vma;
>
> /*
> * So on first glance it looks freaky that we pin the batch here
> @@ -1642,11 +1648,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
> * fitting due to fragmentation.
> * So this is actually safe.
> */
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
> - if (ret)
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto err;
> + }
>
> - params->batch_vma = i915_gem_obj_to_ggtt(obj);
> + params->batch_vma = vma;
> }
>
> /* Allocate a request for this batch buffer nice and early. */
> @@ -1662,7 +1670,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
> * inactive_list and lose its active reference. Hence we do not need
> * to explicitly hold another reference here.
> */
> - params->request->batch_obj = params->batch_vma->obj;
> + params->request->batch = params->batch_vma;
>
> ret = i915_gem_request_add_to_client(params->request, file);
> if (ret)
> diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
> index ee91705734bc..187611eafa99 100644
> --- a/drivers/gpu/drm/i915/i915_gem_fence.c
> +++ b/drivers/gpu/drm/i915/i915_gem_fence.c
> @@ -85,20 +85,14 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
> POSTING_READ(fence_reg_lo);
>
> if (obj) {
> - u32 size = i915_gem_obj_ggtt_size(obj);
> - uint64_t val;
> -
> - /* Adjust fence size to match tiled area */
> - if (obj->tiling_mode != I915_TILING_NONE) {
> - uint32_t row_size = obj->stride *
> - (obj->tiling_mode == I915_TILING_Y ? 32 : 8);
> - size = (size / row_size) * row_size;
> - }
> -
> - val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
> - 0xfffff000) << 32;
> - val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
> - val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift;
> + struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
> + u32 row_size = obj->stride * (obj->tiling_mode == I915_TILING_Y ? 32 : 8);
> + u32 size = (u32)vma->node.size / row_size * row_size;
> + u64 val;
> +
> + val = ((vma->node.start + size - 4096) & 0xfffff000) << 32;
> + val |= vma->node.start & 0xfffff000;
> + val |= (u64)((obj->stride / 128) - 1) << fence_pitch_shift;
> if (obj->tiling_mode == I915_TILING_Y)
> val |= 1 << I965_FENCE_TILING_Y_SHIFT;
> val |= I965_FENCE_REG_VALID;
> @@ -121,15 +115,17 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
> u32 val;
>
> if (obj) {
> - u32 size = i915_gem_obj_ggtt_size(obj);
> + struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
> int pitch_val;
> int tile_width;
>
> - WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) ||
> - (size & -size) != size ||
> - (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
> - "object 0x%08llx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
> - i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size);
> + WARN((vma->node.start & ~I915_FENCE_START_MASK) ||
> + !is_power_of_2(vma->node.size) ||
> + (vma->node.start & (vma->node.size - 1)),
> + "object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08lx) aligned\n",
> + (long)vma->node.start,
> + obj->map_and_fenceable,
> + (long)vma->node.size);
>
> if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
> tile_width = 128;
> @@ -140,10 +136,10 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
> pitch_val = obj->stride / tile_width;
> pitch_val = ffs(pitch_val) - 1;
>
> - val = i915_gem_obj_ggtt_offset(obj);
> + val = vma->node.start;
> if (obj->tiling_mode == I915_TILING_Y)
> val |= 1 << I830_FENCE_TILING_Y_SHIFT;
> - val |= I915_FENCE_SIZE_BITS(size);
> + val |= I915_FENCE_SIZE_BITS(vma->node.size);
> val |= pitch_val << I830_FENCE_PITCH_SHIFT;
> val |= I830_FENCE_REG_VALID;
> } else
> @@ -160,22 +156,22 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
> uint32_t val;
>
> if (obj) {
> - u32 size = i915_gem_obj_ggtt_size(obj);
> + struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
> uint32_t pitch_val;
>
> - WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
> - (size & -size) != size ||
> - (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
> - "object 0x%08llx not 512K or pot-size 0x%08x aligned\n",
> - i915_gem_obj_ggtt_offset(obj), size);
> + WARN((vma->node.start & ~I830_FENCE_START_MASK) ||
> + !is_power_of_2(vma->node.size) ||
> + (vma->node.start & (vma->node.size - 1)),
> + "object 0x%08lx not 512K or pot-size 0x%08lx aligned\n",
> + (long)vma->node.start, (long)vma->node.size);
>
> pitch_val = obj->stride / 128;
> pitch_val = ffs(pitch_val) - 1;
>
> - val = i915_gem_obj_ggtt_offset(obj);
> + val = vma->node.start;
> if (obj->tiling_mode == I915_TILING_Y)
> val |= 1 << I830_FENCE_TILING_Y_SHIFT;
> - val |= I830_FENCE_SIZE_BITS(size);
> + val |= I830_FENCE_SIZE_BITS(vma->node.size);
> val |= pitch_val << I830_FENCE_PITCH_SHIFT;
> val |= I830_FENCE_REG_VALID;
> } else
> @@ -426,13 +422,7 @@ bool
> i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
> {
> if (obj->fence_reg != I915_FENCE_REG_NONE) {
> - struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
> - struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj);
> -
> - WARN_ON(!ggtt_vma ||
> - dev_priv->fence_regs[obj->fence_reg].pin_count >
> - ggtt_vma->pin_count);
> - dev_priv->fence_regs[obj->fence_reg].pin_count++;
> + to_i915(obj->base.dev)->fence_regs[obj->fence_reg].pin_count++;
> return true;
> } else
> return false;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index c7a77e0f18c2..775b5a4e8a5b 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3325,14 +3325,10 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>
> GEM_BUG_ON(vm->closed);
>
> - if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
> - return ERR_PTR(-EINVAL);
> -
> vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL);
> if (vma == NULL)
> return ERR_PTR(-ENOMEM);
>
> - INIT_LIST_HEAD(&vma->obj_link);
> INIT_LIST_HEAD(&vma->exec_list);
> for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
> init_request_active(&vma->last_read[i], i915_vma_retire);
> @@ -3342,49 +3338,69 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
> vma->size = obj->base.size;
> vma->is_ggtt = i915_is_ggtt(vm);
>
> - if (i915_is_ggtt(vm)) {
> + if (ggtt_view) {
> vma->ggtt_view = *ggtt_view;
> if (ggtt_view->type == I915_GGTT_VIEW_PARTIAL)
> vma->size = ggtt_view->params.partial.size << PAGE_SHIFT;
> else if (ggtt_view->type == I915_GGTT_VIEW_ROTATED)
> vma->size = intel_rotation_info_size(&ggtt_view->params.rotated) << PAGE_SHIFT;
> } else
> +
> + if (!vma->is_ggtt)
> i915_ppgtt_get(i915_vm_to_ppgtt(vm));
>
> list_add_tail(&vma->obj_link, &obj->vma_list);
> -
> return vma;
> }
>
> +static inline bool vma_matches(struct i915_vma *vma,
> + struct i915_address_space *vm,
> + const struct i915_ggtt_view *view)
> +{
> + if (vma->vm != vm)
> + return false;
> +
> + if (!vma->is_ggtt)
> + return true;
> +
> + if (view == NULL)
> + return vma->ggtt_view.type == 0;
> +
> + if (vma->ggtt_view.type != view->type)
> + return false;
> +
> + return memcmp(&vma->ggtt_view.params,
> + &view->params,
> + sizeof(view->params)) == 0;
> +}
> +
> struct i915_vma *
> -i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
> - struct i915_address_space *vm)
> +i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
> + struct i915_address_space *vm,
> + const struct i915_ggtt_view *view)
> {
> struct i915_vma *vma;
>
> - vma = i915_gem_obj_to_vma(obj, vm);
> - if (!vma)
> - vma = __i915_gem_vma_create(obj, vm,
> - i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL);
> + list_for_each_entry_reverse(vma, &obj->vma_list, obj_link)
> + if (vma_matches(vma, vm, view))
> + return vma;
>
> - return vma;
> + return NULL;
> }
>
> struct i915_vma *
> -i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
> - const struct i915_ggtt_view *view)
> +i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
> + struct i915_address_space *vm,
> + const struct i915_ggtt_view *view)
> {
> - struct drm_device *dev = obj->base.dev;
> - struct drm_i915_private *dev_priv = to_i915(dev);
> - struct i915_ggtt *ggtt = &dev_priv->ggtt;
> - struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view);
> + struct i915_vma *vma;
>
> + vma = i915_gem_obj_to_vma(obj, vm, view);
> if (!vma)
> - vma = __i915_gem_vma_create(obj, &ggtt->base, view);
> + vma = __i915_gem_vma_create(obj, vm, view);
>
> GEM_BUG_ON(vma->closed);
> return vma;
> -
> }
>
> static struct scatterlist *
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 5655358a60e1..5b28dc251e60 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -590,20 +590,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev);
> int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
> void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj);
>
> -static inline bool
> -i915_ggtt_view_equal(const struct i915_ggtt_view *a,
> - const struct i915_ggtt_view *b)
> -{
> - if (WARN_ON(!a || !b))
> - return false;
> -
> - if (a->type != b->type)
> - return false;
> - if (a->type != I915_GGTT_VIEW_NORMAL)
> - return !memcmp(&a->params, &b->params, sizeof(a->params));
> - return true;
> -}
> -
> /**
> * i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture
> * @vma: VMA to iomap
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
> index 4cf82697b3db..6e6eac43db19 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.c
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
> @@ -31,7 +31,7 @@
> struct render_state {
> const struct intel_renderstate_rodata *rodata;
> struct drm_i915_gem_object *obj;
> - u64 ggtt_offset;
> + struct i915_vma *vma;
> int gen;
> u32 aux_batch_size;
> u32 aux_batch_offset;
> @@ -57,10 +57,9 @@ render_state_get_rodata(const int gen)
> static int render_state_init(struct render_state *so,
> struct drm_i915_private *dev_priv)
> {
> - int ret;
> + struct i915_vma *vma;
>
> so->gen = INTEL_GEN(dev_priv);
> - so->ggtt_offset = 0;
> so->rodata = render_state_get_rodata(so->gen);
> if (so->rodata == NULL)
> return 0;
> @@ -72,16 +71,14 @@ static int render_state_init(struct render_state *so,
> if (IS_ERR(so->obj))
> return PTR_ERR(so->obj);
>
> - ret = i915_gem_object_ggtt_pin(so->obj, NULL, 0, 0, 0);
> - if (ret)
> - goto free_gem;
> + vma = i915_gem_object_ggtt_pin(so->obj, NULL, 0, 0, 0);
> + if (IS_ERR(vma)) {
> + i915_gem_object_put(so->obj);
> + return PTR_ERR(vma);
> + }
>
> - so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj);
> + so->vma = vma;
> return 0;
> -
> -free_gem:
> - i915_gem_object_put(so->obj);
> - return ret;
> }
>
> /*
> @@ -121,7 +118,7 @@ static int render_state_setup(struct render_state *so)
> u32 s = rodata->batch[i];
>
> if (i * 4 == rodata->reloc[reloc_index]) {
> - u64 r = s + so->ggtt_offset;
> + u64 r = s + so->vma->node.start,
> s = lower_32_bits(r);
> if (so->gen >= 8) {
> if (i + 1 >= rodata->batch_items ||
> @@ -176,7 +173,7 @@ err_out:
>
> static void render_state_fini(struct render_state *so)
> {
> - i915_gem_object_ggtt_unpin(so->obj);
> + i915_vma_unpin(so->vma);
> i915_gem_object_put(so->obj);
> }
>
> @@ -209,14 +206,14 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req)
> struct render_state so;
> int ret;
>
> - ret = render_state_prepare(req->engine, &so);
> + ret = render_state_prepare(req->engine, memset(&so, 0, sizeof(so)));
> if (ret)
> return ret;
>
> if (so.rodata == NULL)
> return 0;
>
> - ret = req->engine->emit_bb_start(req, so.ggtt_offset,
> + ret = req->engine->emit_bb_start(req, so.vma->node.start,
> so.rodata->batch_items * 4,
> I915_DISPATCH_SECURE);
> if (ret)
> @@ -224,7 +221,7 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req)
>
> if (so.aux_batch_size > 8) {
> ret = req->engine->emit_bb_start(req,
> - (so.ggtt_offset +
> + (so.vma->node.start +
> so.aux_batch_offset),
> so.aux_batch_size,
> I915_DISPATCH_SECURE);
> @@ -232,7 +229,7 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req)
> goto out;
> }
>
> - i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req, 0);
> + i915_vma_move_to_active(so.vma, req, 0);
> out:
> render_state_fini(&so);
> return ret;
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h
> index c44fca8599bb..18cce3f06e9c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.h
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h
> @@ -24,7 +24,7 @@
> #ifndef _I915_GEM_RENDER_STATE_H_
> #define _I915_GEM_RENDER_STATE_H_
>
> -#include <linux/types.h>
> +struct drm_i915_gem_request;
>
> int i915_gem_render_state_init(struct drm_i915_gem_request *req);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index 8101d9169027..5a3d81e5458b 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -404,18 +404,12 @@ static void i915_gem_mark_busy(struct drm_i915_private *dev_priv,
> */
> void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
> {
> - struct intel_engine_cs *engine;
> - struct intel_ring *ring;
> + struct intel_engine_cs *engine = request->engine;
> + struct intel_ring *ring = request->ring;
> u32 request_start;
> u32 reserved_tail;
> int ret;
>
> - if (WARN_ON(request == NULL))
> - return;
> -
> - engine = request->engine;
> - ring = request->ring;
> -
> /*
> * To ensure that this call will not fail, space for its emissions
> * should already have been reserved in the ring buffer. Let the ring
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
> index 87e055267904..a8e228f5ceb4 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.h
> +++ b/drivers/gpu/drm/i915/i915_gem_request.h
> @@ -111,7 +111,7 @@ struct drm_i915_gem_request {
>
> /** Batch buffer related to this request if any (used for
> * error state dump only) */
> - struct drm_i915_gem_object *batch_obj;
> + struct i915_vma *batch;
> struct list_head active_list;
>
> /** Time at which this request was emitted, in jiffies. */
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index a881c243fca2..415fa04d5232 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -683,7 +683,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
> if (gtt_offset == I915_GTT_OFFSET_NONE)
> return obj;
>
> - vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base);
> + vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base, NULL);
> if (IS_ERR(vma)) {
> ret = PTR_ERR(vma);
> goto err;
> diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
> index d6acd0a27c06..29fc4dfd1947 100644
> --- a/drivers/gpu/drm/i915/i915_gem_tiling.c
> +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
> @@ -114,33 +114,44 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
> }
>
> /* Is the current GTT allocation valid for the change in tiling? */
> -static bool
> +static int
> i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
> {
> + struct i915_vma *vma;
> u32 size;
>
> if (tiling_mode == I915_TILING_NONE)
> - return true;
> + return 0;
>
> - if (INTEL_INFO(obj->base.dev)->gen >= 4)
> - return true;
> + if (INTEL_GEN(obj->base.dev) >= 4)
> + return 0;
> +
> + vma = i915_gem_object_to_ggtt(obj, NULL);
> + if (vma == NULL)
> + return 0;
> +
> + if (!obj->map_and_fenceable)
> + return 0;
>
> if (IS_GEN3(obj->base.dev)) {
> - if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
> - return false;
> + if (vma->node.start & ~I915_FENCE_START_MASK)
> + goto bad;
> } else {
> - if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK)
> - return false;
> + if (vma->node.start & ~I830_FENCE_START_MASK)
> + goto bad;
> }
>
> size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode);
> - if (i915_gem_obj_ggtt_size(obj) != size)
> - return false;
> + if (vma->node.size < size)
> + goto bad;
>
> - if (i915_gem_obj_ggtt_offset(obj) & (size - 1))
> - return false;
> + if (vma->node.start & (size - 1))
> + goto bad;
>
> - return true;
> + return 0;
> +
> +bad:
> + return i915_vma_unbind(vma);
> }
>
> /**
> @@ -227,10 +238,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
> * has to also include the unfenced register the GPU uses
> * whilst executing a fenced command for an untiled object.
> */
> - if (obj->map_and_fenceable &&
> - !i915_gem_object_fence_ok(obj, args->tiling_mode))
> - ret = i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
> -
> + ret = i915_gem_object_fence_ok(obj, args->tiling_mode);
> if (ret == 0) {
> if (obj->pages &&
> obj->madv == I915_MADV_WILLNEED &&
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 367b8b2ce5f2..3e42705e2fa4 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -632,18 +632,21 @@ static void i915_error_state_free(struct kref *error_ref)
>
> static struct drm_i915_error_object *
> i915_error_object_create(struct drm_i915_private *dev_priv,
> - struct drm_i915_gem_object *src,
> - struct i915_address_space *vm)
> + struct i915_vma *vma)
> {
> struct i915_ggtt *ggtt = &dev_priv->ggtt;
> + struct drm_i915_gem_object *src;
> struct drm_i915_error_object *dst;
> - struct i915_vma *vma = NULL;
> int num_pages;
> bool use_ggtt;
> int i = 0;
> u64 reloc_offset;
>
> - if (src == NULL || src->pages == NULL)
> + if (vma == NULL)
> + return NULL;
> +
> + src = vma->obj;
> + if (src->pages == NULL)
> return NULL;
>
> num_pages = src->base.size >> PAGE_SHIFT;
> @@ -652,26 +655,19 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
> if (dst == NULL)
> return NULL;
>
> - if (i915_gem_obj_bound(src, vm))
> - dst->gtt_offset = i915_gem_obj_offset(src, vm);
> - else
> - dst->gtt_offset = -1;
> -
> - reloc_offset = dst->gtt_offset;
> - if (i915_is_ggtt(vm))
> - vma = i915_gem_obj_to_ggtt(src);
> + reloc_offset = dst->gtt_offset = vma->node.start;
> use_ggtt = (src->cache_level == I915_CACHE_NONE &&
> - vma && (vma->bound & GLOBAL_BIND) &&
> + (vma->bound & GLOBAL_BIND) &&
> reloc_offset + num_pages * PAGE_SIZE <= ggtt->mappable_end);
>
> /* Cannot access stolen address directly, try to use the aperture */
> if (src->stolen) {
> use_ggtt = true;
>
> - if (!(vma && vma->bound & GLOBAL_BIND))
> + if (!(vma->bound & GLOBAL_BIND))
> goto unwind;
>
> - reloc_offset = i915_gem_obj_ggtt_offset(src);
> + reloc_offset = vma->node.start;
> if (reloc_offset + num_pages * PAGE_SIZE > ggtt->mappable_end)
> goto unwind;
> }
> @@ -724,8 +720,6 @@ unwind:
> kfree(dst);
> return NULL;
> }
> -#define i915_error_ggtt_object_create(dev_priv, src) \
> - i915_error_object_create((dev_priv), (src), &(dev_priv)->ggtt.base)
>
> /* The error capture is special as tries to run underneath the normal
> * locking rules - so we use the raw version of the i915_gem_active lookup.
> @@ -851,10 +845,10 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
> if (!i915.semaphores)
> return;
>
> - if (!error->semaphore_obj)
> + if (!error->semaphore_obj && dev_priv->semaphore_vma)
> error->semaphore_obj =
> - i915_error_ggtt_object_create(dev_priv,
> - dev_priv->semaphore_obj);
> + i915_error_object_create(dev_priv,
> + dev_priv->semaphore_vma);
>
> for_each_engine_id(to, dev_priv, id) {
> int idx;
> @@ -1042,9 +1036,7 @@ static void i915_gem_record_active_context(struct intel_engine_cs *engine,
>
> list_for_each_entry(vma, &dev_priv->ggtt.base.active_list, vm_link) {
> if ((error->ccid & PAGE_MASK) == vma->node.start) {
> - ering->ctx = i915_error_object_create(dev_priv,
> - vma->obj,
> - vma->vm);
> + ering->ctx = i915_error_object_create(dev_priv, vma);
> break;
> }
> }
> @@ -1086,13 +1078,12 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
> */
> error->ring[i].batchbuffer =
> i915_error_object_create(dev_priv,
> - request->batch_obj,
> - vm);
> + request->batch);
>
> if (HAS_BROKEN_CS_TLB(dev_priv))
> error->ring[i].wa_batchbuffer =
> - i915_error_ggtt_object_create(dev_priv,
> - engine->scratch.obj);
> + i915_error_object_create(dev_priv,
> + engine->scratch);
>
> if (request->pid) {
> struct task_struct *task;
> @@ -1112,17 +1103,15 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
> error->ring[i].cpu_ring_head = ring->head;
> error->ring[i].cpu_ring_tail = ring->tail;
> error->ring[i].ringbuffer =
> - i915_error_ggtt_object_create(dev_priv,
> - ring->obj);
> + i915_error_object_create(dev_priv, ring->vma);
> }
>
> error->ring[i].hws_page =
> - i915_error_ggtt_object_create(dev_priv,
> - engine->status_page.obj);
> + i915_error_object_create(dev_priv,
> + engine->status_page.vma);
>
> error->ring[i].wa_ctx =
> - i915_error_ggtt_object_create(dev_priv,
> - engine->wa_ctx.obj);
> + i915_error_object_create(dev_priv, engine->wa_ctx.vma);
>
> i915_gem_record_active_context(engine, error, &error->ring[i]);
>
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 1c92c4c6b0e1..90db9a88fddc 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -375,7 +375,6 @@ static void guc_init_ctx_desc(struct intel_guc *guc,
> for_each_engine(engine, dev_priv) {
> struct intel_context *ce = &ctx->engine[engine->id];
> struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id];
> - struct drm_i915_gem_object *obj;
>
> /* TODO: We have a design issue to be solved here. Only when we
> * receive the first batch, we know which engine is used by the
> @@ -384,23 +383,20 @@ static void guc_init_ctx_desc(struct intel_guc *guc,
> * for now who owns a GuC client. But for future owner of GuC
> * client, need to make sure lrc is pinned prior to enter here.
> */
> - if (!ce->state)
> + if (!ce->vma)
> break; /* XXX: continue? */
>
> lrc->context_desc = lower_32_bits(ce->lrc_desc);
>
> /* The state page is after PPHWSP */
> - gfx_addr = i915_gem_obj_ggtt_offset(ce->state);
> + gfx_addr = ce->vma->node.start;
> lrc->ring_lcra = gfx_addr + LRC_STATE_PN * PAGE_SIZE;
> lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) |
> (engine->guc_id << GUC_ELC_ENGINE_OFFSET);
>
> - obj = ce->ring->obj;
> - gfx_addr = i915_gem_obj_ggtt_offset(obj);
> -
> - lrc->ring_begin = gfx_addr;
> - lrc->ring_end = gfx_addr + obj->base.size - 1;
> - lrc->ring_next_free_location = gfx_addr;
> + lrc->ring_begin = ce->ring->vma->node.start;
> + lrc->ring_end = gfx_addr + ce->ring->vma->node.size - 1;
> + lrc->ring_next_free_location = lrc->ring_begin;
> lrc->ring_current_tail_pointer_value = 0;
>
> desc.engines_used |= (1 << engine->guc_id);
> @@ -602,23 +598,23 @@ static struct i915_vma *guc_allocate_vma(struct intel_guc *guc, u32 size)
> {
> struct drm_i915_private *dev_priv = guc_to_i915(guc);
> struct drm_i915_gem_object *obj;
> - int ret;
> + struct i915_vma *vma;
>
> obj = i915_gem_object_create(dev_priv->dev, size);
> if (IS_ERR(obj))
> return ERR_CAST(obj);
>
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE,
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE,
> PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
> - if (ret) {
> + if (IS_ERR(vma)) {
> i915_gem_object_put(obj);
> - return ERR_PTR(ret);
> + return vma;
> }
>
> /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
>
> - return i915_gem_obj_to_ggtt(obj);
> + return vma;
> }
>
> /**
> @@ -988,7 +984,7 @@ int intel_guc_suspend(struct drm_device *dev)
> /* any value greater than GUC_POWER_D0 */
> data[1] = GUC_POWER_D1;
> /* first page is shared data with GuC */
> - data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state);
> + data[2] = ctx->engine[RCS].vma->node.start;
>
> return host2guc_action(guc, data, ARRAY_SIZE(data));
> }
> @@ -1013,7 +1009,7 @@ int intel_guc_resume(struct drm_device *dev)
> data[0] = HOST2GUC_ACTION_EXIT_S_STATE;
> data[1] = GUC_POWER_D0;
> /* first page is shared data with GuC */
> - data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state);
> + data[2] = ctx->engine[RCS].vma->node.start;
>
> return host2guc_action(guc, data, ARRAY_SIZE(data));
> }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0cfaace38370..cc6f7a49bf58 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2240,14 +2240,14 @@ static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv
> }
> }
>
> -int
> -intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
> - unsigned int rotation)
> +struct i915_vma *
> +intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
> {
> struct drm_device *dev = fb->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> struct i915_ggtt_view view;
> + struct i915_vma *vma;
> u32 alignment;
> int ret;
>
> @@ -2274,10 +2274,11 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
> */
> intel_runtime_pm_get(dev_priv);
>
> - ret = i915_gem_object_pin_to_display_plane(obj, alignment,
> - &view);
> - if (ret)
> + vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto err_pm;
> + }
>
> /* Install a fence for tiled scan-out. Pre-i965 always needs a
> * fence, whereas 965+ only requires a fence if using
> @@ -2304,19 +2305,20 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
> }
>
> intel_runtime_pm_put(dev_priv);
> - return 0;
> + return vma;
>
> err_unpin:
> - i915_gem_object_unpin_from_display_plane(obj, &view);
> + i915_gem_object_unpin_from_display_plane(vma);
> err_pm:
> intel_runtime_pm_put(dev_priv);
> - return ret;
> + return ERR_PTR(ret);
> }
>
> void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
> {
> struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> struct i915_ggtt_view view;
> + struct i915_vma *vma;
>
> WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
>
> @@ -2325,7 +2327,8 @@ void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
> if (view.type == I915_GGTT_VIEW_NORMAL)
> i915_gem_object_unpin_fence(obj);
>
> - i915_gem_object_unpin_from_display_plane(obj, &view);
> + vma = i915_gem_object_to_ggtt(obj, &view);
> + i915_gem_object_unpin_from_display_plane(vma);
> }
>
> /*
> @@ -2587,7 +2590,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> continue;
>
> obj = intel_fb_obj(fb);
> - if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
> + if (i915_gem_object_ggtt_offset(obj, NULL) == plane_config->base) {
> drm_framebuffer_reference(fb);
> goto valid_fb;
> }
> @@ -2745,11 +2748,11 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
> I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
> if (INTEL_INFO(dev)->gen >= 4) {
> I915_WRITE(DSPSURF(plane),
> - i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
> + i915_gem_object_ggtt_offset(obj, NULL) + intel_crtc->dspaddr_offset);
> I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
> I915_WRITE(DSPLINOFF(plane), linear_offset);
> } else
> - I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
> + I915_WRITE(DSPADDR(plane), i915_gem_object_ggtt_offset(obj, NULL) + linear_offset);
> POSTING_READ(reg);
> }
>
> @@ -2849,7 +2852,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
>
> I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
> I915_WRITE(DSPSURF(plane),
> - i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
> + i915_gem_object_ggtt_offset(obj, NULL) + intel_crtc->dspaddr_offset);
> if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
> } else {
> @@ -2882,7 +2885,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
> intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb,
> intel_plane->base.state->rotation);
>
> - vma = i915_gem_obj_to_ggtt_view(obj, &view);
> + vma = i915_gem_object_to_ggtt(obj, &view);
> if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
> view.type))
> return -1;
> @@ -11385,7 +11388,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
> intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
> MI_SRM_LRM_GLOBAL_GTT);
> intel_ring_emit_reg(ring, DERRMR);
> - intel_ring_emit(ring, req->engine->scratch.gtt_offset + 256);
> + intel_ring_emit(ring, req->engine->scratch->node.start + 256);
> if (IS_GEN8(dev)) {
> intel_ring_emit(ring, 0);
> intel_ring_emit(ring, MI_NOOP);
> @@ -11634,6 +11637,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> struct intel_engine_cs *engine;
> bool mmio_flip;
> struct drm_i915_gem_request *request;
> + struct i915_vma *vma;
> int ret;
>
> /*
> @@ -11739,9 +11743,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>
> mmio_flip = use_mmio_flip(engine, obj);
>
> - ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
> - if (ret)
> + vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto cleanup_pending;
> + }
>
> work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
> obj, 0);
> @@ -13965,7 +13971,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
> if (ret)
> DRM_DEBUG_KMS("failed to attach phys object\n");
> } else {
> - ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
> + struct i915_vma *vma;
> +
> + vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
> + if (IS_ERR(vma))
> + ret = PTR_ERR(vma);
> }
>
> if (ret == 0) {
> @@ -14334,7 +14344,7 @@ intel_update_cursor_plane(struct drm_plane *plane,
> if (!obj)
> addr = 0;
> else if (!INTEL_INFO(dev)->cursor_needs_physical)
> - addr = i915_gem_obj_ggtt_offset(obj);
> + addr = i915_gem_object_ggtt_offset(obj, NULL);
> else
> addr = obj->phys_handle->busaddr;
>
> @@ -16160,7 +16170,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct drm_crtc *c;
> struct drm_i915_gem_object *obj;
> - int ret;
>
> intel_init_gt_powersave(dev_priv);
>
> @@ -16174,15 +16183,17 @@ void intel_modeset_gem_init(struct drm_device *dev)
> * for this.
> */
> for_each_crtc(dev, c) {
> + struct i915_vma *vma;
> +
> obj = intel_fb_obj(c->primary->fb);
> if (obj == NULL)
> continue;
>
> mutex_lock(&dev->struct_mutex);
> - ret = intel_pin_and_fence_fb_obj(c->primary->fb,
> + vma = intel_pin_and_fence_fb_obj(c->primary->fb,
> c->primary->state->rotation);
> mutex_unlock(&dev->struct_mutex);
> - if (ret) {
> + if (IS_ERR(vma)) {
> DRM_ERROR("failed to pin boot fb on pipe %d\n",
> to_intel_crtc(c)->pipe);
> drm_framebuffer_unreference(c->primary->fb);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 834646b4cc3f..30ef29873571 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -159,6 +159,7 @@ struct intel_framebuffer {
> struct intel_fbdev {
> struct drm_fb_helper helper;
> struct intel_framebuffer *fb;
> + struct i915_vma *vma;
> async_cookie_t cookie;
> int preferred_bpp;
> };
> @@ -1207,8 +1208,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
> void intel_release_load_detect_pipe(struct drm_connector *connector,
> struct intel_load_detect_pipe *old,
> struct drm_modeset_acquire_ctx *ctx);
> -int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
> - unsigned int rotation);
> +struct i915_vma *
> +intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation);
> void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation);
> struct drm_framebuffer *
> __intel_framebuffer_create(struct drm_device *dev,
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index 45ee07b888a0..e1eb96b50ec1 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -742,7 +742,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc)
> /* FIXME: We lack the proper locking here, so only run this on the
> * platforms that need. */
> if (IS_GEN(dev_priv, 5, 6))
> - cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj);
> + cache->fb.ilk_ggtt_offset = i915_gem_object_ggtt_offset(obj, NULL);
> cache->fb.pixel_format = fb->pixel_format;
> cache->fb.stride = fb->pitches[0];
> cache->fb.fence_reg = obj->fence_reg;
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index 10600975fe8d..e76d18f7c733 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -187,7 +187,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
> struct fb_info *info;
> struct drm_framebuffer *fb;
> struct i915_vma *vma;
> - struct drm_i915_gem_object *obj;
> bool prealloc = false;
> void *vaddr;
> int ret;
> @@ -215,17 +214,17 @@ static int intelfb_create(struct drm_fb_helper *helper,
> sizes->fb_height = intel_fb->base.height;
> }
>
> - obj = intel_fb->obj;
> -
> mutex_lock(&dev->struct_mutex);
>
> /* Pin the GGTT vma for our access via info->screen_base.
> * This also validates that any existing fb inherited from the
> * BIOS is suitable for own access.
> */
> - ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
> - if (ret)
> + vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto out_unlock;
> + }
>
> info = drm_fb_helper_alloc_fbi(helper);
> if (IS_ERR(info)) {
> @@ -245,8 +244,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
> info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
> info->fbops = &intelfb_ops;
>
> - vma = i915_gem_obj_to_ggtt(obj);
> -
> /* setup aperture base/size for vesafb takeover */
> info->apertures->ranges[0].base = dev->mode_config.fb_base;
> info->apertures->ranges[0].size = ggtt->mappable_end;
> @@ -273,14 +270,14 @@ static int intelfb_create(struct drm_fb_helper *helper,
> * If the object is stolen however, it will be full of whatever
> * garbage was left in there.
> */
> - if (ifbdev->fb->obj->stolen && !prealloc)
> + if (intel_fb->obj->stolen && !prealloc)
> memset_io(info->screen_base, 0, info->screen_size);
>
> /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
>
> - DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
> - fb->width, fb->height,
> - i915_gem_obj_ggtt_offset(obj), obj);
> + DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx\n",
> + fb->width, fb->height, vma->node.start);
> + ifbdev->vma = vma;
>
> mutex_unlock(&dev->struct_mutex);
> vga_switcheroo_client_fb_set(dev->pdev, info);
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 1ecf88fd0b10..64f57c07afcc 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -235,12 +235,12 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
> * Note that GuC needs the CSS header plus uKernel code to be copied by the
> * DMA engine in one operation, whereas the RSA signature is loaded via MMIO.
> */
> -static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
> +static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
> + struct i915_vma *vma)
> {
> struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> - struct drm_i915_gem_object *fw_obj = guc_fw->guc_fw_obj;
> unsigned long offset;
> - struct sg_table *sg = fw_obj->pages;
> + struct sg_table *sg = vma->obj->pages;
> u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
> int i, ret = 0;
>
> @@ -257,7 +257,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
> I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size);
>
> /* Set the source address for the new blob */
> - offset = i915_gem_obj_ggtt_offset(fw_obj) + guc_fw->header_offset;
> + offset = vma->node.start + guc_fw->header_offset;
> I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
> I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
>
> @@ -312,6 +312,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
> {
> struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> struct drm_device *dev = dev_priv->dev;
> + struct i915_vma *vma;
> int ret;
>
> ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
> @@ -320,10 +321,10 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
> return ret;
> }
>
> - ret = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
> - if (ret) {
> - DRM_DEBUG_DRIVER("pin failed %d\n", ret);
> - return ret;
> + vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
> + if (IS_ERR(vma)) {
> + DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
> + return PTR_ERR(vma);
> }
>
> /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> @@ -364,7 +365,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
>
> set_guc_init_params(dev_priv);
>
> - ret = guc_ucode_xfer_dma(dev_priv);
> + ret = guc_ucode_xfer_dma(dev_priv, vma);
>
> intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>
> @@ -372,7 +373,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
> * We keep the object pages for reuse during resume. But we can unpin it
> * now that DMA has completed, so it doesn't continue to take up space.
> */
> - i915_gem_object_ggtt_unpin(guc_fw->guc_fw_obj);
> + i915_vma_unpin(vma);
>
> return ret;
> }
> @@ -653,12 +654,8 @@ fail:
> DRM_ERROR("Failed to fetch GuC firmware from %s (error %d)\n",
> guc_fw->guc_fw_path, err);
>
> - mutex_lock(&dev->struct_mutex);
> - obj = guc_fw->guc_fw_obj;
> - if (obj)
> - i915_gem_object_put(obj);
> + i915_gem_object_put_unlocked(guc_fw->guc_fw_obj);
> guc_fw->guc_fw_obj = NULL;
> - mutex_unlock(&dev->struct_mutex);
>
> release_firmware(fw); /* OK even if fw is NULL */
> guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
> @@ -737,7 +734,7 @@ void intel_guc_fini(struct drm_device *dev)
>
> i915_gem_object_put(guc_fw->guc_fw_obj);
> guc_fw->guc_fw_obj = NULL;
> - mutex_unlock(&dev->struct_mutex);
>
> guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
> + mutex_unlock(&dev->struct_mutex);
> }
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 4bf63af2a282..49e7bf170a04 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -326,7 +326,7 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
> BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (1<<GEN8_CTX_ID_WIDTH));
>
> desc = engine->ctx_desc_template; /* bits 0-11 */
> - desc |= ce->lrc_vma->node.start + LRC_PPHWSP_PN * PAGE_SIZE;
> + desc |= ce->vma->node.start + LRC_PPHWSP_PN * PAGE_SIZE;
> /* bits 12-31 */
> desc |= (u64)ctx->hw_id << GEN8_CTX_ID_SHIFT; /* bits 32-52 */
>
> @@ -765,6 +765,7 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
> {
> struct drm_i915_private *dev_priv = ctx->i915;
> struct intel_context *ce = &ctx->engine[engine->id];
> + struct i915_vma *vma;
> void *vaddr;
> u32 *lrc_reg_state;
> int ret;
> @@ -774,16 +775,18 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
> if (ce->pin_count++)
> return 0;
>
> - ret = i915_gem_object_ggtt_pin(ce->state, NULL,
> + vma = i915_gem_object_ggtt_pin(ce->state, NULL,
> 0, GEN8_LR_CONTEXT_ALIGN,
> PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
> - if (ret)
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto err;
> + }
>
> - vaddr = i915_gem_object_pin_map(ce->state);
> + vaddr = i915_gem_object_pin_map(vma->obj);
> if (IS_ERR(vaddr)) {
> ret = PTR_ERR(vaddr);
> - goto unpin_ctx_obj;
> + goto unpin_vma;
> }
>
> lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
> @@ -792,12 +795,12 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
> if (ret)
> goto unpin_map;
>
> - ce->lrc_vma = i915_gem_obj_to_ggtt(ce->state);
> + ce->vma = vma;
> intel_lr_context_descriptor_update(ctx, engine);
>
> lrc_reg_state[CTX_RING_BUFFER_START+1] = ce->ring->vma->node.start;
> ce->lrc_reg_state = lrc_reg_state;
> - ce->state->dirty = true;
> + vma->obj->dirty = true;
>
> /* Invalidate GuC TLB. */
> if (i915.enable_guc_submission)
> @@ -807,9 +810,9 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
> return 0;
>
> unpin_map:
> - i915_gem_object_unpin_map(ce->state);
> -unpin_ctx_obj:
> - i915_gem_object_ggtt_unpin(ce->state);
> + i915_gem_object_unpin_map(vma->obj);
> +unpin_vma:
> + __i915_vma_unpin(vma);
> err:
> ce->pin_count = 0;
> return ret;
> @@ -829,9 +832,9 @@ void intel_lr_context_unpin(struct i915_gem_context *ctx,
> intel_ring_unpin(ce->ring);
>
> i915_gem_object_unpin_map(ce->state);
> - i915_gem_object_ggtt_unpin(ce->state);
> + i915_vma_unpin(ce->vma);
>
> - ce->lrc_vma = NULL;
> + ce->vma = NULL;
> ce->lrc_desc = 0;
> ce->lrc_reg_state = NULL;
>
> @@ -921,7 +924,7 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
> wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 |
> MI_SRM_LRM_GLOBAL_GTT));
> wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
> - wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256);
> + wa_ctx_emit(batch, index, engine->scratch->node.start + 256);
> wa_ctx_emit(batch, index, 0);
>
> wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
> @@ -939,7 +942,7 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
> wa_ctx_emit(batch, index, (MI_LOAD_REGISTER_MEM_GEN8 |
> MI_SRM_LRM_GLOBAL_GTT));
> wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
> - wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256);
> + wa_ctx_emit(batch, index, engine->scratch->node.start + 256);
> wa_ctx_emit(batch, index, 0);
>
> return index;
> @@ -1013,7 +1016,7 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine,
>
> /* WaClearSlmSpaceAtContextSwitch:bdw,chv */
> /* Actual scratch location is at 128 bytes offset */
> - scratch_addr = engine->scratch.gtt_offset + 2*CACHELINE_BYTES;
> + scratch_addr = engine->scratch->node.start + 2*CACHELINE_BYTES;
>
> wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6));
> wa_ctx_emit(batch, index, (PIPE_CONTROL_FLUSH_L3 |
> @@ -1142,47 +1145,41 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
> return wa_ctx_end(wa_ctx, *offset = index, 1);
> }
>
> -static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size)
> +static struct i915_vma *
> +lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size)
> {
> - int ret;
> + struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
>
> - engine->wa_ctx.obj = i915_gem_object_create(engine->i915->dev,
> - PAGE_ALIGN(size));
> - if (IS_ERR(engine->wa_ctx.obj)) {
> - DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n");
> - ret = PTR_ERR(engine->wa_ctx.obj);
> - engine->wa_ctx.obj = NULL;
> - return ret;
> - }
> + obj = i915_gem_object_create(engine->i915->dev, PAGE_ALIGN(size));
> + if (IS_ERR(obj))
> + return ERR_CAST(obj);
>
> - ret = i915_gem_object_ggtt_pin(engine->wa_ctx.obj, NULL,
> - 0, PAGE_SIZE, 0);
> - if (ret) {
> - DRM_DEBUG_DRIVER("pin LRC WA ctx backing obj failed: %d\n",
> - ret);
> - i915_gem_object_put(engine->wa_ctx.obj);
> - return ret;
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE, 0);
> + if (IS_ERR(vma)) {
> + i915_gem_object_put(obj);
> + return vma;
> }
>
> - return 0;
> + return vma;
> }
>
> static void lrc_destroy_wa_ctx_obj(struct intel_engine_cs *engine)
> {
> - if (engine->wa_ctx.obj) {
> - i915_gem_object_ggtt_unpin(engine->wa_ctx.obj);
> - i915_gem_object_put(engine->wa_ctx.obj);
> - engine->wa_ctx.obj = NULL;
> + if (engine->wa_ctx.vma) {
> + i915_vma_unpin(engine->wa_ctx.vma);
> + i915_gem_object_put(engine->wa_ctx.vma->obj);
> + engine->wa_ctx.vma = NULL;
> }
> }
>
> static int intel_init_workaround_bb(struct intel_engine_cs *engine)
> {
> - int ret;
> + struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx;
> uint32_t *batch;
> uint32_t offset;
> struct page *page;
> - struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx;
> + int ret;
>
> WARN_ON(engine->id != RCS);
>
> @@ -1194,20 +1191,22 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
> }
>
> /* some WA perform writes to scratch page, ensure it is valid */
> - if (engine->scratch.obj == NULL) {
> + if (engine->scratch == NULL) {
> DRM_ERROR("scratch page not allocated for %s\n", engine->name);
> return -EINVAL;
> }
>
> - ret = lrc_setup_wa_ctx_obj(engine, PAGE_SIZE);
> - if (ret) {
> + wa_ctx->vma = lrc_setup_wa_ctx_obj(engine, PAGE_SIZE);
> + if (IS_ERR(wa_ctx->vma)) {
> + ret = PTR_ERR(wa_ctx->vma);
> DRM_DEBUG_DRIVER("Failed to setup context WA page: %d\n", ret);
> return ret;
> }
>
> - page = i915_gem_object_get_dirty_page(wa_ctx->obj, 0);
> + page = i915_gem_object_get_dirty_page(wa_ctx->vma->obj, 0);
> batch = kmap_atomic(page);
> offset = 0;
> + ret = 0;
>
> if (IS_GEN8(engine->i915)) {
> ret = gen8_init_indirectctx_bb(engine,
> @@ -1464,7 +1463,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
> {
> struct intel_ring *ring = request->ring;
> struct intel_engine_cs *engine = request->engine;
> - u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
> + u32 scratch_addr = engine->scratch->node.start + 2 * CACHELINE_BYTES;
> bool vf_flush_wa = false;
> u32 flags = 0;
> int ret;
> @@ -1650,9 +1649,9 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
>
> intel_engine_fini_breadcrumbs(engine);
>
> - if (engine->status_page.obj) {
> - i915_gem_object_unpin_map(engine->status_page.obj);
> - engine->status_page.obj = NULL;
> + if (engine->status_page.vma) {
> + i915_gem_object_unpin_map(engine->status_page.vma->obj);
> + engine->status_page.vma = NULL;
> }
> intel_lr_context_unpin(dev_priv->kernel_context, engine);
>
> @@ -1692,19 +1691,19 @@ logical_ring_default_irqs(struct intel_engine_cs *engine, unsigned shift)
> }
>
> static int
> -lrc_setup_hws(struct intel_engine_cs *engine,
> - struct drm_i915_gem_object *dctx_obj)
> +lrc_setup_hws(struct intel_engine_cs *engine, struct i915_vma *vma)
> {
> +#define HWS_OFFSET (LRC_PPHWSP_PN * PAGE_SIZE)
> void *hws;
>
> /* The HWSP is part of the default context object in LRC mode. */
> - engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj) +
> - LRC_PPHWSP_PN * PAGE_SIZE;
> - hws = i915_gem_object_pin_map(dctx_obj);
> + hws = i915_gem_object_pin_map(vma->obj);
> if (IS_ERR(hws))
> return PTR_ERR(hws);
> - engine->status_page.page_addr = hws + LRC_PPHWSP_PN * PAGE_SIZE;
> - engine->status_page.obj = dctx_obj;
> +
> + engine->status_page.page_addr = hws + HWS_OFFSET;
> + engine->status_page.gfx_addr = vma->node.start + HWS_OFFSET;
> + engine->status_page.vma = vma;
>
> return 0;
> }
> @@ -1828,7 +1827,7 @@ logical_ring_init(struct intel_engine_cs *engine)
> }
>
> /* And setup the hardware status page. */
> - ret = lrc_setup_hws(engine, dctx->engine[engine->id].state);
> + ret = lrc_setup_hws(engine, dctx->engine[engine->id].vma);
> if (ret) {
> DRM_ERROR("Failed to set up hws %s: %d\n", engine->name, ret);
> goto error;
> @@ -2109,9 +2108,9 @@ populate_lr_context(struct i915_gem_context *ctx,
> RING_INDIRECT_CTX(engine->mmio_base), 0);
> ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX_OFFSET,
> RING_INDIRECT_CTX_OFFSET(engine->mmio_base), 0);
> - if (engine->wa_ctx.obj) {
> + if (engine->wa_ctx.vma) {
> struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx;
> - uint32_t ggtt_offset = i915_gem_obj_ggtt_offset(wa_ctx->obj);
> + uint32_t ggtt_offset = wa_ctx->vma->node.start;
>
> reg_state[CTX_RCS_INDIRECT_CTX+1] =
> (ggtt_offset + wa_ctx->indirect_ctx.offset * sizeof(uint32_t)) |
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 9b0fb7e23cbb..75bdd335d565 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -170,8 +170,8 @@ struct overlay_registers {
> struct intel_overlay {
> struct drm_i915_private *i915;
> struct intel_crtc *crtc;
> - struct drm_i915_gem_object *vid_bo;
> - struct drm_i915_gem_object *old_vid_bo;
> + struct drm_i915_gem_object *vid_bo, *old_vid_bo;
> + struct i915_vma *vid_vma, *old_vid_vma;
> bool active;
> bool pfit_active;
> u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
> @@ -316,7 +316,7 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
> {
> struct drm_i915_gem_object *obj = overlay->old_vid_bo;
>
> - i915_gem_object_ggtt_unpin(obj);
> + i915_gem_object_unpin_from_display_plane(overlay->old_vid_vma);
> i915_gem_object_put(obj);
>
> overlay->old_vid_bo = NULL;
> @@ -324,14 +324,13 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
>
> static void intel_overlay_off_tail(struct intel_overlay *overlay)
> {
> - struct drm_i915_gem_object *obj = overlay->vid_bo;
> -
> /* never have the overlay hw on without showing a frame */
> - if (WARN_ON(!obj))
> + if (WARN_ON(overlay->vid_vma))
> return;
>
> - i915_gem_object_ggtt_unpin(obj);
> - i915_gem_object_put(obj);
> + i915_gem_object_unpin_from_display_plane(overlay->vid_vma);
> + i915_gem_object_put(overlay->vid_bo);
> + overlay->vid_vma = NULL;
> overlay->vid_bo = NULL;
>
> overlay->crtc->overlay = NULL;
> @@ -751,6 +750,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
> struct drm_i915_private *dev_priv = overlay->i915;
> u32 swidth, swidthsw, sheight, ostride;
> enum pipe pipe = overlay->crtc->pipe;
> + struct i915_vma *vma;
>
> lockdep_assert_held(&dev_priv->dev->struct_mutex);
> WARN_ON(!drm_modeset_is_locked(&dev_priv->dev->mode_config.connection_mutex));
> @@ -759,10 +759,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
> if (ret != 0)
> return ret;
>
> - ret = i915_gem_object_pin_to_display_plane(new_bo, 0,
> + vma = i915_gem_object_pin_to_display_plane(new_bo, 0,
> &i915_ggtt_view_normal);
> - if (ret != 0)
> - return ret;
> + if (IS_ERR(vma))
> + return PTR_ERR(vma);
>
> ret = i915_gem_object_put_fence(new_bo);
> if (ret)
> @@ -805,7 +805,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
> swidth = params->src_w;
> swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
> sheight = params->src_h;
> - iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, ®s->OBUF_0Y);
> + iowrite32(vma->node.start + params->offset_Y, ®s->OBUF_0Y);
> ostride = params->stride_Y;
>
> if (params->format & I915_OVERLAY_YUV_PLANAR) {
> @@ -819,8 +819,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
> params->src_w/uv_hscale);
> swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
> sheight |= (params->src_h/uv_vscale) << 16;
> - iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, ®s->OBUF_0U);
> - iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, ®s->OBUF_0V);
> + iowrite32(vma->node.start + params->offset_U, ®s->OBUF_0U);
> + iowrite32(vma->node.start + params->offset_V, ®s->OBUF_0V);
> ostride |= params->stride_UV << 16;
> }
>
> @@ -845,14 +845,16 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
> INTEL_FRONTBUFFER_OVERLAY(pipe));
>
> overlay->old_vid_bo = overlay->vid_bo;
> + overlay->old_vid_vma = overlay->vid_vma;
> overlay->vid_bo = new_bo;
> + overlay->vid_vma = vma;
>
> intel_frontbuffer_flip(dev_priv->dev, INTEL_FRONTBUFFER_OVERLAY(pipe));
>
> return 0;
>
> out_unpin:
> - i915_gem_object_ggtt_unpin(new_bo);
> + i915_gem_object_unpin_from_display_plane(vma);
> return ret;
> }
>
> @@ -1380,6 +1382,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
> struct intel_overlay *overlay;
> struct drm_i915_gem_object *reg_bo;
> struct overlay_registers __iomem *regs;
> + struct i915_vma *vma = NULL;
> int ret;
>
> if (!HAS_OVERLAY(dev_priv))
> @@ -1412,13 +1415,14 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
> }
> overlay->flip_addr = reg_bo->phys_handle->busaddr;
> } else {
> - ret = i915_gem_object_ggtt_pin(reg_bo, NULL,
> + vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
> 0, PAGE_SIZE, PIN_MAPPABLE);
> - if (ret) {
> + if (IS_ERR(vma)) {
> DRM_ERROR("failed to pin overlay register bo\n");
> + ret = PTR_ERR(vma);
> goto out_free_bo;
> }
> - overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo);
> + overlay->flip_addr = vma->node.start;
>
> ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
> if (ret) {
> @@ -1450,8 +1454,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
> return;
>
> out_unpin_bo:
> - if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
> - i915_gem_object_ggtt_unpin(reg_bo);
> + if (vma)
> + i915_vma_unpin(vma);
> out_free_bo:
> i915_gem_object_put(reg_bo);
> out_free:
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index c8211913f2d6..32add39ee9dd 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -182,7 +182,7 @@ intel_emit_post_sync_nonzero_flush(struct drm_i915_gem_request *req)
> {
> struct intel_ring *ring = req->ring;
> u32 scratch_addr =
> - req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
> + req->engine->scratch->node.start + 2 * CACHELINE_BYTES;
> int ret;
>
> ret = intel_ring_begin(req, 6);
> @@ -219,7 +219,7 @@ gen6_render_ring_flush(struct drm_i915_gem_request *req,
> {
> struct intel_ring *ring = req->ring;
> u32 scratch_addr =
> - req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
> + req->engine->scratch->node.start + 2 * CACHELINE_BYTES;
> u32 flags = 0;
> int ret;
>
> @@ -294,7 +294,7 @@ gen7_render_ring_flush(struct drm_i915_gem_request *req,
> {
> struct intel_ring *ring = req->ring;
> u32 scratch_addr =
> - req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
> + req->engine->scratch->node.start + 2 * CACHELINE_BYTES;
> u32 flags = 0;
> int ret;
>
> @@ -379,7 +379,8 @@ static int
> gen8_render_ring_flush(struct drm_i915_gem_request *req,
> u32 invalidate_domains, u32 flush_domains)
> {
> - u32 scratch_addr = req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
> + u32 scratch_addr =
> + req->engine->scratch->node.start + 2 * CACHELINE_BYTES;
> u32 flags = 0;
> int ret;
>
> @@ -540,7 +541,7 @@ static int init_ring_common(struct intel_engine_cs *engine)
> {
> struct drm_i915_private *dev_priv = engine->i915;
> struct intel_ring *ring = engine->buffer;
> - struct drm_i915_gem_object *obj = ring->obj;
> + struct i915_vma *vma = ring->vma;
> int ret = 0;
>
> intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> @@ -580,7 +581,7 @@ static int init_ring_common(struct intel_engine_cs *engine)
> * registers with the above sequence (the readback of the HEAD registers
> * also enforces ordering), otherwise the hw might lose the new ring
> * register values. */
> - I915_WRITE_START(engine, i915_gem_obj_ggtt_offset(obj));
> + I915_WRITE_START(engine, vma->node.start);
>
> /* WaClearRingBufHeadRegAtInit:ctg,elk */
> if (I915_READ_HEAD(engine))
> @@ -595,16 +596,15 @@ static int init_ring_common(struct intel_engine_cs *engine)
>
> /* If the head is still not zero, the ring is dead */
> if (wait_for((I915_READ_CTL(engine) & RING_VALID) != 0 &&
> - I915_READ_START(engine) == i915_gem_obj_ggtt_offset(obj) &&
> + I915_READ_START(engine) == vma->node.start &&
> (I915_READ_HEAD(engine) & HEAD_ADDR) == 0, 50)) {
> DRM_ERROR("%s initialization failed "
> - "ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08lx]\n",
> + "ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08x]\n",
> engine->name,
> I915_READ_CTL(engine),
> I915_READ_CTL(engine) & RING_VALID,
> I915_READ_HEAD(engine), I915_READ_TAIL(engine),
> - I915_READ_START(engine),
> - (unsigned long)i915_gem_obj_ggtt_offset(obj));
> + I915_READ_START(engine), (u32)vma->node.start);
> ret = -EIO;
> goto out;
> }
> @@ -624,20 +624,21 @@ out:
>
> void intel_fini_pipe_control(struct intel_engine_cs *engine)
> {
> - if (engine->scratch.obj == NULL)
> + if (!engine->scratch)
> return;
>
> - i915_gem_object_ggtt_unpin(engine->scratch.obj);
> - i915_gem_object_put(engine->scratch.obj);
> - engine->scratch.obj = NULL;
> + i915_vma_unpin(engine->scratch);
> + i915_gem_object_put(engine->scratch->obj);
> + engine->scratch = NULL;
> }
>
> int intel_init_pipe_control(struct intel_engine_cs *engine, int size)
> {
> struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
> int ret;
>
> - WARN_ON(engine->scratch.obj);
> + WARN_ON(engine->scratch);
>
> obj = i915_gem_object_create_stolen(engine->i915->dev, size);
> if (obj == NULL)
> @@ -648,18 +649,19 @@ int intel_init_pipe_control(struct intel_engine_cs *engine, int size)
> goto err;
> }
>
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 4096, PIN_HIGH);
> - if (ret)
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 4096, PIN_HIGH);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> goto err_unref;
> + }
>
> - engine->scratch.obj = obj;
> - engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj);
> - DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
> - engine->name, engine->scratch.gtt_offset);
> + engine->scratch = vma;
> + DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08llx\n",
> + engine->name, (long long)vma->node.start);
> return 0;
>
> err_unref:
> - i915_gem_object_put(engine->scratch.obj);
> + i915_gem_object_put(obj);
> err:
> return ret;
> }
> @@ -1217,10 +1219,13 @@ static void render_ring_cleanup(struct intel_engine_cs *engine)
> {
> struct drm_i915_private *dev_priv = engine->i915;
>
> - if (dev_priv->semaphore_obj) {
> - i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj);
> - i915_gem_object_put(dev_priv->semaphore_obj);
> - dev_priv->semaphore_obj = NULL;
> + if (dev_priv->semaphore_vma) {
> + struct drm_i915_gem_object *obj = dev_priv->semaphore_vma->obj;
> +
> + i915_vma_unpin(dev_priv->semaphore_vma);
> + dev_priv->semaphore_vma = NULL;
> +
> + i915_gem_object_put(obj);
> }
>
> intel_fini_pipe_control(engine);
> @@ -1684,7 +1689,7 @@ i830_emit_bb_start(struct drm_i915_gem_request *req,
> unsigned dispatch_flags)
> {
> struct intel_ring *ring = req->ring;
> - u32 cs_offset = req->engine->scratch.gtt_offset;
> + u32 cs_offset = req->engine->scratch->node.start;
> int ret;
>
> ret = intel_ring_begin(req, 6);
> @@ -1773,67 +1778,68 @@ static void cleanup_phys_status_page(struct intel_engine_cs *engine)
>
> static void cleanup_status_page(struct intel_engine_cs *engine)
> {
> - struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
>
> - obj = engine->status_page.obj;
> - if (obj == NULL)
> + vma = engine->status_page.vma;
> + if (vma == NULL)
> return;
> + engine->status_page.vma = NULL;
>
> - kunmap(sg_page(obj->pages->sgl));
> - i915_gem_object_ggtt_unpin(obj);
> - i915_gem_object_put(obj);
> - engine->status_page.obj = NULL;
> + kunmap(sg_page(vma->obj->pages->sgl));
> + i915_vma_unpin(vma);
> }
>
> static int init_status_page(struct intel_engine_cs *engine)
> {
> - struct drm_i915_gem_object *obj = engine->status_page.obj;
> + struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
> + unsigned flags;
> + int ret;
>
> - if (obj == NULL) {
> - unsigned flags;
> - int ret;
> + if (engine->status_page.vma)
> + return 0;
>
> - obj = i915_gem_object_create(engine->i915->dev, 4096);
> - if (IS_ERR(obj)) {
> - DRM_ERROR("Failed to allocate status page\n");
> - return PTR_ERR(obj);
> - }
> + obj = i915_gem_object_create(engine->i915->dev, 4096);
> + if (IS_ERR(obj)) {
> + DRM_ERROR("Failed to allocate status page\n");
> + return PTR_ERR(obj);
> + }
>
> - ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
> - if (ret)
> - goto err_unref;
> -
> - flags = 0;
> - if (!HAS_LLC(engine->i915))
> - /* On g33, we cannot place HWS above 256MiB, so
> - * restrict its pinning to the low mappable arena.
> - * Though this restriction is not documented for
> - * gen4, gen5, or byt, they also behave similarly
> - * and hang if the HWS is placed at the top of the
> - * GTT. To generalise, it appears that all !llc
> - * platforms have issues with us placing the HWS
> - * above the mappable region (even though we never
> - * actualy map it).
> - */
> - flags |= PIN_MAPPABLE;
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 4096, flags);
> - if (ret) {
> -err_unref:
> - i915_gem_object_put(obj);
> - return ret;
> - }
> + ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
> + if (ret)
> + goto err_unref;
>
> - engine->status_page.obj = obj;
> + flags = 0;
> + if (!HAS_LLC(engine->i915))
> + /* On g33, we cannot place HWS above 256MiB, so
> + * restrict its pinning to the low mappable arena.
> + * Though this restriction is not documented for
> + * gen4, gen5, or byt, they also behave similarly
> + * and hang if the HWS is placed at the top of the
> + * GTT. To generalise, it appears that all !llc
> + * platforms have issues with us placing the HWS
> + * above the mappable region (even though we never
> + * actualy map it).
> + */
> + flags |= PIN_MAPPABLE;
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 4096, flags);
> + if (IS_ERR(vma)) {
> + ret = PTR_ERR(vma);
> + goto err_unref;
> }
>
> - engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
> + engine->status_page.vma = vma;
> + engine->status_page.gfx_addr = vma->node.start;
> engine->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
> - memset(engine->status_page.page_addr, 0, PAGE_SIZE);
>
> DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
> engine->name, engine->status_page.gfx_addr);
>
> return 0;
> +
> +err_unref:
> + i915_gem_object_put(obj);
> + return ret;
> }
>
> static int init_phys_status_page(struct intel_engine_cs *engine)
> @@ -1857,15 +1863,16 @@ int intel_ring_pin(struct intel_ring *ring)
> {
> struct drm_i915_private *dev_priv = ring->engine->i915;
> struct drm_i915_gem_object *obj = ring->obj;
> + struct i915_vma *vma;
> /* Ring wraparound at offset 0 sometimes hangs. No idea why. */
> unsigned flags = PIN_OFFSET_BIAS | 4096;
> void *addr;
> int ret;
>
> if (HAS_LLC(dev_priv) && !obj->stolen) {
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE, flags);
> - if (ret)
> - return ret;
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE, flags);
> + if (IS_ERR(vma))
> + return PTR_ERR(vma);
>
> ret = i915_gem_object_set_to_cpu_domain(obj, true);
> if (ret)
> @@ -1877,10 +1884,10 @@ int intel_ring_pin(struct intel_ring *ring)
> goto err_unpin;
> }
> } else {
> - ret = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE,
> + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, PAGE_SIZE,
> flags | PIN_MAPPABLE);
> - if (ret)
> - return ret;
> + if (IS_ERR(vma))
> + return PTR_ERR(vma);
>
> ret = i915_gem_object_set_to_gtt_domain(obj, true);
> if (ret)
> @@ -1889,7 +1896,7 @@ int intel_ring_pin(struct intel_ring *ring)
> /* Access through the GTT requires the device to be awake. */
> assert_rpm_wakelock_held(dev_priv);
>
> - addr = i915_vma_pin_iomap(i915_gem_obj_to_ggtt(obj));
> + addr = i915_vma_pin_iomap(vma);
> if (IS_ERR(addr)) {
> ret = PTR_ERR(addr);
> goto err_unpin;
> @@ -1897,11 +1904,11 @@ int intel_ring_pin(struct intel_ring *ring)
> }
>
> ring->vaddr = addr;
> - ring->vma = i915_gem_obj_to_ggtt(obj);
> + ring->vma = vma;
> return 0;
>
> err_unpin:
> - i915_gem_object_ggtt_unpin(obj);
> + i915_vma_unpin(vma);
> return ret;
> }
>
> @@ -1916,7 +1923,7 @@ void intel_ring_unpin(struct intel_ring *ring)
> i915_vma_unpin_iomap(ring->vma);
> ring->vaddr = NULL;
>
> - i915_gem_object_ggtt_unpin(ring->obj);
> + i915_vma_unpin(ring->vma);
> ring->vma = NULL;
> }
>
> @@ -2007,10 +2014,14 @@ static int intel_ring_context_pin(struct i915_gem_context *ctx,
> return 0;
>
> if (ce->state) {
> - ret = i915_gem_object_ggtt_pin(ce->state, NULL, 0,
> + struct i915_vma *vma;
> +
> + vma = i915_gem_object_ggtt_pin(ce->state, NULL, 0,
> ctx->ggtt_alignment, PIN_HIGH);
> - if (ret)
> + if (vma)
> goto error;
> +
> + ce->vma = vma;
> }
>
> /* The kernel context is only used as a placeholder for flushing the
> @@ -2041,8 +2052,8 @@ static void intel_ring_context_unpin(struct i915_gem_context *ctx,
> if (--ce->pin_count)
> return;
>
> - if (ce->state)
> - i915_gem_object_ggtt_unpin(ce->state);
> + if (ce->vma)
> + i915_vma_unpin(ce->vma);
>
> i915_gem_context_put(ctx);
> }
> @@ -2335,8 +2346,8 @@ void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno)
> if (HAS_VEBOX(dev_priv))
> I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
> }
> - if (dev_priv->semaphore_obj) {
> - struct drm_i915_gem_object *obj = dev_priv->semaphore_obj;
> + if (dev_priv->semaphore_vma) {
> + struct drm_i915_gem_object *obj = dev_priv->semaphore_vma->obj;
> struct page *page = i915_gem_object_get_dirty_page(obj, 0);
> void *semaphores = kmap(page);
> memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
> @@ -2576,16 +2587,20 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n");
> i915.semaphores = 0;
> } else {
> + struct i915_vma *vma;
> +
> i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
> - ret = i915_gem_object_ggtt_pin(obj, NULL,
> + vma = i915_gem_object_ggtt_pin(obj, NULL,
> 0, 0,
> PIN_HIGH);
> - if (ret != 0) {
> + if (IS_ERR(vma)) {
> i915_gem_object_put(obj);
> DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n");
> i915.semaphores = 0;
> - } else
> - dev_priv->semaphore_obj = obj;
> + vma = NULL;
> + }
> +
> + dev_priv->semaphore_vma = vma;
> }
> }
>
> @@ -2596,7 +2611,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> engine->irq_disable = gen8_ring_disable_irq;
> engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
> if (i915.semaphores) {
> - WARN_ON(!dev_priv->semaphore_obj);
> engine->semaphore.sync_to = gen8_ring_sync;
> engine->semaphore.signal = gen8_rcs_signal;
> GEN8_RING_SEMAPHORE_INIT(engine);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index d19fb8c24919..934d5722dc27 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -26,10 +26,10 @@
> */
> #define I915_RING_FREE_SPACE 64
>
> -struct intel_hw_status_page {
> +struct intel_hw_status_page {
> u32 *page_addr;
> unsigned int gfx_addr;
> - struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
> };
>
> #define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base))
> @@ -57,16 +57,13 @@ struct intel_hw_status_page {
> #define GEN8_SEMAPHORE_OFFSET(__from, __to) \
> (((__from) * I915_NUM_ENGINES + (__to)) * gen8_semaphore_seqno_size)
> #define GEN8_SIGNAL_OFFSET(__ring, to) \
> - (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
> + (dev_priv->semaphore_vma->node.start + \
> GEN8_SEMAPHORE_OFFSET((__ring)->id, (to)))
> #define GEN8_WAIT_OFFSET(__ring, from) \
> - (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
> + (dev_priv->semaphore_vma->node.start + \
> GEN8_SEMAPHORE_OFFSET(from, (__ring)->id))
>
> #define GEN8_RING_SEMAPHORE_INIT(e) do { \
> - if (!dev_priv->semaphore_obj) { \
> - break; \
> - } \
> (e)->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET((e), RCS); \
> (e)->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET((e), VCS); \
> (e)->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET((e), BCS); \
> @@ -97,8 +94,8 @@ struct intel_engine_hangcheck {
>
> struct intel_ring {
> struct drm_i915_gem_object *obj;
> - void *vaddr;
> struct i915_vma *vma;
> + void *vaddr;
>
> struct intel_engine_cs *engine;
> struct list_head link;
> @@ -139,7 +136,7 @@ struct i915_ctx_workarounds {
> u32 offset;
> u32 size;
> } indirect_ctx, per_ctx;
> - struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
> };
>
> struct drm_i915_gem_request;
> @@ -325,10 +322,7 @@ struct intel_engine_cs {
>
> struct intel_engine_hangcheck hangcheck;
>
> - struct {
> - struct drm_i915_gem_object *obj;
> - u32 gtt_offset;
> - } scratch;
> + struct i915_vma *scratch;
>
> bool needs_cmd_parser;
>
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 324ccb06397d..99bdbb9e4037 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -462,8 +462,8 @@ vlv_update_plane(struct drm_plane *dplane,
>
> I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
> I915_WRITE(SPCNTR(pipe, plane), sprctl);
> - I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
> - sprsurf_offset);
> + I915_WRITE(SPSURF(pipe, plane),
> + i915_gem_object_ggtt_offset(obj, NULL) + sprsurf_offset);
> POSTING_READ(SPSURF(pipe, plane));
> }
>
> @@ -602,7 +602,7 @@ ivb_update_plane(struct drm_plane *plane,
> I915_WRITE(SPRSCALE(pipe), sprscale);
> I915_WRITE(SPRCTL(pipe), sprctl);
> I915_WRITE(SPRSURF(pipe),
> - i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
> + i915_gem_object_ggtt_offset(obj, NULL) + sprsurf_offset);
> POSTING_READ(SPRSURF(pipe));
> }
>
> @@ -731,7 +731,7 @@ ilk_update_plane(struct drm_plane *plane,
> I915_WRITE(DVSSCALE(pipe), dvsscale);
> I915_WRITE(DVSCNTR(pipe), dvscntr);
> I915_WRITE(DVSSURF(pipe),
> - i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
> + i915_gem_object_ggtt_offset(obj, NULL) + dvssurf_offset);
> POSTING_READ(DVSSURF(pipe));
> }
>
> --
> 2.8.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the Intel-gfx
mailing list