From c1119b1b092527fbb6950d0b5e51e076ddb00f29 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Jul 2007 06:39:25 -0700 Subject: Replace filp in ioctl arguments with drm_file *file_priv. As a fallout, replace filp storage with file_priv storage for "unique identifier of a client" all over the DRM. There is a 1:1 mapping, so this should be a noop. This could be a minor performance improvement, as everything on Linux dereferenced filp to get file_priv anyway, while only the mmap ioctls went the other direction. --- bsd-core/drm_lock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'bsd-core/drm_lock.c') diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index d0e61d3a..54b64806 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -66,7 +66,7 @@ int drm_lock_transfer(drm_device_t *dev, { unsigned int old, new; - dev->lock.filp = NULL; + dev->lock.file_priv = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -80,7 +80,7 @@ int drm_lock_free(drm_device_t *dev, { unsigned int old, new; - dev->lock.filp = NULL; + dev->lock.file_priv = NULL; do { old = *lock; new = 0; @@ -118,7 +118,7 @@ int drm_lock(DRM_IOCTL_ARGS) DRM_LOCK(); for (;;) { if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { - dev->lock.filp = (void *)(uintptr_t)DRM_CURRENTPID; + dev->lock.file_priv = file_priv; dev->lock.lock_time = jiffies; atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); break; /* Got lock */ -- cgit v1.2.3 From 5b38e134163cc375e91424c4688cc9328c6e9082 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:11:11 -0700 Subject: Replace DRM_IOCTL_ARGS with (dev, data, file_priv) and remove DRM_DEVICE. The data is now in kernel space, copied in/out as appropriate according to the This results in DRM_COPY_{TO,FROM}_USER going away, and error paths to deal with those failures. This also means that XFree86 4.2.0 support for i810 DRM is lost. --- bsd-core/drm_lock.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'bsd-core/drm_lock.c') diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 54b64806..5acb13d3 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -95,29 +95,27 @@ int drm_lock_free(drm_device_t *dev, return 0; } -int drm_lock(DRM_IOCTL_ARGS) +int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_lock_t lock; + drm_lock_t *lock = data; int ret = 0; - DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock)); - - if (lock.context == DRM_KERNEL_CONTEXT) { + if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", - DRM_CURRENTPID, lock.context); + DRM_CURRENTPID, lock->context); return EINVAL; } DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags); + lock->context, DRM_CURRENTPID, dev->lock.hw_lock->lock, + lock->flags); - if (dev->driver.use_dma_queue && lock.context < 0) + if (dev->driver.use_dma_queue && lock->context < 0) return EINVAL; DRM_LOCK(); for (;;) { - if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { + if (drm_lock_take(&dev->lock.hw_lock->lock, lock->context)) { dev->lock.file_priv = file_priv; dev->lock.lock_time = jiffies; atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); @@ -136,7 +134,7 @@ int drm_lock(DRM_IOCTL_ARGS) break; } DRM_UNLOCK(); - DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + DRM_DEBUG("%d %s\n", lock->context, ret ? "interrupted" : "has lock"); if (ret != 0) return ret; @@ -144,22 +142,19 @@ int drm_lock(DRM_IOCTL_ARGS) /* XXX: Add signal blocking here */ if (dev->driver.dma_quiescent != NULL && - (lock.flags & _DRM_LOCK_QUIESCENT)) + (lock->flags & _DRM_LOCK_QUIESCENT)) dev->driver.dma_quiescent(dev); return 0; } -int drm_unlock(DRM_IOCTL_ARGS) +int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_lock_t lock; - - DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock)); + drm_lock_t *lock = data; - if (lock.context == DRM_KERNEL_CONTEXT) { + if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", - DRM_CURRENTPID, lock.context); + DRM_CURRENTPID, lock->context); return EINVAL; } -- cgit v1.2.3 From 5346fc5f36b5e7c55fc7b5cd46f1e4d7563a86a4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Aug 2007 14:41:24 -0700 Subject: BSD: Replace brief description in each file's first line with doxygen later on. The brief descriptions usually had the wrong filename in them. --- bsd-core/drm_lock.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'bsd-core/drm_lock.c') diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 5acb13d3..326c083b 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) -- cgit v1.2.3 From 6e93c35ba7c5001e756d0c9d1a4f534384652a5a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 15 Aug 2007 13:42:04 -0700 Subject: BSD: Return EINVAL if drm_unlock is called on an unheld or other-owner lock. --- bsd-core/drm_lock.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'bsd-core/drm_lock.c') diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 326c083b..fb86fc68 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -173,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]); -- cgit v1.2.3