|
@@ -3518,9 +3518,9 @@ static bool i915_gem_valid_gtt_space(struct i915_vma *vma,
|
|
|
static struct i915_vma *
|
|
|
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
|
|
struct i915_address_space *vm,
|
|
|
+ const struct i915_ggtt_view *ggtt_view,
|
|
|
unsigned alignment,
|
|
|
- uint64_t flags,
|
|
|
- const struct i915_ggtt_view *view)
|
|
|
+ uint64_t flags)
|
|
|
{
|
|
|
struct drm_device *dev = obj->base.dev;
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -3532,6 +3532,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
|
|
struct i915_vma *vma;
|
|
|
int ret;
|
|
|
|
|
|
+ if(WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
fence_size = i915_gem_get_gtt_size(dev,
|
|
|
obj->base.size,
|
|
|
obj->tiling_mode);
|
|
@@ -3570,7 +3573,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
|
|
|
|
|
i915_gem_object_pin_pages(obj);
|
|
|
|
|
|
- vma = i915_gem_obj_lookup_or_create_vma_view(obj, vm, view);
|
|
|
+ vma = ggtt_view ? i915_gem_obj_lookup_or_create_ggtt_vma(obj, ggtt_view) :
|
|
|
+ i915_gem_obj_lookup_or_create_vma(obj, vm);
|
|
|
+
|
|
|
if (IS_ERR(vma))
|
|
|
goto err_unpin;
|
|
|
|
|
@@ -4167,12 +4172,12 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
-i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
|
|
|
- struct i915_address_space *vm,
|
|
|
- uint32_t alignment,
|
|
|
- uint64_t flags,
|
|
|
- const struct i915_ggtt_view *view)
|
|
|
+static int
|
|
|
+i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
|
|
|
+ struct i915_address_space *vm,
|
|
|
+ const struct i915_ggtt_view *ggtt_view,
|
|
|
+ uint32_t alignment,
|
|
|
+ uint64_t flags)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
|
|
struct i915_vma *vma;
|
|
@@ -4188,17 +4193,29 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
|
|
|
if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- vma = i915_gem_obj_to_vma_view(obj, vm, view);
|
|
|
+ if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) :
|
|
|
+ i915_gem_obj_to_vma(obj, vm);
|
|
|
+
|
|
|
+ if (IS_ERR(vma))
|
|
|
+ return PTR_ERR(vma);
|
|
|
+
|
|
|
if (vma) {
|
|
|
if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
|
|
return -EBUSY;
|
|
|
|
|
|
if (i915_vma_misplaced(vma, alignment, flags)) {
|
|
|
+ unsigned long offset;
|
|
|
+ offset = ggtt_view ? i915_gem_obj_ggtt_offset_view(obj, ggtt_view->type) :
|
|
|
+ i915_gem_obj_offset(obj, vm);
|
|
|
WARN(vma->pin_count,
|
|
|
- "bo is already pinned with incorrect alignment:"
|
|
|
+ "bo is already pinned in %s with incorrect alignment:"
|
|
|
" offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
|
|
|
" obj->map_and_fenceable=%d\n",
|
|
|
- i915_gem_obj_offset_view(obj, vm, view->type),
|
|
|
+ ggtt_view ? "ggtt" : "ppgtt",
|
|
|
+ offset,
|
|
|
alignment,
|
|
|
!!(flags & PIN_MAPPABLE),
|
|
|
obj->map_and_fenceable);
|
|
@@ -4212,8 +4229,8 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
|
|
|
|
|
|
bound = vma ? vma->bound : 0;
|
|
|
if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
|
|
|
- vma = i915_gem_object_bind_to_vm(obj, vm, alignment,
|
|
|
- flags, view);
|
|
|
+ vma = i915_gem_object_bind_to_vm(obj, vm, ggtt_view, alignment,
|
|
|
+ flags);
|
|
|
if (IS_ERR(vma))
|
|
|
return PTR_ERR(vma);
|
|
|
}
|
|
@@ -4254,6 +4271,30 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
|
|
+ struct i915_address_space *vm,
|
|
|
+ uint32_t alignment,
|
|
|
+ uint64_t flags)
|
|
|
+{
|
|
|
+ return i915_gem_object_do_pin(obj, vm,
|
|
|
+ i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL,
|
|
|
+ alignment, flags);
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
|
|
|
+ const struct i915_ggtt_view *view,
|
|
|
+ uint32_t alignment,
|
|
|
+ uint64_t flags)
|
|
|
+{
|
|
|
+ if (WARN_ONCE(!view, "no view specified"))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view,
|
|
|
+ alignment, flags);
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
|
|
|
{
|
|
@@ -4559,15 +4600,32 @@ 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_view(struct drm_i915_gem_object *obj,
|
|
|
- struct i915_address_space *vm,
|
|
|
- const struct i915_ggtt_view *view)
|
|
|
+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, vma_link)
|
|
|
- if (vma->vm == vm && vma->ggtt_view.type == view->type)
|
|
|
+ list_for_each_entry(vma, &obj->vma_list, vma_link) {
|
|
|
+ if (i915_is_ggtt(vma->vm) &&
|
|
|
+ vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
|
|
|
+ continue;
|
|
|
+ if (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_address_space *ggtt = i915_obj_to_ggtt(obj);
|
|
|
+ struct i915_vma *vma;
|
|
|
|
|
|
+ if (WARN_ONCE(!view, "no view specified"))
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
+ list_for_each_entry(vma, &obj->vma_list, vma_link)
|
|
|
+ if (vma->vm == ggtt && vma->ggtt_view.type == view->type)
|
|
|
+ return vma;
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
@@ -5176,9 +5234,9 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
|
|
|
}
|
|
|
|
|
|
/* All the new VM stuff */
|
|
|
-unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o,
|
|
|
- struct i915_address_space *vm,
|
|
|
- enum i915_ggtt_view_type view)
|
|
|
+unsigned long
|
|
|
+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;
|
|
@@ -5186,23 +5244,57 @@ unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o,
|
|
|
WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
|
|
|
|
|
|
list_for_each_entry(vma, &o->vma_list, vma_link) {
|
|
|
- if (vma->vm == vm && vma->ggtt_view.type == view)
|
|
|
+ if (i915_is_ggtt(vma->vm) &&
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
-bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o,
|
|
|
- struct i915_address_space *vm,
|
|
|
- enum i915_ggtt_view_type view)
|
|
|
+unsigned long
|
|
|
+i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
|
|
|
+ enum i915_ggtt_view_type view)
|
|
|
{
|
|
|
+ struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
|
|
|
struct i915_vma *vma;
|
|
|
|
|
|
list_for_each_entry(vma, &o->vma_list, vma_link)
|
|
|
- if (vma->vm == vm &&
|
|
|
+ if (vma->vm == ggtt && vma->ggtt_view.type == view)
|
|
|
+ return vma->node.start;
|
|
|
+
|
|
|
+ WARN(1, "global vma for this object not found.\n");
|
|
|
+ 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, vma_link) {
|
|
|
+ if (i915_is_ggtt(vma->vm) &&
|
|
|
+ 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,
|
|
|
+ enum i915_ggtt_view_type view)
|
|
|
+{
|
|
|
+ struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
|
|
|
+ struct i915_vma *vma;
|
|
|
+
|
|
|
+ list_for_each_entry(vma, &o->vma_list, vma_link)
|
|
|
+ if (vma->vm == ggtt &&
|
|
|
vma->ggtt_view.type == view &&
|
|
|
drm_mm_node_allocated(&vma->node))
|
|
|
return true;
|
|
@@ -5231,10 +5323,13 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
|
|
|
|
|
|
BUG_ON(list_empty(&o->vma_list));
|
|
|
|
|
|
- list_for_each_entry(vma, &o->vma_list, vma_link)
|
|
|
+ list_for_each_entry(vma, &o->vma_list, vma_link) {
|
|
|
+ if (i915_is_ggtt(vma->vm) &&
|
|
|
+ vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
|
|
|
+ continue;
|
|
|
if (vma->vm == vm)
|
|
|
return vma->node.size;
|
|
|
-
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -5334,15 +5429,16 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
|
|
|
return NOTIFY_DONE;
|
|
|
}
|
|
|
|
|
|
-struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
|
|
|
+bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
|
|
|
{
|
|
|
- struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
|
|
|
struct i915_vma *vma;
|
|
|
-
|
|
|
- list_for_each_entry(vma, &obj->vma_list, vma_link)
|
|
|
- if (vma->vm == ggtt &&
|
|
|
- vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
|
|
|
- return vma;
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ list_for_each_entry(vma, &obj->vma_list, vma_link) {
|
|
|
+ if (i915_is_ggtt(vma->vm) &&
|
|
|
+ vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
|
|
|
+ continue;
|
|
|
+ if (vma->pin_count > 0)
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
+
|