summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/xe/xe_range_fence.h
blob: edd58b34f5c0b6d3bb031af39f44abcf2e0a0600 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2023 Intel Corporation
 */

#ifndef _XE_RANGE_FENCE_H_
#define _XE_RANGE_FENCE_H_

#include <linux/dma-fence.h>
#include <linux/rbtree.h>
#include <linux/types.h>

struct xe_range_fence_tree;
struct xe_range_fence;

/** struct xe_range_fence_ops - XE range fence ops */
struct xe_range_fence_ops {
	/** @free: free range fence op */
	void (*free)(struct xe_range_fence *rfence);
};

/** struct xe_range_fence - XE range fence (address conflict tracking) */
struct xe_range_fence {
	/** @rb: RB tree node inserted into interval tree */
	struct rb_node rb;
	/** @start: start address of range fence is interval tree */
	u64 start;
	/** @last: last address (inclusive) of range fence is interval tree */
	u64 last;
	/** @__subtree_last: interval tree internal usage */
	u64 __subtree_last;
	/**
	 * @fence: fence signals address in range fence no longer has conflict
	 */
	struct dma_fence *fence;
	/** @tree: interval tree which range fence belongs to */
	struct xe_range_fence_tree *tree;
	/**
	 * @cb: callback when fence signals to remove range fence free from interval tree
	 */
	struct dma_fence_cb cb;
	/** @link: used to defer free of range fence to non-irq context */
	struct llist_node link;
	/** @ops: range fence ops */
	const struct xe_range_fence_ops *ops;
};

/** struct xe_range_fence_tree - interval tree to store range fences */
struct xe_range_fence_tree {
	/** @root: interval tree root */
	struct rb_root_cached root;
	/** @list: list of pending range fences to be freed */
	struct llist_head list;
};

extern const struct xe_range_fence_ops xe_range_fence_kfree_ops;

struct xe_range_fence *
xe_range_fence_tree_first(struct xe_range_fence_tree *tree, u64 start,
			  u64 last);

struct xe_range_fence *
xe_range_fence_tree_next(struct xe_range_fence *rfence, u64 start, u64 last);

void xe_range_fence_tree_init(struct xe_range_fence_tree *tree);

void xe_range_fence_tree_fini(struct xe_range_fence_tree *tree);

int xe_range_fence_insert(struct xe_range_fence_tree *tree,
			  struct xe_range_fence *rfence,
			  const struct xe_range_fence_ops *ops,
			  u64 start, u64 end,
			  struct dma_fence *fence);

#endif