aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-09-27 02:17:17 -0400
committerDave Airlie <airlied@redhat.com>2010-09-30 19:17:44 -0400
commit29d08b3efddca628b0360411ab2b85f7b1723f48 (patch)
treef89a8a3069ebe9828b8a08c4b123f52625bf0bc7 /include
parent130b9851933e6da636502cd85e1ba8f45f862e8c (diff)
drm/gem: handlecount isn't really a kref so don't make it one.
There were lots of places being inconsistent since handle count looked like a kref but it really wasn't. Fix this my just making handle count an atomic on the object, and have it increase the normal object kref. Now i915/radeon/nouveau drivers can drop the normal reference on userspace object creation, and have the handle hold it. This patch fixes a memory leak or corruption on unload, because the driver had no way of knowing if a handle had been actually added for this object, and the fbcon object needed to know this to clean itself up properly. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/drm/drmP.h18
1 files changed, 13 insertions, 5 deletions
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