[PATCH] drm/ttm: move ttm_lock.c to drm/vmwgfx

Daniel Vetter daniel.vetter at ffwll.ch
Fri Dec 14 10:50:52 PST 2012


Dude, you're seriously overshooting here. This patch isn't required
_at_ _all_ to do cross device sharing/reservations/whatever. We've
simply discussed TTM documentation in the context of Maartens work,
and I've suggested to include all the TTM kerneldoc into a nice
DocBook. That way the kerneldoc stuff gets at least check for correct
parameters and similar trivial stuff (core drm sucked royally in that
regard). So Maarten jabbed around, I and Dave joined in and since
besides vmwgfx nothing else uses it at all I've figured this can't
hurt.

If you think all the radeon/nouveau/i915/whatever drivers are screwed
up beyond repair and need to have the ttm_lock.c file where it is as a
stern reminder, I don't care one bit. Personally I think the right
solution is to abolish the drm master concept entirely and aim for
CONFIG_VT=n. Insulation is a userspace problem which e.g. policykit or
whatever the latest thing is can do, or which should be solved for
real with per-process address spaces. Everything else smells too fishy
for me. So yeah, I don't think the fact that vmwgfx is the only driver
with a ->set_master and ->drop_master callback is a good sign, but
alas, not my driver and the core impact is negligible.

Cheers, Daniel

On Fri, Dec 14, 2012 at 4:51 PM, Thomas Hellström <thomas at shipmail.org> wrote:
> Nack,
>
> I'm not against moving the TTM lock away,
> when a replacement strategy for the main use case is presented.
>
> but using wording like "unholy", "scares" just because there is a lack of
> understanding or because it gets in the way of implementing cross-device
> reservation is a really really bad idea, and FWIW I think it's an even
> better idea to refrain from such wording unless you completely understand
> the problem and have a better solution in place.
>
> No other driver uses it, probably simply because the driver writers probably
> aren't aware of the use cases or don't implement parallel command
> submission.
>
> And if it weren't for the TTM lock, the cross device work wouldn't have to
> consider the case where a client
> needs to lock out other reservers, and the cross-device design would suffer.
>
> The main use cases are:
>
> 1) If we change master, clients of other masters need to be locked out from
> claiming memory resources (particularly VRAM).
> 2) If we're about to suspend and have cleaned VRAM, client's need to be
> stopped from validating VRAM buffer objects.
> 3) If a client needs access to the complete video memory space or need to
> defragment, it needs to lock out other reservers in a parallell command
> submission environment
>
> Now, present a better solution to those use cases, and I'll ack this patch
> and implement that solution, or
> leave the TTM lock in place as a reminder that these things need to be
> considered, and that we should have a common solution to them.
>
> /Thomas
>
>
>
>
>
> On 12/10/12 11:26 AM, Daniel Vetter wrote:
>>
>> ... it's the only user. Also move the header fil there.
>>
>> <mlankhorst> but seriously, ttm_lock is best left undocumented since
>> nobody should use that unholy thing..
>> <danvet> agreed ;-)
>> <danvet> imo we should shovel that under drm/vmwgfx ...
>> <airlied> amen
>> <airlied> that thing scares me
>> <danvet> out of sight, out of mind ...
>>
>> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
>> ---
>>   drivers/gpu/drm/ttm/Makefile        |    2 +-
>>   drivers/gpu/drm/ttm/ttm_lock.c      |  310
>> -----------------------------------
>>   drivers/gpu/drm/vmwgfx/Makefile     |    2 +-
>>   drivers/gpu/drm/vmwgfx/ttm_lock.c   |  310
>> +++++++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/vmwgfx/ttm_lock.h   |  247 ++++++++++++++++++++++++++++
>>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |    2 +-
>>   include/drm/ttm/ttm_lock.h          |  247 ----------------------------
>>   7 files changed, 560 insertions(+), 560 deletions(-)
>>   delete mode 100644 drivers/gpu/drm/ttm/ttm_lock.c
>>   create mode 100644 drivers/gpu/drm/vmwgfx/ttm_lock.c
>>   create mode 100644 drivers/gpu/drm/vmwgfx/ttm_lock.h
>>   delete mode 100644 include/drm/ttm/ttm_lock.h
>>
>> diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile
>> index b2b33dd..607a0b6 100644
>> --- a/drivers/gpu/drm/ttm/Makefile
>> +++ b/drivers/gpu/drm/ttm/Makefile
>> @@ -4,7 +4,7 @@
>>   ccflags-y := -Iinclude/drm
>>   ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \
>>         ttm_bo_util.o ttm_bo_vm.o ttm_module.o \
>> -       ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o \
>> +       ttm_object.o ttm_execbuf_util.o ttm_page_alloc.o \
>>         ttm_bo_manager.o
>>     ifeq ($(CONFIG_SWIOTLB),y)
>> diff --git a/drivers/gpu/drm/ttm/ttm_lock.c
>> b/drivers/gpu/drm/ttm/ttm_lock.c
>> deleted file mode 100644
>> index 3daa9a3..0000000
>> --- a/drivers/gpu/drm/ttm/ttm_lock.c
>> +++ /dev/null
>> @@ -1,310 +0,0 @@
>>
>> -/**************************************************************************
>> - *
>> - * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
>> - * All Rights Reserved.
>> - *
>> - * Permission is hereby granted, free of charge, to any person obtaining
>> a
>> - * copy of this software and associated documentation files (the
>> - * "Software"), to deal in the Software without restriction, including
>> - * without limitation the rights to use, copy, modify, merge, publish,
>> - * distribute, sub license, and/or sell copies of the Software, and to
>> - * permit persons to whom the Software is furnished to do so, subject to
>> - * the following conditions:
>> - *
>> - * The above copyright notice and this permission notice (including the
>> - * next paragraph) shall be included in all copies or substantial
>> portions
>> - * of the Software.
>> - *
>> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> EXPRESS OR
>> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> MERCHANTABILITY,
>> - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT
>> SHALL
>> - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
>> CLAIM,
>> - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
>> - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
>> THE
>> - * USE OR OTHER DEALINGS IN THE SOFTWARE.
>> - *
>> -
>> **************************************************************************/
>> -/*
>> - * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
>> - */
>> -
>> -#include <drm/ttm/ttm_lock.h>
>> -#include <drm/ttm/ttm_module.h>
>> -#include <linux/atomic.h>
>> -#include <linux/errno.h>
>> -#include <linux/wait.h>
>> -#include <linux/sched.h>
>> -#include <linux/module.h>
>> -
>> -#define TTM_WRITE_LOCK_PENDING    (1 << 0)
>> -#define TTM_VT_LOCK_PENDING       (1 << 1)
>> -#define TTM_SUSPEND_LOCK_PENDING  (1 << 2)
>> -#define TTM_VT_LOCK               (1 << 3)
>> -#define TTM_SUSPEND_LOCK          (1 << 4)
>> -
>> -void ttm_lock_init(struct ttm_lock *lock)
>> -{
>> -       spin_lock_init(&lock->lock);
>> -       init_waitqueue_head(&lock->queue);
>> -       lock->rw = 0;
>> -       lock->flags = 0;
>> -       lock->kill_takers = false;
>> -       lock->signal = SIGKILL;
>> -}
>> -EXPORT_SYMBOL(ttm_lock_init);
>> -
>> -void ttm_read_unlock(struct ttm_lock *lock)
>> -{
>> -       spin_lock(&lock->lock);
>> -       if (--lock->rw == 0)
>> -               wake_up_all(&lock->queue);
>> -       spin_unlock(&lock->lock);
>> -}
>> -EXPORT_SYMBOL(ttm_read_unlock);
>> -
>> -static bool __ttm_read_lock(struct ttm_lock *lock)
>> -{
>> -       bool locked = false;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (unlikely(lock->kill_takers)) {
>> -               send_sig(lock->signal, current, 0);
>> -               spin_unlock(&lock->lock);
>> -               return false;
>> -       }
>> -       if (lock->rw >= 0 && lock->flags == 0) {
>> -               ++lock->rw;
>> -               locked = true;
>> -       }
>> -       spin_unlock(&lock->lock);
>> -       return locked;
>> -}
>> -
>> -int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
>> -{
>> -       int ret = 0;
>> -
>> -       if (interruptible)
>> -               ret = wait_event_interruptible(lock->queue,
>> -                                              __ttm_read_lock(lock));
>> -       else
>> -               wait_event(lock->queue, __ttm_read_lock(lock));
>> -       return ret;
>> -}
>> -EXPORT_SYMBOL(ttm_read_lock);
>> -
>> -static bool __ttm_read_trylock(struct ttm_lock *lock, bool *locked)
>> -{
>> -       bool block = true;
>> -
>> -       *locked = false;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (unlikely(lock->kill_takers)) {
>> -               send_sig(lock->signal, current, 0);
>> -               spin_unlock(&lock->lock);
>> -               return false;
>> -       }
>> -       if (lock->rw >= 0 && lock->flags == 0) {
>> -               ++lock->rw;
>> -               block = false;
>> -               *locked = true;
>> -       } else if (lock->flags == 0) {
>> -               block = false;
>> -       }
>> -       spin_unlock(&lock->lock);
>> -
>> -       return !block;
>> -}
>> -
>> -int ttm_read_trylock(struct ttm_lock *lock, bool interruptible)
>> -{
>> -       int ret = 0;
>> -       bool locked;
>> -
>> -       if (interruptible)
>> -               ret = wait_event_interruptible
>> -                       (lock->queue, __ttm_read_trylock(lock, &locked));
>> -       else
>> -               wait_event(lock->queue, __ttm_read_trylock(lock,
>> &locked));
>> -
>> -       if (unlikely(ret != 0)) {
>> -               BUG_ON(locked);
>> -               return ret;
>> -       }
>> -
>> -       return (locked) ? 0 : -EBUSY;
>> -}
>> -
>> -void ttm_write_unlock(struct ttm_lock *lock)
>> -{
>> -       spin_lock(&lock->lock);
>> -       lock->rw = 0;
>> -       wake_up_all(&lock->queue);
>> -       spin_unlock(&lock->lock);
>> -}
>> -EXPORT_SYMBOL(ttm_write_unlock);
>> -
>> -static bool __ttm_write_lock(struct ttm_lock *lock)
>> -{
>> -       bool locked = false;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (unlikely(lock->kill_takers)) {
>> -               send_sig(lock->signal, current, 0);
>> -               spin_unlock(&lock->lock);
>> -               return false;
>> -       }
>> -       if (lock->rw == 0 && ((lock->flags & ~TTM_WRITE_LOCK_PENDING) ==
>> 0)) {
>> -               lock->rw = -1;
>> -               lock->flags &= ~TTM_WRITE_LOCK_PENDING;
>> -               locked = true;
>> -       } else {
>> -               lock->flags |= TTM_WRITE_LOCK_PENDING;
>> -       }
>> -       spin_unlock(&lock->lock);
>> -       return locked;
>> -}
>> -
>> -int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
>> -{
>> -       int ret = 0;
>> -
>> -       if (interruptible) {
>> -               ret = wait_event_interruptible(lock->queue,
>> -                                              __ttm_write_lock(lock));
>> -               if (unlikely(ret != 0)) {
>> -                       spin_lock(&lock->lock);
>> -                       lock->flags &= ~TTM_WRITE_LOCK_PENDING;
>> -                       wake_up_all(&lock->queue);
>> -                       spin_unlock(&lock->lock);
>> -               }
>> -       } else
>> -               wait_event(lock->queue, __ttm_read_lock(lock));
>> -
>> -       return ret;
>> -}
>> -EXPORT_SYMBOL(ttm_write_lock);
>> -
>> -void ttm_write_lock_downgrade(struct ttm_lock *lock)
>> -{
>> -       spin_lock(&lock->lock);
>> -       lock->rw = 1;
>> -       wake_up_all(&lock->queue);
>> -       spin_unlock(&lock->lock);
>> -}
>> -
>> -static int __ttm_vt_unlock(struct ttm_lock *lock)
>> -{
>> -       int ret = 0;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (unlikely(!(lock->flags & TTM_VT_LOCK)))
>> -               ret = -EINVAL;
>> -       lock->flags &= ~TTM_VT_LOCK;
>> -       wake_up_all(&lock->queue);
>> -       spin_unlock(&lock->lock);
>> -
>> -       return ret;
>> -}
>> -
>> -static void ttm_vt_lock_remove(struct ttm_base_object **p_base)
>> -{
>> -       struct ttm_base_object *base = *p_base;
>> -       struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
>> -       int ret;
>> -
>> -       *p_base = NULL;
>> -       ret = __ttm_vt_unlock(lock);
>> -       BUG_ON(ret != 0);
>> -}
>> -
>> -static bool __ttm_vt_lock(struct ttm_lock *lock)
>> -{
>> -       bool locked = false;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (lock->rw == 0) {
>> -               lock->flags &= ~TTM_VT_LOCK_PENDING;
>> -               lock->flags |= TTM_VT_LOCK;
>> -               locked = true;
>> -       } else {
>> -               lock->flags |= TTM_VT_LOCK_PENDING;
>> -       }
>> -       spin_unlock(&lock->lock);
>> -       return locked;
>> -}
>> -
>> -int ttm_vt_lock(struct ttm_lock *lock,
>> -               bool interruptible,
>> -               struct ttm_object_file *tfile)
>> -{
>> -       int ret = 0;
>> -
>> -       if (interruptible) {
>> -               ret = wait_event_interruptible(lock->queue,
>> -                                              __ttm_vt_lock(lock));
>> -               if (unlikely(ret != 0)) {
>> -                       spin_lock(&lock->lock);
>> -                       lock->flags &= ~TTM_VT_LOCK_PENDING;
>> -                       wake_up_all(&lock->queue);
>> -                       spin_unlock(&lock->lock);
>> -                       return ret;
>> -               }
>> -       } else
>> -               wait_event(lock->queue, __ttm_vt_lock(lock));
>> -
>> -       /*
>> -        * Add a base-object, the destructor of which will
>> -        * make sure the lock is released if the client dies
>> -        * while holding it.
>> -        */
>> -
>> -       ret = ttm_base_object_init(tfile, &lock->base, false,
>> -                                  ttm_lock_type, &ttm_vt_lock_remove,
>> NULL);
>> -       if (ret)
>> -               (void)__ttm_vt_unlock(lock);
>> -       else
>> -               lock->vt_holder = tfile;
>> -
>> -       return ret;
>> -}
>> -EXPORT_SYMBOL(ttm_vt_lock);
>> -
>> -int ttm_vt_unlock(struct ttm_lock *lock)
>> -{
>> -       return ttm_ref_object_base_unref(lock->vt_holder,
>> -                                        lock->base.hash.key,
>> TTM_REF_USAGE);
>> -}
>> -EXPORT_SYMBOL(ttm_vt_unlock);
>> -
>> -void ttm_suspend_unlock(struct ttm_lock *lock)
>> -{
>> -       spin_lock(&lock->lock);
>> -       lock->flags &= ~TTM_SUSPEND_LOCK;
>> -       wake_up_all(&lock->queue);
>> -       spin_unlock(&lock->lock);
>> -}
>> -EXPORT_SYMBOL(ttm_suspend_unlock);
>> -
>> -static bool __ttm_suspend_lock(struct ttm_lock *lock)
>> -{
>> -       bool locked = false;
>> -
>> -       spin_lock(&lock->lock);
>> -       if (lock->rw == 0) {
>> -               lock->flags &= ~TTM_SUSPEND_LOCK_PENDING;
>> -               lock->flags |= TTM_SUSPEND_LOCK;
>> -               locked = true;
>> -       } else {
>> -               lock->flags |= TTM_SUSPEND_LOCK_PENDING;
>> -       }
>> -       spin_unlock(&lock->lock);
>> -       return locked;
>> -}
>> -
>> -void ttm_suspend_lock(struct ttm_lock *lock)
>> -{
>> -       wait_event(lock->queue, __ttm_suspend_lock(lock));
>> -}
>> -EXPORT_SYMBOL(ttm_suspend_lock);
>> diff --git a/drivers/gpu/drm/vmwgfx/Makefile
>> b/drivers/gpu/drm/vmwgfx/Makefile
>> index 586869c..74bd973 100644
>> --- a/drivers/gpu/drm/vmwgfx/Makefile
>> +++ b/drivers/gpu/drm/vmwgfx/Makefile
>> @@ -5,6 +5,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o
>> vmwgfx_drv.o \
>>             vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \
>>             vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
>>             vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \
>> -           vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o
>> +           vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o ttm_lock.o
>>     obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
>> diff --git a/drivers/gpu/drm/vmwgfx/ttm_lock.c
>> b/drivers/gpu/drm/vmwgfx/ttm_lock.c
>> new file mode 100644
>> index 0000000..c859427
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vmwgfx/ttm_lock.c
>> @@ -0,0 +1,310 @@
>>
>> +/**************************************************************************
>> + *
>> + * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
>> + * All Rights Reserved.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining
>> a
>> + * copy of this software and associated documentation files (the
>> + * "Software"), to deal in the Software without restriction, including
>> + * without limitation the rights to use, copy, modify, merge, publish,
>> + * distribute, sub license, and/or sell copies of the Software, and to
>> + * permit persons to whom the Software is furnished to do so, subject to
>> + * the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including the
>> + * next paragraph) shall be included in all copies or substantial
>> portions
>> + * of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT
>> SHALL
>> + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
>> CLAIM,
>> + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
>> + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
>> THE
>> + * USE OR OTHER DEALINGS IN THE SOFTWARE.
>> + *
>> +
>> **************************************************************************/
>> +/*
>> + * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
>> + */
>> +
>> +#include "ttm_lock.h"
>> +#include <drm/ttm/ttm_module.h>
>> +#include <linux/atomic.h>
>> +#include <linux/errno.h>
>> +#include <linux/wait.h>
>> +#include <linux/sched.h>
>> +#include <linux/module.h>
>> +
>> +#define TTM_WRITE_LOCK_PENDING    (1 << 0)
>> +#define TTM_VT_LOCK_PENDING       (1 << 1)
>> +#define TTM_SUSPEND_LOCK_PENDING  (1 << 2)
>> +#define TTM_VT_LOCK               (1 << 3)
>> +#define TTM_SUSPEND_LOCK          (1 << 4)
>> +
>> +void ttm_lock_init(struct ttm_lock *lock)
>> +{
>> +       spin_lock_init(&lock->lock);
>> +       init_waitqueue_head(&lock->queue);
>> +       lock->rw = 0;
>> +       lock->flags = 0;
>> +       lock->kill_takers = false;
>> +       lock->signal = SIGKILL;
>> +}
>> +EXPORT_SYMBOL(ttm_lock_init);
>> +
>> +void ttm_read_unlock(struct ttm_lock *lock)
>> +{
>> +       spin_lock(&lock->lock);
>> +       if (--lock->rw == 0)
>> +               wake_up_all(&lock->queue);
>> +       spin_unlock(&lock->lock);
>> +}
>> +EXPORT_SYMBOL(ttm_read_unlock);
>> +
>> +static bool __ttm_read_lock(struct ttm_lock *lock)
>> +{
>> +       bool locked = false;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (unlikely(lock->kill_takers)) {
>> +               send_sig(lock->signal, current, 0);
>> +               spin_unlock(&lock->lock);
>> +               return false;
>> +       }
>> +       if (lock->rw >= 0 && lock->flags == 0) {
>> +               ++lock->rw;
>> +               locked = true;
>> +       }
>> +       spin_unlock(&lock->lock);
>> +       return locked;
>> +}
>> +
>> +int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
>> +{
>> +       int ret = 0;
>> +
>> +       if (interruptible)
>> +               ret = wait_event_interruptible(lock->queue,
>> +                                              __ttm_read_lock(lock));
>> +       else
>> +               wait_event(lock->queue, __ttm_read_lock(lock));
>> +       return ret;
>> +}
>> +EXPORT_SYMBOL(ttm_read_lock);
>> +
>> +static bool __ttm_read_trylock(struct ttm_lock *lock, bool *locked)
>> +{
>> +       bool block = true;
>> +
>> +       *locked = false;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (unlikely(lock->kill_takers)) {
>> +               send_sig(lock->signal, current, 0);
>> +               spin_unlock(&lock->lock);
>> +               return false;
>> +       }
>> +       if (lock->rw >= 0 && lock->flags == 0) {
>> +               ++lock->rw;
>> +               block = false;
>> +               *locked = true;
>> +       } else if (lock->flags == 0) {
>> +               block = false;
>> +       }
>> +       spin_unlock(&lock->lock);
>> +
>> +       return !block;
>> +}
>> +
>> +int ttm_read_trylock(struct ttm_lock *lock, bool interruptible)
>> +{
>> +       int ret = 0;
>> +       bool locked;
>> +
>> +       if (interruptible)
>> +               ret = wait_event_interruptible
>> +                       (lock->queue, __ttm_read_trylock(lock, &locked));
>> +       else
>> +               wait_event(lock->queue, __ttm_read_trylock(lock,
>> &locked));
>> +
>> +       if (unlikely(ret != 0)) {
>> +               BUG_ON(locked);
>> +               return ret;
>> +       }
>> +
>> +       return (locked) ? 0 : -EBUSY;
>> +}
>> +
>> +void ttm_write_unlock(struct ttm_lock *lock)
>> +{
>> +       spin_lock(&lock->lock);
>> +       lock->rw = 0;
>> +       wake_up_all(&lock->queue);
>> +       spin_unlock(&lock->lock);
>> +}
>> +EXPORT_SYMBOL(ttm_write_unlock);
>> +
>> +static bool __ttm_write_lock(struct ttm_lock *lock)
>> +{
>> +       bool locked = false;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (unlikely(lock->kill_takers)) {
>> +               send_sig(lock->signal, current, 0);
>> +               spin_unlock(&lock->lock);
>> +               return false;
>> +       }
>> +       if (lock->rw == 0 && ((lock->flags & ~TTM_WRITE_LOCK_PENDING) ==
>> 0)) {
>> +               lock->rw = -1;
>> +               lock->flags &= ~TTM_WRITE_LOCK_PENDING;
>> +               locked = true;
>> +       } else {
>> +               lock->flags |= TTM_WRITE_LOCK_PENDING;
>> +       }
>> +       spin_unlock(&lock->lock);
>> +       return locked;
>> +}
>> +
>> +int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
>> +{
>> +       int ret = 0;
>> +
>> +       if (interruptible) {
>> +               ret = wait_event_interruptible(lock->queue,
>> +                                              __ttm_write_lock(lock));
>> +               if (unlikely(ret != 0)) {
>> +                       spin_lock(&lock->lock);
>> +                       lock->flags &= ~TTM_WRITE_LOCK_PENDING;
>> +                       wake_up_all(&lock->queue);
>> +                       spin_unlock(&lock->lock);
>> +               }
>> +       } else
>> +               wait_event(lock->queue, __ttm_read_lock(lock));
>> +
>> +       return ret;
>> +}
>> +EXPORT_SYMBOL(ttm_write_lock);
>> +
>> +void ttm_write_lock_downgrade(struct ttm_lock *lock)
>> +{
>> +       spin_lock(&lock->lock);
>> +       lock->rw = 1;
>> +       wake_up_all(&lock->queue);
>> +       spin_unlock(&lock->lock);
>> +}
>> +
>> +static int __ttm_vt_unlock(struct ttm_lock *lock)
>> +{
>> +       int ret = 0;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (unlikely(!(lock->flags & TTM_VT_LOCK)))
>> +               ret = -EINVAL;
>> +       lock->flags &= ~TTM_VT_LOCK;
>> +       wake_up_all(&lock->queue);
>> +       spin_unlock(&lock->lock);
>> +
>> +       return ret;
>> +}
>> +
>> +static void ttm_vt_lock_remove(struct ttm_base_object **p_base)
>> +{
>> +       struct ttm_base_object *base = *p_base;
>> +       struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
>> +       int ret;
>> +
>> +       *p_base = NULL;
>> +       ret = __ttm_vt_unlock(lock);
>> +       BUG_ON(ret != 0);
>> +}
>> +
>> +static bool __ttm_vt_lock(struct ttm_lock *lock)
>> +{
>> +       bool locked = false;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (lock->rw == 0) {
>> +               lock->flags &= ~TTM_VT_LOCK_PENDING;
>> +               lock->flags |= TTM_VT_LOCK;
>> +               locked = true;
>> +       } else {
>> +               lock->flags |= TTM_VT_LOCK_PENDING;
>> +       }
>> +       spin_unlock(&lock->lock);
>> +       return locked;
>> +}
>> +
>> +int ttm_vt_lock(struct ttm_lock *lock,
>> +               bool interruptible,
>> +               struct ttm_object_file *tfile)
>> +{
>> +       int ret = 0;
>> +
>> +       if (interruptible) {
>> +               ret = wait_event_interruptible(lock->queue,
>> +                                              __ttm_vt_lock(lock));
>> +               if (unlikely(ret != 0)) {
>> +                       spin_lock(&lock->lock);
>> +                       lock->flags &= ~TTM_VT_LOCK_PENDING;
>> +                       wake_up_all(&lock->queue);
>> +                       spin_unlock(&lock->lock);
>> +                       return ret;
>> +               }
>> +       } else
>> +               wait_event(lock->queue, __ttm_vt_lock(lock));
>> +
>> +       /*
>> +        * Add a base-object, the destructor of which will
>> +        * make sure the lock is released if the client dies
>> +        * while holding it.
>> +        */
>> +
>> +       ret = ttm_base_object_init(tfile, &lock->base, false,
>> +                                  ttm_lock_type, &ttm_vt_lock_remove,
>> NULL);
>> +       if (ret)
>> +               (void)__ttm_vt_unlock(lock);
>> +       else
>> +               lock->vt_holder = tfile;
>> +
>> +       return ret;
>> +}
>> +EXPORT_SYMBOL(ttm_vt_lock);
>> +
>> +int ttm_vt_unlock(struct ttm_lock *lock)
>> +{
>> +       return ttm_ref_object_base_unref(lock->vt_holder,
>> +                                        lock->base.hash.key,
>> TTM_REF_USAGE);
>> +}
>> +EXPORT_SYMBOL(ttm_vt_unlock);
>> +
>> +void ttm_suspend_unlock(struct ttm_lock *lock)
>> +{
>> +       spin_lock(&lock->lock);
>> +       lock->flags &= ~TTM_SUSPEND_LOCK;
>> +       wake_up_all(&lock->queue);
>> +       spin_unlock(&lock->lock);
>> +}
>> +EXPORT_SYMBOL(ttm_suspend_unlock);
>> +
>> +static bool __ttm_suspend_lock(struct ttm_lock *lock)
>> +{
>> +       bool locked = false;
>> +
>> +       spin_lock(&lock->lock);
>> +       if (lock->rw == 0) {
>> +               lock->flags &= ~TTM_SUSPEND_LOCK_PENDING;
>> +               lock->flags |= TTM_SUSPEND_LOCK;
>> +               locked = true;
>> +       } else {
>> +               lock->flags |= TTM_SUSPEND_LOCK_PENDING;
>> +       }
>> +       spin_unlock(&lock->lock);
>> +       return locked;
>> +}
>> +
>> +void ttm_suspend_lock(struct ttm_lock *lock)
>> +{
>> +       wait_event(lock->queue, __ttm_suspend_lock(lock));
>> +}
>> +EXPORT_SYMBOL(ttm_suspend_lock);
>> diff --git a/drivers/gpu/drm/vmwgfx/ttm_lock.h
>> b/drivers/gpu/drm/vmwgfx/ttm_lock.h
>> new file mode 100644
>> index 0000000..2902beb
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vmwgfx/ttm_lock.h
>> @@ -0,0 +1,247 @@
>>
>> +/**************************************************************************
>> + *
>> + * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
>> + * All Rights Reserved.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining
>> a
>> + * copy of this software and associated documentation files (the
>> + * "Software"), to deal in the Software without restriction, including
>> + * without limitation the rights to use, copy, modify, merge, publish,
>> + * distribute, sub license, and/or sell copies of the Software, and to
>> + * permit persons to whom the Software is furnished to do so, subject to
>> + * the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including the
>> + * next paragraph) shall be included in all copies or substantial
>> portions
>> + * of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT
>> SHALL
>> + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
>> CLAIM,
>> + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
>> + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
>> THE
>> + * USE OR OTHER DEALINGS IN THE SOFTWARE.
>> + *
>> +
>> **************************************************************************/
>> +/*
>> + * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
>> + */
>> +
>> +/** @file ttm_lock.h
>> + * This file implements a simple replacement for the buffer manager use
>> + * of the DRM heavyweight hardware lock.
>> + * The lock is a read-write lock. Taking it in read mode and write mode
>> + * is relatively fast, and intended for in-kernel use only.
>> + *
>> + * The vt mode is used only when there is a need to block all
>> + * user-space processes from validating buffers.
>> + * It's allowed to leave kernel space with the vt lock held.
>> + * If a user-space process dies while having the vt-lock,
>> + * it will be released during the file descriptor release. The vt lock
>> + * excludes write lock and read lock.
>> + *
>> + * The suspend mode is used to lock out all TTM users when preparing for
>> + * and executing suspend operations.
>> + *
>> + */
>> +
>> +#ifndef _TTM_LOCK_H_
>> +#define _TTM_LOCK_H_
>> +
>> +#include <ttm/ttm_object.h>
>> +#include <linux/wait.h>
>> +#include <linux/atomic.h>
>> +
>> +/**
>> + * struct ttm_lock
>> + *
>> + * @base: ttm base object used solely to release the lock if the client
>> + * holding the lock dies.
>> + * @queue: Queue for processes waiting for lock change-of-status.
>> + * @lock: Spinlock protecting some lock members.
>> + * @rw: Read-write lock counter. Protected by @lock.
>> + * @flags: Lock state. Protected by @lock.
>> + * @kill_takers: Boolean whether to kill takers of the lock.
>> + * @signal: Signal to send when kill_takers is true.
>> + */
>> +
>> +struct ttm_lock {
>> +       struct ttm_base_object base;
>> +       wait_queue_head_t queue;
>> +       spinlock_t lock;
>> +       int32_t rw;
>> +       uint32_t flags;
>> +       bool kill_takers;
>> +       int signal;
>> +       struct ttm_object_file *vt_holder;
>> +};
>> +
>> +
>> +/**
>> + * ttm_lock_init
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * Initializes the lock.
>> + */
>> +extern void ttm_lock_init(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_read_unlock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Releases a read lock.
>> + */
>> +extern void ttm_read_unlock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_read_lock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @interruptible: Interruptible sleeping while waiting for a lock.
>> + *
>> + * Takes the lock in read mode.
>> + * Returns:
>> + * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> + */
>> +extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
>> +
>> +/**
>> + * ttm_read_trylock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @interruptible: Interruptible sleeping while waiting for a lock.
>> + *
>> + * Tries to take the lock in read mode. If the lock is already held
>> + * in write mode, the function will return -EBUSY. If the lock is held
>> + * in vt or suspend mode, the function will sleep until these modes
>> + * are unlocked.
>> + *
>> + * Returns:
>> + * -EBUSY The lock was already held in write mode.
>> + * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> + */
>> +extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
>> +
>> +/**
>> + * ttm_write_unlock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Releases a write lock.
>> + */
>> +extern void ttm_write_unlock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_write_lock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @interruptible: Interruptible sleeping while waiting for a lock.
>> + *
>> + * Takes the lock in write mode.
>> + * Returns:
>> + * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> + */
>> +extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
>> +
>> +/**
>> + * ttm_lock_downgrade
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Downgrades a write lock to a read lock.
>> + */
>> +extern void ttm_lock_downgrade(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_suspend_lock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Takes the lock in suspend mode. Excludes read and write mode.
>> + */
>> +extern void ttm_suspend_lock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_suspend_unlock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Releases a suspend lock
>> + */
>> +extern void ttm_suspend_unlock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_vt_lock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @interruptible: Interruptible sleeping while waiting for a lock.
>> + * @tfile: Pointer to a struct ttm_object_file to register the lock with.
>> + *
>> + * Takes the lock in vt mode.
>> + * Returns:
>> + * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> + * -ENOMEM: Out of memory when locking.
>> + */
>> +extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
>> +                      struct ttm_object_file *tfile);
>> +
>> +/**
>> + * ttm_vt_unlock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Releases a vt lock.
>> + * Returns:
>> + * -EINVAL If the lock was not held.
>> + */
>> +extern int ttm_vt_unlock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_write_unlock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + *
>> + * Releases a write lock.
>> + */
>> +extern void ttm_write_unlock(struct ttm_lock *lock);
>> +
>> +/**
>> + * ttm_write_lock
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @interruptible: Interruptible sleeping while waiting for a lock.
>> + *
>> + * Takes the lock in write mode.
>> + * Returns:
>> + * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> + */
>> +extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
>> +
>> +/**
>> + * ttm_lock_set_kill
>> + *
>> + * @lock: Pointer to a struct ttm_lock
>> + * @val: Boolean whether to kill processes taking the lock.
>> + * @signal: Signal to send to the process taking the lock.
>> + *
>> + * The kill-when-taking-lock functionality is used to kill processes that
>> keep
>> + * on using the TTM functionality when its resources has been taken down,
>> for
>> + * example when the X server exits. A typical sequence would look like
>> this:
>> + * - X server takes lock in write mode.
>> + * - ttm_lock_set_kill() is called with @val set to true.
>> + * - As part of X server exit, TTM resources are taken down.
>> + * - X server releases the lock on file release.
>> + * - Another dri client wants to render, takes the lock and is killed.
>> + *
>> + */
>> +static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val,
>> +                                    int signal)
>> +{
>> +       lock->kill_takers = val;
>> +       if (val)
>> +               lock->signal = signal;
>> +}
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
>> b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
>> index 7c6f6e3..94e6de1 100644
>> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
>> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
>> @@ -35,7 +35,7 @@
>>   #include <linux/suspend.h>
>>   #include <drm/ttm/ttm_bo_driver.h>
>>   #include <drm/ttm/ttm_object.h>
>> -#include <drm/ttm/ttm_lock.h>
>> +#include "ttm_lock.h"
>>   #include <drm/ttm/ttm_execbuf_util.h>
>>   #include <drm/ttm/ttm_module.h>
>>   #include "vmwgfx_fence.h"
>> diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h
>> deleted file mode 100644
>> index 2902beb..0000000
>> --- a/include/drm/ttm/ttm_lock.h
>> +++ /dev/null
>> @@ -1,247 +0,0 @@
>>
>> -/**************************************************************************
>> - *
>> - * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
>> - * All Rights Reserved.
>> - *
>> - * Permission is hereby granted, free of charge, to any person obtaining
>> a
>> - * copy of this software and associated documentation files (the
>> - * "Software"), to deal in the Software without restriction, including
>> - * without limitation the rights to use, copy, modify, merge, publish,
>> - * distribute, sub license, and/or sell copies of the Software, and to
>> - * permit persons to whom the Software is furnished to do so, subject to
>> - * the following conditions:
>> - *
>> - * The above copyright notice and this permission notice (including the
>> - * next paragraph) shall be included in all copies or substantial
>> portions
>> - * of the Software.
>> - *
>> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> EXPRESS OR
>> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> MERCHANTABILITY,
>> - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT
>> SHALL
>> - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
>> CLAIM,
>> - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
>> - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
>> THE
>> - * USE OR OTHER DEALINGS IN THE SOFTWARE.
>> - *
>> -
>> **************************************************************************/
>> -/*
>> - * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
>> - */
>> -
>> -/** @file ttm_lock.h
>> - * This file implements a simple replacement for the buffer manager use
>> - * of the DRM heavyweight hardware lock.
>> - * The lock is a read-write lock. Taking it in read mode and write mode
>> - * is relatively fast, and intended for in-kernel use only.
>> - *
>> - * The vt mode is used only when there is a need to block all
>> - * user-space processes from validating buffers.
>> - * It's allowed to leave kernel space with the vt lock held.
>> - * If a user-space process dies while having the vt-lock,
>> - * it will be released during the file descriptor release. The vt lock
>> - * excludes write lock and read lock.
>> - *
>> - * The suspend mode is used to lock out all TTM users when preparing for
>> - * and executing suspend operations.
>> - *
>> - */
>> -
>> -#ifndef _TTM_LOCK_H_
>> -#define _TTM_LOCK_H_
>> -
>> -#include <ttm/ttm_object.h>
>> -#include <linux/wait.h>
>> -#include <linux/atomic.h>
>> -
>> -/**
>> - * struct ttm_lock
>> - *
>> - * @base: ttm base object used solely to release the lock if the client
>> - * holding the lock dies.
>> - * @queue: Queue for processes waiting for lock change-of-status.
>> - * @lock: Spinlock protecting some lock members.
>> - * @rw: Read-write lock counter. Protected by @lock.
>> - * @flags: Lock state. Protected by @lock.
>> - * @kill_takers: Boolean whether to kill takers of the lock.
>> - * @signal: Signal to send when kill_takers is true.
>> - */
>> -
>> -struct ttm_lock {
>> -       struct ttm_base_object base;
>> -       wait_queue_head_t queue;
>> -       spinlock_t lock;
>> -       int32_t rw;
>> -       uint32_t flags;
>> -       bool kill_takers;
>> -       int signal;
>> -       struct ttm_object_file *vt_holder;
>> -};
>> -
>> -
>> -/**
>> - * ttm_lock_init
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * Initializes the lock.
>> - */
>> -extern void ttm_lock_init(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_read_unlock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Releases a read lock.
>> - */
>> -extern void ttm_read_unlock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_read_lock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @interruptible: Interruptible sleeping while waiting for a lock.
>> - *
>> - * Takes the lock in read mode.
>> - * Returns:
>> - * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> - */
>> -extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
>> -
>> -/**
>> - * ttm_read_trylock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @interruptible: Interruptible sleeping while waiting for a lock.
>> - *
>> - * Tries to take the lock in read mode. If the lock is already held
>> - * in write mode, the function will return -EBUSY. If the lock is held
>> - * in vt or suspend mode, the function will sleep until these modes
>> - * are unlocked.
>> - *
>> - * Returns:
>> - * -EBUSY The lock was already held in write mode.
>> - * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> - */
>> -extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
>> -
>> -/**
>> - * ttm_write_unlock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Releases a write lock.
>> - */
>> -extern void ttm_write_unlock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_write_lock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @interruptible: Interruptible sleeping while waiting for a lock.
>> - *
>> - * Takes the lock in write mode.
>> - * Returns:
>> - * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> - */
>> -extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
>> -
>> -/**
>> - * ttm_lock_downgrade
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Downgrades a write lock to a read lock.
>> - */
>> -extern void ttm_lock_downgrade(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_suspend_lock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Takes the lock in suspend mode. Excludes read and write mode.
>> - */
>> -extern void ttm_suspend_lock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_suspend_unlock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Releases a suspend lock
>> - */
>> -extern void ttm_suspend_unlock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_vt_lock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @interruptible: Interruptible sleeping while waiting for a lock.
>> - * @tfile: Pointer to a struct ttm_object_file to register the lock with.
>> - *
>> - * Takes the lock in vt mode.
>> - * Returns:
>> - * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> - * -ENOMEM: Out of memory when locking.
>> - */
>> -extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
>> -                      struct ttm_object_file *tfile);
>> -
>> -/**
>> - * ttm_vt_unlock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Releases a vt lock.
>> - * Returns:
>> - * -EINVAL If the lock was not held.
>> - */
>> -extern int ttm_vt_unlock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_write_unlock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - *
>> - * Releases a write lock.
>> - */
>> -extern void ttm_write_unlock(struct ttm_lock *lock);
>> -
>> -/**
>> - * ttm_write_lock
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @interruptible: Interruptible sleeping while waiting for a lock.
>> - *
>> - * Takes the lock in write mode.
>> - * Returns:
>> - * -ERESTARTSYS If interrupted by a signal and interruptible is true.
>> - */
>> -extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
>> -
>> -/**
>> - * ttm_lock_set_kill
>> - *
>> - * @lock: Pointer to a struct ttm_lock
>> - * @val: Boolean whether to kill processes taking the lock.
>> - * @signal: Signal to send to the process taking the lock.
>> - *
>> - * The kill-when-taking-lock functionality is used to kill processes that
>> keep
>> - * on using the TTM functionality when its resources has been taken down,
>> for
>> - * example when the X server exits. A typical sequence would look like
>> this:
>> - * - X server takes lock in write mode.
>> - * - ttm_lock_set_kill() is called with @val set to true.
>> - * - As part of X server exit, TTM resources are taken down.
>> - * - X server releases the lock on file release.
>> - * - Another dri client wants to render, takes the lock and is killed.
>> - *
>> - */
>> -static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val,
>> -                                    int signal)
>> -{
>> -       lock->kill_takers = val;
>> -       if (val)
>> -               lock->signal = signal;
>> -}
>> -
>> -#endif
>
>
>
>



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


More information about the dri-devel mailing list