libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD.
[linux-2.6-microblaze.git] / include / linux / dma-fence-chain.h
index 10462a0..54fe344 100644 (file)
 
 #include <linux/dma-fence.h>
 #include <linux/irq_work.h>
+#include <linux/slab.h>
 
 /**
  * struct dma_fence_chain - fence to represent an node of a fence chain
  * @base: fence base class
- * @lock: spinlock for fence handling
  * @prev: previous fence of the chain
  * @prev_seqno: original previous seqno before garbage collection
  * @fence: encapsulated fence
- * @cb: callback structure for signaling
- * @work: irq work item for signaling
+ * @lock: spinlock for fence handling
  */
 struct dma_fence_chain {
        struct dma_fence base;
-       spinlock_t lock;
        struct dma_fence __rcu *prev;
        u64 prev_seqno;
        struct dma_fence *fence;
-       struct dma_fence_cb cb;
-       struct irq_work work;
+       union {
+               /**
+                * @cb: callback for signaling
+                *
+                * This is used to add the callback for signaling the
+                * complection of the fence chain. Never used at the same time
+                * as the irq work.
+                */
+               struct dma_fence_cb cb;
+
+               /**
+                * @work: irq work item for signaling
+                *
+                * Irq work structure to allow us to add the callback without
+                * running into lock inversion. Never used at the same time as
+                * the callback.
+                */
+               struct irq_work work;
+       };
+       spinlock_t lock;
 };
 
 extern const struct dma_fence_ops dma_fence_chain_ops;
@@ -51,6 +67,30 @@ to_dma_fence_chain(struct dma_fence *fence)
        return container_of(fence, struct dma_fence_chain, base);
 }
 
+/**
+ * dma_fence_chain_alloc
+ *
+ * Returns a new struct dma_fence_chain object or NULL on failure.
+ */
+static inline struct dma_fence_chain *dma_fence_chain_alloc(void)
+{
+       return kmalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+};
+
+/**
+ * dma_fence_chain_free
+ * @chain: chain node to free
+ *
+ * Frees up an allocated but not used struct dma_fence_chain object. This
+ * doesn't need an RCU grace period since the fence was never initialized nor
+ * published. After dma_fence_chain_init() has been called the fence must be
+ * released by calling dma_fence_put(), and not through this function.
+ */
+static inline void dma_fence_chain_free(struct dma_fence_chain *chain)
+{
+       kfree(chain);
+};
+
 /**
  * dma_fence_chain_for_each - iterate over all fences in chain
  * @iter: current fence