aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_lock.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-27 23:22:24 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:22 -0500
commit7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch)
tree1b5debcc86ff20bd5e11b42ea5c52da42214e376 /drivers/gpu/drm/drm_lock.c
parente7f7ab45ebcb54fd5f814ea15ea079e079662f67 (diff)
drm: move to kref per-master structures.
This is step one towards having multiple masters sharing a drm device in order to get fast-user-switching to work. It splits out the information associated with the drm master into a separate kref counted structure, and allocates this when a master opens the device node. It also allows the current master to abdicate (say while VT switched), and a new master to take over the hardware. It moves the Intel and radeon drivers to using the sarea from within the new master structures. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_lock.c')
-rw-r--r--drivers/gpu/drm/drm_lock.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 1cfa72031f8f..46e7b28f0707 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -52,6 +52,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
52{ 52{
53 DECLARE_WAITQUEUE(entry, current); 53 DECLARE_WAITQUEUE(entry, current);
54 struct drm_lock *lock = data; 54 struct drm_lock *lock = data;
55 struct drm_master *master = file_priv->master;
55 int ret = 0; 56 int ret = 0;
56 57
57 ++file_priv->lock_count; 58 ++file_priv->lock_count;
@@ -64,26 +65,27 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
64 65
65 DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", 66 DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
66 lock->context, task_pid_nr(current), 67 lock->context, task_pid_nr(current),
67 dev->lock.hw_lock->lock, lock->flags); 68 master->lock.hw_lock->lock, lock->flags);
68 69
69 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) 70 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
70 if (lock->context < 0) 71 if (lock->context < 0)
71 return -EINVAL; 72 return -EINVAL;
72 73
73 add_wait_queue(&dev->lock.lock_queue, &entry); 74 add_wait_queue(&master->lock.lock_queue, &entry);
74 spin_lock_bh(&dev->lock.spinlock); 75 spin_lock_bh(&master->lock.spinlock);
75 dev->lock.user_waiters++; 76 master->lock.user_waiters++;
76 spin_unlock_bh(&dev->lock.spinlock); 77 spin_unlock_bh(&master->lock.spinlock);
78
77 for (;;) { 79 for (;;) {
78 __set_current_state(TASK_INTERRUPTIBLE); 80 __set_current_state(TASK_INTERRUPTIBLE);
79 if (!dev->lock.hw_lock) { 81 if (!master->lock.hw_lock) {
80 /* Device has been unregistered */ 82 /* Device has been unregistered */
81 ret = -EINTR; 83 ret = -EINTR;
82 break; 84 break;
83 } 85 }
84 if (drm_lock_take(&dev->lock, lock->context)) { 86 if (drm_lock_take(&master->lock, lock->context)) {
85 dev->lock.file_priv = file_priv; 87 master->lock.file_priv = file_priv;
86 dev->lock.lock_time = jiffies; 88 master->lock.lock_time = jiffies;
87 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); 89 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
88 break; /* Got lock */ 90 break; /* Got lock */
89 } 91 }
@@ -95,11 +97,11 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
95 break; 97 break;
96 } 98 }
97 } 99 }
98 spin_lock_bh(&dev->lock.spinlock); 100 spin_lock_bh(&master->lock.spinlock);
99 dev->lock.user_waiters--; 101 master->lock.user_waiters--;
100 spin_unlock_bh(&dev->lock.spinlock); 102 spin_unlock_bh(&master->lock.spinlock);
101 __set_current_state(TASK_RUNNING); 103 __set_current_state(TASK_RUNNING);
102 remove_wait_queue(&dev->lock.lock_queue, &entry); 104 remove_wait_queue(&master->lock.lock_queue, &entry);
103 105
104 DRM_DEBUG("%d %s\n", lock->context, 106 DRM_DEBUG("%d %s\n", lock->context,
105 ret ? "interrupted" : "has lock"); 107 ret ? "interrupted" : "has lock");
@@ -108,14 +110,14 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
108 /* don't set the block all signals on the master process for now 110 /* don't set the block all signals on the master process for now
109 * really probably not the correct answer but lets us debug xkb 111 * really probably not the correct answer but lets us debug xkb
110 * xserver for now */ 112 * xserver for now */
111 if (!file_priv->master) { 113 if (!file_priv->is_master) {
112 sigemptyset(&dev->sigmask); 114 sigemptyset(&dev->sigmask);
113 sigaddset(&dev->sigmask, SIGSTOP); 115 sigaddset(&dev->sigmask, SIGSTOP);
114 sigaddset(&dev->sigmask, SIGTSTP); 116 sigaddset(&dev->sigmask, SIGTSTP);
115 sigaddset(&dev->sigmask, SIGTTIN); 117 sigaddset(&dev->sigmask, SIGTTIN);
116 sigaddset(&dev->sigmask, SIGTTOU); 118 sigaddset(&dev->sigmask, SIGTTOU);
117 dev->sigdata.context = lock->context; 119 dev->sigdata.context = lock->context;
118 dev->sigdata.lock = dev->lock.hw_lock; 120 dev->sigdata.lock = master->lock.hw_lock;
119 block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); 121 block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
120 } 122 }
121 123
@@ -154,6 +156,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
154int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) 156int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
155{ 157{
156 struct drm_lock *lock = data; 158 struct drm_lock *lock = data;
159 struct drm_master *master = file_priv->master;
157 160
158 if (lock->context == DRM_KERNEL_CONTEXT) { 161 if (lock->context == DRM_KERNEL_CONTEXT) {
159 DRM_ERROR("Process %d using kernel context %d\n", 162 DRM_ERROR("Process %d using kernel context %d\n",
@@ -169,7 +172,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
169 if (dev->driver->kernel_context_switch_unlock) 172 if (dev->driver->kernel_context_switch_unlock)
170 dev->driver->kernel_context_switch_unlock(dev); 173 dev->driver->kernel_context_switch_unlock(dev);
171 else { 174 else {
172 if (drm_lock_free(&dev->lock,lock->context)) { 175 if (drm_lock_free(&master->lock, lock->context)) {
173 /* FIXME: Should really bail out here. */ 176 /* FIXME: Should really bail out here. */
174 } 177 }
175 } 178 }
@@ -379,9 +382,10 @@ EXPORT_SYMBOL(drm_idlelock_release);
379 382
380int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) 383int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv)
381{ 384{
382 return (file_priv->lock_count && dev->lock.hw_lock && 385 struct drm_master *master = file_priv->master;
383 _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && 386 return (file_priv->lock_count && master->lock.hw_lock &&
384 dev->lock.file_priv == file_priv); 387 _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) &&
388 master->lock.file_priv == file_priv);
385} 389}
386 390
387EXPORT_SYMBOL(drm_i_have_hw_lock); 391EXPORT_SYMBOL(drm_i_have_hw_lock);