[Intel-gfx] [PATCH 4/4] drm/i915/gt: Distinguish the virtual breadcrumbs from the irq breadcrumbs
kernel test robot
lkp at intel.com
Fri Jul 17 15:50:35 UTC 2020
Hi Chris,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on drm-intel/for-linux-next]
[also build test WARNING on drm-tip/drm-tip next-20200717]
[cannot apply to linus/master v5.8-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Chris-Wilson/drm-i915-Remove-requirement-for-holding-i915_request-lock-for-breadcrumbs/20200717-173754
base: git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-14) 9.3.0
reproduce (this is a W=1 build):
# save the attached .config to linux build tree
make W=1 ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>
All warnings (new ones prefixed by >>):
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:71:6: warning: no previous prototype for 'intel_breadcrumbs_park' [-Wmissing-prototypes]
71 | void intel_breadcrumbs_park(struct intel_breadcrumbs *b)
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:248:1: warning: no previous prototype for 'intel_breadcrumbs_create' [-Wmissing-prototypes]
248 | intel_breadcrumbs_create(struct intel_engine_cs *irq_engine)
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:269:6: warning: no previous prototype for 'intel_breadcrumbs_reset' [-Wmissing-prototypes]
269 | void intel_breadcrumbs_reset(struct intel_breadcrumbs *b)
| ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:286:6: warning: no previous prototype for 'intel_breadcrumbs_free' [-Wmissing-prototypes]
286 | void intel_breadcrumbs_free(struct intel_breadcrumbs *b)
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:344:6: warning: no previous prototype for 'i915_request_enable_breadcrumb' [-Wmissing-prototypes]
344 | bool i915_request_enable_breadcrumb(struct i915_request *rq)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:400:6: warning: no previous prototype for 'i915_request_cancel_breadcrumb' [-Wmissing-prototypes]
400 | void i915_request_cancel_breadcrumb(struct i915_request *rq)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_breadcrumbs.c:423:6: warning: no previous prototype for 'intel_engine_print_breadcrumbs' [-Wmissing-prototypes]
423 | void intel_engine_print_breadcrumbs(struct intel_engine_cs *engine,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/intel_breadcrumbs_park +71 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
70
> 71 void intel_breadcrumbs_park(struct intel_breadcrumbs *b)
72 {
73 unsigned long flags;
74
75 if (!READ_ONCE(b->irq_armed))
76 return;
77
78 spin_lock_irqsave(&b->irq_lock, flags);
79 if (b->irq_armed)
80 __intel_breadcrumbs_disarm_irq(b);
81 spin_unlock_irqrestore(&b->irq_lock, flags);
82 }
83
84 static inline bool __request_completed(const struct i915_request *rq)
85 {
86 return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
87 }
88
89 __maybe_unused static bool
90 check_signal_order(struct intel_context *ce, struct i915_request *rq)
91 {
92 if (!list_is_last(&rq->signal_link, &ce->signals) &&
93 i915_seqno_passed(rq->fence.seqno,
94 list_next_entry(rq, signal_link)->fence.seqno))
95 return false;
96
97 if (!list_is_first(&rq->signal_link, &ce->signals) &&
98 i915_seqno_passed(list_prev_entry(rq, signal_link)->fence.seqno,
99 rq->fence.seqno))
100 return false;
101
102 return true;
103 }
104
105 static bool
106 __dma_fence_signal(struct dma_fence *fence)
107 {
108 return !test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags);
109 }
110
111 static void
112 __dma_fence_signal__timestamp(struct dma_fence *fence, ktime_t timestamp)
113 {
114 fence->timestamp = timestamp;
115 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
116 trace_dma_fence_signaled(fence);
117 }
118
119 static void
120 __dma_fence_signal__notify(struct dma_fence *fence,
121 const struct list_head *list)
122 {
123 struct dma_fence_cb *cur, *tmp;
124
125 lockdep_assert_held(fence->lock);
126
127 list_for_each_entry_safe(cur, tmp, list, node) {
128 INIT_LIST_HEAD(&cur->node);
129 cur->func(fence, cur);
130 }
131 }
132
133 static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl)
134 {
135 if (b->irq_engine)
136 intel_engine_add_retire(b->irq_engine, tl);
137 }
138
139 static void __signal_request(struct i915_request *rq, struct list_head *signals)
140 {
141 clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
142
143 if (!__dma_fence_signal(&rq->fence))
144 return;
145
146 i915_request_get(rq);
147 list_add_tail(&rq->signal_link, signals);
148 }
149
150 static void signal_irq_work(struct irq_work *work)
151 {
152 struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work);
153 const ktime_t timestamp = ktime_get();
154 struct intel_context *ce, *cn;
155 struct list_head *pos, *next;
156 LIST_HEAD(signal);
157
158 spin_lock(&b->irq_lock);
159
160 if (b->irq_armed && list_empty(&b->signalers))
161 __intel_breadcrumbs_disarm_irq(b);
162
163 list_splice_init(&b->signaled_requests, &signal);
164
165 list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) {
166 GEM_BUG_ON(list_empty(&ce->signals));
167
168 list_for_each_safe(pos, next, &ce->signals) {
169 struct i915_request *rq =
170 list_entry(pos, typeof(*rq), signal_link);
171
172 GEM_BUG_ON(!check_signal_order(ce, rq));
173 if (!__request_completed(rq))
174 break;
175
176 /*
177 * Queue for execution after dropping the signaling
178 * spinlock as the callback chain may end up adding
179 * more signalers to the same context or engine.
180 */
181 __signal_request(rq, &signal);
182 }
183
184 /*
185 * We process the list deletion in bulk, only using a list_add
186 * (not list_move) above but keeping the status of
187 * rq->signal_link known with the I915_FENCE_FLAG_SIGNAL bit.
188 */
189 if (!list_is_first(pos, &ce->signals)) {
190 /* Advance the list to the first incomplete request */
191 __list_del_many(&ce->signals, pos);
192 if (&ce->signals == pos) { /* now empty */
193 list_del_init(&ce->signal_link);
194 add_retire(b, ce->timeline);
195 }
196 }
197 }
198
199 spin_unlock(&b->irq_lock);
200
201 list_for_each_safe(pos, next, &signal) {
202 struct i915_request *rq =
203 list_entry(pos, typeof(*rq), signal_link);
204 struct list_head cb_list;
205
206 spin_lock(&rq->lock);
207 list_replace(&rq->fence.cb_list, &cb_list);
208 __dma_fence_signal__timestamp(&rq->fence, timestamp);
209 __dma_fence_signal__notify(&rq->fence, &cb_list);
210 spin_unlock(&rq->lock);
211
212 i915_request_put(rq);
213 }
214 }
215
216 static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b)
217 {
218 lockdep_assert_held(&b->irq_lock);
219
220 if (b->irq_armed)
221 return;
222
223 GEM_BUG_ON(!b->irq_engine);
224 if (!intel_gt_pm_get_if_awake(b->irq_engine->gt))
225 return;
226
227 /*
228 * The breadcrumb irq will be disarmed on the interrupt after the
229 * waiters are signaled. This gives us a single interrupt window in
230 * which we can add a new waiter and avoid the cost of re-enabling
231 * the irq.
232 */
233 WRITE_ONCE(b->irq_armed, true);
234
235 /*
236 * Since we are waiting on a request, the GPU should be busy
237 * and should have its own rpm reference. This is tracked
238 * by i915->gt.awake, we can forgo holding our own wakref
239 * for the interrupt as before i915->gt.awake is released (when
240 * the driver is idle) we disarm the breadcrumbs.
241 */
242
243 if (!b->irq_enabled++)
244 irq_enable(b->irq_engine);
245 }
246
247 struct intel_breadcrumbs *
> 248 intel_breadcrumbs_create(struct intel_engine_cs *irq_engine)
249 {
250 struct intel_breadcrumbs *b;
251
252 b = kzalloc(sizeof(*b), GFP_KERNEL);
253 if (!b)
254 return NULL;
255
256 spin_lock_init(&b->irq_lock);
257 INIT_LIST_HEAD(&b->signalers);
258 INIT_LIST_HEAD(&b->signaled_requests);
259
260 init_irq_work(&b->irq_work, signal_irq_work);
261
262 b->irq_engine = irq_engine;
263 if (!irq_engine)
264 b->irq_armed = true; /* fake HW, used for irq_work */
265
266 return b;
267 }
268
> 269 void intel_breadcrumbs_reset(struct intel_breadcrumbs *b)
270 {
271 unsigned long flags;
272
273 if (!b->irq_engine)
274 return;
275
276 spin_lock_irqsave(&b->irq_lock, flags);
277
278 if (b->irq_enabled)
279 irq_enable(b->irq_engine);
280 else
281 irq_disable(b->irq_engine);
282
283 spin_unlock_irqrestore(&b->irq_lock, flags);
284 }
285
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 74073 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gfx/attachments/20200717/a0955826/attachment-0001.gz>
More information about the Intel-gfx
mailing list