iowait.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #ifndef _HFI1_IOWAIT_H
  2. #define _HFI1_IOWAIT_H
  3. /*
  4. * Copyright(c) 2015, 2016 Intel Corporation.
  5. *
  6. * This file is provided under a dual BSD/GPLv2 license. When using or
  7. * redistributing this file, you may do so under either license.
  8. *
  9. * GPL LICENSE SUMMARY
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of version 2 of the GNU General Public License as
  13. * published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * General Public License for more details.
  19. *
  20. * BSD LICENSE
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. *
  26. * - Redistributions of source code must retain the above copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * - Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in
  30. * the documentation and/or other materials provided with the
  31. * distribution.
  32. * - Neither the name of Intel Corporation nor the names of its
  33. * contributors may be used to endorse or promote products derived
  34. * from this software without specific prior written permission.
  35. *
  36. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  37. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  38. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  39. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  40. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  43. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  44. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  46. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47. *
  48. */
  49. #include <linux/list.h>
  50. #include <linux/workqueue.h>
  51. #include <linux/sched.h>
  52. #include "sdma_txreq.h"
  53. /*
  54. * typedef (*restart_t)() - restart callback
  55. * @work: pointer to work structure
  56. */
  57. typedef void (*restart_t)(struct work_struct *work);
  58. struct sdma_txreq;
  59. struct sdma_engine;
  60. /**
  61. * struct iowait - linkage for delayed progress/waiting
  62. * @list: used to add/insert into QP/PQ wait lists
  63. * @tx_head: overflow list of sdma_txreq's
  64. * @sleep: no space callback
  65. * @wakeup: space callback wakeup
  66. * @sdma_drained: sdma count drained
  67. * @iowork: workqueue overhead
  68. * @wait_dma: wait for sdma_busy == 0
  69. * @wait_pio: wait for pio_busy == 0
  70. * @sdma_busy: # of packets in flight
  71. * @count: total number of descriptors in tx_head'ed list
  72. * @tx_limit: limit for overflow queuing
  73. * @tx_count: number of tx entry's in tx_head'ed list
  74. *
  75. * This is to be embedded in user's state structure
  76. * (QP or PQ).
  77. *
  78. * The sleep and wakeup members are a
  79. * bit misnamed. They do not strictly
  80. * speaking sleep or wake up, but they
  81. * are callbacks for the ULP to implement
  82. * what ever queuing/dequeuing of
  83. * the embedded iowait and its containing struct
  84. * when a resource shortage like SDMA ring space is seen.
  85. *
  86. * Both potentially have locks help
  87. * so sleeping is not allowed.
  88. *
  89. * The wait_dma member along with the iow
  90. */
  91. struct iowait {
  92. struct list_head list;
  93. struct list_head tx_head;
  94. int (*sleep)(
  95. struct sdma_engine *sde,
  96. struct iowait *wait,
  97. struct sdma_txreq *tx,
  98. unsigned seq);
  99. void (*wakeup)(struct iowait *wait, int reason);
  100. void (*sdma_drained)(struct iowait *wait);
  101. struct work_struct iowork;
  102. wait_queue_head_t wait_dma;
  103. wait_queue_head_t wait_pio;
  104. atomic_t sdma_busy;
  105. atomic_t pio_busy;
  106. u32 count;
  107. u32 tx_limit;
  108. u32 tx_count;
  109. };
  110. #define SDMA_AVAIL_REASON 0
  111. /**
  112. * iowait_init() - initialize wait structure
  113. * @wait: wait struct to initialize
  114. * @tx_limit: limit for overflow queuing
  115. * @func: restart function for workqueue
  116. * @sleep: sleep function for no space
  117. * @resume: wakeup function for no space
  118. *
  119. * This function initializes the iowait
  120. * structure embedded in the QP or PQ.
  121. *
  122. */
  123. static inline void iowait_init(
  124. struct iowait *wait,
  125. u32 tx_limit,
  126. void (*func)(struct work_struct *work),
  127. int (*sleep)(
  128. struct sdma_engine *sde,
  129. struct iowait *wait,
  130. struct sdma_txreq *tx,
  131. unsigned seq),
  132. void (*wakeup)(struct iowait *wait, int reason),
  133. void (*sdma_drained)(struct iowait *wait))
  134. {
  135. wait->count = 0;
  136. INIT_LIST_HEAD(&wait->list);
  137. INIT_LIST_HEAD(&wait->tx_head);
  138. INIT_WORK(&wait->iowork, func);
  139. init_waitqueue_head(&wait->wait_dma);
  140. init_waitqueue_head(&wait->wait_pio);
  141. atomic_set(&wait->sdma_busy, 0);
  142. atomic_set(&wait->pio_busy, 0);
  143. wait->tx_limit = tx_limit;
  144. wait->sleep = sleep;
  145. wait->wakeup = wakeup;
  146. wait->sdma_drained = sdma_drained;
  147. }
  148. /**
  149. * iowait_schedule() - initialize wait structure
  150. * @wait: wait struct to schedule
  151. * @wq: workqueue for schedule
  152. * @cpu: cpu
  153. */
  154. static inline void iowait_schedule(
  155. struct iowait *wait,
  156. struct workqueue_struct *wq,
  157. int cpu)
  158. {
  159. queue_work_on(cpu, wq, &wait->iowork);
  160. }
  161. /**
  162. * iowait_sdma_drain() - wait for DMAs to drain
  163. *
  164. * @wait: iowait structure
  165. *
  166. * This will delay until the iowait sdmas have
  167. * completed.
  168. */
  169. static inline void iowait_sdma_drain(struct iowait *wait)
  170. {
  171. wait_event(wait->wait_dma, !atomic_read(&wait->sdma_busy));
  172. }
  173. /**
  174. * iowait_sdma_pending() - return sdma pending count
  175. *
  176. * @wait: iowait structure
  177. *
  178. */
  179. static inline int iowait_sdma_pending(struct iowait *wait)
  180. {
  181. return atomic_read(&wait->sdma_busy);
  182. }
  183. /**
  184. * iowait_sdma_inc - note sdma io pending
  185. * @wait: iowait structure
  186. */
  187. static inline void iowait_sdma_inc(struct iowait *wait)
  188. {
  189. atomic_inc(&wait->sdma_busy);
  190. }
  191. /**
  192. * iowait_sdma_add - add count to pending
  193. * @wait: iowait structure
  194. */
  195. static inline void iowait_sdma_add(struct iowait *wait, int count)
  196. {
  197. atomic_add(count, &wait->sdma_busy);
  198. }
  199. /**
  200. * iowait_sdma_dec - note sdma complete
  201. * @wait: iowait structure
  202. */
  203. static inline int iowait_sdma_dec(struct iowait *wait)
  204. {
  205. return atomic_dec_and_test(&wait->sdma_busy);
  206. }
  207. /**
  208. * iowait_pio_drain() - wait for pios to drain
  209. *
  210. * @wait: iowait structure
  211. *
  212. * This will delay until the iowait pios have
  213. * completed.
  214. */
  215. static inline void iowait_pio_drain(struct iowait *wait)
  216. {
  217. wait_event_timeout(wait->wait_pio,
  218. !atomic_read(&wait->pio_busy),
  219. HZ);
  220. }
  221. /**
  222. * iowait_pio_pending() - return pio pending count
  223. *
  224. * @wait: iowait structure
  225. *
  226. */
  227. static inline int iowait_pio_pending(struct iowait *wait)
  228. {
  229. return atomic_read(&wait->pio_busy);
  230. }
  231. /**
  232. * iowait_pio_inc - note pio pending
  233. * @wait: iowait structure
  234. */
  235. static inline void iowait_pio_inc(struct iowait *wait)
  236. {
  237. atomic_inc(&wait->pio_busy);
  238. }
  239. /**
  240. * iowait_sdma_dec - note pio complete
  241. * @wait: iowait structure
  242. */
  243. static inline int iowait_pio_dec(struct iowait *wait)
  244. {
  245. return atomic_dec_and_test(&wait->pio_busy);
  246. }
  247. /**
  248. * iowait_drain_wakeup() - trigger iowait_drain() waiter
  249. *
  250. * @wait: iowait structure
  251. *
  252. * This will trigger any waiters.
  253. */
  254. static inline void iowait_drain_wakeup(struct iowait *wait)
  255. {
  256. wake_up(&wait->wait_dma);
  257. wake_up(&wait->wait_pio);
  258. if (wait->sdma_drained)
  259. wait->sdma_drained(wait);
  260. }
  261. /**
  262. * iowait_get_txhead() - get packet off of iowait list
  263. *
  264. * @wait wait struture
  265. */
  266. static inline struct sdma_txreq *iowait_get_txhead(struct iowait *wait)
  267. {
  268. struct sdma_txreq *tx = NULL;
  269. if (!list_empty(&wait->tx_head)) {
  270. tx = list_first_entry(
  271. &wait->tx_head,
  272. struct sdma_txreq,
  273. list);
  274. list_del_init(&tx->list);
  275. }
  276. return tx;
  277. }
  278. #endif