diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2007-03-22 22:28:33 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-03-22 22:28:33 -0400 |
commit | 040ac32048d5efabd557c1e0a6ab8aec2c710c56 (patch) | |
tree | ba714a33105695c7d57ff833dbd18875ddb82492 /drivers/char/drm/drmP.h | |
parent | 4b560fde06aeb342f3ff0bce924627ab722d251a (diff) |
drm: fix driver deadlock with AIGLX and reclaim_buffers_locked
Bugzilla Bug #9457
Add refcounting of user waiters to the DRM hardware lock, so that we can use
DRM_LOCK_CONT flag more conservatively.
Also add a kernel waiter refcount that if nonzero transfers the lock for the
kernel context when it is released. This is useful when waiting for idle and can be used for very simple fence object driver implementations for the new memory manager
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/drmP.h')
-rw-r--r-- | drivers/char/drm/drmP.h | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 09705da8cdd7..80041d5b792d 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -414,6 +414,10 @@ typedef struct drm_lock_data { | |||
414 | struct file *filp; /**< File descr of lock holder (0=kernel) */ | 414 | struct file *filp; /**< File descr of lock holder (0=kernel) */ |
415 | wait_queue_head_t lock_queue; /**< Queue of blocked processes */ | 415 | wait_queue_head_t lock_queue; /**< Queue of blocked processes */ |
416 | unsigned long lock_time; /**< Time of last lock in jiffies */ | 416 | unsigned long lock_time; /**< Time of last lock in jiffies */ |
417 | spinlock_t spinlock; | ||
418 | uint32_t kernel_waiters; | ||
419 | uint32_t user_waiters; | ||
420 | int idle_has_lock; | ||
417 | } drm_lock_data_t; | 421 | } drm_lock_data_t; |
418 | 422 | ||
419 | /** | 423 | /** |
@@ -590,6 +594,8 @@ struct drm_driver { | |||
590 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); | 594 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); |
591 | void (*reclaim_buffers_locked) (struct drm_device *dev, | 595 | void (*reclaim_buffers_locked) (struct drm_device *dev, |
592 | struct file *filp); | 596 | struct file *filp); |
597 | void (*reclaim_buffers_idlelocked) (struct drm_device *dev, | ||
598 | struct file * filp); | ||
593 | unsigned long (*get_map_ofs) (drm_map_t * map); | 599 | unsigned long (*get_map_ofs) (drm_map_t * map); |
594 | unsigned long (*get_reg_ofs) (struct drm_device * dev); | 600 | unsigned long (*get_reg_ofs) (struct drm_device * dev); |
595 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); | 601 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); |
@@ -915,9 +921,18 @@ extern int drm_lock(struct inode *inode, struct file *filp, | |||
915 | unsigned int cmd, unsigned long arg); | 921 | unsigned int cmd, unsigned long arg); |
916 | extern int drm_unlock(struct inode *inode, struct file *filp, | 922 | extern int drm_unlock(struct inode *inode, struct file *filp, |
917 | unsigned int cmd, unsigned long arg); | 923 | unsigned int cmd, unsigned long arg); |
918 | extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); | 924 | extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context); |
919 | extern int drm_lock_free(drm_device_t * dev, | 925 | extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context); |
920 | __volatile__ unsigned int *lock, unsigned int context); | 926 | extern void drm_idlelock_take(drm_lock_data_t *lock_data); |
927 | extern void drm_idlelock_release(drm_lock_data_t *lock_data); | ||
928 | |||
929 | /* | ||
930 | * These are exported to drivers so that they can implement fencing using | ||
931 | * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. | ||
932 | */ | ||
933 | |||
934 | extern int drm_i_have_hw_lock(struct file *filp); | ||
935 | extern int drm_kernel_take_hw_lock(struct file *filp); | ||
921 | 936 | ||
922 | /* Buffer management support (drm_bufs.h) */ | 937 | /* Buffer management support (drm_bufs.h) */ |
923 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); | 938 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); |