summaryrefslogtreecommitdiff
path: root/bsd-core/drm_lock.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-09-19 15:55:58 -0700
committerEric Anholt <eric@anholt.net>2007-09-19 15:55:58 -0700
commit3d3a96ad4e5596187236898ca241515a21661b69 (patch)
tree89b2b0900cf02235741fa670e7947babc8959ebe /bsd-core/drm_lock.c
parent0055fd5c35306a6363b0414f7f2220b3d1c27ecc (diff)
parente349b58b4a6ebfe299720cb921039a600c145e65 (diff)
Merge branch 'origin' into bo-set-pin
Diffstat (limited to 'bsd-core/drm_lock.c')
-rw-r--r--bsd-core/drm_lock.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c
index 5acb13d3..fb86fc68 100644
--- a/bsd-core/drm_lock.c
+++ b/bsd-core/drm_lock.c
@@ -1,6 +1,3 @@
-/* lock.c -- IOCTLs for locking -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,25 @@
*
*/
+/** @file drm_lock.c
+ * Implementation of the ioctls and other support code for dealing with the
+ * hardware lock.
+ *
+ * The DRM hardware lock is a shared structure between the kernel and userland.
+ *
+ * On uncontended access where the new context was the last context, the
+ * client may take the lock without dropping down into the kernel, using atomic
+ * compare-and-set.
+ *
+ * If the client finds during compare-and-set that it was not the last owner
+ * of the lock, it calls the DRM lock ioctl, which may sleep waiting for the
+ * lock, and may have side-effects of kernel-managed context switching.
+ *
+ * When the client releases the lock, if the lock is marked as being contended
+ * by another client, then the DRM unlock ioctl is called so that the
+ * contending client may be woken up.
+ */
+
#include "drmP.h"
int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
@@ -157,6 +173,12 @@ int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv)
DRM_CURRENTPID, lock->context);
return EINVAL;
}
+ /* Check that the context unlock being requested actually matches
+ * who currently holds the lock.
+ */
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) != lock->context)
+ return EINVAL;
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);