iowait.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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. * @lock: uses to record the list head lock
  64. * @tx_head: overflow list of sdma_txreq's
  65. * @sleep: no space callback
  66. * @wakeup: space callback wakeup
  67. * @sdma_drained: sdma count drained
  68. * @iowork: workqueue overhead
  69. * @wait_dma: wait for sdma_busy == 0
  70. * @wait_pio: wait for pio_busy == 0
  71. * @sdma_busy: # of packets in flight
  72. * @count: total number of descriptors in tx_head'ed list
  73. * @tx_limit: limit for overflow queuing
  74. * @tx_count: number of tx entry's in tx_head'ed list
  75. *
  76. * This is to be embedded in user's state structure
  77. * (QP or PQ).
  78. *
  79. * The sleep and wakeup members are a
  80. * bit misnamed. They do not strictly
  81. * speaking sleep or wake up, but they
  82. * are callbacks for the ULP to implement
  83. * what ever queuing/dequeuing of
  84. * the embedded iowait and its containing struct
  85. * when a resource shortage like SDMA ring space is seen.
  86. *
  87. * Both potentially have locks help
  88. * so sleeping is not allowed.
  89. *
  90. * The wait_dma member along with the iow
  91. *
  92. * The lock field is used by waiters to record
  93. * the seqlock_t that guards the list head.
  94. * Waiters explicity know that, but the destroy
  95. * code that unwaits QPs does not.
  96. */
  97. struct iowait {
  98. struct list_head list;
  99. struct list_head tx_head;
  100. int (*sleep)(
  101. struct sdma_engine *sde,
  102. struct iowait *wait,
  103. struct sdma_txreq *tx,
  104. uint seq,
  105. bool pkts_sent
  106. );
  107. void (*wakeup)(struct iowait *wait, int reason);
  108. void (*sdma_drained)(struct iowait *wait);
  109. seqlock_t *lock;
  110. struct work_struct iowork;
  111. wait_queue_head_t wait_dma;
  112. wait_queue_head_t wait_pio;
  113. atomic_t sdma_busy;
  114. atomic_t pio_busy;
  115. u32 count;
  116. u32 tx_limit;
  117. u32 tx_count;
  118. u8 starved_cnt;
  119. };
  120. #define SDMA_AVAIL_REASON 0
  121. /**
  122. * iowait_init() - initialize wait structure
  123. * @wait: wait struct to initialize
  124. * @tx_limit: limit for overflow queuing
  125. * @func: restart function for workqueue
  126. * @sleep: sleep function for no space
  127. * @resume: wakeup function for no space
  128. *
  129. * This function initializes the iowait
  130. * structure embedded in the QP or PQ.
  131. *
  132. */
  133. static inline void iowait_init(
  134. struct iowait *wait,
  135. u32 tx_limit,
  136. void (*func)(struct work_struct *work),
  137. int (*sleep)(
  138. struct sdma_engine *sde,
  139. struct iowait *wait,
  140. struct sdma_txreq *tx,
  141. uint seq,
  142. bool pkts_sent),
  143. void (*wakeup)(struct iowait *wait, int reason),
  144. void (*sdma_drained)(struct iowait *wait))
  145. {
  146. wait->count = 0;
  147. wait->lock = NULL;
  148. INIT_LIST_HEAD(&wait->list);
  149. INIT_LIST_HEAD(&wait->tx_head);
  150. INIT_WORK(&wait->iowork, func);
  151. init_waitqueue_head(&wait->wait_dma);
  152. init_waitqueue_head(&wait->wait_pio);
  153. atomic_set(&wait->sdma_busy, 0);
  154. atomic_set(&wait->pio_busy, 0);
  155. wait->tx_limit = tx_limit;
  156. wait->sleep = sleep;
  157. wait->wakeup = wakeup;
  158. wait->sdma_drained = sdma_drained;
  159. }
  160. /**
  161. * iowait_schedule() - initialize wait structure
  162. * @wait: wait struct to schedule
  163. * @wq: workqueue for schedule
  164. * @cpu: cpu
  165. */
  166. static inline void iowait_schedule(
  167. struct iowait *wait,
  168. struct workqueue_struct *wq,
  169. int cpu)
  170. {
  171. queue_work_on(cpu, wq, &wait->iowork);
  172. }
  173. /**
  174. * iowait_sdma_drain() - wait for DMAs to drain
  175. *
  176. * @wait: iowait structure
  177. *
  178. * This will delay until the iowait sdmas have
  179. * completed.
  180. */
  181. static inline void iowait_sdma_drain(struct iowait *wait)
  182. {
  183. wait_event(wait->wait_dma, !atomic_read(&wait->sdma_busy));
  184. }
  185. /**
  186. * iowait_sdma_pending() - return sdma pending count
  187. *
  188. * @wait: iowait structure
  189. *
  190. */
  191. static inline int iowait_sdma_pending(struct iowait *wait)
  192. {
  193. return atomic_read(&wait->sdma_busy);
  194. }
  195. /**
  196. * iowait_sdma_inc - note sdma io pending
  197. * @wait: iowait structure
  198. */
  199. static inline void iowait_sdma_inc(struct iowait *wait)
  200. {
  201. atomic_inc(&wait->sdma_busy);
  202. }
  203. /**
  204. * iowait_sdma_add - add count to pending
  205. * @wait: iowait structure
  206. */
  207. static inline void iowait_sdma_add(struct iowait *wait, int count)
  208. {
  209. atomic_add(count, &wait->sdma_busy);
  210. }
  211. /**
  212. * iowait_sdma_dec - note sdma complete
  213. * @wait: iowait structure
  214. */
  215. static inline int iowait_sdma_dec(struct iowait *wait)
  216. {
  217. return atomic_dec_and_test(&wait->sdma_busy);
  218. }
  219. /**
  220. * iowait_pio_drain() - wait for pios to drain
  221. *
  222. * @wait: iowait structure
  223. *
  224. * This will delay until the iowait pios have
  225. * completed.
  226. */
  227. static inline void iowait_pio_drain(struct iowait *wait)
  228. {
  229. wait_event_timeout(wait->wait_pio,
  230. !atomic_read(&wait->pio_busy),
  231. HZ);
  232. }
  233. /**
  234. * iowait_pio_pending() - return pio pending count
  235. *
  236. * @wait: iowait structure
  237. *
  238. */
  239. static inline int iowait_pio_pending(struct iowait *wait)
  240. {
  241. return atomic_read(&wait->pio_busy);
  242. }
  243. /**
  244. * iowait_pio_inc - note pio pending
  245. * @wait: iowait structure
  246. */
  247. static inline void iowait_pio_inc(struct iowait *wait)
  248. {
  249. atomic_inc(&wait->pio_busy);
  250. }
  251. /**
  252. * iowait_sdma_dec - note pio complete
  253. * @wait: iowait structure
  254. */
  255. static inline int iowait_pio_dec(struct iowait *wait)
  256. {
  257. return atomic_dec_and_test(&wait->pio_busy);
  258. }
  259. /**
  260. * iowait_drain_wakeup() - trigger iowait_drain() waiter
  261. *
  262. * @wait: iowait structure
  263. *
  264. * This will trigger any waiters.
  265. */
  266. static inline void iowait_drain_wakeup(struct iowait *wait)
  267. {
  268. wake_up(&wait->wait_dma);
  269. wake_up(&wait->wait_pio);
  270. if (wait->sdma_drained)
  271. wait->sdma_drained(wait);
  272. }
  273. /**
  274. * iowait_get_txhead() - get packet off of iowait list
  275. *
  276. * @wait wait struture
  277. */
  278. static inline struct sdma_txreq *iowait_get_txhead(struct iowait *wait)
  279. {
  280. struct sdma_txreq *tx = NULL;
  281. if (!list_empty(&wait->tx_head)) {
  282. tx = list_first_entry(
  283. &wait->tx_head,
  284. struct sdma_txreq,
  285. list);
  286. list_del_init(&tx->list);
  287. }
  288. return tx;
  289. }
  290. /**
  291. * iowait_queue - Put the iowait on a wait queue
  292. * @pkts_sent: have some packets been sent before queuing?
  293. * @w: the iowait struct
  294. * @wait_head: the wait queue
  295. *
  296. * This function is called to insert an iowait struct into a
  297. * wait queue after a resource (eg, sdma decriptor or pio
  298. * buffer) is run out.
  299. */
  300. static inline void iowait_queue(bool pkts_sent, struct iowait *w,
  301. struct list_head *wait_head)
  302. {
  303. /*
  304. * To play fair, insert the iowait at the tail of the wait queue if it
  305. * has already sent some packets; Otherwise, put it at the head.
  306. */
  307. if (pkts_sent) {
  308. list_add_tail(&w->list, wait_head);
  309. w->starved_cnt = 0;
  310. } else {
  311. list_add(&w->list, wait_head);
  312. w->starved_cnt++;
  313. }
  314. }
  315. /**
  316. * iowait_starve_clear - clear the wait queue's starve count
  317. * @pkts_sent: have some packets been sent?
  318. * @w: the iowait struct
  319. *
  320. * This function is called to clear the starve count. If no
  321. * packets have been sent, the starve count will not be cleared.
  322. */
  323. static inline void iowait_starve_clear(bool pkts_sent, struct iowait *w)
  324. {
  325. if (pkts_sent)
  326. w->starved_cnt = 0;
  327. }
  328. /**
  329. * iowait_starve_find_max - Find the maximum of the starve count
  330. * @w: the iowait struct
  331. * @max: a variable containing the max starve count
  332. * @idx: the index of the current iowait in an array
  333. * @max_idx: a variable containing the array index for the
  334. * iowait entry that has the max starve count
  335. *
  336. * This function is called to compare the starve count of a
  337. * given iowait with the given max starve count. The max starve
  338. * count and the index will be updated if the iowait's start
  339. * count is larger.
  340. */
  341. static inline void iowait_starve_find_max(struct iowait *w, u8 *max,
  342. uint idx, uint *max_idx)
  343. {
  344. if (w->starved_cnt > *max) {
  345. *max = w->starved_cnt;
  346. *max_idx = idx;
  347. }
  348. }
  349. /**
  350. * iowait_packet_queued() - determine if a packet is already built
  351. * @wait: the wait structure
  352. */
  353. static inline bool iowait_packet_queued(struct iowait *wait)
  354. {
  355. return !list_empty(&wait->tx_head);
  356. }
  357. #endif