File: | dev/pci/drm/i915/gt/intel_ring.h |
Warning: | line 92, column 15 Value stored to 'head' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * SPDX-License-Identifier: MIT |
3 | * |
4 | * Copyright © 2019 Intel Corporation |
5 | */ |
6 | |
7 | #ifndef INTEL_RING_H |
8 | #define INTEL_RING_H |
9 | |
10 | #include "i915_gem.h" /* GEM_BUG_ON */ |
11 | #include "i915_request.h" |
12 | #include "intel_ring_types.h" |
13 | |
14 | struct intel_engine_cs; |
15 | |
16 | struct intel_ring * |
17 | intel_engine_create_ring(struct intel_engine_cs *engine, int size); |
18 | |
19 | u32 *intel_ring_begin(struct i915_request *rq, unsigned int num_dwords); |
20 | int intel_ring_cacheline_align(struct i915_request *rq); |
21 | |
22 | unsigned int intel_ring_update_space(struct intel_ring *ring); |
23 | |
24 | void __intel_ring_pin(struct intel_ring *ring); |
25 | int intel_ring_pin(struct intel_ring *ring, struct i915_gem_ww_ctx *ww); |
26 | void intel_ring_unpin(struct intel_ring *ring); |
27 | void intel_ring_reset(struct intel_ring *ring, u32 tail); |
28 | |
29 | void intel_ring_free(struct kref *ref); |
30 | |
31 | static inline struct intel_ring *intel_ring_get(struct intel_ring *ring) |
32 | { |
33 | kref_get(&ring->ref); |
34 | return ring; |
35 | } |
36 | |
37 | static inline void intel_ring_put(struct intel_ring *ring) |
38 | { |
39 | kref_put(&ring->ref, intel_ring_free); |
40 | } |
41 | |
42 | static inline void intel_ring_advance(struct i915_request *rq, u32 *cs) |
43 | { |
44 | /* Dummy function. |
45 | * |
46 | * This serves as a placeholder in the code so that the reader |
47 | * can compare against the preceding intel_ring_begin() and |
48 | * check that the number of dwords emitted matches the space |
49 | * reserved for the command packet (i.e. the value passed to |
50 | * intel_ring_begin()). |
51 | */ |
52 | GEM_BUG_ON((rq->ring->vaddr + rq->ring->emit) != cs)((void)0); |
53 | } |
54 | |
55 | static inline u32 intel_ring_wrap(const struct intel_ring *ring, u32 pos) |
56 | { |
57 | return pos & (ring->size - 1); |
58 | } |
59 | |
60 | static inline int intel_ring_direction(const struct intel_ring *ring, |
61 | u32 next, u32 prev) |
62 | { |
63 | typecheck(typeof(ring->size), next)1; |
64 | typecheck(typeof(ring->size), prev)1; |
65 | return (next - prev) << ring->wrap; |
66 | } |
67 | |
68 | static inline bool_Bool |
69 | intel_ring_offset_valid(const struct intel_ring *ring, |
70 | unsigned int pos) |
71 | { |
72 | if (pos & -ring->size) /* must be strictly within the ring */ |
73 | return false0; |
74 | |
75 | if (!IS_ALIGNED(pos, 8)(((pos) & ((8) - 1)) == 0)) /* must be qword aligned */ |
76 | return false0; |
77 | |
78 | return true1; |
79 | } |
80 | |
81 | static inline u32 intel_ring_offset(const struct i915_request *rq, void *addr) |
82 | { |
83 | /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ |
84 | u32 offset = addr - rq->ring->vaddr; |
85 | GEM_BUG_ON(offset > rq->ring->size)((void)0); |
86 | return intel_ring_wrap(rq->ring, offset); |
87 | } |
88 | |
89 | static inline void |
90 | assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail) |
91 | { |
92 | unsigned int head = READ_ONCE(ring->head)({ typeof(ring->head) __tmp = *(volatile typeof(ring->head ) *)&(ring->head); membar_datadep_consumer(); __tmp; } ); |
Value stored to 'head' during its initialization is never read | |
93 | |
94 | GEM_BUG_ON(!intel_ring_offset_valid(ring, tail))((void)0); |
95 | |
96 | /* |
97 | * "Ring Buffer Use" |
98 | * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 |
99 | * Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5 |
100 | * Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5 |
101 | * "If the Ring Buffer Head Pointer and the Tail Pointer are on the |
102 | * same cacheline, the Head Pointer must not be greater than the Tail |
103 | * Pointer." |
104 | * |
105 | * We use ring->head as the last known location of the actual RING_HEAD, |
106 | * it may have advanced but in the worst case it is equally the same |
107 | * as ring->head and so we should never program RING_TAIL to advance |
108 | * into the same cacheline as ring->head. |
109 | */ |
110 | #define cacheline(a) round_down(a, CACHELINE_BYTES)(((a) / (64)) * (64)) |
111 | GEM_BUG_ON(cacheline(tail) == cacheline(head) && tail < head)((void)0); |
112 | #undef cacheline |
113 | } |
114 | |
115 | static inline unsigned int |
116 | intel_ring_set_tail(struct intel_ring *ring, unsigned int tail) |
117 | { |
118 | /* Whilst writes to the tail are strictly order, there is no |
119 | * serialisation between readers and the writers. The tail may be |
120 | * read by i915_request_retire() just as it is being updated |
121 | * by execlists, as although the breadcrumb is complete, the context |
122 | * switch hasn't been seen. |
123 | */ |
124 | assert_ring_tail_valid(ring, tail); |
125 | ring->tail = tail; |
126 | return tail; |
127 | } |
128 | |
129 | static inline unsigned int |
130 | __intel_ring_space(unsigned int head, unsigned int tail, unsigned int size) |
131 | { |
132 | /* |
133 | * "If the Ring Buffer Head Pointer and the Tail Pointer are on the |
134 | * same cacheline, the Head Pointer must not be greater than the Tail |
135 | * Pointer." |
136 | */ |
137 | GEM_BUG_ON(!is_power_of_2(size))((void)0); |
138 | return (head - tail - CACHELINE_BYTES64) & (size - 1); |
139 | } |
140 | |
141 | #endif /* INTEL_RING_H */ |