dma-fence-chain.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * fence-chain: chain fences together in a timeline
  4. *
  5. * Copyright (C) 2018 Advanced Micro Devices, Inc.
  6. * Authors:
  7. * Christian König <[email protected]>
  8. */
  9. #ifndef __LINUX_DMA_FENCE_CHAIN_H
  10. #define __LINUX_DMA_FENCE_CHAIN_H
  11. #include <linux/dma-fence.h>
  12. #include <linux/irq_work.h>
  13. #include <linux/slab.h>
  14. /**
  15. * struct dma_fence_chain - fence to represent an node of a fence chain
  16. * @base: fence base class
  17. * @prev: previous fence of the chain
  18. * @prev_seqno: original previous seqno before garbage collection
  19. * @fence: encapsulated fence
  20. * @lock: spinlock for fence handling
  21. */
  22. struct dma_fence_chain {
  23. struct dma_fence base;
  24. struct dma_fence __rcu *prev;
  25. u64 prev_seqno;
  26. struct dma_fence *fence;
  27. union {
  28. /**
  29. * @cb: callback for signaling
  30. *
  31. * This is used to add the callback for signaling the
  32. * complection of the fence chain. Never used at the same time
  33. * as the irq work.
  34. */
  35. struct dma_fence_cb cb;
  36. /**
  37. * @work: irq work item for signaling
  38. *
  39. * Irq work structure to allow us to add the callback without
  40. * running into lock inversion. Never used at the same time as
  41. * the callback.
  42. */
  43. struct irq_work work;
  44. };
  45. spinlock_t lock;
  46. };
  47. /**
  48. * to_dma_fence_chain - cast a fence to a dma_fence_chain
  49. * @fence: fence to cast to a dma_fence_array
  50. *
  51. * Returns NULL if the fence is not a dma_fence_chain,
  52. * or the dma_fence_chain otherwise.
  53. */
  54. static inline struct dma_fence_chain *
  55. to_dma_fence_chain(struct dma_fence *fence)
  56. {
  57. if (!fence || !dma_fence_is_chain(fence))
  58. return NULL;
  59. return container_of(fence, struct dma_fence_chain, base);
  60. }
  61. /**
  62. * dma_fence_chain_contained - return the contained fence
  63. * @fence: the fence to test
  64. *
  65. * If the fence is a dma_fence_chain the function returns the fence contained
  66. * inside the chain object, otherwise it returns the fence itself.
  67. */
  68. static inline struct dma_fence *
  69. dma_fence_chain_contained(struct dma_fence *fence)
  70. {
  71. struct dma_fence_chain *chain = to_dma_fence_chain(fence);
  72. return chain ? chain->fence : fence;
  73. }
  74. /**
  75. * dma_fence_chain_alloc
  76. *
  77. * Returns a new struct dma_fence_chain object or NULL on failure.
  78. */
  79. static inline struct dma_fence_chain *dma_fence_chain_alloc(void)
  80. {
  81. return kmalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
  82. };
  83. /**
  84. * dma_fence_chain_free
  85. * @chain: chain node to free
  86. *
  87. * Frees up an allocated but not used struct dma_fence_chain object. This
  88. * doesn't need an RCU grace period since the fence was never initialized nor
  89. * published. After dma_fence_chain_init() has been called the fence must be
  90. * released by calling dma_fence_put(), and not through this function.
  91. */
  92. static inline void dma_fence_chain_free(struct dma_fence_chain *chain)
  93. {
  94. kfree(chain);
  95. };
  96. /**
  97. * dma_fence_chain_for_each - iterate over all fences in chain
  98. * @iter: current fence
  99. * @head: starting point
  100. *
  101. * Iterate over all fences in the chain. We keep a reference to the current
  102. * fence while inside the loop which must be dropped when breaking out.
  103. *
  104. * For a deep dive iterator see dma_fence_unwrap_for_each().
  105. */
  106. #define dma_fence_chain_for_each(iter, head) \
  107. for (iter = dma_fence_get(head); iter; \
  108. iter = dma_fence_chain_walk(iter))
  109. struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence);
  110. int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno);
  111. void dma_fence_chain_init(struct dma_fence_chain *chain,
  112. struct dma_fence *prev,
  113. struct dma_fence *fence,
  114. uint64_t seqno);
  115. #endif /* __LINUX_DMA_FENCE_CHAIN_H */