diff options
author | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2015-03-16 08:11:13 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-03-20 06:48:03 -0400 |
commit | ec7adb6ee79c8c9fe64d63ad638a31cd62e55515 (patch) | |
tree | 9af18c1e023146304feacf5dd5006ae07498d267 | |
parent | aca5e361e84d20ac68eedb37b7c4561a33f56198 (diff) |
drm/i915: Do not use ggtt_view with (aliasing) PPGTT
GGTT views are only applicable when dealing with GGTT. Change the code to
reject ggtt_view where it should not be used and require it when it should
be.
v2:
- Dropped _ppgtt_ infixes, allow both types to be passed
- Disregard other but normal views when no view is specified
- More checks that valid parameters are passed
- More readable error checking
v3:
- Prefer WARN_ONCE over BUG_ON when there is code path for failure
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
[danvet: Drop unecessary forward decl from earlier patch iterations.]
[danvet: Remove unused variable spotted by Tvrtko.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 100 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 174 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 71 |
3 files changed, 226 insertions, 119 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8ba7e1b7b733..81f60b48def2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2623,20 +2623,16 @@ void i915_gem_vma_destroy(struct i915_vma *vma); | |||
2623 | #define PIN_GLOBAL 0x4 | 2623 | #define PIN_GLOBAL 0x4 |
2624 | #define PIN_OFFSET_BIAS 0x8 | 2624 | #define PIN_OFFSET_BIAS 0x8 |
2625 | #define PIN_OFFSET_MASK (~4095) | 2625 | #define PIN_OFFSET_MASK (~4095) |
2626 | int __must_check i915_gem_object_pin_view(struct drm_i915_gem_object *obj, | 2626 | int __must_check |
2627 | struct i915_address_space *vm, | 2627 | i915_gem_object_pin(struct drm_i915_gem_object *obj, |
2628 | uint32_t alignment, | 2628 | struct i915_address_space *vm, |
2629 | uint64_t flags, | 2629 | uint32_t alignment, |
2630 | const struct i915_ggtt_view *view); | 2630 | uint64_t flags); |
2631 | static inline | 2631 | int __must_check |
2632 | int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, | 2632 | i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, |
2633 | struct i915_address_space *vm, | 2633 | const struct i915_ggtt_view *view, |
2634 | uint32_t alignment, | 2634 | uint32_t alignment, |
2635 | uint64_t flags) | 2635 | uint64_t flags); |
2636 | { | ||
2637 | return i915_gem_object_pin_view(obj, vm, alignment, flags, | ||
2638 | &i915_ggtt_view_normal); | ||
2639 | } | ||
2640 | 2636 | ||
2641 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, | 2637 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, |
2642 | u32 flags); | 2638 | u32 flags); |
@@ -2800,60 +2796,46 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | |||
2800 | 2796 | ||
2801 | void i915_gem_restore_fences(struct drm_device *dev); | 2797 | void i915_gem_restore_fences(struct drm_device *dev); |
2802 | 2798 | ||
2803 | unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, | 2799 | unsigned long |
2804 | struct i915_address_space *vm, | 2800 | i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, |
2805 | enum i915_ggtt_view_type view); | 2801 | enum i915_ggtt_view_type view); |
2806 | static inline | 2802 | unsigned long |
2807 | unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, | 2803 | i915_gem_obj_offset(struct drm_i915_gem_object *o, |
2808 | struct i915_address_space *vm) | 2804 | struct i915_address_space *vm); |
2805 | static inline unsigned long | ||
2806 | i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) | ||
2809 | { | 2807 | { |
2810 | return i915_gem_obj_offset_view(o, vm, I915_GGTT_VIEW_NORMAL); | 2808 | return i915_gem_obj_ggtt_offset_view(o, I915_GGTT_VIEW_NORMAL); |
2811 | } | 2809 | } |
2810 | |||
2812 | bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o); | 2811 | bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o); |
2813 | bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o, | 2812 | bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o, |
2814 | struct i915_address_space *vm, | 2813 | enum i915_ggtt_view_type view); |
2815 | enum i915_ggtt_view_type view); | ||
2816 | static inline | ||
2817 | bool i915_gem_obj_bound(struct drm_i915_gem_object *o, | 2814 | bool i915_gem_obj_bound(struct drm_i915_gem_object *o, |
2818 | struct i915_address_space *vm) | 2815 | struct i915_address_space *vm); |
2819 | { | ||
2820 | return i915_gem_obj_bound_view(o, vm, I915_GGTT_VIEW_NORMAL); | ||
2821 | } | ||
2822 | 2816 | ||
2823 | unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, | 2817 | unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, |
2824 | struct i915_address_space *vm); | 2818 | struct i915_address_space *vm); |
2825 | struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj, | ||
2826 | struct i915_address_space *vm, | ||
2827 | const struct i915_ggtt_view *view); | ||
2828 | static inline | ||
2829 | struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, | ||
2830 | struct i915_address_space *vm) | ||
2831 | { | ||
2832 | return i915_gem_obj_to_vma_view(obj, vm, &i915_ggtt_view_normal); | ||
2833 | } | ||
2834 | |||
2835 | struct i915_vma * | 2819 | struct i915_vma * |
2836 | i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj, | 2820 | i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, |
2837 | struct i915_address_space *vm, | 2821 | struct i915_address_space *vm); |
2838 | const struct i915_ggtt_view *view); | 2822 | struct i915_vma * |
2823 | i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj, | ||
2824 | const struct i915_ggtt_view *view); | ||
2839 | 2825 | ||
2840 | static inline | ||
2841 | struct i915_vma * | 2826 | struct i915_vma * |
2842 | i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, | 2827 | i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, |
2843 | struct i915_address_space *vm) | 2828 | struct i915_address_space *vm); |
2844 | { | 2829 | struct i915_vma * |
2845 | return i915_gem_obj_lookup_or_create_vma_view(obj, vm, | 2830 | i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, |
2846 | &i915_ggtt_view_normal); | 2831 | const struct i915_ggtt_view *view); |
2847 | } | ||
2848 | 2832 | ||
2849 | struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj); | 2833 | static inline struct i915_vma * |
2850 | static inline bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) { | 2834 | i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) |
2851 | struct i915_vma *vma; | 2835 | { |
2852 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 2836 | return i915_gem_obj_to_ggtt_view(obj, &i915_ggtt_view_normal); |
2853 | if (vma->pin_count > 0) | ||
2854 | return true; | ||
2855 | return false; | ||
2856 | } | 2837 | } |
2838 | bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj); | ||
2857 | 2839 | ||
2858 | /* Some GGTT VM helpers */ | 2840 | /* Some GGTT VM helpers */ |
2859 | #define i915_obj_to_ggtt(obj) \ | 2841 | #define i915_obj_to_ggtt(obj) \ |
@@ -2876,13 +2858,7 @@ i915_vm_to_ppgtt(struct i915_address_space *vm) | |||
2876 | 2858 | ||
2877 | static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) | 2859 | static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) |
2878 | { | 2860 | { |
2879 | return i915_gem_obj_bound(obj, i915_obj_to_ggtt(obj)); | 2861 | return i915_gem_obj_ggtt_bound_view(obj, I915_GGTT_VIEW_NORMAL); |
2880 | } | ||
2881 | |||
2882 | static inline unsigned long | ||
2883 | i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *obj) | ||
2884 | { | ||
2885 | return i915_gem_obj_offset(obj, i915_obj_to_ggtt(obj)); | ||
2886 | } | 2862 | } |
2887 | 2863 | ||
2888 | static inline unsigned long | 2864 | static inline unsigned long |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0fe313d0f609..cc8672a16da4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3518,9 +3518,9 @@ static bool i915_gem_valid_gtt_space(struct i915_vma *vma, | |||
3518 | static struct i915_vma * | 3518 | static struct i915_vma * |
3519 | i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | 3519 | i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, |
3520 | struct i915_address_space *vm, | 3520 | struct i915_address_space *vm, |
3521 | const struct i915_ggtt_view *ggtt_view, | ||
3521 | unsigned alignment, | 3522 | unsigned alignment, |
3522 | uint64_t flags, | 3523 | uint64_t flags) |
3523 | const struct i915_ggtt_view *view) | ||
3524 | { | 3524 | { |
3525 | struct drm_device *dev = obj->base.dev; | 3525 | struct drm_device *dev = obj->base.dev; |
3526 | struct drm_i915_private *dev_priv = dev->dev_private; | 3526 | 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, | |||
3532 | struct i915_vma *vma; | 3532 | struct i915_vma *vma; |
3533 | int ret; | 3533 | int ret; |
3534 | 3534 | ||
3535 | if(WARN_ON(i915_is_ggtt(vm) != !!ggtt_view)) | ||
3536 | return ERR_PTR(-EINVAL); | ||
3537 | |||
3535 | fence_size = i915_gem_get_gtt_size(dev, | 3538 | fence_size = i915_gem_get_gtt_size(dev, |
3536 | obj->base.size, | 3539 | obj->base.size, |
3537 | obj->tiling_mode); | 3540 | obj->tiling_mode); |
@@ -3570,7 +3573,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | |||
3570 | 3573 | ||
3571 | i915_gem_object_pin_pages(obj); | 3574 | i915_gem_object_pin_pages(obj); |
3572 | 3575 | ||
3573 | vma = i915_gem_obj_lookup_or_create_vma_view(obj, vm, view); | 3576 | vma = ggtt_view ? i915_gem_obj_lookup_or_create_ggtt_vma(obj, ggtt_view) : |
3577 | i915_gem_obj_lookup_or_create_vma(obj, vm); | ||
3578 | |||
3574 | if (IS_ERR(vma)) | 3579 | if (IS_ERR(vma)) |
3575 | goto err_unpin; | 3580 | goto err_unpin; |
3576 | 3581 | ||
@@ -4167,12 +4172,12 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) | |||
4167 | return false; | 4172 | return false; |
4168 | } | 4173 | } |
4169 | 4174 | ||
4170 | int | 4175 | static int |
4171 | i915_gem_object_pin_view(struct drm_i915_gem_object *obj, | 4176 | i915_gem_object_do_pin(struct drm_i915_gem_object *obj, |
4172 | struct i915_address_space *vm, | 4177 | struct i915_address_space *vm, |
4173 | uint32_t alignment, | 4178 | const struct i915_ggtt_view *ggtt_view, |
4174 | uint64_t flags, | 4179 | uint32_t alignment, |
4175 | const struct i915_ggtt_view *view) | 4180 | uint64_t flags) |
4176 | { | 4181 | { |
4177 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 4182 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
4178 | struct i915_vma *vma; | 4183 | struct i915_vma *vma; |
@@ -4188,17 +4193,29 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj, | |||
4188 | if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) | 4193 | if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) |
4189 | return -EINVAL; | 4194 | return -EINVAL; |
4190 | 4195 | ||
4191 | vma = i915_gem_obj_to_vma_view(obj, vm, view); | 4196 | if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view)) |
4197 | return -EINVAL; | ||
4198 | |||
4199 | vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) : | ||
4200 | i915_gem_obj_to_vma(obj, vm); | ||
4201 | |||
4202 | if (IS_ERR(vma)) | ||
4203 | return PTR_ERR(vma); | ||
4204 | |||
4192 | if (vma) { | 4205 | if (vma) { |
4193 | if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) | 4206 | if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) |
4194 | return -EBUSY; | 4207 | return -EBUSY; |
4195 | 4208 | ||
4196 | if (i915_vma_misplaced(vma, alignment, flags)) { | 4209 | if (i915_vma_misplaced(vma, alignment, flags)) { |
4210 | unsigned long offset; | ||
4211 | offset = ggtt_view ? i915_gem_obj_ggtt_offset_view(obj, ggtt_view->type) : | ||
4212 | i915_gem_obj_offset(obj, vm); | ||
4197 | WARN(vma->pin_count, | 4213 | WARN(vma->pin_count, |
4198 | "bo is already pinned with incorrect alignment:" | 4214 | "bo is already pinned in %s with incorrect alignment:" |
4199 | " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," | 4215 | " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," |
4200 | " obj->map_and_fenceable=%d\n", | 4216 | " obj->map_and_fenceable=%d\n", |
4201 | i915_gem_obj_offset_view(obj, vm, view->type), | 4217 | ggtt_view ? "ggtt" : "ppgtt", |
4218 | offset, | ||
4202 | alignment, | 4219 | alignment, |
4203 | !!(flags & PIN_MAPPABLE), | 4220 | !!(flags & PIN_MAPPABLE), |
4204 | obj->map_and_fenceable); | 4221 | obj->map_and_fenceable); |
@@ -4212,8 +4229,8 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj, | |||
4212 | 4229 | ||
4213 | bound = vma ? vma->bound : 0; | 4230 | bound = vma ? vma->bound : 0; |
4214 | if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { | 4231 | if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { |
4215 | vma = i915_gem_object_bind_to_vm(obj, vm, alignment, | 4232 | vma = i915_gem_object_bind_to_vm(obj, vm, ggtt_view, alignment, |
4216 | flags, view); | 4233 | flags); |
4217 | if (IS_ERR(vma)) | 4234 | if (IS_ERR(vma)) |
4218 | return PTR_ERR(vma); | 4235 | return PTR_ERR(vma); |
4219 | } | 4236 | } |
@@ -4254,6 +4271,30 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj, | |||
4254 | return 0; | 4271 | return 0; |
4255 | } | 4272 | } |
4256 | 4273 | ||
4274 | int | ||
4275 | i915_gem_object_pin(struct drm_i915_gem_object *obj, | ||
4276 | struct i915_address_space *vm, | ||
4277 | uint32_t alignment, | ||
4278 | uint64_t flags) | ||
4279 | { | ||
4280 | return i915_gem_object_do_pin(obj, vm, | ||
4281 | i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL, | ||
4282 | alignment, flags); | ||
4283 | } | ||
4284 | |||
4285 | int | ||
4286 | i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, | ||
4287 | const struct i915_ggtt_view *view, | ||
4288 | uint32_t alignment, | ||
4289 | uint64_t flags) | ||
4290 | { | ||
4291 | if (WARN_ONCE(!view, "no view specified")) | ||
4292 | return -EINVAL; | ||
4293 | |||
4294 | return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view, | ||
4295 | alignment, flags); | ||
4296 | } | ||
4297 | |||
4257 | void | 4298 | void |
4258 | i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj) | 4299 | i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj) |
4259 | { | 4300 | { |
@@ -4559,15 +4600,32 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
4559 | intel_runtime_pm_put(dev_priv); | 4600 | intel_runtime_pm_put(dev_priv); |
4560 | } | 4601 | } |
4561 | 4602 | ||
4562 | struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj, | 4603 | struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, |
4563 | struct i915_address_space *vm, | 4604 | struct i915_address_space *vm) |
4564 | const struct i915_ggtt_view *view) | ||
4565 | { | 4605 | { |
4566 | struct i915_vma *vma; | 4606 | struct i915_vma *vma; |
4567 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 4607 | list_for_each_entry(vma, &obj->vma_list, vma_link) { |
4568 | if (vma->vm == vm && vma->ggtt_view.type == view->type) | 4608 | if (i915_is_ggtt(vma->vm) && |
4609 | vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) | ||
4610 | continue; | ||
4611 | if (vma->vm == vm) | ||
4569 | return vma; | 4612 | return vma; |
4613 | } | ||
4614 | return NULL; | ||
4615 | } | ||
4616 | |||
4617 | struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj, | ||
4618 | const struct i915_ggtt_view *view) | ||
4619 | { | ||
4620 | struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); | ||
4621 | struct i915_vma *vma; | ||
4570 | 4622 | ||
4623 | if (WARN_ONCE(!view, "no view specified")) | ||
4624 | return ERR_PTR(-EINVAL); | ||
4625 | |||
4626 | list_for_each_entry(vma, &obj->vma_list, vma_link) | ||
4627 | if (vma->vm == ggtt && vma->ggtt_view.type == view->type) | ||
4628 | return vma; | ||
4571 | return NULL; | 4629 | return NULL; |
4572 | } | 4630 | } |
4573 | 4631 | ||
@@ -5176,9 +5234,9 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) | |||
5176 | } | 5234 | } |
5177 | 5235 | ||
5178 | /* All the new VM stuff */ | 5236 | /* All the new VM stuff */ |
5179 | unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, | 5237 | unsigned long |
5180 | struct i915_address_space *vm, | 5238 | i915_gem_obj_offset(struct drm_i915_gem_object *o, |
5181 | enum i915_ggtt_view_type view) | 5239 | struct i915_address_space *vm) |
5182 | { | 5240 | { |
5183 | struct drm_i915_private *dev_priv = o->base.dev->dev_private; | 5241 | struct drm_i915_private *dev_priv = o->base.dev->dev_private; |
5184 | struct i915_vma *vma; | 5242 | struct i915_vma *vma; |
@@ -5186,23 +5244,57 @@ unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, | |||
5186 | WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); | 5244 | WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); |
5187 | 5245 | ||
5188 | list_for_each_entry(vma, &o->vma_list, vma_link) { | 5246 | list_for_each_entry(vma, &o->vma_list, vma_link) { |
5189 | if (vma->vm == vm && vma->ggtt_view.type == view) | 5247 | if (i915_is_ggtt(vma->vm) && |
5248 | vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) | ||
5249 | continue; | ||
5250 | if (vma->vm == vm) | ||
5190 | return vma->node.start; | 5251 | return vma->node.start; |
5191 | |||
5192 | } | 5252 | } |
5253 | |||
5193 | WARN(1, "%s vma for this object not found.\n", | 5254 | WARN(1, "%s vma for this object not found.\n", |
5194 | i915_is_ggtt(vm) ? "global" : "ppgtt"); | 5255 | i915_is_ggtt(vm) ? "global" : "ppgtt"); |
5195 | return -1; | 5256 | return -1; |
5196 | } | 5257 | } |
5197 | 5258 | ||
5198 | bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o, | 5259 | unsigned long |
5199 | struct i915_address_space *vm, | 5260 | i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, |
5200 | enum i915_ggtt_view_type view) | 5261 | enum i915_ggtt_view_type view) |
5201 | { | 5262 | { |
5263 | struct i915_address_space *ggtt = i915_obj_to_ggtt(o); | ||
5202 | struct i915_vma *vma; | 5264 | struct i915_vma *vma; |
5203 | 5265 | ||
5204 | list_for_each_entry(vma, &o->vma_list, vma_link) | 5266 | list_for_each_entry(vma, &o->vma_list, vma_link) |
5205 | if (vma->vm == vm && | 5267 | if (vma->vm == ggtt && vma->ggtt_view.type == view) |
5268 | return vma->node.start; | ||
5269 | |||
5270 | WARN(1, "global vma for this object not found.\n"); | ||
5271 | return -1; | ||
5272 | } | ||
5273 | |||
5274 | bool i915_gem_obj_bound(struct drm_i915_gem_object *o, | ||
5275 | struct i915_address_space *vm) | ||
5276 | { | ||
5277 | struct i915_vma *vma; | ||
5278 | |||
5279 | list_for_each_entry(vma, &o->vma_list, vma_link) { | ||
5280 | if (i915_is_ggtt(vma->vm) && | ||
5281 | vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) | ||
5282 | continue; | ||
5283 | if (vma->vm == vm && drm_mm_node_allocated(&vma->node)) | ||
5284 | return true; | ||
5285 | } | ||
5286 | |||
5287 | return false; | ||
5288 | } | ||
5289 | |||
5290 | bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o, | ||
5291 | enum i915_ggtt_view_type view) | ||
5292 | { | ||
5293 | struct i915_address_space *ggtt = i915_obj_to_ggtt(o); | ||
5294 | struct i915_vma *vma; | ||
5295 | |||
5296 | list_for_each_entry(vma, &o->vma_list, vma_link) | ||
5297 | if (vma->vm == ggtt && | ||
5206 | vma->ggtt_view.type == view && | 5298 | vma->ggtt_view.type == view && |
5207 | drm_mm_node_allocated(&vma->node)) | 5299 | drm_mm_node_allocated(&vma->node)) |
5208 | return true; | 5300 | return true; |
@@ -5231,10 +5323,13 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, | |||
5231 | 5323 | ||
5232 | BUG_ON(list_empty(&o->vma_list)); | 5324 | BUG_ON(list_empty(&o->vma_list)); |
5233 | 5325 | ||
5234 | list_for_each_entry(vma, &o->vma_list, vma_link) | 5326 | list_for_each_entry(vma, &o->vma_list, vma_link) { |
5327 | if (i915_is_ggtt(vma->vm) && | ||
5328 | vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) | ||
5329 | continue; | ||
5235 | if (vma->vm == vm) | 5330 | if (vma->vm == vm) |
5236 | return vma->node.size; | 5331 | return vma->node.size; |
5237 | 5332 | } | |
5238 | return 0; | 5333 | return 0; |
5239 | } | 5334 | } |
5240 | 5335 | ||
@@ -5334,15 +5429,16 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) | |||
5334 | return NOTIFY_DONE; | 5429 | return NOTIFY_DONE; |
5335 | } | 5430 | } |
5336 | 5431 | ||
5337 | struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) | 5432 | bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) |
5338 | { | 5433 | { |
5339 | struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); | ||
5340 | struct i915_vma *vma; | 5434 | struct i915_vma *vma; |
5341 | 5435 | list_for_each_entry(vma, &obj->vma_list, vma_link) { | |
5342 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 5436 | if (i915_is_ggtt(vma->vm) && |
5343 | if (vma->vm == ggtt && | 5437 | vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) |
5344 | vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) | 5438 | continue; |
5345 | return vma; | 5439 | if (vma->pin_count > 0) |
5346 | 5440 | return true; | |
5347 | return NULL; | 5441 | } |
5442 | return false; | ||
5348 | } | 5443 | } |
5444 | |||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2034f7cf238b..f1b9ea61de4b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -67,8 +67,9 @@ | |||
67 | * i915_ggtt_view_type and struct i915_ggtt_view. | 67 | * i915_ggtt_view_type and struct i915_ggtt_view. |
68 | * | 68 | * |
69 | * A new flavour of core GEM functions which work with GGTT bound objects were | 69 | * A new flavour of core GEM functions which work with GGTT bound objects were |
70 | * added with the _view suffix. They take the struct i915_ggtt_view parameter | 70 | * added with the _ggtt_ infix, and sometimes with _view postfix to avoid |
71 | * encapsulating all metadata required to implement a view. | 71 | * renaming in large amounts of code. They take the struct i915_ggtt_view |
72 | * parameter encapsulating all metadata required to implement a view. | ||
72 | * | 73 | * |
73 | * As a helper for callers which are only interested in the normal view, | 74 | * As a helper for callers which are only interested in the normal view, |
74 | * globally const i915_ggtt_view_normal singleton instance exists. All old core | 75 | * globally const i915_ggtt_view_normal singleton instance exists. All old core |
@@ -1726,11 +1727,15 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1726 | struct drm_device *dev = vma->vm->dev; | 1727 | struct drm_device *dev = vma->vm->dev; |
1727 | struct drm_i915_private *dev_priv = dev->dev_private; | 1728 | struct drm_i915_private *dev_priv = dev->dev_private; |
1728 | struct drm_i915_gem_object *obj = vma->obj; | 1729 | struct drm_i915_gem_object *obj = vma->obj; |
1730 | struct sg_table *pages = obj->pages; | ||
1729 | 1731 | ||
1730 | /* Currently applicable only to VLV */ | 1732 | /* Currently applicable only to VLV */ |
1731 | if (obj->gt_ro) | 1733 | if (obj->gt_ro) |
1732 | flags |= PTE_READ_ONLY; | 1734 | flags |= PTE_READ_ONLY; |
1733 | 1735 | ||
1736 | if (i915_is_ggtt(vma->vm)) | ||
1737 | pages = vma->ggtt_view.pages; | ||
1738 | |||
1734 | /* If there is no aliasing PPGTT, or the caller needs a global mapping, | 1739 | /* If there is no aliasing PPGTT, or the caller needs a global mapping, |
1735 | * or we have a global mapping already but the cacheability flags have | 1740 | * or we have a global mapping already but the cacheability flags have |
1736 | * changed, set the global PTEs. | 1741 | * changed, set the global PTEs. |
@@ -1745,7 +1750,7 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1745 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { | 1750 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { |
1746 | if (!(vma->bound & GLOBAL_BIND) || | 1751 | if (!(vma->bound & GLOBAL_BIND) || |
1747 | (cache_level != obj->cache_level)) { | 1752 | (cache_level != obj->cache_level)) { |
1748 | vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages, | 1753 | vma->vm->insert_entries(vma->vm, pages, |
1749 | vma->node.start, | 1754 | vma->node.start, |
1750 | cache_level, flags); | 1755 | cache_level, flags); |
1751 | vma->bound |= GLOBAL_BIND; | 1756 | vma->bound |= GLOBAL_BIND; |
@@ -1756,8 +1761,7 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1756 | (!(vma->bound & LOCAL_BIND) || | 1761 | (!(vma->bound & LOCAL_BIND) || |
1757 | (cache_level != obj->cache_level))) { | 1762 | (cache_level != obj->cache_level))) { |
1758 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; | 1763 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; |
1759 | appgtt->base.insert_entries(&appgtt->base, | 1764 | appgtt->base.insert_entries(&appgtt->base, pages, |
1760 | vma->ggtt_view.pages, | ||
1761 | vma->node.start, | 1765 | vma->node.start, |
1762 | cache_level, flags); | 1766 | cache_level, flags); |
1763 | vma->bound |= LOCAL_BIND; | 1767 | vma->bound |= LOCAL_BIND; |
@@ -2331,23 +2335,28 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
2331 | return 0; | 2335 | return 0; |
2332 | } | 2336 | } |
2333 | 2337 | ||
2334 | static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, | 2338 | static struct i915_vma * |
2335 | struct i915_address_space *vm, | 2339 | __i915_gem_vma_create(struct drm_i915_gem_object *obj, |
2336 | const struct i915_ggtt_view *view) | 2340 | struct i915_address_space *vm, |
2341 | const struct i915_ggtt_view *ggtt_view) | ||
2337 | { | 2342 | { |
2338 | struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); | 2343 | struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); |
2339 | if (vma == NULL) | 2344 | if (vma == NULL) |
2340 | return ERR_PTR(-ENOMEM); | 2345 | return ERR_PTR(-ENOMEM); |
2341 | 2346 | ||
2347 | if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view)) | ||
2348 | return ERR_PTR(-EINVAL); | ||
2349 | |||
2342 | INIT_LIST_HEAD(&vma->vma_link); | 2350 | INIT_LIST_HEAD(&vma->vma_link); |
2343 | INIT_LIST_HEAD(&vma->mm_list); | 2351 | INIT_LIST_HEAD(&vma->mm_list); |
2344 | INIT_LIST_HEAD(&vma->exec_list); | 2352 | INIT_LIST_HEAD(&vma->exec_list); |
2345 | vma->vm = vm; | 2353 | vma->vm = vm; |
2346 | vma->obj = obj; | 2354 | vma->obj = obj; |
2347 | vma->ggtt_view = *view; | ||
2348 | 2355 | ||
2349 | if (INTEL_INFO(vm->dev)->gen >= 6) { | 2356 | if (INTEL_INFO(vm->dev)->gen >= 6) { |
2350 | if (i915_is_ggtt(vm)) { | 2357 | if (i915_is_ggtt(vm)) { |
2358 | vma->ggtt_view = *ggtt_view; | ||
2359 | |||
2351 | vma->unbind_vma = ggtt_unbind_vma; | 2360 | vma->unbind_vma = ggtt_unbind_vma; |
2352 | vma->bind_vma = ggtt_bind_vma; | 2361 | vma->bind_vma = ggtt_bind_vma; |
2353 | } else { | 2362 | } else { |
@@ -2356,6 +2365,7 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, | |||
2356 | } | 2365 | } |
2357 | } else { | 2366 | } else { |
2358 | BUG_ON(!i915_is_ggtt(vm)); | 2367 | BUG_ON(!i915_is_ggtt(vm)); |
2368 | vma->ggtt_view = *ggtt_view; | ||
2359 | vma->unbind_vma = i915_ggtt_unbind_vma; | 2369 | vma->unbind_vma = i915_ggtt_unbind_vma; |
2360 | vma->bind_vma = i915_ggtt_bind_vma; | 2370 | vma->bind_vma = i915_ggtt_bind_vma; |
2361 | } | 2371 | } |
@@ -2368,21 +2378,44 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, | |||
2368 | } | 2378 | } |
2369 | 2379 | ||
2370 | struct i915_vma * | 2380 | struct i915_vma * |
2371 | i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj, | 2381 | i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, |
2372 | struct i915_address_space *vm, | 2382 | struct i915_address_space *vm) |
2383 | { | ||
2384 | struct i915_vma *vma; | ||
2385 | |||
2386 | vma = i915_gem_obj_to_vma(obj, vm); | ||
2387 | if (!vma) | ||
2388 | vma = __i915_gem_vma_create(obj, vm, | ||
2389 | i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL); | ||
2390 | |||
2391 | return vma; | ||
2392 | } | ||
2393 | |||
2394 | struct i915_vma * | ||
2395 | i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, | ||
2373 | const struct i915_ggtt_view *view) | 2396 | const struct i915_ggtt_view *view) |
2374 | { | 2397 | { |
2398 | struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); | ||
2375 | struct i915_vma *vma; | 2399 | struct i915_vma *vma; |
2376 | 2400 | ||
2377 | vma = i915_gem_obj_to_vma_view(obj, vm, view); | 2401 | if (WARN_ON(!view)) |
2402 | return ERR_PTR(-EINVAL); | ||
2403 | |||
2404 | vma = i915_gem_obj_to_ggtt_view(obj, view); | ||
2405 | |||
2406 | if (IS_ERR(vma)) | ||
2407 | return vma; | ||
2408 | |||
2378 | if (!vma) | 2409 | if (!vma) |
2379 | vma = __i915_gem_vma_create(obj, vm, view); | 2410 | vma = __i915_gem_vma_create(obj, ggtt, view); |
2380 | 2411 | ||
2381 | return vma; | 2412 | return vma; |
2413 | |||
2382 | } | 2414 | } |
2383 | 2415 | ||
2416 | |||
2384 | static inline | 2417 | static inline |
2385 | int i915_get_vma_pages(struct i915_vma *vma) | 2418 | int i915_get_ggtt_vma_pages(struct i915_vma *vma) |
2386 | { | 2419 | { |
2387 | if (vma->ggtt_view.pages) | 2420 | if (vma->ggtt_view.pages) |
2388 | return 0; | 2421 | return 0; |
@@ -2394,7 +2427,7 @@ int i915_get_vma_pages(struct i915_vma *vma) | |||
2394 | vma->ggtt_view.type); | 2427 | vma->ggtt_view.type); |
2395 | 2428 | ||
2396 | if (!vma->ggtt_view.pages) { | 2429 | if (!vma->ggtt_view.pages) { |
2397 | DRM_ERROR("Failed to get pages for VMA view type %u!\n", | 2430 | DRM_ERROR("Failed to get pages for GGTT view type %u!\n", |
2398 | vma->ggtt_view.type); | 2431 | vma->ggtt_view.type); |
2399 | return -EINVAL; | 2432 | return -EINVAL; |
2400 | } | 2433 | } |
@@ -2415,10 +2448,12 @@ int i915_get_vma_pages(struct i915_vma *vma) | |||
2415 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, | 2448 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, |
2416 | u32 flags) | 2449 | u32 flags) |
2417 | { | 2450 | { |
2418 | int ret = i915_get_vma_pages(vma); | 2451 | if (i915_is_ggtt(vma->vm)) { |
2452 | int ret = i915_get_ggtt_vma_pages(vma); | ||
2419 | 2453 | ||
2420 | if (ret) | 2454 | if (ret) |
2421 | return ret; | 2455 | return ret; |
2456 | } | ||
2422 | 2457 | ||
2423 | vma->bind_vma(vma, cache_level, flags); | 2458 | vma->bind_vma(vma, cache_level, flags); |
2424 | 2459 | ||