aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-11-15 06:32:30 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-11-30 17:44:05 -0500
commit42dcedd4f2e715dc0313e359c8288e6397843fff (patch)
treebb5f86097d2e7f5e855824e76fe51bec8e97e635
parent8040513870399f1cb032cb8bc805df5042fedcdf (diff)
drm/i915: Use a slab for object allocation
The primary purpose of this was to debug some use-after-free memory corruption that was causing an OOPS inside drm/i915. As it turned out the corruption was being caused elsewhere and i915.ko as a major user of many objects was being hit hardest. Indeed as we do frequent the generic kmalloc caches, dedicating one to ourselves (or at least naming one for us depending upon the core) aids debugging our own slab usage. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c28
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c5
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c4
5 files changed, 34 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 80ed75117b6d..2635ee6a34d4 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1736,6 +1736,9 @@ int i915_driver_unload(struct drm_device *dev)
1736 1736
1737 destroy_workqueue(dev_priv->wq); 1737 destroy_workqueue(dev_priv->wq);
1738 1738
1739 if (dev_priv->slab)
1740 kmem_cache_destroy(dev_priv->slab);
1741
1739 pci_dev_put(dev_priv->bridge_dev); 1742 pci_dev_put(dev_priv->bridge_dev);
1740 kfree(dev->dev_private); 1743 kfree(dev->dev_private);
1741 1744
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d1d68f0b55e8..e2944e9bc750 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -614,6 +614,7 @@ struct intel_l3_parity {
614 614
615typedef struct drm_i915_private { 615typedef struct drm_i915_private {
616 struct drm_device *dev; 616 struct drm_device *dev;
617 struct kmem_cache *slab;
617 618
618 const struct intel_device_info *info; 619 const struct intel_device_info *info;
619 620
@@ -1379,12 +1380,15 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
1379int i915_gem_wait_ioctl(struct drm_device *dev, void *data, 1380int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
1380 struct drm_file *file_priv); 1381 struct drm_file *file_priv);
1381void i915_gem_load(struct drm_device *dev); 1382void i915_gem_load(struct drm_device *dev);
1383void *i915_gem_object_alloc(struct drm_device *dev);
1384void i915_gem_object_free(struct drm_i915_gem_object *obj);
1382int i915_gem_init_object(struct drm_gem_object *obj); 1385int i915_gem_init_object(struct drm_gem_object *obj);
1383void i915_gem_object_init(struct drm_i915_gem_object *obj, 1386void i915_gem_object_init(struct drm_i915_gem_object *obj,
1384 const struct drm_i915_gem_object_ops *ops); 1387 const struct drm_i915_gem_object_ops *ops);
1385struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, 1388struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
1386 size_t size); 1389 size_t size);
1387void i915_gem_free_object(struct drm_gem_object *obj); 1390void i915_gem_free_object(struct drm_gem_object *obj);
1391
1388int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, 1392int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
1389 uint32_t alignment, 1393 uint32_t alignment,
1390 bool map_and_fenceable, 1394 bool map_and_fenceable,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3de62b0127a5..dfe7174a7c03 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -192,6 +192,18 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
192 return 0; 192 return 0;
193} 193}
194 194
195void *i915_gem_object_alloc(struct drm_device *dev)
196{
197 struct drm_i915_private *dev_priv = dev->dev_private;
198 return kmem_cache_alloc(dev_priv->slab, GFP_KERNEL | __GFP_ZERO);
199}
200
201void i915_gem_object_free(struct drm_i915_gem_object *obj)
202{
203 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
204 kmem_cache_free(dev_priv->slab, obj);
205}
206
195static int 207static int
196i915_gem_create(struct drm_file *file, 208i915_gem_create(struct drm_file *file,
197 struct drm_device *dev, 209 struct drm_device *dev,
@@ -215,7 +227,7 @@ i915_gem_create(struct drm_file *file,
215 if (ret) { 227 if (ret) {
216 drm_gem_object_release(&obj->base); 228 drm_gem_object_release(&obj->base);
217 i915_gem_info_remove_obj(dev->dev_private, obj->base.size); 229 i915_gem_info_remove_obj(dev->dev_private, obj->base.size);
218 kfree(obj); 230 i915_gem_object_free(obj);
219 return ret; 231 return ret;
220 } 232 }
221 233
@@ -3695,12 +3707,12 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
3695 struct address_space *mapping; 3707 struct address_space *mapping;
3696 u32 mask; 3708 u32 mask;
3697 3709
3698 obj = kzalloc(sizeof(*obj), GFP_KERNEL); 3710 obj = i915_gem_object_alloc(dev);
3699 if (obj == NULL) 3711 if (obj == NULL)
3700 return NULL; 3712 return NULL;
3701 3713
3702 if (drm_gem_object_init(dev, &obj->base, size) != 0) { 3714 if (drm_gem_object_init(dev, &obj->base, size) != 0) {
3703 kfree(obj); 3715 i915_gem_object_free(obj);
3704 return NULL; 3716 return NULL;
3705 } 3717 }
3706 3718
@@ -3783,7 +3795,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
3783 i915_gem_info_remove_obj(dev_priv, obj->base.size); 3795 i915_gem_info_remove_obj(dev_priv, obj->base.size);
3784 3796
3785 kfree(obj->bit_17); 3797 kfree(obj->bit_17);
3786 kfree(obj); 3798 i915_gem_object_free(obj);
3787} 3799}
3788 3800
3789int 3801int
@@ -4101,8 +4113,14 @@ init_ring_lists(struct intel_ring_buffer *ring)
4101void 4113void
4102i915_gem_load(struct drm_device *dev) 4114i915_gem_load(struct drm_device *dev)
4103{ 4115{
4104 int i;
4105 drm_i915_private_t *dev_priv = dev->dev_private; 4116 drm_i915_private_t *dev_priv = dev->dev_private;
4117 int i;
4118
4119 dev_priv->slab =
4120 kmem_cache_create("i915_gem_object",
4121 sizeof(struct drm_i915_gem_object), 0,
4122 SLAB_HWCACHE_ALIGN,
4123 NULL);
4106 4124
4107 INIT_LIST_HEAD(&dev_priv->mm.active_list); 4125 INIT_LIST_HEAD(&dev_priv->mm.active_list);
4108 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4126 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 773ef77b6c22..defb888ef7f5 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -276,8 +276,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
276 if (IS_ERR(attach)) 276 if (IS_ERR(attach))
277 return ERR_CAST(attach); 277 return ERR_CAST(attach);
278 278
279 279 obj = i915_gem_object_alloc(dev);
280 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
281 if (obj == NULL) { 280 if (obj == NULL) {
282 ret = -ENOMEM; 281 ret = -ENOMEM;
283 goto fail_detach; 282 goto fail_detach;
@@ -285,7 +284,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
285 284
286 ret = drm_gem_private_object_init(dev, &obj->base, dma_buf->size); 285 ret = drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
287 if (ret) { 286 if (ret) {
288 kfree(obj); 287 i915_gem_object_free(obj);
289 goto fail_detach; 288 goto fail_detach;
290 } 289 }
291 290
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 7299d632663c..f817b0cac116 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -252,7 +252,7 @@ _i915_gem_object_create_stolen(struct drm_device *dev,
252{ 252{
253 struct drm_i915_gem_object *obj; 253 struct drm_i915_gem_object *obj;
254 254
255 obj = kzalloc(sizeof(*obj), GFP_KERNEL); 255 obj = i915_gem_object_alloc(dev);
256 if (obj == NULL) 256 if (obj == NULL)
257 return NULL; 257 return NULL;
258 258
@@ -277,7 +277,7 @@ _i915_gem_object_create_stolen(struct drm_device *dev,
277 return obj; 277 return obj;
278 278
279cleanup: 279cleanup:
280 kfree(obj); 280 i915_gem_object_free(obj);
281 return NULL; 281 return NULL;
282} 282}
283 283