aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_gem.c8
-rw-r--r--drivers/gpu/drm/drm_info.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c6
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_notifier.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c4
-rw-r--r--include/drm/drmP.h18
11 files changed, 33 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 6fe2cd298c12..f7e61be8430a 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev,
148 return -ENOMEM; 148 return -ENOMEM;
149 149
150 kref_init(&obj->refcount); 150 kref_init(&obj->refcount);
151 kref_init(&obj->handlecount); 151 atomic_set(&obj->handle_count, 0);
152 obj->size = size; 152 obj->size = size;
153 153
154 atomic_inc(&dev->object_count); 154 atomic_inc(&dev->object_count);
@@ -496,12 +496,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref)
496 * called before drm_gem_object_free or we'll be touching 496 * called before drm_gem_object_free or we'll be touching
497 * freed memory 497 * freed memory
498 */ 498 */
499void 499void drm_gem_object_handle_free(struct drm_gem_object *obj)
500drm_gem_object_handle_free(struct kref *kref)
501{ 500{
502 struct drm_gem_object *obj = container_of(kref,
503 struct drm_gem_object,
504 handlecount);
505 struct drm_device *dev = obj->dev; 501 struct drm_device *dev = obj->dev;
506 502
507 /* Remove any name for this object */ 503 /* Remove any name for this object */
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 2ef2c7827243..974e970ce3f8 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data)
255 255
256 seq_printf(m, "%6d %8zd %7d %8d\n", 256 seq_printf(m, "%6d %8zd %7d %8d\n",
257 obj->name, obj->size, 257 obj->name, obj->size,
258 atomic_read(&obj->handlecount.refcount), 258 atomic_read(&obj->handle_count),
259 atomic_read(&obj->refcount.refcount)); 259 atomic_read(&obj->refcount.refcount));
260 return 0; 260 return 0;
261} 261}
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cf4ffbee1c00..4cdf74264ee8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
136 return -ENOMEM; 136 return -ENOMEM;
137 137
138 ret = drm_gem_handle_create(file_priv, obj, &handle); 138 ret = drm_gem_handle_create(file_priv, obj, &handle);
139 /* drop reference from allocate - handle holds it now */
140 drm_gem_object_unreference_unlocked(obj);
139 if (ret) { 141 if (ret) {
140 drm_gem_object_unreference_unlocked(obj);
141 return ret; 142 return ret;
142 } 143 }
143 144
144 /* Sink the floating reference from kref_init(handlecount) */
145 drm_gem_object_handle_unreference_unlocked(obj);
146
147 args->handle = handle; 145 args->handle = handle;
148 return 0; 146 return 0;
149} 147}
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 7bdc96256bf5..56ad9df2ccb5 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev,
237 drm_fb_helper_fini(&ifbdev->helper); 237 drm_fb_helper_fini(&ifbdev->helper);
238 238
239 drm_framebuffer_cleanup(&ifb->base); 239 drm_framebuffer_cleanup(&ifb->base);
240 if (ifb->obj) 240 if (ifb->obj) {
241 drm_gem_object_handle_unreference(ifb->obj);
241 drm_gem_object_unreference(ifb->obj); 242 drm_gem_object_unreference(ifb->obj);
243 }
242 244
243 return 0; 245 return 0;
244} 246}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index dbd30b2e43fd..d2047713dc59 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -352,6 +352,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
352 352
353 if (nouveau_fb->nvbo) { 353 if (nouveau_fb->nvbo) {
354 nouveau_bo_unmap(nouveau_fb->nvbo); 354 nouveau_bo_unmap(nouveau_fb->nvbo);
355 drm_gem_object_handle_unreference_unlocked(nouveau_fb->nvbo->gem);
355 drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); 356 drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
356 nouveau_fb->nvbo = NULL; 357 nouveau_fb->nvbo = NULL;
357 } 358 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index ead7b8fc53fc..19620a6709f5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
167 goto out; 167 goto out;
168 168
169 ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); 169 ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
170 /* drop reference from allocate - handle holds it now */
171 drm_gem_object_unreference_unlocked(nvbo->gem);
170out: 172out:
171 drm_gem_object_handle_unreference_unlocked(nvbo->gem);
172
173 if (ret)
174 drm_gem_object_unreference_unlocked(nvbo->gem);
175 return ret; 173 return ret;
176} 174}
177 175
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
index 3ec181ff50ce..3c9964a8fbad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
@@ -79,6 +79,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
79 mutex_lock(&dev->struct_mutex); 79 mutex_lock(&dev->struct_mutex);
80 nouveau_bo_unpin(chan->notifier_bo); 80 nouveau_bo_unpin(chan->notifier_bo);
81 mutex_unlock(&dev->struct_mutex); 81 mutex_unlock(&dev->struct_mutex);
82 drm_gem_object_handle_unreference_unlocked(chan->notifier_bo->gem);
82 drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); 83 drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
83 drm_mm_takedown(&chan->notifier_heap); 84 drm_mm_takedown(&chan->notifier_heap);
84} 85}
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 7422f274615a..b92d2f2fcbed 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -843,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
843{ 843{
844 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 844 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
845 845
846 if (radeon_fb->obj) 846 if (radeon_fb->obj) {
847 drm_gem_object_unreference_unlocked(radeon_fb->obj); 847 drm_gem_object_unreference_unlocked(radeon_fb->obj);
848 }
848 drm_framebuffer_cleanup(fb); 849 drm_framebuffer_cleanup(fb);
849 kfree(radeon_fb); 850 kfree(radeon_fb);
850} 851}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index c74a8b20d941..9cdf6a35bc2c 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -94,8 +94,10 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
94 ret = radeon_bo_reserve(rbo, false); 94 ret = radeon_bo_reserve(rbo, false);
95 if (likely(ret == 0)) { 95 if (likely(ret == 0)) {
96 radeon_bo_kunmap(rbo); 96 radeon_bo_kunmap(rbo);
97 radeon_bo_unpin(rbo);
97 radeon_bo_unreserve(rbo); 98 radeon_bo_unreserve(rbo);
98 } 99 }
100 drm_gem_object_handle_unreference(gobj);
99 drm_gem_object_unreference_unlocked(gobj); 101 drm_gem_object_unreference_unlocked(gobj);
100} 102}
101 103
@@ -325,8 +327,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
325{ 327{
326 struct fb_info *info; 328 struct fb_info *info;
327 struct radeon_framebuffer *rfb = &rfbdev->rfb; 329 struct radeon_framebuffer *rfb = &rfbdev->rfb;
328 struct radeon_bo *rbo;
329 int r;
330 330
331 if (rfbdev->helper.fbdev) { 331 if (rfbdev->helper.fbdev) {
332 info = rfbdev->helper.fbdev; 332 info = rfbdev->helper.fbdev;
@@ -338,14 +338,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
338 } 338 }
339 339
340 if (rfb->obj) { 340 if (rfb->obj) {
341 rbo = rfb->obj->driver_private; 341 radeonfb_destroy_pinned_object(rfb->obj);
342 r = radeon_bo_reserve(rbo, false); 342 rfb->obj = NULL;
343 if (likely(r == 0)) {
344 radeon_bo_kunmap(rbo);
345 radeon_bo_unpin(rbo);
346 radeon_bo_unreserve(rbo);
347 }
348 drm_gem_object_unreference_unlocked(rfb->obj);
349 } 343 }
350 drm_fb_helper_fini(&rfbdev->helper); 344 drm_fb_helper_fini(&rfbdev->helper);
351 drm_framebuffer_cleanup(&rfb->base); 345 drm_framebuffer_cleanup(&rfb->base);
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index c578f265b24c..d1e595d91723 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
201 return r; 201 return r;
202 } 202 }
203 r = drm_gem_handle_create(filp, gobj, &handle); 203 r = drm_gem_handle_create(filp, gobj, &handle);
204 /* drop reference from allocate - handle holds it now */
205 drm_gem_object_unreference_unlocked(gobj);
204 if (r) { 206 if (r) {
205 drm_gem_object_unreference_unlocked(gobj);
206 return r; 207 return r;
207 } 208 }
208 drm_gem_object_handle_unreference_unlocked(gobj);
209 args->handle = handle; 209 args->handle = handle;
210 return 0; 210 return 0;
211} 211}
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 774e1d49509b..07e4726a4ee0 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -612,7 +612,7 @@ struct drm_gem_object {
612 struct kref refcount; 612 struct kref refcount;
613 613
614 /** Handle count of this object. Each handle also holds a reference */ 614 /** Handle count of this object. Each handle also holds a reference */
615 struct kref handlecount; 615 atomic_t handle_count; /* number of handles on this object */
616 616
617 /** Related drm device */ 617 /** Related drm device */
618 struct drm_device *dev; 618 struct drm_device *dev;
@@ -1461,7 +1461,7 @@ struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
1461 size_t size); 1461 size_t size);
1462int drm_gem_object_init(struct drm_device *dev, 1462int drm_gem_object_init(struct drm_device *dev,
1463 struct drm_gem_object *obj, size_t size); 1463 struct drm_gem_object *obj, size_t size);
1464void drm_gem_object_handle_free(struct kref *kref); 1464void drm_gem_object_handle_free(struct drm_gem_object *obj);
1465void drm_gem_vm_open(struct vm_area_struct *vma); 1465void drm_gem_vm_open(struct vm_area_struct *vma);
1466void drm_gem_vm_close(struct vm_area_struct *vma); 1466void drm_gem_vm_close(struct vm_area_struct *vma);
1467int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 1467int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -1496,7 +1496,7 @@ static inline void
1496drm_gem_object_handle_reference(struct drm_gem_object *obj) 1496drm_gem_object_handle_reference(struct drm_gem_object *obj)
1497{ 1497{
1498 drm_gem_object_reference(obj); 1498 drm_gem_object_reference(obj);
1499 kref_get(&obj->handlecount); 1499 atomic_inc(&obj->handle_count);
1500} 1500}
1501 1501
1502static inline void 1502static inline void
@@ -1505,12 +1505,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj)
1505 if (obj == NULL) 1505 if (obj == NULL)
1506 return; 1506 return;
1507 1507
1508 if (atomic_read(&obj->handle_count) == 0)
1509 return;
1508 /* 1510 /*
1509 * Must bump handle count first as this may be the last 1511 * Must bump handle count first as this may be the last
1510 * ref, in which case the object would disappear before we 1512 * ref, in which case the object would disappear before we
1511 * checked for a name 1513 * checked for a name
1512 */ 1514 */
1513 kref_put(&obj->handlecount, drm_gem_object_handle_free); 1515 if (atomic_dec_and_test(&obj->handle_count))
1516 drm_gem_object_handle_free(obj);
1514 drm_gem_object_unreference(obj); 1517 drm_gem_object_unreference(obj);
1515} 1518}
1516 1519
@@ -1520,12 +1523,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
1520 if (obj == NULL) 1523 if (obj == NULL)
1521 return; 1524 return;
1522 1525
1526 if (atomic_read(&obj->handle_count) == 0)
1527 return;
1528
1523 /* 1529 /*
1524 * Must bump handle count first as this may be the last 1530 * Must bump handle count first as this may be the last
1525 * ref, in which case the object would disappear before we 1531 * ref, in which case the object would disappear before we
1526 * checked for a name 1532 * checked for a name
1527 */ 1533 */
1528 kref_put(&obj->handlecount, drm_gem_object_handle_free); 1534
1535 if (atomic_dec_and_test(&obj->handle_count))
1536 drm_gem_object_handle_free(obj);
1529 drm_gem_object_unreference_unlocked(obj); 1537 drm_gem_object_unreference_unlocked(obj);
1530} 1538}
1531 1539