68 lines
1.7 KiB
C
68 lines
1.7 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
|
|
/*
|
|
* Copyright © 2019 Intel Corporation
|
|
*/
|
|
|
|
#ifndef I915_SW_FENCE_WORK_H
|
|
#define I915_SW_FENCE_WORK_H
|
|
|
|
#include <linux/dma-fence.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/workqueue.h>
|
|
|
|
#include "i915_sw_fence.h"
|
|
|
|
struct dma_fence_work;
|
|
|
|
struct dma_fence_work_ops {
|
|
const char *name;
|
|
void (*work)(struct dma_fence_work *f);
|
|
void (*release)(struct dma_fence_work *f);
|
|
};
|
|
|
|
struct dma_fence_work {
|
|
struct dma_fence dma;
|
|
spinlock_t lock;
|
|
|
|
struct i915_sw_fence chain;
|
|
struct i915_sw_dma_fence_cb cb;
|
|
|
|
struct work_struct work;
|
|
const struct dma_fence_work_ops *ops;
|
|
};
|
|
|
|
enum {
|
|
DMA_FENCE_WORK_IMM = DMA_FENCE_FLAG_USER_BITS,
|
|
};
|
|
|
|
void dma_fence_work_init(struct dma_fence_work *f,
|
|
const struct dma_fence_work_ops *ops);
|
|
int dma_fence_work_chain(struct dma_fence_work *f, struct dma_fence *signal);
|
|
|
|
static inline void dma_fence_work_commit(struct dma_fence_work *f)
|
|
{
|
|
i915_sw_fence_commit(&f->chain);
|
|
}
|
|
|
|
/**
|
|
* dma_fence_work_commit_imm: Commit the fence, and if possible execute locally.
|
|
* @f: the fenced worker
|
|
*
|
|
* Instead of always scheduling a worker to execute the callback (see
|
|
* dma_fence_work_commit()), we try to execute the callback immediately in
|
|
* the local context. It is required that the fence be committed before it
|
|
* is published, and that no other threads try to tamper with the number
|
|
* of asynchronous waits on the fence (or else the callback will be
|
|
* executed in the wrong context, i.e. not the callers).
|
|
*/
|
|
static inline void dma_fence_work_commit_imm(struct dma_fence_work *f)
|
|
{
|
|
if (atomic_read(&f->chain.pending) <= 1)
|
|
__set_bit(DMA_FENCE_WORK_IMM, &f->dma.flags);
|
|
|
|
dma_fence_work_commit(f);
|
|
}
|
|
|
|
#endif /* I915_SW_FENCE_WORK_H */
|