ttm_lock.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. /** @file ttm_lock.h
  31. * This file implements a simple replacement for the buffer manager use
  32. * of the DRM heavyweight hardware lock.
  33. * The lock is a read-write lock. Taking it in read mode and write mode
  34. * is relatively fast, and intended for in-kernel use only.
  35. *
  36. * The vt mode is used only when there is a need to block all
  37. * user-space processes from validating buffers.
  38. * It's allowed to leave kernel space with the vt lock held.
  39. * If a user-space process dies while having the vt-lock,
  40. * it will be released during the file descriptor release. The vt lock
  41. * excludes write lock and read lock.
  42. *
  43. * The suspend mode is used to lock out all TTM users when preparing for
  44. * and executing suspend operations.
  45. *
  46. */
  47. #ifndef _TTM_LOCK_H_
  48. #define _TTM_LOCK_H_
  49. #include <ttm/ttm_object.h>
  50. #include <linux/wait.h>
  51. #include <linux/atomic.h>
  52. /**
  53. * struct ttm_lock
  54. *
  55. * @base: ttm base object used solely to release the lock if the client
  56. * holding the lock dies.
  57. * @queue: Queue for processes waiting for lock change-of-status.
  58. * @lock: Spinlock protecting some lock members.
  59. * @rw: Read-write lock counter. Protected by @lock.
  60. * @flags: Lock state. Protected by @lock.
  61. * @kill_takers: Boolean whether to kill takers of the lock.
  62. * @signal: Signal to send when kill_takers is true.
  63. */
  64. struct ttm_lock {
  65. struct ttm_base_object base;
  66. wait_queue_head_t queue;
  67. spinlock_t lock;
  68. int32_t rw;
  69. uint32_t flags;
  70. bool kill_takers;
  71. int signal;
  72. struct ttm_object_file *vt_holder;
  73. };
  74. /**
  75. * ttm_lock_init
  76. *
  77. * @lock: Pointer to a struct ttm_lock
  78. * Initializes the lock.
  79. */
  80. extern void ttm_lock_init(struct ttm_lock *lock);
  81. /**
  82. * ttm_read_unlock
  83. *
  84. * @lock: Pointer to a struct ttm_lock
  85. *
  86. * Releases a read lock.
  87. */
  88. extern void ttm_read_unlock(struct ttm_lock *lock);
  89. /**
  90. * ttm_read_lock
  91. *
  92. * @lock: Pointer to a struct ttm_lock
  93. * @interruptible: Interruptible sleeping while waiting for a lock.
  94. *
  95. * Takes the lock in read mode.
  96. * Returns:
  97. * -ERESTARTSYS If interrupted by a signal and interruptible is true.
  98. */
  99. extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
  100. /**
  101. * ttm_read_trylock
  102. *
  103. * @lock: Pointer to a struct ttm_lock
  104. * @interruptible: Interruptible sleeping while waiting for a lock.
  105. *
  106. * Tries to take the lock in read mode. If the lock is already held
  107. * in write mode, the function will return -EBUSY. If the lock is held
  108. * in vt or suspend mode, the function will sleep until these modes
  109. * are unlocked.
  110. *
  111. * Returns:
  112. * -EBUSY The lock was already held in write mode.
  113. * -ERESTARTSYS If interrupted by a signal and interruptible is true.
  114. */
  115. extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
  116. /**
  117. * ttm_write_unlock
  118. *
  119. * @lock: Pointer to a struct ttm_lock
  120. *
  121. * Releases a write lock.
  122. */
  123. extern void ttm_write_unlock(struct ttm_lock *lock);
  124. /**
  125. * ttm_write_lock
  126. *
  127. * @lock: Pointer to a struct ttm_lock
  128. * @interruptible: Interruptible sleeping while waiting for a lock.
  129. *
  130. * Takes the lock in write mode.
  131. * Returns:
  132. * -ERESTARTSYS If interrupted by a signal and interruptible is true.
  133. */
  134. extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
  135. /**
  136. * ttm_lock_downgrade
  137. *
  138. * @lock: Pointer to a struct ttm_lock
  139. *
  140. * Downgrades a write lock to a read lock.
  141. */
  142. extern void ttm_lock_downgrade(struct ttm_lock *lock);
  143. /**
  144. * ttm_suspend_lock
  145. *
  146. * @lock: Pointer to a struct ttm_lock
  147. *
  148. * Takes the lock in suspend mode. Excludes read and write mode.
  149. */
  150. extern void ttm_suspend_lock(struct ttm_lock *lock);
  151. /**
  152. * ttm_suspend_unlock
  153. *
  154. * @lock: Pointer to a struct ttm_lock
  155. *
  156. * Releases a suspend lock
  157. */
  158. extern void ttm_suspend_unlock(struct ttm_lock *lock);
  159. /**
  160. * ttm_vt_lock
  161. *
  162. * @lock: Pointer to a struct ttm_lock
  163. * @interruptible: Interruptible sleeping while waiting for a lock.
  164. * @tfile: Pointer to a struct ttm_object_file to register the lock with.
  165. *
  166. * Takes the lock in vt mode.
  167. * Returns:
  168. * -ERESTARTSYS If interrupted by a signal and interruptible is true.
  169. * -ENOMEM: Out of memory when locking.
  170. */
  171. extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
  172. struct ttm_object_file *tfile);
  173. /**
  174. * ttm_vt_unlock
  175. *
  176. * @lock: Pointer to a struct ttm_lock
  177. *
  178. * Releases a vt lock.
  179. * Returns:
  180. * -EINVAL If the lock was not held.
  181. */
  182. extern int ttm_vt_unlock(struct ttm_lock *lock);
  183. /**
  184. * ttm_write_unlock
  185. *
  186. * @lock: Pointer to a struct ttm_lock
  187. *
  188. * Releases a write lock.
  189. */
  190. extern void ttm_write_unlock(struct ttm_lock *lock);
  191. /**
  192. * ttm_write_lock
  193. *
  194. * @lock: Pointer to a struct ttm_lock
  195. * @interruptible: Interruptible sleeping while waiting for a lock.
  196. *
  197. * Takes the lock in write mode.
  198. * Returns:
  199. * -ERESTARTSYS If interrupted by a signal and interruptible is true.
  200. */
  201. extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
  202. /**
  203. * ttm_lock_set_kill
  204. *
  205. * @lock: Pointer to a struct ttm_lock
  206. * @val: Boolean whether to kill processes taking the lock.
  207. * @signal: Signal to send to the process taking the lock.
  208. *
  209. * The kill-when-taking-lock functionality is used to kill processes that keep
  210. * on using the TTM functionality when its resources has been taken down, for
  211. * example when the X server exits. A typical sequence would look like this:
  212. * - X server takes lock in write mode.
  213. * - ttm_lock_set_kill() is called with @val set to true.
  214. * - As part of X server exit, TTM resources are taken down.
  215. * - X server releases the lock on file release.
  216. * - Another dri client wants to render, takes the lock and is killed.
  217. *
  218. */
  219. static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val,
  220. int signal)
  221. {
  222. lock->kill_takers = val;
  223. if (val)
  224. lock->signal = signal;
  225. }
  226. #endif