iowait.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #ifndef _HFI1_IOWAIT_H
  2. #define _HFI1_IOWAIT_H
  3. /*
  4. * Copyright(c) 2015 - 2018 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/wait.h>
  52. #include <linux/sched.h>
  53. #include "sdma_txreq.h"
  54. /*
  55. * typedef (*restart_t)() - restart callback
  56. * @work: pointer to work structure
  57. */
  58. typedef void (*restart_t)(struct work_struct *work);
  59. #define IOWAIT_PENDING_IB 0x0
  60. #define IOWAIT_PENDING_TID 0x1
  61. /*
  62. * A QP can have multiple Send Engines (SEs).
  63. *
  64. * The current use case is for supporting a TID RDMA
  65. * packet build/xmit mechanism independent from verbs.
  66. */
  67. #define IOWAIT_SES 2
  68. #define IOWAIT_IB_SE 0
  69. #define IOWAIT_TID_SE 1
  70. struct sdma_txreq;
  71. struct sdma_engine;
  72. /**
  73. * @iowork: the work struct
  74. * @tx_head: list of prebuilt packets
  75. * @iow: the parent iowait structure
  76. *
  77. * This structure is the work item (process) specific
  78. * details associated with the each of the two SEs of the
  79. * QP.
  80. *
  81. * The workstruct and the queued TXs are unique to each
  82. * SE.
  83. */
  84. struct iowait;
  85. struct iowait_work {
  86. struct work_struct iowork;
  87. struct list_head tx_head;
  88. struct iowait *iow;
  89. };
  90. /**
  91. * @list: used to add/insert into QP/PQ wait lists
  92. * @tx_head: overflow list of sdma_txreq's
  93. * @sleep: no space callback
  94. * @wakeup: space callback wakeup
  95. * @sdma_drained: sdma count drained
  96. * @lock: lock protected head of wait queue
  97. * @iowork: workqueue overhead
  98. * @wait_dma: wait for sdma_busy == 0
  99. * @wait_pio: wait for pio_busy == 0
  100. * @sdma_busy: # of packets in flight
  101. * @count: total number of descriptors in tx_head'ed list
  102. * @tx_limit: limit for overflow queuing
  103. * @tx_count: number of tx entry's in tx_head'ed list
  104. * @flags: wait flags (one per QP)
  105. * @wait: SE array
  106. *
  107. * This is to be embedded in user's state structure
  108. * (QP or PQ).
  109. *
  110. * The sleep and wakeup members are a
  111. * bit misnamed. They do not strictly
  112. * speaking sleep or wake up, but they
  113. * are callbacks for the ULP to implement
  114. * what ever queuing/dequeuing of
  115. * the embedded iowait and its containing struct
  116. * when a resource shortage like SDMA ring space is seen.
  117. *
  118. * Both potentially have locks help
  119. * so sleeping is not allowed.
  120. *
  121. * The wait_dma member along with the iow
  122. *
  123. * The lock field is used by waiters to record
  124. * the seqlock_t that guards the list head.
  125. * Waiters explicity know that, but the destroy
  126. * code that unwaits QPs does not.
  127. */
  128. struct iowait {
  129. struct list_head list;
  130. int (*sleep)(
  131. struct sdma_engine *sde,
  132. struct iowait_work *wait,
  133. struct sdma_txreq *tx,
  134. uint seq,
  135. bool pkts_sent
  136. );
  137. void (*wakeup)(struct iowait *wait, int reason);
  138. void (*sdma_drained)(struct iowait *wait);
  139. seqlock_t *lock;
  140. wait_queue_head_t wait_dma;
  141. wait_queue_head_t wait_pio;
  142. atomic_t sdma_busy;
  143. atomic_t pio_busy;
  144. u32 count;
  145. u32 tx_limit;
  146. u32 tx_count;
  147. u8 starved_cnt;
  148. unsigned long flags;
  149. struct iowait_work wait[IOWAIT_SES];
  150. };
  151. #define SDMA_AVAIL_REASON 0
  152. void iowait_set_flag(struct iowait *wait, u32 flag);
  153. bool iowait_flag_set(struct iowait *wait, u32 flag);
  154. void iowait_clear_flag(struct iowait *wait, u32 flag);
  155. void iowait_init(struct iowait *wait, u32 tx_limit,
  156. void (*func)(struct work_struct *work),
  157. void (*tidfunc)(struct work_struct *work),
  158. int (*sleep)(struct sdma_engine *sde,
  159. struct iowait_work *wait,
  160. struct sdma_txreq *tx,
  161. uint seq,
  162. bool pkts_sent),
  163. void (*wakeup)(struct iowait *wait, int reason),
  164. void (*sdma_drained)(struct iowait *wait));
  165. /**
  166. * iowait_schedule() - schedule the default send engine work
  167. * @wait: wait struct to schedule
  168. * @wq: workqueue for schedule
  169. * @cpu: cpu
  170. */
  171. static inline bool iowait_schedule(struct iowait *wait,
  172. struct workqueue_struct *wq, int cpu)
  173. {
  174. return !!queue_work_on(cpu, wq, &wait->wait[IOWAIT_IB_SE].iowork);
  175. }
  176. /**
  177. * iowait_sdma_drain() - wait for DMAs to drain
  178. *
  179. * @wait: iowait structure
  180. *
  181. * This will delay until the iowait sdmas have
  182. * completed.
  183. */
  184. static inline void iowait_sdma_drain(struct iowait *wait)
  185. {
  186. wait_event(wait->wait_dma, !atomic_read(&wait->sdma_busy));
  187. }
  188. /**
  189. * iowait_sdma_pending() - return sdma pending count
  190. *
  191. * @wait: iowait structure
  192. *
  193. */
  194. static inline int iowait_sdma_pending(struct iowait *wait)
  195. {
  196. return atomic_read(&wait->sdma_busy);
  197. }
  198. /**
  199. * iowait_sdma_inc - note sdma io pending
  200. * @wait: iowait structure
  201. */
  202. static inline void iowait_sdma_inc(struct iowait *wait)
  203. {
  204. atomic_inc(&wait->sdma_busy);
  205. }
  206. /**
  207. * iowait_sdma_add - add count to pending
  208. * @wait: iowait structure
  209. */
  210. static inline void iowait_sdma_add(struct iowait *wait, int count)
  211. {
  212. atomic_add(count, &wait->sdma_busy);
  213. }
  214. /**
  215. * iowait_sdma_dec - note sdma complete
  216. * @wait: iowait structure
  217. */
  218. static inline int iowait_sdma_dec(struct iowait *wait)
  219. {
  220. if (!wait)
  221. return 0;
  222. return atomic_dec_and_test(&wait->sdma_busy);
  223. }
  224. /**
  225. * iowait_pio_drain() - wait for pios to drain
  226. *
  227. * @wait: iowait structure
  228. *
  229. * This will delay until the iowait pios have
  230. * completed.
  231. */
  232. static inline void iowait_pio_drain(struct iowait *wait)
  233. {
  234. wait_event_timeout(wait->wait_pio,
  235. !atomic_read(&wait->pio_busy),
  236. HZ);
  237. }
  238. /**
  239. * iowait_pio_pending() - return pio pending count
  240. *
  241. * @wait: iowait structure
  242. *
  243. */
  244. static inline int iowait_pio_pending(struct iowait *wait)
  245. {
  246. return atomic_read(&wait->pio_busy);
  247. }
  248. /**
  249. * iowait_pio_inc - note pio pending
  250. * @wait: iowait structure
  251. */
  252. static inline void iowait_pio_inc(struct iowait *wait)
  253. {
  254. atomic_inc(&wait->pio_busy);
  255. }
  256. /**
  257. * iowait_pio_dec - note pio complete
  258. * @wait: iowait structure
  259. */
  260. static inline int iowait_pio_dec(struct iowait *wait)
  261. {
  262. if (!wait)
  263. return 0;
  264. return atomic_dec_and_test(&wait->pio_busy);
  265. }
  266. /**
  267. * iowait_drain_wakeup() - trigger iowait_drain() waiter
  268. *
  269. * @wait: iowait structure
  270. *
  271. * This will trigger any waiters.
  272. */
  273. static inline void iowait_drain_wakeup(struct iowait *wait)
  274. {
  275. wake_up(&wait->wait_dma);
  276. wake_up(&wait->wait_pio);
  277. if (wait->sdma_drained)
  278. wait->sdma_drained(wait);
  279. }
  280. /**
  281. * iowait_get_txhead() - get packet off of iowait list
  282. *
  283. * @wait iowait_work struture
  284. */
  285. static inline struct sdma_txreq *iowait_get_txhead(struct iowait_work *wait)
  286. {
  287. struct sdma_txreq *tx = NULL;
  288. if (!list_empty(&wait->tx_head)) {
  289. tx = list_first_entry(
  290. &wait->tx_head,
  291. struct sdma_txreq,
  292. list);
  293. list_del_init(&tx->list);
  294. }
  295. return tx;
  296. }
  297. static inline u16 iowait_get_desc(struct iowait_work *w)
  298. {
  299. u16 num_desc = 0;
  300. struct sdma_txreq *tx = NULL;
  301. if (!list_empty(&w->tx_head)) {
  302. tx = list_first_entry(&w->tx_head, struct sdma_txreq,
  303. list);
  304. num_desc = tx->num_desc;
  305. }
  306. return num_desc;
  307. }
  308. static inline u32 iowait_get_all_desc(struct iowait *w)
  309. {
  310. u32 num_desc = 0;
  311. num_desc = iowait_get_desc(&w->wait[IOWAIT_IB_SE]);
  312. num_desc += iowait_get_desc(&w->wait[IOWAIT_TID_SE]);
  313. return num_desc;
  314. }
  315. /**
  316. * iowait_queue - Put the iowait on a wait queue
  317. * @pkts_sent: have some packets been sent before queuing?
  318. * @w: the iowait struct
  319. * @wait_head: the wait queue
  320. *
  321. * This function is called to insert an iowait struct into a
  322. * wait queue after a resource (eg, sdma decriptor or pio
  323. * buffer) is run out.
  324. */
  325. static inline void iowait_queue(bool pkts_sent, struct iowait *w,
  326. struct list_head *wait_head)
  327. {
  328. /*
  329. * To play fair, insert the iowait at the tail of the wait queue if it
  330. * has already sent some packets; Otherwise, put it at the head.
  331. */
  332. if (pkts_sent) {
  333. list_add_tail(&w->list, wait_head);
  334. w->starved_cnt = 0;
  335. } else {
  336. list_add(&w->list, wait_head);
  337. w->starved_cnt++;
  338. }
  339. }
  340. /**
  341. * iowait_starve_clear - clear the wait queue's starve count
  342. * @pkts_sent: have some packets been sent?
  343. * @w: the iowait struct
  344. *
  345. * This function is called to clear the starve count. If no
  346. * packets have been sent, the starve count will not be cleared.
  347. */
  348. static inline void iowait_starve_clear(bool pkts_sent, struct iowait *w)
  349. {
  350. if (pkts_sent)
  351. w->starved_cnt = 0;
  352. }
  353. /**
  354. * iowait_starve_find_max - Find the maximum of the starve count
  355. * @w: the iowait struct
  356. * @max: a variable containing the max starve count
  357. * @idx: the index of the current iowait in an array
  358. * @max_idx: a variable containing the array index for the
  359. * iowait entry that has the max starve count
  360. *
  361. * This function is called to compare the starve count of a
  362. * given iowait with the given max starve count. The max starve
  363. * count and the index will be updated if the iowait's start
  364. * count is larger.
  365. */
  366. static inline void iowait_starve_find_max(struct iowait *w, u8 *max,
  367. uint idx, uint *max_idx)
  368. {
  369. if (w->starved_cnt > *max) {
  370. *max = w->starved_cnt;
  371. *max_idx = idx;
  372. }
  373. }
  374. /**
  375. * iowait_packet_queued() - determine if a packet is queued
  376. * @wait: the iowait_work structure
  377. */
  378. static inline bool iowait_packet_queued(struct iowait_work *wait)
  379. {
  380. return !list_empty(&wait->tx_head);
  381. }
  382. /**
  383. * inc_wait_count - increment wait counts
  384. * @w: the log work struct
  385. * @n: the count
  386. */
  387. static inline void iowait_inc_wait_count(struct iowait_work *w, u16 n)
  388. {
  389. if (!w)
  390. return;
  391. w->iow->tx_count++;
  392. w->iow->count += n;
  393. }
  394. /**
  395. * iowait_get_tid_work - return iowait_work for tid SE
  396. * @w: the iowait struct
  397. */
  398. static inline struct iowait_work *iowait_get_tid_work(struct iowait *w)
  399. {
  400. return &w->wait[IOWAIT_TID_SE];
  401. }
  402. /**
  403. * iowait_get_ib_work - return iowait_work for ib SE
  404. * @w: the iowait struct
  405. */
  406. static inline struct iowait_work *iowait_get_ib_work(struct iowait *w)
  407. {
  408. return &w->wait[IOWAIT_IB_SE];
  409. }
  410. /**
  411. * iowait_ioww_to_iow - return iowait given iowait_work
  412. * @w: the iowait_work struct
  413. */
  414. static inline struct iowait *iowait_ioww_to_iow(struct iowait_work *w)
  415. {
  416. if (likely(w))
  417. return w->iow;
  418. return NULL;
  419. }
  420. void iowait_cancel_work(struct iowait *w);
  421. int iowait_set_work_flag(struct iowait_work *w);
  422. #endif