This doesn't actually do the switch, but will actually add and remove the new address spaces as needed. It is a good point for bisection. It also adds create/destroy trace events. Notice the FIXME by the destroy where I acknowledge a layering violation which can be fixed later (or copy pasted, whatever). Signed-off-by: Ben Widawsky <ben at bwidawsk.net> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 17 ++++------------- drivers/gpu/drm/i915/i915_gem_gtt.c | 9 +++++++-- drivers/gpu/drm/i915/i915_irq.c | 3 --- drivers/gpu/drm/i915/i915_trace.h | 18 ++++++++++++++++++ 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 736c714..c251724 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1678,6 +1678,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); +void i915_init_vm(struct drm_i915_private *dev_priv, + struct i915_address_space *vm); struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, struct i915_address_space *vm); void i915_gem_vma_destroy(struct i915_vma *vma); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 73e116e..af0150e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3151,11 +3151,6 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, struct i915_vma *vma; int ret; - if (WARN_ON(!list_empty(&obj->vma_list))) - return -EBUSY; - - BUG_ON(!is_i915_ggtt(vm)); - fence_size = i915_gem_get_gtt_size(dev, obj->base.size, obj->tiling_mode); @@ -3194,9 +3189,6 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, i915_gem_object_pin_pages(obj); - /* For now we only ever use 1 vma per object */ - WARN_ON(!list_empty(&obj->vma_list)); - vma = i915_gem_vma_create(obj, vm); if (vma == NULL) { i915_gem_object_unpin_pages(obj); @@ -4077,9 +4069,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) i915_gem_detach_phys_object(dev, obj); obj->pin_count = 0; - /* NB: 0 or 1 elements */ - WARN_ON(!list_empty(&obj->vma_list) && - !list_is_singular(&obj->vma_list)); + list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { int ret = i915_gem_object_unbind(obj, vma->vm); if (WARN_ON(ret == -ERESTARTSYS)) { @@ -4516,8 +4506,8 @@ init_ring_lists(struct intel_ring_buffer *ring) INIT_LIST_HEAD(&ring->request_list); } -static void i915_init_vm(struct drm_i915_private *dev_priv, - struct i915_address_space *vm) +void i915_init_vm(struct drm_i915_private *dev_priv, + struct i915_address_space *vm) { vm->dev = dev_priv->dev; INIT_LIST_HEAD(&vm->active_list); @@ -4525,6 +4515,7 @@ static void i915_init_vm(struct drm_i915_private *dev_priv, INIT_LIST_HEAD(&vm->global_link); INIT_LIST_HEAD(&vm->vma_list); list_add(&vm->global_link, &dev_priv->vm_list); + trace_i915_address_space_create(vm); } void diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7e9b2e2..2f9af3e 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -289,6 +289,10 @@ static void gen6_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) struct i915_address_space *vm = &ppgtt->base; int i; + trace_i915_address_space_destroy(vm); + /* FIXME: It's a bit of a layering violation to remove ourselves here. + * Fix when we have more VM types */ + list_del(&ppgtt->base.global_link); drm_mm_remove_node(&ppgtt->node); drm_mm_takedown(&ppgtt->base.mm); @@ -437,10 +441,11 @@ int i915_gem_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) gen6_write_pdes(ppgtt); drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, ppgtt->base.total); + i915_init_vm(dev->dev_private, &ppgtt->base); + DRM_DEBUG("Adding PPGTT at offset %x\n", + ppgtt->pd_offset << 10); } - /* i915_init_vm(dev_priv, &ppgtt->base) */ - return ret; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e1653fd..5622012 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1937,9 +1937,6 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, list_for_each_entry(vm, &dev_priv->vm_list, global_link) cnt++; - if (WARN(cnt > 1, "Multiple VMs not yet supported\n")) - cnt = 1; - vm = &dev_priv->gtt.base; error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC); diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 3f019d3..afd0428 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -194,6 +194,24 @@ DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, TP_ARGS(obj) ); +DECLARE_EVENT_CLASS(i915_address_space, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm), + TP_STRUCT__entry(__field(struct i915_address_space *, vm)), + TP_fast_assign(__entry->vm = vm;), + TP_printk("vm = %p", __entry->vm) + ); + +DEFINE_EVENT(i915_address_space, i915_address_space_create, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm) + ); + +DEFINE_EVENT(i915_address_space, i915_address_space_destroy, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm) + ); + TRACE_EVENT(i915_gem_evict, TP_PROTO(struct drm_device *dev, u32 size, u32 align, bool mappable), TP_ARGS(dev, size, align, mappable), -- 1.8.3.1