iowait.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  2. /*
  3. * Copyright(c) 2018 Intel Corporation.
  4. *
  5. */
  6. #include "iowait.h"
  7. #include "trace_iowait.h"
  8. void iowait_set_flag(struct iowait *wait, u32 flag)
  9. {
  10. trace_hfi1_iowait_set(wait, flag);
  11. set_bit(flag, &wait->flags);
  12. }
  13. bool iowait_flag_set(struct iowait *wait, u32 flag)
  14. {
  15. return test_bit(flag, &wait->flags);
  16. }
  17. inline void iowait_clear_flag(struct iowait *wait, u32 flag)
  18. {
  19. trace_hfi1_iowait_clear(wait, flag);
  20. clear_bit(flag, &wait->flags);
  21. }
  22. /**
  23. * iowait_init() - initialize wait structure
  24. * @wait: wait struct to initialize
  25. * @tx_limit: limit for overflow queuing
  26. * @func: restart function for workqueue
  27. * @sleep: sleep function for no space
  28. * @resume: wakeup function for no space
  29. *
  30. * This function initializes the iowait
  31. * structure embedded in the QP or PQ.
  32. *
  33. */
  34. void iowait_init(struct iowait *wait, u32 tx_limit,
  35. void (*func)(struct work_struct *work),
  36. void (*tidfunc)(struct work_struct *work),
  37. int (*sleep)(struct sdma_engine *sde,
  38. struct iowait_work *wait,
  39. struct sdma_txreq *tx,
  40. uint seq,
  41. bool pkts_sent),
  42. void (*wakeup)(struct iowait *wait, int reason),
  43. void (*sdma_drained)(struct iowait *wait))
  44. {
  45. int i;
  46. wait->count = 0;
  47. INIT_LIST_HEAD(&wait->list);
  48. init_waitqueue_head(&wait->wait_dma);
  49. init_waitqueue_head(&wait->wait_pio);
  50. atomic_set(&wait->sdma_busy, 0);
  51. atomic_set(&wait->pio_busy, 0);
  52. wait->tx_limit = tx_limit;
  53. wait->sleep = sleep;
  54. wait->wakeup = wakeup;
  55. wait->sdma_drained = sdma_drained;
  56. wait->flags = 0;
  57. for (i = 0; i < IOWAIT_SES; i++) {
  58. wait->wait[i].iow = wait;
  59. INIT_LIST_HEAD(&wait->wait[i].tx_head);
  60. if (i == IOWAIT_IB_SE)
  61. INIT_WORK(&wait->wait[i].iowork, func);
  62. else
  63. INIT_WORK(&wait->wait[i].iowork, tidfunc);
  64. }
  65. }
  66. /**
  67. * iowait_cancel_work - cancel all work in iowait
  68. * @w: the iowait struct
  69. */
  70. void iowait_cancel_work(struct iowait *w)
  71. {
  72. cancel_work_sync(&iowait_get_ib_work(w)->iowork);
  73. cancel_work_sync(&iowait_get_tid_work(w)->iowork);
  74. }
  75. /**
  76. * iowait_set_work_flag - set work flag based on leg
  77. * @w - the iowait work struct
  78. */
  79. int iowait_set_work_flag(struct iowait_work *w)
  80. {
  81. if (w == &w->iow->wait[IOWAIT_IB_SE]) {
  82. iowait_set_flag(w->iow, IOWAIT_PENDING_IB);
  83. return IOWAIT_IB_SE;
  84. }
  85. iowait_set_flag(w->iow, IOWAIT_PENDING_TID);
  86. return IOWAIT_TID_SE;
  87. }