[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