36 #include <linux/export.h>
39 static int drm_notifier(
void *
priv);
41 static int drm_lock_take(
struct drm_lock_data *lock_data,
unsigned int context);
58 struct drm_master *master = file_priv->master;
61 ++file_priv->lock_count;
63 if (lock->
context == DRM_KERNEL_CONTEXT) {
64 DRM_ERROR(
"Process %d using kernel context %d\n",
69 DRM_DEBUG(
"%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
71 master->lock.hw_lock->lock, lock->
flags);
74 spin_lock_bh(&master->lock.spinlock);
75 master->lock.user_waiters++;
76 spin_unlock_bh(&master->lock.spinlock);
80 if (!master->lock.hw_lock) {
86 if (drm_lock_take(&master->lock, lock->
context)) {
87 master->lock.file_priv = file_priv;
88 master->lock.lock_time =
jiffies;
102 spin_lock_bh(&master->lock.spinlock);
103 master->lock.user_waiters--;
104 spin_unlock_bh(&master->lock.spinlock);
108 DRM_DEBUG(
"%d %s\n", lock->
context,
109 ret ?
"interrupted" :
"has lock");
115 if (!file_priv->is_master) {
116 sigemptyset(&dev->sigmask);
117 sigaddset(&dev->sigmask,
SIGSTOP);
118 sigaddset(&dev->sigmask,
SIGTSTP);
119 sigaddset(&dev->sigmask,
SIGTTIN);
120 sigaddset(&dev->sigmask,
SIGTTOU);
121 dev->sigdata.context = lock->
context;
122 dev->sigdata.lock = master->lock.hw_lock;
128 if (dev->driver->dma_quiescent(dev)) {
129 DRM_DEBUG(
"%d waiting for DMA quiescent\n",
152 struct drm_master *master = file_priv->master;
154 if (lock->
context == DRM_KERNEL_CONTEXT) {
155 DRM_ERROR(
"Process %d using kernel context %d\n",
180 int drm_lock_take(
struct drm_lock_data *lock_data,
183 unsigned int old,
new,
prev;
184 volatile unsigned int *
lock = &lock_data->hw_lock->lock;
186 spin_lock_bh(&lock_data->spinlock);
192 new = context | _DRM_LOCK_HELD |
193 ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ?
196 prev =
cmpxchg(lock, old,
new);
197 }
while (prev != old);
198 spin_unlock_bh(&lock_data->spinlock);
202 if (context != DRM_KERNEL_CONTEXT) {
203 DRM_ERROR(
"%d holds heavyweight lock\n",
229 static int drm_lock_transfer(
struct drm_lock_data *lock_data,
230 unsigned int context)
232 unsigned int old,
new,
prev;
233 volatile unsigned int *lock = &lock_data->hw_lock->lock;
235 lock_data->file_priv =
NULL;
239 prev =
cmpxchg(lock, old,
new);
240 }
while (prev != old);
257 unsigned int old,
new,
prev;
258 volatile unsigned int *lock = &lock_data->hw_lock->lock;
260 spin_lock_bh(&lock_data->spinlock);
261 if (lock_data->kernel_waiters != 0) {
262 drm_lock_transfer(lock_data, 0);
263 lock_data->idle_has_lock = 1;
264 spin_unlock_bh(&lock_data->spinlock);
267 spin_unlock_bh(&lock_data->spinlock);
272 prev =
cmpxchg(lock, old,
new);
273 }
while (prev != old);
276 DRM_ERROR(
"%d freed heavyweight lock held by %d\n",
295 static int drm_notifier(
void *
priv)
297 struct drm_sigdata *
s = (
struct drm_sigdata *) priv;
298 unsigned int old,
new,
prev;
310 prev =
cmpxchg(&s->lock->lock, old,
new);
311 }
while (prev != old);
332 spin_lock_bh(&lock_data->spinlock);
333 lock_data->kernel_waiters++;
334 if (!lock_data->idle_has_lock) {
336 spin_unlock_bh(&lock_data->spinlock);
337 ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT);
338 spin_lock_bh(&lock_data->spinlock);
341 lock_data->idle_has_lock = 1;
343 spin_unlock_bh(&lock_data->spinlock);
349 unsigned int old,
prev;
350 volatile unsigned int *lock = &lock_data->hw_lock->lock;
352 spin_lock_bh(&lock_data->spinlock);
353 if (--lock_data->kernel_waiters == 0) {
354 if (lock_data->idle_has_lock) {
357 prev =
cmpxchg(lock, old, DRM_KERNEL_CONTEXT);
358 }
while (prev != old);
360 lock_data->idle_has_lock = 0;
363 spin_unlock_bh(&lock_data->spinlock);
369 struct drm_master *master = file_priv->master;
370 return (file_priv->lock_count && master->lock.hw_lock &&
372 master->lock.file_priv == file_priv);