xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/vmwgfx/ttm_lock.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /**************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
4*4882a593Smuzhiyun  * All Rights Reserved.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
7*4882a593Smuzhiyun  * copy of this software and associated documentation files (the
8*4882a593Smuzhiyun  * "Software"), to deal in the Software without restriction, including
9*4882a593Smuzhiyun  * without limitation the rights to use, copy, modify, merge, publish,
10*4882a593Smuzhiyun  * distribute, sub license, and/or sell copies of the Software, and to
11*4882a593Smuzhiyun  * permit persons to whom the Software is furnished to do so, subject to
12*4882a593Smuzhiyun  * the following conditions:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the
15*4882a593Smuzhiyun  * next paragraph) shall be included in all copies or substantial portions
16*4882a593Smuzhiyun  * of the Software.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22*4882a593Smuzhiyun  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23*4882a593Smuzhiyun  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24*4882a593Smuzhiyun  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  **************************************************************************/
27*4882a593Smuzhiyun /*
28*4882a593Smuzhiyun  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /** @file ttm_lock.h
32*4882a593Smuzhiyun  * This file implements a simple replacement for the buffer manager use
33*4882a593Smuzhiyun  * of the DRM heavyweight hardware lock.
34*4882a593Smuzhiyun  * The lock is a read-write lock. Taking it in read mode and write mode
35*4882a593Smuzhiyun  * is relatively fast, and intended for in-kernel use only.
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * The vt mode is used only when there is a need to block all
38*4882a593Smuzhiyun  * user-space processes from validating buffers.
39*4882a593Smuzhiyun  * It's allowed to leave kernel space with the vt lock held.
40*4882a593Smuzhiyun  * If a user-space process dies while having the vt-lock,
41*4882a593Smuzhiyun  * it will be released during the file descriptor release. The vt lock
42*4882a593Smuzhiyun  * excludes write lock and read lock.
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  * The suspend mode is used to lock out all TTM users when preparing for
45*4882a593Smuzhiyun  * and executing suspend operations.
46*4882a593Smuzhiyun  *
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #ifndef _TTM_LOCK_H_
50*4882a593Smuzhiyun #define _TTM_LOCK_H_
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #include <linux/atomic.h>
53*4882a593Smuzhiyun #include <linux/wait.h>
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #include "ttm_object.h"
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /**
58*4882a593Smuzhiyun  * struct ttm_lock
59*4882a593Smuzhiyun  *
60*4882a593Smuzhiyun  * @base: ttm base object used solely to release the lock if the client
61*4882a593Smuzhiyun  * holding the lock dies.
62*4882a593Smuzhiyun  * @queue: Queue for processes waiting for lock change-of-status.
63*4882a593Smuzhiyun  * @lock: Spinlock protecting some lock members.
64*4882a593Smuzhiyun  * @rw: Read-write lock counter. Protected by @lock.
65*4882a593Smuzhiyun  * @flags: Lock state. Protected by @lock.
66*4882a593Smuzhiyun  */
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun struct ttm_lock {
69*4882a593Smuzhiyun 	struct ttm_base_object base;
70*4882a593Smuzhiyun 	wait_queue_head_t queue;
71*4882a593Smuzhiyun 	spinlock_t lock;
72*4882a593Smuzhiyun 	int32_t rw;
73*4882a593Smuzhiyun 	uint32_t flags;
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /**
78*4882a593Smuzhiyun  * ttm_lock_init
79*4882a593Smuzhiyun  *
80*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
81*4882a593Smuzhiyun  * Initializes the lock.
82*4882a593Smuzhiyun  */
83*4882a593Smuzhiyun extern void ttm_lock_init(struct ttm_lock *lock);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /**
86*4882a593Smuzhiyun  * ttm_read_unlock
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
89*4882a593Smuzhiyun  *
90*4882a593Smuzhiyun  * Releases a read lock.
91*4882a593Smuzhiyun  */
92*4882a593Smuzhiyun extern void ttm_read_unlock(struct ttm_lock *lock);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /**
95*4882a593Smuzhiyun  * ttm_read_lock
96*4882a593Smuzhiyun  *
97*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
98*4882a593Smuzhiyun  * @interruptible: Interruptible sleeping while waiting for a lock.
99*4882a593Smuzhiyun  *
100*4882a593Smuzhiyun  * Takes the lock in read mode.
101*4882a593Smuzhiyun  * Returns:
102*4882a593Smuzhiyun  * -ERESTARTSYS If interrupted by a signal and interruptible is true.
103*4882a593Smuzhiyun  */
104*4882a593Smuzhiyun extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun  * ttm_read_trylock
108*4882a593Smuzhiyun  *
109*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
110*4882a593Smuzhiyun  * @interruptible: Interruptible sleeping while waiting for a lock.
111*4882a593Smuzhiyun  *
112*4882a593Smuzhiyun  * Tries to take the lock in read mode. If the lock is already held
113*4882a593Smuzhiyun  * in write mode, the function will return -EBUSY. If the lock is held
114*4882a593Smuzhiyun  * in vt or suspend mode, the function will sleep until these modes
115*4882a593Smuzhiyun  * are unlocked.
116*4882a593Smuzhiyun  *
117*4882a593Smuzhiyun  * Returns:
118*4882a593Smuzhiyun  * -EBUSY The lock was already held in write mode.
119*4882a593Smuzhiyun  * -ERESTARTSYS If interrupted by a signal and interruptible is true.
120*4882a593Smuzhiyun  */
121*4882a593Smuzhiyun extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun /**
124*4882a593Smuzhiyun  * ttm_write_unlock
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  * Releases a write lock.
129*4882a593Smuzhiyun  */
130*4882a593Smuzhiyun extern void ttm_write_unlock(struct ttm_lock *lock);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /**
133*4882a593Smuzhiyun  * ttm_write_lock
134*4882a593Smuzhiyun  *
135*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
136*4882a593Smuzhiyun  * @interruptible: Interruptible sleeping while waiting for a lock.
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * Takes the lock in write mode.
139*4882a593Smuzhiyun  * Returns:
140*4882a593Smuzhiyun  * -ERESTARTSYS If interrupted by a signal and interruptible is true.
141*4882a593Smuzhiyun  */
142*4882a593Smuzhiyun extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /**
145*4882a593Smuzhiyun  * ttm_lock_downgrade
146*4882a593Smuzhiyun  *
147*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
148*4882a593Smuzhiyun  *
149*4882a593Smuzhiyun  * Downgrades a write lock to a read lock.
150*4882a593Smuzhiyun  */
151*4882a593Smuzhiyun extern void ttm_lock_downgrade(struct ttm_lock *lock);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /**
154*4882a593Smuzhiyun  * ttm_suspend_lock
155*4882a593Smuzhiyun  *
156*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
157*4882a593Smuzhiyun  *
158*4882a593Smuzhiyun  * Takes the lock in suspend mode. Excludes read and write mode.
159*4882a593Smuzhiyun  */
160*4882a593Smuzhiyun extern void ttm_suspend_lock(struct ttm_lock *lock);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun /**
163*4882a593Smuzhiyun  * ttm_suspend_unlock
164*4882a593Smuzhiyun  *
165*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
166*4882a593Smuzhiyun  *
167*4882a593Smuzhiyun  * Releases a suspend lock
168*4882a593Smuzhiyun  */
169*4882a593Smuzhiyun extern void ttm_suspend_unlock(struct ttm_lock *lock);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /**
172*4882a593Smuzhiyun  * ttm_vt_lock
173*4882a593Smuzhiyun  *
174*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
175*4882a593Smuzhiyun  * @interruptible: Interruptible sleeping while waiting for a lock.
176*4882a593Smuzhiyun  * @tfile: Pointer to a struct ttm_object_file to register the lock with.
177*4882a593Smuzhiyun  *
178*4882a593Smuzhiyun  * Takes the lock in vt mode.
179*4882a593Smuzhiyun  * Returns:
180*4882a593Smuzhiyun  * -ERESTARTSYS If interrupted by a signal and interruptible is true.
181*4882a593Smuzhiyun  * -ENOMEM: Out of memory when locking.
182*4882a593Smuzhiyun  */
183*4882a593Smuzhiyun extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
184*4882a593Smuzhiyun 		       struct ttm_object_file *tfile);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun /**
187*4882a593Smuzhiyun  * ttm_vt_unlock
188*4882a593Smuzhiyun  *
189*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
190*4882a593Smuzhiyun  *
191*4882a593Smuzhiyun  * Releases a vt lock.
192*4882a593Smuzhiyun  * Returns:
193*4882a593Smuzhiyun  * -EINVAL If the lock was not held.
194*4882a593Smuzhiyun  */
195*4882a593Smuzhiyun extern int ttm_vt_unlock(struct ttm_lock *lock);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun /**
198*4882a593Smuzhiyun  * ttm_write_unlock
199*4882a593Smuzhiyun  *
200*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
201*4882a593Smuzhiyun  *
202*4882a593Smuzhiyun  * Releases a write lock.
203*4882a593Smuzhiyun  */
204*4882a593Smuzhiyun extern void ttm_write_unlock(struct ttm_lock *lock);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun /**
207*4882a593Smuzhiyun  * ttm_write_lock
208*4882a593Smuzhiyun  *
209*4882a593Smuzhiyun  * @lock: Pointer to a struct ttm_lock
210*4882a593Smuzhiyun  * @interruptible: Interruptible sleeping while waiting for a lock.
211*4882a593Smuzhiyun  *
212*4882a593Smuzhiyun  * Takes the lock in write mode.
213*4882a593Smuzhiyun  * Returns:
214*4882a593Smuzhiyun  * -ERESTARTSYS If interrupted by a signal and interruptible is true.
215*4882a593Smuzhiyun  */
216*4882a593Smuzhiyun extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun #endif
219