aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drmP.h
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2007-03-22 22:28:33 -0400
committerDave Airlie <airlied@linux.ie>2007-03-22 22:28:33 -0400
commit040ac32048d5efabd557c1e0a6ab8aec2c710c56 (patch)
treeba714a33105695c7d57ff833dbd18875ddb82492 /drivers/char/drm/drmP.h
parent4b560fde06aeb342f3ff0bce924627ab722d251a (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.h21
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);
916extern int drm_unlock(struct inode *inode, struct file *filp, 922extern int drm_unlock(struct inode *inode, struct file *filp,
917 unsigned int cmd, unsigned long arg); 923 unsigned int cmd, unsigned long arg);
918extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); 924extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context);
919extern int drm_lock_free(drm_device_t * dev, 925extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context);
920 __volatile__ unsigned int *lock, unsigned int context); 926extern void drm_idlelock_take(drm_lock_data_t *lock_data);
927extern 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
934extern int drm_i_have_hw_lock(struct file *filp);
935extern 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) */
923extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); 938extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);