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