diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 110 |
1 files changed, 76 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 302beee03197..16c4b7b9602c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -68,6 +68,49 @@ i915_gem_object_put_pages(struct drm_gem_object *obj); | |||
68 | static LIST_HEAD(shrink_list); | 68 | static LIST_HEAD(shrink_list); |
69 | static DEFINE_SPINLOCK(shrink_list_lock); | 69 | static DEFINE_SPINLOCK(shrink_list_lock); |
70 | 70 | ||
71 | /* some bookkeeping */ | ||
72 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | ||
73 | size_t size) | ||
74 | { | ||
75 | dev_priv->mm.object_count++; | ||
76 | dev_priv->mm.object_memory += size; | ||
77 | } | ||
78 | |||
79 | static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, | ||
80 | size_t size) | ||
81 | { | ||
82 | dev_priv->mm.object_count--; | ||
83 | dev_priv->mm.object_memory -= size; | ||
84 | } | ||
85 | |||
86 | static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, | ||
87 | size_t size) | ||
88 | { | ||
89 | dev_priv->mm.gtt_count++; | ||
90 | dev_priv->mm.gtt_memory += size; | ||
91 | } | ||
92 | |||
93 | static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, | ||
94 | size_t size) | ||
95 | { | ||
96 | dev_priv->mm.gtt_count--; | ||
97 | dev_priv->mm.gtt_memory -= size; | ||
98 | } | ||
99 | |||
100 | static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, | ||
101 | size_t size) | ||
102 | { | ||
103 | dev_priv->mm.pin_count++; | ||
104 | dev_priv->mm.pin_memory += size; | ||
105 | } | ||
106 | |||
107 | static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, | ||
108 | size_t size) | ||
109 | { | ||
110 | dev_priv->mm.pin_count--; | ||
111 | dev_priv->mm.pin_memory -= size; | ||
112 | } | ||
113 | |||
71 | int | 114 | int |
72 | i915_gem_check_is_wedged(struct drm_device *dev) | 115 | i915_gem_check_is_wedged(struct drm_device *dev) |
73 | { | 116 | { |
@@ -128,7 +171,8 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | |||
128 | obj_priv->pin_count == 0; | 171 | obj_priv->pin_count == 0; |
129 | } | 172 | } |
130 | 173 | ||
131 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 174 | int i915_gem_do_init(struct drm_device *dev, |
175 | unsigned long start, | ||
132 | unsigned long end) | 176 | unsigned long end) |
133 | { | 177 | { |
134 | drm_i915_private_t *dev_priv = dev->dev_private; | 178 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -142,7 +186,7 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, | |||
142 | drm_mm_init(&dev_priv->mm.gtt_space, start, | 186 | drm_mm_init(&dev_priv->mm.gtt_space, start, |
143 | end - start); | 187 | end - start); |
144 | 188 | ||
145 | dev->gtt_total = (uint32_t) (end - start); | 189 | dev_priv->mm.gtt_total = end - start; |
146 | 190 | ||
147 | return 0; | 191 | return 0; |
148 | } | 192 | } |
@@ -165,14 +209,16 @@ int | |||
165 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 209 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
166 | struct drm_file *file_priv) | 210 | struct drm_file *file_priv) |
167 | { | 211 | { |
212 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
168 | struct drm_i915_gem_get_aperture *args = data; | 213 | struct drm_i915_gem_get_aperture *args = data; |
169 | 214 | ||
170 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 215 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
171 | return -ENODEV; | 216 | return -ENODEV; |
172 | 217 | ||
173 | args->aper_size = dev->gtt_total; | 218 | mutex_lock(&dev->struct_mutex); |
174 | args->aper_available_size = (args->aper_size - | 219 | args->aper_size = dev_priv->mm.gtt_total; |
175 | atomic_read(&dev->pin_memory)); | 220 | args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory; |
221 | mutex_unlock(&dev->struct_mutex); | ||
176 | 222 | ||
177 | return 0; | 223 | return 0; |
178 | } | 224 | } |
@@ -2084,6 +2130,7 @@ int | |||
2084 | i915_gem_object_unbind(struct drm_gem_object *obj) | 2130 | i915_gem_object_unbind(struct drm_gem_object *obj) |
2085 | { | 2131 | { |
2086 | struct drm_device *dev = obj->dev; | 2132 | struct drm_device *dev = obj->dev; |
2133 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2087 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2134 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2088 | int ret = 0; | 2135 | int ret = 0; |
2089 | 2136 | ||
@@ -2116,25 +2163,18 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2116 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 2163 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
2117 | i915_gem_clear_fence_reg(obj); | 2164 | i915_gem_clear_fence_reg(obj); |
2118 | 2165 | ||
2119 | if (obj_priv->agp_mem != NULL) { | 2166 | drm_unbind_agp(obj_priv->agp_mem); |
2120 | drm_unbind_agp(obj_priv->agp_mem); | 2167 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); |
2121 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); | ||
2122 | obj_priv->agp_mem = NULL; | ||
2123 | } | ||
2124 | 2168 | ||
2125 | i915_gem_object_put_pages(obj); | 2169 | i915_gem_object_put_pages(obj); |
2126 | BUG_ON(obj_priv->pages_refcount); | 2170 | BUG_ON(obj_priv->pages_refcount); |
2127 | 2171 | ||
2128 | if (obj_priv->gtt_space) { | 2172 | i915_gem_info_remove_gtt(dev_priv, obj->size); |
2129 | atomic_dec(&dev->gtt_count); | ||
2130 | atomic_sub(obj->size, &dev->gtt_memory); | ||
2131 | |||
2132 | drm_mm_put_block(obj_priv->gtt_space); | ||
2133 | obj_priv->gtt_space = NULL; | ||
2134 | } | ||
2135 | |||
2136 | list_del_init(&obj_priv->list); | 2173 | list_del_init(&obj_priv->list); |
2137 | 2174 | ||
2175 | drm_mm_put_block(obj_priv->gtt_space); | ||
2176 | obj_priv->gtt_space = NULL; | ||
2177 | |||
2138 | if (i915_gem_object_is_purgeable(obj_priv)) | 2178 | if (i915_gem_object_is_purgeable(obj_priv)) |
2139 | i915_gem_object_truncate(obj); | 2179 | i915_gem_object_truncate(obj); |
2140 | 2180 | ||
@@ -2619,7 +2659,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2619 | /* If the object is bigger than the entire aperture, reject it early | 2659 | /* If the object is bigger than the entire aperture, reject it early |
2620 | * before evicting everything in a vain attempt to find space. | 2660 | * before evicting everything in a vain attempt to find space. |
2621 | */ | 2661 | */ |
2622 | if (obj->size > dev->gtt_total) { | 2662 | if (obj->size > dev_priv->mm.gtt_total) { |
2623 | DRM_ERROR("Attempting to bind an object larger than the aperture\n"); | 2663 | DRM_ERROR("Attempting to bind an object larger than the aperture\n"); |
2624 | return -E2BIG; | 2664 | return -E2BIG; |
2625 | } | 2665 | } |
@@ -2688,11 +2728,10 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2688 | 2728 | ||
2689 | goto search_free; | 2729 | goto search_free; |
2690 | } | 2730 | } |
2691 | atomic_inc(&dev->gtt_count); | ||
2692 | atomic_add(obj->size, &dev->gtt_memory); | ||
2693 | 2731 | ||
2694 | /* keep track of bounds object by adding it to the inactive list */ | 2732 | /* keep track of bounds object by adding it to the inactive list */ |
2695 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | 2733 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); |
2734 | i915_gem_info_add_gtt(dev_priv, obj->size); | ||
2696 | 2735 | ||
2697 | /* Assert that the object is not currently in any GPU domain. As it | 2736 | /* Assert that the object is not currently in any GPU domain. As it |
2698 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2737 | * wasn't in the GTT, there shouldn't be any way it could have been in |
@@ -3779,15 +3818,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3779 | pinned+1, args->buffer_count, | 3818 | pinned+1, args->buffer_count, |
3780 | total_size, num_fences, | 3819 | total_size, num_fences, |
3781 | ret); | 3820 | ret); |
3782 | DRM_ERROR("%d objects [%d pinned], " | 3821 | DRM_ERROR("%u objects [%u pinned, %u GTT], " |
3783 | "%d object bytes [%d pinned], " | 3822 | "%zu object bytes [%zu pinned], " |
3784 | "%d/%d gtt bytes\n", | 3823 | "%zu /%zu gtt bytes\n", |
3785 | atomic_read(&dev->object_count), | 3824 | dev_priv->mm.object_count, |
3786 | atomic_read(&dev->pin_count), | 3825 | dev_priv->mm.pin_count, |
3787 | atomic_read(&dev->object_memory), | 3826 | dev_priv->mm.gtt_count, |
3788 | atomic_read(&dev->pin_memory), | 3827 | dev_priv->mm.object_memory, |
3789 | atomic_read(&dev->gtt_memory), | 3828 | dev_priv->mm.pin_memory, |
3790 | dev->gtt_total); | 3829 | dev_priv->mm.gtt_memory, |
3830 | dev_priv->mm.gtt_total); | ||
3791 | } | 3831 | } |
3792 | goto err; | 3832 | goto err; |
3793 | } | 3833 | } |
@@ -4119,8 +4159,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4119 | * remove it from the inactive list | 4159 | * remove it from the inactive list |
4120 | */ | 4160 | */ |
4121 | if (obj_priv->pin_count == 1) { | 4161 | if (obj_priv->pin_count == 1) { |
4122 | atomic_inc(&dev->pin_count); | 4162 | i915_gem_info_add_pin(dev_priv, obj->size); |
4123 | atomic_add(obj->size, &dev->pin_memory); | ||
4124 | if (!obj_priv->active) | 4163 | if (!obj_priv->active) |
4125 | list_move_tail(&obj_priv->list, | 4164 | list_move_tail(&obj_priv->list, |
4126 | &dev_priv->mm.pinned_list); | 4165 | &dev_priv->mm.pinned_list); |
@@ -4150,8 +4189,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) | |||
4150 | if (!obj_priv->active) | 4189 | if (!obj_priv->active) |
4151 | list_move_tail(&obj_priv->list, | 4190 | list_move_tail(&obj_priv->list, |
4152 | &dev_priv->mm.inactive_list); | 4191 | &dev_priv->mm.inactive_list); |
4153 | atomic_dec(&dev->pin_count); | 4192 | i915_gem_info_remove_pin(dev_priv, obj->size); |
4154 | atomic_sub(obj->size, &dev->pin_memory); | ||
4155 | } | 4193 | } |
4156 | WARN_ON(i915_verify_lists(dev)); | 4194 | WARN_ON(i915_verify_lists(dev)); |
4157 | } | 4195 | } |
@@ -4378,6 +4416,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
4378 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | 4416 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, |
4379 | size_t size) | 4417 | size_t size) |
4380 | { | 4418 | { |
4419 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4381 | struct drm_i915_gem_object *obj; | 4420 | struct drm_i915_gem_object *obj; |
4382 | 4421 | ||
4383 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); | 4422 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); |
@@ -4389,6 +4428,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | |||
4389 | return NULL; | 4428 | return NULL; |
4390 | } | 4429 | } |
4391 | 4430 | ||
4431 | i915_gem_info_add_obj(dev_priv, size); | ||
4432 | |||
4392 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 4433 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
4393 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 4434 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
4394 | 4435 | ||
@@ -4429,6 +4470,7 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj) | |||
4429 | i915_gem_free_mmap_offset(obj); | 4470 | i915_gem_free_mmap_offset(obj); |
4430 | 4471 | ||
4431 | drm_gem_object_release(obj); | 4472 | drm_gem_object_release(obj); |
4473 | i915_gem_info_remove_obj(dev_priv, obj->size); | ||
4432 | 4474 | ||
4433 | kfree(obj_priv->page_cpu_valid); | 4475 | kfree(obj_priv->page_cpu_valid); |
4434 | kfree(obj_priv->bit_17); | 4476 | kfree(obj_priv->bit_17); |