diff options
Diffstat (limited to 'include/drm/drmP.h')
-rw-r--r-- | include/drm/drmP.h | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2a512bc0d4ab..4c9461a4f9e6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -305,14 +305,16 @@ struct drm_ioctl_desc { | |||
305 | unsigned int cmd; | 305 | unsigned int cmd; |
306 | int flags; | 306 | int flags; |
307 | drm_ioctl_t *func; | 307 | drm_ioctl_t *func; |
308 | unsigned int cmd_drv; | ||
308 | }; | 309 | }; |
309 | 310 | ||
310 | /** | 311 | /** |
311 | * Creates a driver or general drm_ioctl_desc array entry for the given | 312 | * Creates a driver or general drm_ioctl_desc array entry for the given |
312 | * ioctl, for use by drm_ioctl(). | 313 | * ioctl, for use by drm_ioctl(). |
313 | */ | 314 | */ |
314 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | 315 | |
315 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags} | 316 | #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ |
317 | [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl} | ||
316 | 318 | ||
317 | struct drm_magic_entry { | 319 | struct drm_magic_entry { |
318 | struct list_head head; | 320 | struct list_head head; |
@@ -610,7 +612,7 @@ struct drm_gem_object { | |||
610 | struct kref refcount; | 612 | struct kref refcount; |
611 | 613 | ||
612 | /** Handle count of this object. Each handle also holds a reference */ | 614 | /** Handle count of this object. Each handle also holds a reference */ |
613 | struct kref handlecount; | 615 | atomic_t handle_count; /* number of handles on this object */ |
614 | 616 | ||
615 | /** Related drm device */ | 617 | /** Related drm device */ |
616 | struct drm_device *dev; | 618 | struct drm_device *dev; |
@@ -806,7 +808,6 @@ struct drm_driver { | |||
806 | */ | 808 | */ |
807 | int (*gem_init_object) (struct drm_gem_object *obj); | 809 | int (*gem_init_object) (struct drm_gem_object *obj); |
808 | void (*gem_free_object) (struct drm_gem_object *obj); | 810 | void (*gem_free_object) (struct drm_gem_object *obj); |
809 | void (*gem_free_object_unlocked) (struct drm_gem_object *obj); | ||
810 | 811 | ||
811 | /* vga arb irq handler */ | 812 | /* vga arb irq handler */ |
812 | void (*vgaarb_irq)(struct drm_device *dev, bool state); | 813 | void (*vgaarb_irq)(struct drm_device *dev, bool state); |
@@ -1173,6 +1174,7 @@ extern int drm_release(struct inode *inode, struct file *filp); | |||
1173 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); | 1174 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); |
1174 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); | 1175 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); |
1175 | extern void drm_vm_open_locked(struct vm_area_struct *vma); | 1176 | extern void drm_vm_open_locked(struct vm_area_struct *vma); |
1177 | extern void drm_vm_close_locked(struct vm_area_struct *vma); | ||
1176 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); | 1178 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); |
1177 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); | 1179 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); |
1178 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); | 1180 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); |
@@ -1453,12 +1455,11 @@ int drm_gem_init(struct drm_device *dev); | |||
1453 | void drm_gem_destroy(struct drm_device *dev); | 1455 | void drm_gem_destroy(struct drm_device *dev); |
1454 | void drm_gem_object_release(struct drm_gem_object *obj); | 1456 | void drm_gem_object_release(struct drm_gem_object *obj); |
1455 | void drm_gem_object_free(struct kref *kref); | 1457 | void drm_gem_object_free(struct kref *kref); |
1456 | void drm_gem_object_free_unlocked(struct kref *kref); | ||
1457 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, | 1458 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, |
1458 | size_t size); | 1459 | size_t size); |
1459 | int drm_gem_object_init(struct drm_device *dev, | 1460 | int drm_gem_object_init(struct drm_device *dev, |
1460 | struct drm_gem_object *obj, size_t size); | 1461 | struct drm_gem_object *obj, size_t size); |
1461 | void drm_gem_object_handle_free(struct kref *kref); | 1462 | void drm_gem_object_handle_free(struct drm_gem_object *obj); |
1462 | void drm_gem_vm_open(struct vm_area_struct *vma); | 1463 | void drm_gem_vm_open(struct vm_area_struct *vma); |
1463 | void drm_gem_vm_close(struct vm_area_struct *vma); | 1464 | void drm_gem_vm_close(struct vm_area_struct *vma); |
1464 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); | 1465 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); |
@@ -1481,8 +1482,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj) | |||
1481 | static inline void | 1482 | static inline void |
1482 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) | 1483 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) |
1483 | { | 1484 | { |
1484 | if (obj != NULL) | 1485 | if (obj != NULL) { |
1485 | kref_put(&obj->refcount, drm_gem_object_free_unlocked); | 1486 | struct drm_device *dev = obj->dev; |
1487 | mutex_lock(&dev->struct_mutex); | ||
1488 | kref_put(&obj->refcount, drm_gem_object_free); | ||
1489 | mutex_unlock(&dev->struct_mutex); | ||
1490 | } | ||
1486 | } | 1491 | } |
1487 | 1492 | ||
1488 | int drm_gem_handle_create(struct drm_file *file_priv, | 1493 | int drm_gem_handle_create(struct drm_file *file_priv, |
@@ -1493,7 +1498,7 @@ static inline void | |||
1493 | drm_gem_object_handle_reference(struct drm_gem_object *obj) | 1498 | drm_gem_object_handle_reference(struct drm_gem_object *obj) |
1494 | { | 1499 | { |
1495 | drm_gem_object_reference(obj); | 1500 | drm_gem_object_reference(obj); |
1496 | kref_get(&obj->handlecount); | 1501 | atomic_inc(&obj->handle_count); |
1497 | } | 1502 | } |
1498 | 1503 | ||
1499 | static inline void | 1504 | static inline void |
@@ -1502,12 +1507,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) | |||
1502 | if (obj == NULL) | 1507 | if (obj == NULL) |
1503 | return; | 1508 | return; |
1504 | 1509 | ||
1510 | if (atomic_read(&obj->handle_count) == 0) | ||
1511 | return; | ||
1505 | /* | 1512 | /* |
1506 | * Must bump handle count first as this may be the last | 1513 | * Must bump handle count first as this may be the last |
1507 | * ref, in which case the object would disappear before we | 1514 | * ref, in which case the object would disappear before we |
1508 | * checked for a name | 1515 | * checked for a name |
1509 | */ | 1516 | */ |
1510 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1517 | if (atomic_dec_and_test(&obj->handle_count)) |
1518 | drm_gem_object_handle_free(obj); | ||
1511 | drm_gem_object_unreference(obj); | 1519 | drm_gem_object_unreference(obj); |
1512 | } | 1520 | } |
1513 | 1521 | ||
@@ -1517,12 +1525,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | |||
1517 | if (obj == NULL) | 1525 | if (obj == NULL) |
1518 | return; | 1526 | return; |
1519 | 1527 | ||
1528 | if (atomic_read(&obj->handle_count) == 0) | ||
1529 | return; | ||
1530 | |||
1520 | /* | 1531 | /* |
1521 | * Must bump handle count first as this may be the last | 1532 | * Must bump handle count first as this may be the last |
1522 | * ref, in which case the object would disappear before we | 1533 | * ref, in which case the object would disappear before we |
1523 | * checked for a name | 1534 | * checked for a name |
1524 | */ | 1535 | */ |
1525 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1536 | |
1537 | if (atomic_dec_and_test(&obj->handle_count)) | ||
1538 | drm_gem_object_handle_free(obj); | ||
1526 | drm_gem_object_unreference_unlocked(obj); | 1539 | drm_gem_object_unreference_unlocked(obj); |
1527 | } | 1540 | } |
1528 | 1541 | ||