kds.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. *
  3. * (C) COPYRIGHT ARM Limited. All rights reserved.
  4. *
  5. * This program is free software and is provided to you under the terms of the
  6. * GNU General Public License version 2 as published by the Free Software
  7. * Foundation, and any use by you of this program is subject to the terms
  8. * of such GNU licence.
  9. *
  10. * A copy of the licence is included with the program, and can also be obtained
  11. * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  12. * Boston, MA 02110-1301, USA.
  13. *
  14. */
  15. #ifndef _KDS_H_
  16. #define _KDS_H_
  17. #include <linux/list.h>
  18. #include <linux/workqueue.h>
  19. #define KDS_WAIT_BLOCKING (ULONG_MAX)
  20. struct kds_resource_set;
  21. typedef void (*kds_callback_fn) (void *callback_parameter, void *callback_extra_parameter);
  22. struct kds_callback
  23. {
  24. kds_callback_fn user_cb; /* real cb */
  25. int direct; /* do direct or queued call? */
  26. struct workqueue_struct *wq;
  27. };
  28. struct kds_link
  29. {
  30. struct kds_resource_set *parent;
  31. struct list_head link;
  32. unsigned long state;
  33. };
  34. struct kds_resource
  35. {
  36. struct kds_link waiters;
  37. };
  38. /* callback API */
  39. /* Initialize a callback object.
  40. *
  41. * Typically created per context or per hw resource.
  42. *
  43. * Callbacks can be performed directly if no nested locking can
  44. * happen in the client.
  45. *
  46. * Nested locking can occur when a lock is held during the kds_async_waitall or
  47. * kds_resource_set_release call. If the callback needs to take the same lock
  48. * nested locking will happen.
  49. *
  50. * If nested locking could happen non-direct callbacks can be requested.
  51. * Callbacks will then be called asynchronous to the triggering call.
  52. */
  53. int kds_callback_init(struct kds_callback *cb, int direct, kds_callback_fn user_cb);
  54. /* Terminate the use of a callback object.
  55. *
  56. * If the callback object was set up as non-direct
  57. * any pending callbacks will be flushed first.
  58. * Note that to avoid a deadlock the lock callbacks needs
  59. * can't be held when a callback object is terminated.
  60. */
  61. void kds_callback_term(struct kds_callback *cb);
  62. /* resource object API */
  63. /* initialize a resource handle for a shared resource */
  64. void kds_resource_init(struct kds_resource * const resource);
  65. /*
  66. * Will return 0 on success.
  67. * If the resource is being used or waited -EBUSY is returned.
  68. * The caller should NOT try to terminate a resource that could still have clients.
  69. * After the function returns the resource is no longer known by kds.
  70. */
  71. int kds_resource_term(struct kds_resource *resource);
  72. /* Asynchronous wait for a set of resources.
  73. * Callback will be called when all resources are available.
  74. * If all the resources was available the callback will be called before kds_async_waitall returns.
  75. * So one must not hold any locks the callback code-flow can take when calling kds_async_waitall.
  76. * Caller considered to own/use the resources until \a kds_rset_release is called.
  77. * exclusive_access_bitmap is a bitmap where a high bit means exclusive access while a low bit means shared access.
  78. * Use the Linux __set_bit API, where the index of the buffer to control is used as the bit index.
  79. *
  80. * Standard Linux error return value.
  81. */
  82. int kds_async_waitall(
  83. struct kds_resource_set ** const pprset,
  84. struct kds_callback *cb,
  85. void *callback_parameter,
  86. void *callback_extra_parameter,
  87. int number_resources,
  88. unsigned long *exclusive_access_bitmap,
  89. struct kds_resource **resource_list);
  90. /* Synchronous wait for a set of resources.
  91. * Function will return when one of these have happened:
  92. * - all resources have been obtained
  93. * - timeout lapsed while waiting
  94. * - a signal was received while waiting
  95. *
  96. * To wait without a timeout, specify KDS_WAIT_BLOCKING for \a jifies_timeout, otherwise
  97. * the timeout in jiffies. A zero timeout attempts to obtain all resources and returns
  98. * immediately with a timeout if all resources could not be obtained.
  99. *
  100. * Caller considered to own/use the resources when the function returns.
  101. * Caller must release the resources using \a kds_rset_release.
  102. *
  103. * Calling this function while holding already locked resources or other locking primitives is dangerous.
  104. * One must if this is needed decide on a lock order of the resources and/or the other locking primitives
  105. * and always take the resources/locking primitives in the specific order.
  106. *
  107. * Use the ERR_PTR framework to decode the return value.
  108. * NULL = time out
  109. * If IS_ERR then PTR_ERR gives:
  110. * ERESTARTSYS = signal received, retry call after signal
  111. * all other values = internal error, lock failed
  112. * Other values = successful wait, now the owner, must call kds_resource_set_release
  113. */
  114. struct kds_resource_set *kds_waitall(
  115. int number_resources,
  116. unsigned long *exclusive_access_bitmap,
  117. struct kds_resource **resource_list,
  118. unsigned long jifies_timeout);
  119. /* Release resources after use.
  120. * Caller must handle that other async callbacks will trigger,
  121. * so must avoid holding any locks a callback will take.
  122. *
  123. * The function takes a pointer to your poiner to handle a race
  124. * between a cancelation and a completion.
  125. *
  126. * If the caller can't guarantee that a race can't occur then
  127. * the passed in pointer must be the same in both call paths
  128. * to allow kds to manage the potential race.
  129. */
  130. void kds_resource_set_release(struct kds_resource_set **pprset);
  131. /* Release resources after use and wait callbacks to complete.
  132. * Caller must handle that other async callbacks will trigger,
  133. * so must avoid holding any locks a callback will take.
  134. *
  135. * The function takes a pointer to your poiner to handle a race
  136. * between a cancelation and a completion.
  137. *
  138. * If the caller can't guarantee that a race can't occur then
  139. * the passed in pointer must be the same in both call paths
  140. * to allow kds to manage the potential race.
  141. *
  142. * This should be used to cancel waits which are pending on a kds
  143. * resource.
  144. *
  145. * It is a bug to call this from atomic contexts and from within
  146. * a kds callback that now owns the kds_rseource.
  147. */
  148. void kds_resource_set_release_sync(struct kds_resource_set **pprset);
  149. #endif /* _KDS_H_ */