187df8fc6SFrançois Tigeot /*
287df8fc6SFrançois Tigeot * Copyright © 2008-2015 Intel Corporation
387df8fc6SFrançois Tigeot *
487df8fc6SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
587df8fc6SFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
687df8fc6SFrançois Tigeot * to deal in the Software without restriction, including without limitation
787df8fc6SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
887df8fc6SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
987df8fc6SFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
1087df8fc6SFrançois Tigeot *
1187df8fc6SFrançois Tigeot * The above copyright notice and this permission notice (including the next
1287df8fc6SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the
1387df8fc6SFrançois Tigeot * Software.
1487df8fc6SFrançois Tigeot *
1587df8fc6SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1687df8fc6SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1787df8fc6SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1887df8fc6SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1987df8fc6SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2087df8fc6SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2187df8fc6SFrançois Tigeot * IN THE SOFTWARE.
2287df8fc6SFrançois Tigeot *
2387df8fc6SFrançois Tigeot */
2487df8fc6SFrançois Tigeot
2571f41f3eSFrançois Tigeot #include <linux/prefetch.h>
264be47400SFrançois Tigeot #include <linux/dma-fence-array.h>
27a85cb24fSFrançois Tigeot #include <linux/sched.h>
28a85cb24fSFrançois Tigeot #include <linux/sched/clock.h>
29a85cb24fSFrançois Tigeot #include <linux/sched/signal.h>
3071f41f3eSFrançois Tigeot
3187df8fc6SFrançois Tigeot #include "i915_drv.h"
3287df8fc6SFrançois Tigeot
i915_fence_get_driver_name(struct dma_fence * fence)336559babbSFrançois Tigeot static const char *i915_fence_get_driver_name(struct dma_fence *fence)
3487df8fc6SFrançois Tigeot {
3587df8fc6SFrançois Tigeot return "i915";
3687df8fc6SFrançois Tigeot }
3787df8fc6SFrançois Tigeot
i915_fence_get_timeline_name(struct dma_fence * fence)386559babbSFrançois Tigeot static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
3987df8fc6SFrançois Tigeot {
40a85cb24fSFrançois Tigeot /* The timeline struct (as part of the ppgtt underneath a context)
41a85cb24fSFrançois Tigeot * may be freed when the request is no longer in use by the GPU.
42a85cb24fSFrançois Tigeot * We could extend the life of a context to beyond that of all
43a85cb24fSFrançois Tigeot * fences, possibly keeping the hw resource around indefinitely,
44a85cb24fSFrançois Tigeot * or we just give them a false name. Since
45a85cb24fSFrançois Tigeot * dma_fence_ops.get_timeline_name is a debug feature, the occasional
46a85cb24fSFrançois Tigeot * lie seems justifiable.
47a85cb24fSFrançois Tigeot */
48a85cb24fSFrançois Tigeot if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
49a85cb24fSFrançois Tigeot return "signaled";
50a85cb24fSFrançois Tigeot
514be47400SFrançois Tigeot return to_request(fence)->timeline->common->name;
5287df8fc6SFrançois Tigeot }
5387df8fc6SFrançois Tigeot
i915_fence_signaled(struct dma_fence * fence)546559babbSFrançois Tigeot static bool i915_fence_signaled(struct dma_fence *fence)
5587df8fc6SFrançois Tigeot {
5687df8fc6SFrançois Tigeot return i915_gem_request_completed(to_request(fence));
5787df8fc6SFrançois Tigeot }
5887df8fc6SFrançois Tigeot
i915_fence_enable_signaling(struct dma_fence * fence)596559babbSFrançois Tigeot static bool i915_fence_enable_signaling(struct dma_fence *fence)
6087df8fc6SFrançois Tigeot {
6187df8fc6SFrançois Tigeot if (i915_fence_signaled(fence))
6287df8fc6SFrançois Tigeot return false;
6387df8fc6SFrançois Tigeot
64*3f2dd94aSFrançois Tigeot intel_engine_enable_signaling(to_request(fence), true);
65*3f2dd94aSFrançois Tigeot return !i915_fence_signaled(fence);
6687df8fc6SFrançois Tigeot }
6787df8fc6SFrançois Tigeot
i915_fence_wait(struct dma_fence * fence,bool interruptible,signed long timeout)686559babbSFrançois Tigeot static signed long i915_fence_wait(struct dma_fence *fence,
6987df8fc6SFrançois Tigeot bool interruptible,
704be47400SFrançois Tigeot signed long timeout)
7187df8fc6SFrançois Tigeot {
724be47400SFrançois Tigeot return i915_wait_request(to_request(fence), interruptible, timeout);
7387df8fc6SFrançois Tigeot }
7487df8fc6SFrançois Tigeot
i915_fence_release(struct dma_fence * fence)756559babbSFrançois Tigeot static void i915_fence_release(struct dma_fence *fence)
7687df8fc6SFrançois Tigeot {
7787df8fc6SFrançois Tigeot struct drm_i915_gem_request *req = to_request(fence);
7887df8fc6SFrançois Tigeot
79a85cb24fSFrançois Tigeot /* The request is put onto a RCU freelist (i.e. the address
80a85cb24fSFrançois Tigeot * is immediately reused), mark the fences as being freed now.
81a85cb24fSFrançois Tigeot * Otherwise the debugobjects for the fences are only marked as
82a85cb24fSFrançois Tigeot * freed when the slab cache itself is freed, and so we would get
83a85cb24fSFrançois Tigeot * caught trying to reuse dead objects.
84a85cb24fSFrançois Tigeot */
85a85cb24fSFrançois Tigeot i915_sw_fence_fini(&req->submit);
86a85cb24fSFrançois Tigeot
8787df8fc6SFrançois Tigeot kmem_cache_free(req->i915->requests, req);
8887df8fc6SFrançois Tigeot }
8987df8fc6SFrançois Tigeot
906559babbSFrançois Tigeot const struct dma_fence_ops i915_fence_ops = {
9187df8fc6SFrançois Tigeot .get_driver_name = i915_fence_get_driver_name,
9287df8fc6SFrançois Tigeot .get_timeline_name = i915_fence_get_timeline_name,
9387df8fc6SFrançois Tigeot .enable_signaling = i915_fence_enable_signaling,
9487df8fc6SFrançois Tigeot .signaled = i915_fence_signaled,
9587df8fc6SFrançois Tigeot .wait = i915_fence_wait,
9687df8fc6SFrançois Tigeot .release = i915_fence_release,
9787df8fc6SFrançois Tigeot };
9887df8fc6SFrançois Tigeot
9987df8fc6SFrançois Tigeot static inline void
i915_gem_request_remove_from_client(struct drm_i915_gem_request * request)10087df8fc6SFrançois Tigeot i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
10187df8fc6SFrançois Tigeot {
102a85cb24fSFrançois Tigeot struct drm_i915_file_private *file_priv;
10387df8fc6SFrançois Tigeot
104a85cb24fSFrançois Tigeot file_priv = request->file_priv;
10587df8fc6SFrançois Tigeot if (!file_priv)
10687df8fc6SFrançois Tigeot return;
10787df8fc6SFrançois Tigeot
10887df8fc6SFrançois Tigeot lockmgr(&file_priv->mm.lock, LK_EXCLUSIVE);
109a85cb24fSFrançois Tigeot if (request->file_priv) {
110a85cb24fSFrançois Tigeot list_del(&request->client_link);
11187df8fc6SFrançois Tigeot request->file_priv = NULL;
112a85cb24fSFrançois Tigeot }
11387df8fc6SFrançois Tigeot lockmgr(&file_priv->mm.lock, LK_RELEASE);
11487df8fc6SFrançois Tigeot }
11587df8fc6SFrançois Tigeot
1164be47400SFrançois Tigeot static struct i915_dependency *
i915_dependency_alloc(struct drm_i915_private * i915)1174be47400SFrançois Tigeot i915_dependency_alloc(struct drm_i915_private *i915)
1184be47400SFrançois Tigeot {
1194be47400SFrançois Tigeot return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
1204be47400SFrançois Tigeot }
1214be47400SFrançois Tigeot
1224be47400SFrançois Tigeot static void
i915_dependency_free(struct drm_i915_private * i915,struct i915_dependency * dep)1234be47400SFrançois Tigeot i915_dependency_free(struct drm_i915_private *i915,
1244be47400SFrançois Tigeot struct i915_dependency *dep)
1254be47400SFrançois Tigeot {
1264be47400SFrançois Tigeot kmem_cache_free(i915->dependencies, dep);
1274be47400SFrançois Tigeot }
1284be47400SFrançois Tigeot
1294be47400SFrançois Tigeot static void
__i915_priotree_add_dependency(struct i915_priotree * pt,struct i915_priotree * signal,struct i915_dependency * dep,unsigned long flags)1304be47400SFrançois Tigeot __i915_priotree_add_dependency(struct i915_priotree *pt,
1314be47400SFrançois Tigeot struct i915_priotree *signal,
1324be47400SFrançois Tigeot struct i915_dependency *dep,
1334be47400SFrançois Tigeot unsigned long flags)
1344be47400SFrançois Tigeot {
1354be47400SFrançois Tigeot INIT_LIST_HEAD(&dep->dfs_link);
1364be47400SFrançois Tigeot list_add(&dep->wait_link, &signal->waiters_list);
1374be47400SFrançois Tigeot list_add(&dep->signal_link, &pt->signalers_list);
1384be47400SFrançois Tigeot dep->signaler = signal;
1394be47400SFrançois Tigeot dep->flags = flags;
1404be47400SFrançois Tigeot }
1414be47400SFrançois Tigeot
1424be47400SFrançois Tigeot static int
i915_priotree_add_dependency(struct drm_i915_private * i915,struct i915_priotree * pt,struct i915_priotree * signal)1434be47400SFrançois Tigeot i915_priotree_add_dependency(struct drm_i915_private *i915,
1444be47400SFrançois Tigeot struct i915_priotree *pt,
1454be47400SFrançois Tigeot struct i915_priotree *signal)
1464be47400SFrançois Tigeot {
1474be47400SFrançois Tigeot struct i915_dependency *dep;
1484be47400SFrançois Tigeot
1494be47400SFrançois Tigeot dep = i915_dependency_alloc(i915);
1504be47400SFrançois Tigeot if (!dep)
1514be47400SFrançois Tigeot return -ENOMEM;
1524be47400SFrançois Tigeot
1534be47400SFrançois Tigeot __i915_priotree_add_dependency(pt, signal, dep, I915_DEPENDENCY_ALLOC);
1544be47400SFrançois Tigeot return 0;
1554be47400SFrançois Tigeot }
1564be47400SFrançois Tigeot
1574be47400SFrançois Tigeot static void
i915_priotree_fini(struct drm_i915_private * i915,struct i915_priotree * pt)1584be47400SFrançois Tigeot i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
1594be47400SFrançois Tigeot {
1604be47400SFrançois Tigeot struct i915_dependency *dep, *next;
1614be47400SFrançois Tigeot
162*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!list_empty(&pt->link));
1634be47400SFrançois Tigeot
1644be47400SFrançois Tigeot /* Everyone we depended upon (the fences we wait to be signaled)
1654be47400SFrançois Tigeot * should retire before us and remove themselves from our list.
1664be47400SFrançois Tigeot * However, retirement is run independently on each timeline and
1674be47400SFrançois Tigeot * so we may be called out-of-order.
1684be47400SFrançois Tigeot */
1694be47400SFrançois Tigeot list_for_each_entry_safe(dep, next, &pt->signalers_list, signal_link) {
1704be47400SFrançois Tigeot list_del(&dep->wait_link);
1714be47400SFrançois Tigeot if (dep->flags & I915_DEPENDENCY_ALLOC)
1724be47400SFrançois Tigeot i915_dependency_free(i915, dep);
1734be47400SFrançois Tigeot }
1744be47400SFrançois Tigeot
1754be47400SFrançois Tigeot /* Remove ourselves from everyone who depends upon us */
1764be47400SFrançois Tigeot list_for_each_entry_safe(dep, next, &pt->waiters_list, wait_link) {
1774be47400SFrançois Tigeot list_del(&dep->signal_link);
1784be47400SFrançois Tigeot if (dep->flags & I915_DEPENDENCY_ALLOC)
1794be47400SFrançois Tigeot i915_dependency_free(i915, dep);
1804be47400SFrançois Tigeot }
1814be47400SFrançois Tigeot }
1824be47400SFrançois Tigeot
1834be47400SFrançois Tigeot static void
i915_priotree_init(struct i915_priotree * pt)1844be47400SFrançois Tigeot i915_priotree_init(struct i915_priotree *pt)
1854be47400SFrançois Tigeot {
1864be47400SFrançois Tigeot INIT_LIST_HEAD(&pt->signalers_list);
1874be47400SFrançois Tigeot INIT_LIST_HEAD(&pt->waiters_list);
188*3f2dd94aSFrançois Tigeot INIT_LIST_HEAD(&pt->link);
189*3f2dd94aSFrançois Tigeot pt->priority = I915_PRIORITY_INVALID;
1904be47400SFrançois Tigeot }
1914be47400SFrançois Tigeot
reset_all_global_seqno(struct drm_i915_private * i915,u32 seqno)192a85cb24fSFrançois Tigeot static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
193a85cb24fSFrançois Tigeot {
194a85cb24fSFrançois Tigeot struct intel_engine_cs *engine;
195a85cb24fSFrançois Tigeot enum intel_engine_id id;
196a85cb24fSFrançois Tigeot int ret;
197a85cb24fSFrançois Tigeot
198a85cb24fSFrançois Tigeot /* Carefully retire all requests without writing to the rings */
199a85cb24fSFrançois Tigeot ret = i915_gem_wait_for_idle(i915,
200a85cb24fSFrançois Tigeot I915_WAIT_INTERRUPTIBLE |
201a85cb24fSFrançois Tigeot I915_WAIT_LOCKED);
202a85cb24fSFrançois Tigeot if (ret)
203a85cb24fSFrançois Tigeot return ret;
204a85cb24fSFrançois Tigeot
205a85cb24fSFrançois Tigeot /* If the seqno wraps around, we need to clear the breadcrumb rbtree */
206a85cb24fSFrançois Tigeot for_each_engine(engine, i915, id) {
207a85cb24fSFrançois Tigeot struct i915_gem_timeline *timeline;
208a85cb24fSFrançois Tigeot struct intel_timeline *tl = engine->timeline;
209a85cb24fSFrançois Tigeot
210a85cb24fSFrançois Tigeot if (!i915_seqno_passed(seqno, tl->seqno)) {
211a85cb24fSFrançois Tigeot /* spin until threads are complete */
212a85cb24fSFrançois Tigeot while (intel_breadcrumbs_busy(engine))
213a85cb24fSFrançois Tigeot cond_resched();
214a85cb24fSFrançois Tigeot }
215a85cb24fSFrançois Tigeot
216*3f2dd94aSFrançois Tigeot /* Check we are idle before we fiddle with hw state! */
217*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!intel_engine_is_idle(engine));
218*3f2dd94aSFrançois Tigeot GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
219*3f2dd94aSFrançois Tigeot
220a85cb24fSFrançois Tigeot /* Finally reset hw state */
221a85cb24fSFrançois Tigeot intel_engine_init_global_seqno(engine, seqno);
222*3f2dd94aSFrançois Tigeot tl->seqno = seqno;
223a85cb24fSFrançois Tigeot
224a85cb24fSFrançois Tigeot list_for_each_entry(timeline, &i915->gt.timelines, link)
225*3f2dd94aSFrançois Tigeot memset(timeline->engine[id].global_sync, 0,
226*3f2dd94aSFrançois Tigeot sizeof(timeline->engine[id].global_sync));
227a85cb24fSFrançois Tigeot }
228a85cb24fSFrançois Tigeot
229a85cb24fSFrançois Tigeot return 0;
230a85cb24fSFrançois Tigeot }
231a85cb24fSFrançois Tigeot
i915_gem_set_global_seqno(struct drm_device * dev,u32 seqno)232a85cb24fSFrançois Tigeot int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
233a85cb24fSFrançois Tigeot {
234a85cb24fSFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
235a85cb24fSFrançois Tigeot
236a85cb24fSFrançois Tigeot lockdep_assert_held(&dev_priv->drm.struct_mutex);
237a85cb24fSFrançois Tigeot
238a85cb24fSFrançois Tigeot if (seqno == 0)
239a85cb24fSFrançois Tigeot return -EINVAL;
240a85cb24fSFrançois Tigeot
241a85cb24fSFrançois Tigeot /* HWS page needs to be set less than what we
242a85cb24fSFrançois Tigeot * will inject to ring
243a85cb24fSFrançois Tigeot */
244a85cb24fSFrançois Tigeot return reset_all_global_seqno(dev_priv, seqno - 1);
245a85cb24fSFrançois Tigeot }
246a85cb24fSFrançois Tigeot
mark_busy(struct drm_i915_private * i915)247*3f2dd94aSFrançois Tigeot static void mark_busy(struct drm_i915_private *i915)
248a85cb24fSFrançois Tigeot {
249*3f2dd94aSFrançois Tigeot if (i915->gt.awake)
250*3f2dd94aSFrançois Tigeot return;
251*3f2dd94aSFrançois Tigeot
252*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!i915->gt.active_requests);
253*3f2dd94aSFrançois Tigeot
254*3f2dd94aSFrançois Tigeot intel_runtime_pm_get_noresume(i915);
255*3f2dd94aSFrançois Tigeot i915->gt.awake = true;
256*3f2dd94aSFrançois Tigeot
257*3f2dd94aSFrançois Tigeot intel_enable_gt_powersave(i915);
258*3f2dd94aSFrançois Tigeot i915_update_gfx_val(i915);
259*3f2dd94aSFrançois Tigeot if (INTEL_GEN(i915) >= 6)
260*3f2dd94aSFrançois Tigeot gen6_rps_busy(i915);
261*3f2dd94aSFrançois Tigeot
262*3f2dd94aSFrançois Tigeot queue_delayed_work(i915->wq,
263*3f2dd94aSFrançois Tigeot &i915->gt.retire_work,
264*3f2dd94aSFrançois Tigeot round_jiffies_up_relative(HZ));
265*3f2dd94aSFrançois Tigeot }
266*3f2dd94aSFrançois Tigeot
reserve_engine(struct intel_engine_cs * engine)267*3f2dd94aSFrançois Tigeot static int reserve_engine(struct intel_engine_cs *engine)
268*3f2dd94aSFrançois Tigeot {
269*3f2dd94aSFrançois Tigeot struct drm_i915_private *i915 = engine->i915;
270a85cb24fSFrançois Tigeot u32 active = ++engine->timeline->inflight_seqnos;
271a85cb24fSFrançois Tigeot u32 seqno = engine->timeline->seqno;
272a85cb24fSFrançois Tigeot int ret;
273a85cb24fSFrançois Tigeot
274a85cb24fSFrançois Tigeot /* Reservation is fine until we need to wrap around */
275*3f2dd94aSFrançois Tigeot if (unlikely(add_overflows(seqno, active))) {
276*3f2dd94aSFrançois Tigeot ret = reset_all_global_seqno(i915, 0);
277a85cb24fSFrançois Tigeot if (ret) {
278a85cb24fSFrançois Tigeot engine->timeline->inflight_seqnos--;
279a85cb24fSFrançois Tigeot return ret;
280a85cb24fSFrançois Tigeot }
281*3f2dd94aSFrançois Tigeot }
282*3f2dd94aSFrançois Tigeot
283*3f2dd94aSFrançois Tigeot if (!i915->gt.active_requests++)
284*3f2dd94aSFrançois Tigeot mark_busy(i915);
285a85cb24fSFrançois Tigeot
286a85cb24fSFrançois Tigeot return 0;
287a85cb24fSFrançois Tigeot }
288a85cb24fSFrançois Tigeot
unreserve_engine(struct intel_engine_cs * engine)289*3f2dd94aSFrançois Tigeot static void unreserve_engine(struct intel_engine_cs *engine)
290a85cb24fSFrançois Tigeot {
291*3f2dd94aSFrançois Tigeot struct drm_i915_private *i915 = engine->i915;
292*3f2dd94aSFrançois Tigeot
293*3f2dd94aSFrançois Tigeot if (!--i915->gt.active_requests) {
294*3f2dd94aSFrançois Tigeot /* Cancel the mark_busy() from our reserve_engine() */
295*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!i915->gt.awake);
296*3f2dd94aSFrançois Tigeot mod_delayed_work(i915->wq,
297*3f2dd94aSFrançois Tigeot &i915->gt.idle_work,
298*3f2dd94aSFrançois Tigeot msecs_to_jiffies(100));
299*3f2dd94aSFrançois Tigeot }
300*3f2dd94aSFrançois Tigeot
301a85cb24fSFrançois Tigeot GEM_BUG_ON(!engine->timeline->inflight_seqnos);
302a85cb24fSFrançois Tigeot engine->timeline->inflight_seqnos--;
303a85cb24fSFrançois Tigeot }
304a85cb24fSFrançois Tigeot
i915_gem_retire_noop(struct i915_gem_active * active,struct drm_i915_gem_request * request)30571f41f3eSFrançois Tigeot void i915_gem_retire_noop(struct i915_gem_active *active,
30671f41f3eSFrançois Tigeot struct drm_i915_gem_request *request)
30771f41f3eSFrançois Tigeot {
30871f41f3eSFrançois Tigeot /* Space left intentionally blank */
30971f41f3eSFrançois Tigeot }
31071f41f3eSFrançois Tigeot
advance_ring(struct drm_i915_gem_request * request)311*3f2dd94aSFrançois Tigeot static void advance_ring(struct drm_i915_gem_request *request)
312*3f2dd94aSFrançois Tigeot {
313*3f2dd94aSFrançois Tigeot unsigned int tail;
314*3f2dd94aSFrançois Tigeot
315*3f2dd94aSFrançois Tigeot /* We know the GPU must have read the request to have
316*3f2dd94aSFrançois Tigeot * sent us the seqno + interrupt, so use the position
317*3f2dd94aSFrançois Tigeot * of tail of the request to update the last known position
318*3f2dd94aSFrançois Tigeot * of the GPU head.
319*3f2dd94aSFrançois Tigeot *
320*3f2dd94aSFrançois Tigeot * Note this requires that we are always called in request
321*3f2dd94aSFrançois Tigeot * completion order.
322*3f2dd94aSFrançois Tigeot */
323*3f2dd94aSFrançois Tigeot if (list_is_last(&request->ring_link, &request->ring->request_list)) {
324*3f2dd94aSFrançois Tigeot /* We may race here with execlists resubmitting this request
325*3f2dd94aSFrançois Tigeot * as we retire it. The resubmission will move the ring->tail
326*3f2dd94aSFrançois Tigeot * forwards (to request->wa_tail). We either read the
327*3f2dd94aSFrançois Tigeot * current value that was written to hw, or the value that
328*3f2dd94aSFrançois Tigeot * is just about to be. Either works, if we miss the last two
329*3f2dd94aSFrançois Tigeot * noops - they are safe to be replayed on a reset.
330*3f2dd94aSFrançois Tigeot */
331*3f2dd94aSFrançois Tigeot tail = READ_ONCE(request->ring->tail);
332*3f2dd94aSFrançois Tigeot } else {
333*3f2dd94aSFrançois Tigeot tail = request->postfix;
334*3f2dd94aSFrançois Tigeot }
335*3f2dd94aSFrançois Tigeot list_del(&request->ring_link);
336*3f2dd94aSFrançois Tigeot
337*3f2dd94aSFrançois Tigeot request->ring->head = tail;
338*3f2dd94aSFrançois Tigeot }
339*3f2dd94aSFrançois Tigeot
free_capture_list(struct drm_i915_gem_request * request)340*3f2dd94aSFrançois Tigeot static void free_capture_list(struct drm_i915_gem_request *request)
341*3f2dd94aSFrançois Tigeot {
342*3f2dd94aSFrançois Tigeot struct i915_gem_capture_list *capture;
343*3f2dd94aSFrançois Tigeot
344*3f2dd94aSFrançois Tigeot capture = request->capture_list;
345*3f2dd94aSFrançois Tigeot while (capture) {
346*3f2dd94aSFrançois Tigeot struct i915_gem_capture_list *next = capture->next;
347*3f2dd94aSFrançois Tigeot
348*3f2dd94aSFrançois Tigeot kfree(capture);
349*3f2dd94aSFrançois Tigeot capture = next;
350*3f2dd94aSFrançois Tigeot }
351*3f2dd94aSFrançois Tigeot }
352*3f2dd94aSFrançois Tigeot
i915_gem_request_retire(struct drm_i915_gem_request * request)35387df8fc6SFrançois Tigeot static void i915_gem_request_retire(struct drm_i915_gem_request *request)
35487df8fc6SFrançois Tigeot {
355a85cb24fSFrançois Tigeot struct intel_engine_cs *engine = request->engine;
35671f41f3eSFrançois Tigeot struct i915_gem_active *active, *next;
35771f41f3eSFrançois Tigeot
3584be47400SFrançois Tigeot lockdep_assert_held(&request->i915->drm.struct_mutex);
3594be47400SFrançois Tigeot GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit));
3604be47400SFrançois Tigeot GEM_BUG_ON(!i915_gem_request_completed(request));
3614be47400SFrançois Tigeot GEM_BUG_ON(!request->i915->gt.active_requests);
3624be47400SFrançois Tigeot
36387df8fc6SFrançois Tigeot trace_i915_gem_request_retire(request);
3644be47400SFrançois Tigeot
365a85cb24fSFrançois Tigeot spin_lock_irq(&engine->timeline->lock);
3664be47400SFrançois Tigeot list_del_init(&request->link);
367a85cb24fSFrançois Tigeot spin_unlock_irq(&engine->timeline->lock);
36887df8fc6SFrançois Tigeot
369*3f2dd94aSFrançois Tigeot unreserve_engine(request->engine);
370*3f2dd94aSFrançois Tigeot advance_ring(request);
371*3f2dd94aSFrançois Tigeot
372*3f2dd94aSFrançois Tigeot free_capture_list(request);
37371f41f3eSFrançois Tigeot
37471f41f3eSFrançois Tigeot /* Walk through the active list, calling retire on each. This allows
37571f41f3eSFrançois Tigeot * objects to track their GPU activity and mark themselves as idle
37671f41f3eSFrançois Tigeot * when their *last* active request is completed (updating state
37771f41f3eSFrançois Tigeot * tracking lists for eviction, active references for GEM, etc).
37871f41f3eSFrançois Tigeot *
37971f41f3eSFrançois Tigeot * As the ->retire() may free the node, we decouple it first and
38071f41f3eSFrançois Tigeot * pass along the auxiliary information (to avoid dereferencing
38171f41f3eSFrançois Tigeot * the node after the callback).
38271f41f3eSFrançois Tigeot */
38371f41f3eSFrançois Tigeot list_for_each_entry_safe(active, next, &request->active_list, link) {
38471f41f3eSFrançois Tigeot /* In microbenchmarks or focusing upon time inside the kernel,
38571f41f3eSFrançois Tigeot * we may spend an inordinate amount of time simply handling
38671f41f3eSFrançois Tigeot * the retirement of requests and processing their callbacks.
38771f41f3eSFrançois Tigeot * Of which, this loop itself is particularly hot due to the
38871f41f3eSFrançois Tigeot * cache misses when jumping around the list of i915_gem_active.
38971f41f3eSFrançois Tigeot * So we try to keep this loop as streamlined as possible and
39071f41f3eSFrançois Tigeot * also prefetch the next i915_gem_active to try and hide
39171f41f3eSFrançois Tigeot * the likely cache miss.
39271f41f3eSFrançois Tigeot */
39371f41f3eSFrançois Tigeot prefetchw(next);
39471f41f3eSFrançois Tigeot
39571f41f3eSFrançois Tigeot INIT_LIST_HEAD(&active->link);
39671f41f3eSFrançois Tigeot RCU_INIT_POINTER(active->request, NULL);
39771f41f3eSFrançois Tigeot
39871f41f3eSFrançois Tigeot active->retire(active, request);
39971f41f3eSFrançois Tigeot }
40087df8fc6SFrançois Tigeot
40187df8fc6SFrançois Tigeot i915_gem_request_remove_from_client(request);
40287df8fc6SFrançois Tigeot
403a85cb24fSFrançois Tigeot /* Retirement decays the ban score as it is a sign of ctx progress */
404*3f2dd94aSFrançois Tigeot atomic_dec_if_positive(&request->ctx->ban_score);
40587df8fc6SFrançois Tigeot
406a85cb24fSFrançois Tigeot /* The backing object for the context is done after switching to the
407a85cb24fSFrançois Tigeot * *next* context. Therefore we cannot retire the previous context until
408a85cb24fSFrançois Tigeot * the next context has already started running. However, since we
409a85cb24fSFrançois Tigeot * cannot take the required locks at i915_gem_request_submit() we
410a85cb24fSFrançois Tigeot * defer the unpinning of the active context to now, retirement of
411a85cb24fSFrançois Tigeot * the subsequent request.
412a85cb24fSFrançois Tigeot */
413a85cb24fSFrançois Tigeot if (engine->last_retired_context)
414a85cb24fSFrançois Tigeot engine->context_unpin(engine, engine->last_retired_context);
415a85cb24fSFrançois Tigeot engine->last_retired_context = request->ctx;
4164be47400SFrançois Tigeot
417*3f2dd94aSFrançois Tigeot spin_lock_irq(&request->lock);
418*3f2dd94aSFrançois Tigeot if (request->waitboost)
419*3f2dd94aSFrançois Tigeot atomic_dec(&request->i915->gt_pm.rps.num_waiters);
420*3f2dd94aSFrançois Tigeot dma_fence_signal_locked(&request->fence);
421*3f2dd94aSFrançois Tigeot spin_unlock_irq(&request->lock);
4224be47400SFrançois Tigeot
4234be47400SFrançois Tigeot i915_priotree_fini(request->i915, &request->priotree);
42487df8fc6SFrançois Tigeot i915_gem_request_put(request);
42587df8fc6SFrançois Tigeot }
42687df8fc6SFrançois Tigeot
i915_gem_request_retire_upto(struct drm_i915_gem_request * req)42787df8fc6SFrançois Tigeot void i915_gem_request_retire_upto(struct drm_i915_gem_request *req)
42887df8fc6SFrançois Tigeot {
42987df8fc6SFrançois Tigeot struct intel_engine_cs *engine = req->engine;
43087df8fc6SFrançois Tigeot struct drm_i915_gem_request *tmp;
43187df8fc6SFrançois Tigeot
43287df8fc6SFrançois Tigeot lockdep_assert_held(&req->i915->drm.struct_mutex);
433a85cb24fSFrançois Tigeot GEM_BUG_ON(!i915_gem_request_completed(req));
434a85cb24fSFrançois Tigeot
4354be47400SFrançois Tigeot if (list_empty(&req->link))
4364be47400SFrançois Tigeot return;
43787df8fc6SFrançois Tigeot
43887df8fc6SFrançois Tigeot do {
4394be47400SFrançois Tigeot tmp = list_first_entry(&engine->timeline->requests,
44071f41f3eSFrançois Tigeot typeof(*tmp), link);
44187df8fc6SFrançois Tigeot
44287df8fc6SFrançois Tigeot i915_gem_request_retire(tmp);
44387df8fc6SFrançois Tigeot } while (tmp != req);
44487df8fc6SFrançois Tigeot }
44587df8fc6SFrançois Tigeot
timeline_get_seqno(struct intel_timeline * tl)446a85cb24fSFrançois Tigeot static u32 timeline_get_seqno(struct intel_timeline *tl)
44787df8fc6SFrançois Tigeot {
448a85cb24fSFrançois Tigeot return ++tl->seqno;
4494be47400SFrançois Tigeot }
4504be47400SFrançois Tigeot
__i915_gem_request_submit(struct drm_i915_gem_request * request)4514be47400SFrançois Tigeot void __i915_gem_request_submit(struct drm_i915_gem_request *request)
4524be47400SFrançois Tigeot {
4534be47400SFrançois Tigeot struct intel_engine_cs *engine = request->engine;
4544be47400SFrançois Tigeot struct intel_timeline *timeline;
4554be47400SFrançois Tigeot u32 seqno;
4564be47400SFrançois Tigeot
457a85cb24fSFrançois Tigeot // GEM_BUG_ON(!irqs_disabled());
458a85cb24fSFrançois Tigeot lockdep_assert_held(&engine->timeline->lock);
459a85cb24fSFrançois Tigeot
460a85cb24fSFrançois Tigeot trace_i915_gem_request_execute(request);
461a85cb24fSFrançois Tigeot
4624be47400SFrançois Tigeot /* Transfer from per-context onto the global per-engine timeline */
4634be47400SFrançois Tigeot timeline = engine->timeline;
4644be47400SFrançois Tigeot GEM_BUG_ON(timeline == request->timeline);
4654be47400SFrançois Tigeot
466a85cb24fSFrançois Tigeot seqno = timeline_get_seqno(timeline);
4674be47400SFrançois Tigeot GEM_BUG_ON(!seqno);
4684be47400SFrançois Tigeot GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
4694be47400SFrançois Tigeot
4704be47400SFrançois Tigeot /* We may be recursing from the signal callback of another i915 fence */
4714be47400SFrançois Tigeot lockmgr(&request->lock, LK_EXCLUSIVE);
4724be47400SFrançois Tigeot request->global_seqno = seqno;
4734be47400SFrançois Tigeot if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
474*3f2dd94aSFrançois Tigeot intel_engine_enable_signaling(request, false);
4754be47400SFrançois Tigeot lockmgr(&request->lock, LK_RELEASE);
4764be47400SFrançois Tigeot
4774be47400SFrançois Tigeot engine->emit_breadcrumb(request,
4784be47400SFrançois Tigeot request->ring->vaddr + request->postfix);
4794be47400SFrançois Tigeot
4804be47400SFrançois Tigeot lockmgr(&request->timeline->lock, LK_EXCLUSIVE);
4814be47400SFrançois Tigeot list_move_tail(&request->link, &timeline->requests);
4824be47400SFrançois Tigeot lockmgr(&request->timeline->lock, LK_RELEASE);
4834be47400SFrançois Tigeot
484a85cb24fSFrançois Tigeot wake_up_all(&request->execute);
4854be47400SFrançois Tigeot }
4864be47400SFrançois Tigeot
i915_gem_request_submit(struct drm_i915_gem_request * request)4874be47400SFrançois Tigeot void i915_gem_request_submit(struct drm_i915_gem_request *request)
4884be47400SFrançois Tigeot {
4894be47400SFrançois Tigeot struct intel_engine_cs *engine = request->engine;
4904be47400SFrançois Tigeot unsigned long flags;
4914be47400SFrançois Tigeot
4924be47400SFrançois Tigeot /* Will be called from irq-context when using foreign fences. */
4934be47400SFrançois Tigeot spin_lock_irqsave(&engine->timeline->lock, flags);
4944be47400SFrançois Tigeot
4954be47400SFrançois Tigeot __i915_gem_request_submit(request);
4964be47400SFrançois Tigeot
4974be47400SFrançois Tigeot spin_unlock_irqrestore(&engine->timeline->lock, flags);
4984be47400SFrançois Tigeot }
4994be47400SFrançois Tigeot
__i915_gem_request_unsubmit(struct drm_i915_gem_request * request)500a85cb24fSFrançois Tigeot void __i915_gem_request_unsubmit(struct drm_i915_gem_request *request)
501a85cb24fSFrançois Tigeot {
502a85cb24fSFrançois Tigeot struct intel_engine_cs *engine = request->engine;
503a85cb24fSFrançois Tigeot struct intel_timeline *timeline;
504a85cb24fSFrançois Tigeot
505a85cb24fSFrançois Tigeot GEM_BUG_ON(!irqs_disabled());
506a85cb24fSFrançois Tigeot lockdep_assert_held(&engine->timeline->lock);
507a85cb24fSFrançois Tigeot
508a85cb24fSFrançois Tigeot /* Only unwind in reverse order, required so that the per-context list
509a85cb24fSFrançois Tigeot * is kept in seqno/ring order.
510a85cb24fSFrançois Tigeot */
511a85cb24fSFrançois Tigeot GEM_BUG_ON(request->global_seqno != engine->timeline->seqno);
512a85cb24fSFrançois Tigeot engine->timeline->seqno--;
513a85cb24fSFrançois Tigeot
514a85cb24fSFrançois Tigeot /* We may be recursing from the signal callback of another i915 fence */
515a85cb24fSFrançois Tigeot lockmgr(&request->lock, LK_EXCLUSIVE);
516a85cb24fSFrançois Tigeot request->global_seqno = 0;
517a85cb24fSFrançois Tigeot if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
518a85cb24fSFrançois Tigeot intel_engine_cancel_signaling(request);
519a85cb24fSFrançois Tigeot lockmgr(&request->lock, LK_RELEASE);
520a85cb24fSFrançois Tigeot
521a85cb24fSFrançois Tigeot /* Transfer back from the global per-engine timeline to per-context */
522a85cb24fSFrançois Tigeot timeline = request->timeline;
523a85cb24fSFrançois Tigeot GEM_BUG_ON(timeline == engine->timeline);
524a85cb24fSFrançois Tigeot
525a85cb24fSFrançois Tigeot lockmgr(&timeline->lock, LK_EXCLUSIVE);
526a85cb24fSFrançois Tigeot list_move(&request->link, &timeline->requests);
527a85cb24fSFrançois Tigeot lockmgr(&timeline->lock, LK_RELEASE);
528a85cb24fSFrançois Tigeot
529a85cb24fSFrançois Tigeot /* We don't need to wake_up any waiters on request->execute, they
530a85cb24fSFrançois Tigeot * will get woken by any other event or us re-adding this request
531a85cb24fSFrançois Tigeot * to the engine timeline (__i915_gem_request_submit()). The waiters
532a85cb24fSFrançois Tigeot * should be quite adapt at finding that the request now has a new
533a85cb24fSFrançois Tigeot * global_seqno to the one they went to sleep on.
534a85cb24fSFrançois Tigeot */
535a85cb24fSFrançois Tigeot }
536a85cb24fSFrançois Tigeot
i915_gem_request_unsubmit(struct drm_i915_gem_request * request)537a85cb24fSFrançois Tigeot void i915_gem_request_unsubmit(struct drm_i915_gem_request *request)
538a85cb24fSFrançois Tigeot {
539a85cb24fSFrançois Tigeot struct intel_engine_cs *engine = request->engine;
540a85cb24fSFrançois Tigeot unsigned long flags;
541a85cb24fSFrançois Tigeot
542a85cb24fSFrançois Tigeot /* Will be called from irq-context when using foreign fences. */
543a85cb24fSFrançois Tigeot spin_lock_irqsave(&engine->timeline->lock, flags);
544a85cb24fSFrançois Tigeot
545a85cb24fSFrançois Tigeot __i915_gem_request_unsubmit(request);
546a85cb24fSFrançois Tigeot
547a85cb24fSFrançois Tigeot spin_unlock_irqrestore(&engine->timeline->lock, flags);
548a85cb24fSFrançois Tigeot }
549a85cb24fSFrançois Tigeot
5501e12ee3bSFrançois Tigeot static int __i915_sw_fence_call
submit_notify(struct i915_sw_fence * fence,enum i915_sw_fence_notify state)5511e12ee3bSFrançois Tigeot submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
5521e12ee3bSFrançois Tigeot {
5531e12ee3bSFrançois Tigeot struct drm_i915_gem_request *request =
5541e12ee3bSFrançois Tigeot container_of(fence, typeof(*request), submit);
5551e12ee3bSFrançois Tigeot
5561e12ee3bSFrançois Tigeot switch (state) {
5571e12ee3bSFrançois Tigeot case FENCE_COMPLETE:
558a85cb24fSFrançois Tigeot trace_i915_gem_request_submit(request);
559*3f2dd94aSFrançois Tigeot /*
560*3f2dd94aSFrançois Tigeot * We need to serialize use of the submit_request() callback with its
561*3f2dd94aSFrançois Tigeot * hotplugging performed during an emergency i915_gem_set_wedged().
562*3f2dd94aSFrançois Tigeot * We use the RCU mechanism to mark the critical section in order to
563*3f2dd94aSFrançois Tigeot * force i915_gem_set_wedged() to wait until the submit_request() is
564*3f2dd94aSFrançois Tigeot * completed before proceeding.
565*3f2dd94aSFrançois Tigeot */
566*3f2dd94aSFrançois Tigeot rcu_read_lock();
5671e12ee3bSFrançois Tigeot request->engine->submit_request(request);
568*3f2dd94aSFrançois Tigeot rcu_read_unlock();
5691e12ee3bSFrançois Tigeot break;
5701e12ee3bSFrançois Tigeot
5711e12ee3bSFrançois Tigeot case FENCE_FREE:
5724be47400SFrançois Tigeot i915_gem_request_put(request);
5734be47400SFrançois Tigeot break;
5744be47400SFrançois Tigeot }
5754be47400SFrançois Tigeot
5764be47400SFrançois Tigeot return NOTIFY_DONE;
5774be47400SFrançois Tigeot }
5784be47400SFrançois Tigeot
57987df8fc6SFrançois Tigeot /**
58087df8fc6SFrançois Tigeot * i915_gem_request_alloc - allocate a request structure
58187df8fc6SFrançois Tigeot *
58287df8fc6SFrançois Tigeot * @engine: engine that we wish to issue the request on.
58387df8fc6SFrançois Tigeot * @ctx: context that the request will be associated with.
58487df8fc6SFrançois Tigeot *
58587df8fc6SFrançois Tigeot * Returns a pointer to the allocated request if successful,
58687df8fc6SFrançois Tigeot * or an error code if not.
58787df8fc6SFrançois Tigeot */
58887df8fc6SFrançois Tigeot struct drm_i915_gem_request *
i915_gem_request_alloc(struct intel_engine_cs * engine,struct i915_gem_context * ctx)58987df8fc6SFrançois Tigeot i915_gem_request_alloc(struct intel_engine_cs *engine,
59087df8fc6SFrançois Tigeot struct i915_gem_context *ctx)
59187df8fc6SFrançois Tigeot {
59271f41f3eSFrançois Tigeot struct drm_i915_private *dev_priv = engine->i915;
59387df8fc6SFrançois Tigeot struct drm_i915_gem_request *req;
594*3f2dd94aSFrançois Tigeot struct intel_ring *ring;
59571f41f3eSFrançois Tigeot int ret;
59687df8fc6SFrançois Tigeot
5974be47400SFrançois Tigeot lockdep_assert_held(&dev_priv->drm.struct_mutex);
5984be47400SFrançois Tigeot
599*3f2dd94aSFrançois Tigeot /*
600*3f2dd94aSFrançois Tigeot * Preempt contexts are reserved for exclusive use to inject a
601*3f2dd94aSFrançois Tigeot * preemption context switch. They are never to be used for any trivial
602*3f2dd94aSFrançois Tigeot * request!
603*3f2dd94aSFrançois Tigeot */
604*3f2dd94aSFrançois Tigeot GEM_BUG_ON(ctx == dev_priv->preempt_context);
605*3f2dd94aSFrançois Tigeot
60671f41f3eSFrançois Tigeot /* ABI: Before userspace accesses the GPU (e.g. execbuffer), report
607a85cb24fSFrançois Tigeot * EIO if the GPU is already wedged.
60871f41f3eSFrançois Tigeot */
609a85cb24fSFrançois Tigeot if (i915_terminally_wedged(&dev_priv->gpu_error))
610a85cb24fSFrançois Tigeot return ERR_PTR(-EIO);
611a85cb24fSFrançois Tigeot
612a85cb24fSFrançois Tigeot /* Pinning the contexts may generate requests in order to acquire
613a85cb24fSFrançois Tigeot * GGTT space, so do this first before we reserve a seqno for
614a85cb24fSFrançois Tigeot * ourselves.
615a85cb24fSFrançois Tigeot */
616*3f2dd94aSFrançois Tigeot ring = engine->context_pin(engine, ctx);
617*3f2dd94aSFrançois Tigeot if (IS_ERR(ring))
618*3f2dd94aSFrançois Tigeot return ERR_CAST(ring);
619*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!ring);
62071f41f3eSFrançois Tigeot
621*3f2dd94aSFrançois Tigeot ret = reserve_engine(engine);
6224be47400SFrançois Tigeot if (ret)
623a85cb24fSFrançois Tigeot goto err_unpin;
6244be47400SFrançois Tigeot
62571f41f3eSFrançois Tigeot /* Move the oldest request to the slab-cache (if not in use!) */
6264be47400SFrançois Tigeot req = list_first_entry_or_null(&engine->timeline->requests,
62771f41f3eSFrançois Tigeot typeof(*req), link);
628a85cb24fSFrançois Tigeot if (req && i915_gem_request_completed(req))
62971f41f3eSFrançois Tigeot i915_gem_request_retire(req);
63071f41f3eSFrançois Tigeot
63171f41f3eSFrançois Tigeot /* Beware: Dragons be flying overhead.
63271f41f3eSFrançois Tigeot *
63371f41f3eSFrançois Tigeot * We use RCU to look up requests in flight. The lookups may
63471f41f3eSFrançois Tigeot * race with the request being allocated from the slab freelist.
63571f41f3eSFrançois Tigeot * That is the request we are writing to here, may be in the process
6361e12ee3bSFrançois Tigeot * of being read by __i915_gem_active_get_rcu(). As such,
63771f41f3eSFrançois Tigeot * we have to be very careful when overwriting the contents. During
63871f41f3eSFrançois Tigeot * the RCU lookup, we change chase the request->engine pointer,
6394be47400SFrançois Tigeot * read the request->global_seqno and increment the reference count.
64071f41f3eSFrançois Tigeot *
64171f41f3eSFrançois Tigeot * The reference count is incremented atomically. If it is zero,
64271f41f3eSFrançois Tigeot * the lookup knows the request is unallocated and complete. Otherwise,
64371f41f3eSFrançois Tigeot * it is either still in use, or has been reallocated and reset
6446559babbSFrançois Tigeot * with dma_fence_init(). This increment is safe for release as we
6456559babbSFrançois Tigeot * check that the request we have a reference to and matches the active
64671f41f3eSFrançois Tigeot * request.
64771f41f3eSFrançois Tigeot *
64871f41f3eSFrançois Tigeot * Before we increment the refcount, we chase the request->engine
64971f41f3eSFrançois Tigeot * pointer. We must not call kmem_cache_zalloc() or else we set
65071f41f3eSFrançois Tigeot * that pointer to NULL and cause a crash during the lookup. If
65171f41f3eSFrançois Tigeot * we see the request is completed (based on the value of the
65271f41f3eSFrançois Tigeot * old engine and seqno), the lookup is complete and reports NULL.
65371f41f3eSFrançois Tigeot * If we decide the request is not completed (new engine or seqno),
65471f41f3eSFrançois Tigeot * then we grab a reference and double check that it is still the
65571f41f3eSFrançois Tigeot * active request - which it won't be and restart the lookup.
65671f41f3eSFrançois Tigeot *
65771f41f3eSFrançois Tigeot * Do not use kmem_cache_zalloc() here!
65871f41f3eSFrançois Tigeot */
65965d5e47fSFrançois Tigeot req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL);
6604be47400SFrançois Tigeot if (!req) {
6614be47400SFrançois Tigeot ret = -ENOMEM;
6624be47400SFrançois Tigeot goto err_unreserve;
6634be47400SFrançois Tigeot }
66471f41f3eSFrançois Tigeot
6654be47400SFrançois Tigeot req->timeline = i915_gem_context_lookup_timeline(ctx, engine);
6664be47400SFrançois Tigeot GEM_BUG_ON(req->timeline == engine->timeline);
66771f41f3eSFrançois Tigeot
66871f41f3eSFrançois Tigeot lockinit(&req->lock, "i915_rl", 0, 0);
6696559babbSFrançois Tigeot dma_fence_init(&req->fence,
67071f41f3eSFrançois Tigeot &i915_fence_ops,
67171f41f3eSFrançois Tigeot &req->lock,
6724be47400SFrançois Tigeot req->timeline->fence_context,
673a85cb24fSFrançois Tigeot timeline_get_seqno(req->timeline));
67471f41f3eSFrançois Tigeot
6754be47400SFrançois Tigeot /* We bump the ref for the fence chain */
6764be47400SFrançois Tigeot i915_sw_fence_init(&i915_gem_request_get(req)->submit, submit_notify);
677a85cb24fSFrançois Tigeot init_waitqueue_head(&req->execute);
6784be47400SFrançois Tigeot
6794be47400SFrançois Tigeot i915_priotree_init(&req->priotree);
6801e12ee3bSFrançois Tigeot
68171f41f3eSFrançois Tigeot INIT_LIST_HEAD(&req->active_list);
68271f41f3eSFrançois Tigeot req->i915 = dev_priv;
68371f41f3eSFrançois Tigeot req->engine = engine;
684a85cb24fSFrançois Tigeot req->ctx = ctx;
685*3f2dd94aSFrançois Tigeot req->ring = ring;
68671f41f3eSFrançois Tigeot
68771f41f3eSFrançois Tigeot /* No zalloc, must clear what we need by hand */
6884be47400SFrançois Tigeot req->global_seqno = 0;
68971f41f3eSFrançois Tigeot req->file_priv = NULL;
6901e12ee3bSFrançois Tigeot req->batch = NULL;
691*3f2dd94aSFrançois Tigeot req->capture_list = NULL;
692*3f2dd94aSFrançois Tigeot req->waitboost = false;
69371f41f3eSFrançois Tigeot
69471f41f3eSFrançois Tigeot /*
69571f41f3eSFrançois Tigeot * Reserve space in the ring buffer for all the commands required to
69671f41f3eSFrançois Tigeot * eventually emit this request. This is to guarantee that the
69771f41f3eSFrançois Tigeot * i915_add_request() call can't fail. Note that the reserve may need
69871f41f3eSFrançois Tigeot * to be redone if the request is not actually submitted straight
69971f41f3eSFrançois Tigeot * away, e.g. because a GPU scheduler has deferred it.
70071f41f3eSFrançois Tigeot */
70171f41f3eSFrançois Tigeot req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
7024be47400SFrançois Tigeot GEM_BUG_ON(req->reserved_space < engine->emit_breadcrumb_sz);
70371f41f3eSFrançois Tigeot
704a85cb24fSFrançois Tigeot ret = engine->request_alloc(req);
70571f41f3eSFrançois Tigeot if (ret)
70671f41f3eSFrançois Tigeot goto err_ctx;
70771f41f3eSFrançois Tigeot
7081e12ee3bSFrançois Tigeot /* Record the position of the start of the request so that
7091e12ee3bSFrançois Tigeot * should we detect the updated seqno part-way through the
7101e12ee3bSFrançois Tigeot * GPU processing the request, we never over-estimate the
7111e12ee3bSFrançois Tigeot * position of the head.
7121e12ee3bSFrançois Tigeot */
713a85cb24fSFrançois Tigeot req->head = req->ring->emit;
7141e12ee3bSFrançois Tigeot
715a85cb24fSFrançois Tigeot /* Check that we didn't interrupt ourselves with a new request */
716a85cb24fSFrançois Tigeot GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
71771f41f3eSFrançois Tigeot return req;
71871f41f3eSFrançois Tigeot
71971f41f3eSFrançois Tigeot err_ctx:
720a85cb24fSFrançois Tigeot /* Make sure we didn't add ourselves to external state before freeing */
721a85cb24fSFrançois Tigeot GEM_BUG_ON(!list_empty(&req->active_list));
722a85cb24fSFrançois Tigeot GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));
723a85cb24fSFrançois Tigeot GEM_BUG_ON(!list_empty(&req->priotree.waiters_list));
724a85cb24fSFrançois Tigeot
72571f41f3eSFrançois Tigeot kmem_cache_free(dev_priv->requests, req);
7264be47400SFrançois Tigeot err_unreserve:
727*3f2dd94aSFrançois Tigeot unreserve_engine(engine);
728a85cb24fSFrançois Tigeot err_unpin:
729a85cb24fSFrançois Tigeot engine->context_unpin(engine, ctx);
73071f41f3eSFrançois Tigeot return ERR_PTR(ret);
73187df8fc6SFrançois Tigeot }
73287df8fc6SFrançois Tigeot
7331e12ee3bSFrançois Tigeot static int
i915_gem_request_await_request(struct drm_i915_gem_request * to,struct drm_i915_gem_request * from)7341e12ee3bSFrançois Tigeot i915_gem_request_await_request(struct drm_i915_gem_request *to,
7351e12ee3bSFrançois Tigeot struct drm_i915_gem_request *from)
7361e12ee3bSFrançois Tigeot {
7374be47400SFrançois Tigeot int ret;
7381e12ee3bSFrançois Tigeot
7391e12ee3bSFrançois Tigeot GEM_BUG_ON(to == from);
740*3f2dd94aSFrançois Tigeot GEM_BUG_ON(to->timeline == from->timeline);
7411e12ee3bSFrançois Tigeot
742a85cb24fSFrançois Tigeot if (i915_gem_request_completed(from))
743a85cb24fSFrançois Tigeot return 0;
744a85cb24fSFrançois Tigeot
7454be47400SFrançois Tigeot if (to->engine->schedule) {
7464be47400SFrançois Tigeot ret = i915_priotree_add_dependency(to->i915,
7474be47400SFrançois Tigeot &to->priotree,
7484be47400SFrançois Tigeot &from->priotree);
7494be47400SFrançois Tigeot if (ret < 0)
7504be47400SFrançois Tigeot return ret;
7514be47400SFrançois Tigeot }
7524be47400SFrançois Tigeot
7534be47400SFrançois Tigeot if (to->engine == from->engine) {
7544be47400SFrançois Tigeot ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
7554be47400SFrançois Tigeot &from->submit,
7564be47400SFrançois Tigeot GFP_KERNEL);
7574be47400SFrançois Tigeot return ret < 0 ? ret : 0;
7584be47400SFrançois Tigeot }
7594be47400SFrançois Tigeot
760*3f2dd94aSFrançois Tigeot if (to->engine->semaphore.sync_to) {
761*3f2dd94aSFrançois Tigeot u32 seqno;
762*3f2dd94aSFrançois Tigeot
763*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!from->engine->semaphore.signal);
764*3f2dd94aSFrançois Tigeot
765a85cb24fSFrançois Tigeot seqno = i915_gem_request_global_seqno(from);
766*3f2dd94aSFrançois Tigeot if (!seqno)
767*3f2dd94aSFrançois Tigeot goto await_dma_fence;
768*3f2dd94aSFrançois Tigeot
769*3f2dd94aSFrançois Tigeot if (seqno <= to->timeline->global_sync[from->engine->id])
770*3f2dd94aSFrançois Tigeot return 0;
771*3f2dd94aSFrançois Tigeot
772*3f2dd94aSFrançois Tigeot trace_i915_gem_ring_sync_to(to, from);
773*3f2dd94aSFrançois Tigeot ret = to->engine->semaphore.sync_to(to, from);
774*3f2dd94aSFrançois Tigeot if (ret)
775*3f2dd94aSFrançois Tigeot return ret;
776*3f2dd94aSFrançois Tigeot
777*3f2dd94aSFrançois Tigeot to->timeline->global_sync[from->engine->id] = seqno;
778*3f2dd94aSFrançois Tigeot return 0;
779*3f2dd94aSFrançois Tigeot }
780*3f2dd94aSFrançois Tigeot
781*3f2dd94aSFrançois Tigeot await_dma_fence:
7824be47400SFrançois Tigeot ret = i915_sw_fence_await_dma_fence(&to->submit,
7834be47400SFrançois Tigeot &from->fence, 0,
7844be47400SFrançois Tigeot GFP_KERNEL);
7854be47400SFrançois Tigeot return ret < 0 ? ret : 0;
7864be47400SFrançois Tigeot }
7874be47400SFrançois Tigeot
7884be47400SFrançois Tigeot int
i915_gem_request_await_dma_fence(struct drm_i915_gem_request * req,struct dma_fence * fence)7894be47400SFrançois Tigeot i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
7904be47400SFrançois Tigeot struct dma_fence *fence)
7914be47400SFrançois Tigeot {
792*3f2dd94aSFrançois Tigeot struct dma_fence **child = &fence;
793*3f2dd94aSFrançois Tigeot unsigned int nchild = 1;
7944be47400SFrançois Tigeot int ret;
7954be47400SFrançois Tigeot
7964be47400SFrançois Tigeot /* Note that if the fence-array was created in signal-on-any mode,
7974be47400SFrançois Tigeot * we should *not* decompose it into its individual fences. However,
7984be47400SFrançois Tigeot * we don't currently store which mode the fence-array is operating
7994be47400SFrançois Tigeot * in. Fortunately, the only user of signal-on-any is private to
8004be47400SFrançois Tigeot * amdgpu and we should not see any incoming fence-array from
8014be47400SFrançois Tigeot * sync-file being in signal-on-any mode.
8024be47400SFrançois Tigeot */
803*3f2dd94aSFrançois Tigeot if (dma_fence_is_array(fence)) {
804*3f2dd94aSFrançois Tigeot struct dma_fence_array *array = to_dma_fence_array(fence);
8054be47400SFrançois Tigeot
806*3f2dd94aSFrançois Tigeot child = array->fences;
807*3f2dd94aSFrançois Tigeot nchild = array->num_fences;
808*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!nchild);
809*3f2dd94aSFrançois Tigeot }
8104be47400SFrançois Tigeot
811*3f2dd94aSFrançois Tigeot do {
812*3f2dd94aSFrançois Tigeot fence = *child++;
813*3f2dd94aSFrançois Tigeot if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
814*3f2dd94aSFrançois Tigeot continue;
815*3f2dd94aSFrançois Tigeot
816*3f2dd94aSFrançois Tigeot /*
817*3f2dd94aSFrançois Tigeot * Requests on the same timeline are explicitly ordered, along
818*3f2dd94aSFrançois Tigeot * with their dependencies, by i915_add_request() which ensures
819*3f2dd94aSFrançois Tigeot * that requests are submitted in-order through each ring.
820*3f2dd94aSFrançois Tigeot */
821*3f2dd94aSFrançois Tigeot if (fence->context == req->fence.context)
822*3f2dd94aSFrançois Tigeot continue;
823*3f2dd94aSFrançois Tigeot
824*3f2dd94aSFrançois Tigeot /* Squash repeated waits to the same timelines */
825*3f2dd94aSFrançois Tigeot if (fence->context != req->i915->mm.unordered_timeline &&
826*3f2dd94aSFrançois Tigeot intel_timeline_sync_is_later(req->timeline, fence))
827*3f2dd94aSFrançois Tigeot continue;
828*3f2dd94aSFrançois Tigeot
829*3f2dd94aSFrançois Tigeot if (dma_fence_is_i915(fence))
8304be47400SFrançois Tigeot ret = i915_gem_request_await_request(req,
831*3f2dd94aSFrançois Tigeot to_request(fence));
8324be47400SFrançois Tigeot else
833*3f2dd94aSFrançois Tigeot ret = i915_sw_fence_await_dma_fence(&req->submit, fence,
834*3f2dd94aSFrançois Tigeot I915_FENCE_TIMEOUT,
8354be47400SFrançois Tigeot GFP_KERNEL);
8364be47400SFrançois Tigeot if (ret < 0)
8374be47400SFrançois Tigeot return ret;
838*3f2dd94aSFrançois Tigeot
839*3f2dd94aSFrançois Tigeot /* Record the latest fence used against each timeline */
840*3f2dd94aSFrançois Tigeot if (fence->context != req->i915->mm.unordered_timeline)
841*3f2dd94aSFrançois Tigeot intel_timeline_sync_set(req->timeline, fence);
842*3f2dd94aSFrançois Tigeot } while (--nchild);
8434be47400SFrançois Tigeot
8441e12ee3bSFrançois Tigeot return 0;
8451e12ee3bSFrançois Tigeot }
8461e12ee3bSFrançois Tigeot
8471e12ee3bSFrançois Tigeot /**
8481e12ee3bSFrançois Tigeot * i915_gem_request_await_object - set this request to (async) wait upon a bo
8491e12ee3bSFrançois Tigeot *
8501e12ee3bSFrançois Tigeot * @to: request we are wishing to use
8511e12ee3bSFrançois Tigeot * @obj: object which may be in use on another ring.
8521e12ee3bSFrançois Tigeot *
8531e12ee3bSFrançois Tigeot * This code is meant to abstract object synchronization with the GPU.
8541e12ee3bSFrançois Tigeot * Conceptually we serialise writes between engines inside the GPU.
8551e12ee3bSFrançois Tigeot * We only allow one engine to write into a buffer at any time, but
8561e12ee3bSFrançois Tigeot * multiple readers. To ensure each has a coherent view of memory, we must:
8571e12ee3bSFrançois Tigeot *
8581e12ee3bSFrançois Tigeot * - If there is an outstanding write request to the object, the new
8591e12ee3bSFrançois Tigeot * request must wait for it to complete (either CPU or in hw, requests
8601e12ee3bSFrançois Tigeot * on the same ring will be naturally ordered).
8611e12ee3bSFrançois Tigeot *
8621e12ee3bSFrançois Tigeot * - If we are a write request (pending_write_domain is set), the new
8631e12ee3bSFrançois Tigeot * request must wait for outstanding read requests to complete.
8641e12ee3bSFrançois Tigeot *
8651e12ee3bSFrançois Tigeot * Returns 0 if successful, else propagates up the lower layer error.
8661e12ee3bSFrançois Tigeot */
8671e12ee3bSFrançois Tigeot int
i915_gem_request_await_object(struct drm_i915_gem_request * to,struct drm_i915_gem_object * obj,bool write)8681e12ee3bSFrançois Tigeot i915_gem_request_await_object(struct drm_i915_gem_request *to,
8691e12ee3bSFrançois Tigeot struct drm_i915_gem_object *obj,
8701e12ee3bSFrançois Tigeot bool write)
8711e12ee3bSFrançois Tigeot {
8724be47400SFrançois Tigeot struct dma_fence *excl;
8734be47400SFrançois Tigeot int ret = 0;
8741e12ee3bSFrançois Tigeot
8751e12ee3bSFrançois Tigeot if (write) {
8764be47400SFrançois Tigeot struct dma_fence **shared;
8774be47400SFrançois Tigeot unsigned int count, i;
8781e12ee3bSFrançois Tigeot
8794be47400SFrançois Tigeot ret = reservation_object_get_fences_rcu(obj->resv,
8804be47400SFrançois Tigeot &excl, &count, &shared);
8811e12ee3bSFrançois Tigeot if (ret)
8821e12ee3bSFrançois Tigeot return ret;
8834be47400SFrançois Tigeot
8844be47400SFrançois Tigeot for (i = 0; i < count; i++) {
8854be47400SFrançois Tigeot ret = i915_gem_request_await_dma_fence(to, shared[i]);
8864be47400SFrançois Tigeot if (ret)
8874be47400SFrançois Tigeot break;
8884be47400SFrançois Tigeot
8894be47400SFrançois Tigeot dma_fence_put(shared[i]);
8901e12ee3bSFrançois Tigeot }
8911e12ee3bSFrançois Tigeot
8924be47400SFrançois Tigeot for (; i < count; i++)
8934be47400SFrançois Tigeot dma_fence_put(shared[i]);
8944be47400SFrançois Tigeot kfree(shared);
8954be47400SFrançois Tigeot } else {
8964be47400SFrançois Tigeot excl = reservation_object_get_excl_rcu(obj->resv);
8974be47400SFrançois Tigeot }
8984be47400SFrançois Tigeot
8994be47400SFrançois Tigeot if (excl) {
9004be47400SFrançois Tigeot if (ret == 0)
9014be47400SFrançois Tigeot ret = i915_gem_request_await_dma_fence(to, excl);
9024be47400SFrançois Tigeot
9034be47400SFrançois Tigeot dma_fence_put(excl);
9044be47400SFrançois Tigeot }
9054be47400SFrançois Tigeot
9064be47400SFrançois Tigeot return ret;
9071e12ee3bSFrançois Tigeot }
9081e12ee3bSFrançois Tigeot
90987df8fc6SFrançois Tigeot /*
91087df8fc6SFrançois Tigeot * NB: This function is not allowed to fail. Doing so would mean the the
91187df8fc6SFrançois Tigeot * request is not being tracked for completion but the work itself is
91287df8fc6SFrançois Tigeot * going to happen on the hardware. This would be a Bad Thing(tm).
91387df8fc6SFrançois Tigeot */
__i915_add_request(struct drm_i915_gem_request * request,bool flush_caches)9141e12ee3bSFrançois Tigeot void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
91587df8fc6SFrançois Tigeot {
9161e12ee3bSFrançois Tigeot struct intel_engine_cs *engine = request->engine;
9171e12ee3bSFrançois Tigeot struct intel_ring *ring = request->ring;
9184be47400SFrançois Tigeot struct intel_timeline *timeline = request->timeline;
9191e12ee3bSFrançois Tigeot struct drm_i915_gem_request *prev;
920a85cb24fSFrançois Tigeot u32 *cs;
9214be47400SFrançois Tigeot int err;
92287df8fc6SFrançois Tigeot
9234be47400SFrançois Tigeot lockdep_assert_held(&request->i915->drm.struct_mutex);
9241e12ee3bSFrançois Tigeot trace_i915_gem_request_add(request);
92587df8fc6SFrançois Tigeot
926a85cb24fSFrançois Tigeot /* Make sure that no request gazumped us - if it was allocated after
927a85cb24fSFrançois Tigeot * our i915_gem_request_alloc() and called __i915_add_request() before
928a85cb24fSFrançois Tigeot * us, the timeline will hold its seqno which is later than ours.
929a85cb24fSFrançois Tigeot */
930a85cb24fSFrançois Tigeot GEM_BUG_ON(timeline->seqno != request->fence.seqno);
931a85cb24fSFrançois Tigeot
93287df8fc6SFrançois Tigeot /*
93387df8fc6SFrançois Tigeot * To ensure that this call will not fail, space for its emissions
93487df8fc6SFrançois Tigeot * should already have been reserved in the ring buffer. Let the ring
93587df8fc6SFrançois Tigeot * know that it is time to use that space up.
93687df8fc6SFrançois Tigeot */
93787df8fc6SFrançois Tigeot request->reserved_space = 0;
93887df8fc6SFrançois Tigeot
93987df8fc6SFrançois Tigeot /*
94087df8fc6SFrançois Tigeot * Emit any outstanding flushes - execbuf can fail to emit the flush
94187df8fc6SFrançois Tigeot * after having emitted the batchbuffer command. Hence we need to fix
94287df8fc6SFrançois Tigeot * things up similar to emitting the lazy request. The difference here
94387df8fc6SFrançois Tigeot * is that the flush _must_ happen before the next request, no matter
94487df8fc6SFrançois Tigeot * what.
94587df8fc6SFrançois Tigeot */
94687df8fc6SFrançois Tigeot if (flush_caches) {
9474be47400SFrançois Tigeot err = engine->emit_flush(request, EMIT_FLUSH);
94871f41f3eSFrançois Tigeot
94987df8fc6SFrançois Tigeot /* Not allowed to fail! */
9504be47400SFrançois Tigeot WARN(err, "engine->emit_flush() failed: %d!\n", err);
95187df8fc6SFrançois Tigeot }
95287df8fc6SFrançois Tigeot
9531e12ee3bSFrançois Tigeot /* Record the position of the start of the breadcrumb so that
95487df8fc6SFrançois Tigeot * should we detect the updated seqno part-way through the
95587df8fc6SFrançois Tigeot * GPU processing the request, we never over-estimate the
9561e12ee3bSFrançois Tigeot * position of the ring's HEAD.
95787df8fc6SFrançois Tigeot */
958a85cb24fSFrançois Tigeot cs = intel_ring_begin(request, engine->emit_breadcrumb_sz);
959a85cb24fSFrançois Tigeot GEM_BUG_ON(IS_ERR(cs));
960a85cb24fSFrançois Tigeot request->postfix = intel_ring_offset(request, cs);
96187df8fc6SFrançois Tigeot
9621e12ee3bSFrançois Tigeot /* Seal the request and mark it as pending execution. Note that
9631e12ee3bSFrançois Tigeot * we may inspect this state, without holding any locks, during
9641e12ee3bSFrançois Tigeot * hangcheck. Hence we apply the barrier to ensure that we do not
9651e12ee3bSFrançois Tigeot * see a more recent value in the hws than we are tracking.
9661e12ee3bSFrançois Tigeot */
9671e12ee3bSFrançois Tigeot
9684be47400SFrançois Tigeot prev = i915_gem_active_raw(&timeline->last_request,
9691e12ee3bSFrançois Tigeot &request->i915->drm.struct_mutex);
9704be47400SFrançois Tigeot if (prev) {
9711e12ee3bSFrançois Tigeot i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
9721e12ee3bSFrançois Tigeot &request->submitq);
9734be47400SFrançois Tigeot if (engine->schedule)
9744be47400SFrançois Tigeot __i915_priotree_add_dependency(&request->priotree,
9754be47400SFrançois Tigeot &prev->priotree,
9764be47400SFrançois Tigeot &request->dep,
9774be47400SFrançois Tigeot 0);
9784be47400SFrançois Tigeot }
9791e12ee3bSFrançois Tigeot
9804be47400SFrançois Tigeot spin_lock_irq(&timeline->lock);
9814be47400SFrançois Tigeot list_add_tail(&request->link, &timeline->requests);
9824be47400SFrançois Tigeot spin_unlock_irq(&timeline->lock);
9834be47400SFrançois Tigeot
984a85cb24fSFrançois Tigeot GEM_BUG_ON(timeline->seqno != request->fence.seqno);
9854be47400SFrançois Tigeot i915_gem_active_set(&timeline->last_request, request);
9864be47400SFrançois Tigeot
9871e12ee3bSFrançois Tigeot list_add_tail(&request->ring_link, &ring->request_list);
9884be47400SFrançois Tigeot request->emitted_jiffies = jiffies;
9891e12ee3bSFrançois Tigeot
9904be47400SFrançois Tigeot /* Let the backend know a new request has arrived that may need
9914be47400SFrançois Tigeot * to adjust the existing execution schedule due to a high priority
9924be47400SFrançois Tigeot * request - i.e. we may want to preempt the current request in order
9934be47400SFrançois Tigeot * to run a high priority dependency chain *before* we can execute this
9944be47400SFrançois Tigeot * request.
9954be47400SFrançois Tigeot *
9964be47400SFrançois Tigeot * This is called before the request is ready to run so that we can
9974be47400SFrançois Tigeot * decide whether to preempt the entire chain so that it is ready to
9984be47400SFrançois Tigeot * run at the earliest possible convenience.
9994be47400SFrançois Tigeot */
10004be47400SFrançois Tigeot if (engine->schedule)
10014be47400SFrançois Tigeot engine->schedule(request, request->ctx->priority);
10024be47400SFrançois Tigeot
10031e12ee3bSFrançois Tigeot local_bh_disable();
10041e12ee3bSFrançois Tigeot i915_sw_fence_commit(&request->submit);
10051e12ee3bSFrançois Tigeot local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
10061e12ee3bSFrançois Tigeot }
10071e12ee3bSFrançois Tigeot
local_clock_us(unsigned int * cpu)100887df8fc6SFrançois Tigeot static unsigned long local_clock_us(unsigned int *cpu)
100987df8fc6SFrançois Tigeot {
101087df8fc6SFrançois Tigeot unsigned long t;
101187df8fc6SFrançois Tigeot
101287df8fc6SFrançois Tigeot /* Cheaply and approximately convert from nanoseconds to microseconds.
101387df8fc6SFrançois Tigeot * The result and subsequent calculations are also defined in the same
101487df8fc6SFrançois Tigeot * approximate microseconds units. The principal source of timing
101587df8fc6SFrançois Tigeot * error here is from the simple truncation.
101687df8fc6SFrançois Tigeot *
101787df8fc6SFrançois Tigeot * Note that local_clock() is only defined wrt to the current CPU;
101887df8fc6SFrançois Tigeot * the comparisons are no longer valid if we switch CPUs. Instead of
101987df8fc6SFrançois Tigeot * blocking preemption for the entire busywait, we can detect the CPU
102087df8fc6SFrançois Tigeot * switch and use that as indicator of system load and a reason to
102187df8fc6SFrançois Tigeot * stop busywaiting, see busywait_stop().
102287df8fc6SFrançois Tigeot */
102387df8fc6SFrançois Tigeot *cpu = get_cpu();
102487df8fc6SFrançois Tigeot t = local_clock() >> 10;
102587df8fc6SFrançois Tigeot put_cpu();
102687df8fc6SFrançois Tigeot
102787df8fc6SFrançois Tigeot return t;
102887df8fc6SFrançois Tigeot }
102987df8fc6SFrançois Tigeot
busywait_stop(unsigned long timeout,unsigned int cpu)103087df8fc6SFrançois Tigeot static bool busywait_stop(unsigned long timeout, unsigned int cpu)
103187df8fc6SFrançois Tigeot {
103287df8fc6SFrançois Tigeot unsigned int this_cpu;
103387df8fc6SFrançois Tigeot
103487df8fc6SFrançois Tigeot if (time_after(local_clock_us(&this_cpu), timeout))
103587df8fc6SFrançois Tigeot return true;
103687df8fc6SFrançois Tigeot
103787df8fc6SFrançois Tigeot return this_cpu != cpu;
103887df8fc6SFrançois Tigeot }
103987df8fc6SFrançois Tigeot
__i915_spin_request(const struct drm_i915_gem_request * req,u32 seqno,int state,unsigned long timeout_us)1040*3f2dd94aSFrançois Tigeot static bool __i915_spin_request(const struct drm_i915_gem_request *req,
1041a85cb24fSFrançois Tigeot u32 seqno, int state, unsigned long timeout_us)
104287df8fc6SFrançois Tigeot {
1043a85cb24fSFrançois Tigeot struct intel_engine_cs *engine = req->engine;
1044a85cb24fSFrançois Tigeot unsigned int irq, cpu;
104587df8fc6SFrançois Tigeot
1046*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!seqno);
1047*3f2dd94aSFrançois Tigeot
1048*3f2dd94aSFrançois Tigeot /*
1049*3f2dd94aSFrançois Tigeot * Only wait for the request if we know it is likely to complete.
1050*3f2dd94aSFrançois Tigeot *
1051*3f2dd94aSFrançois Tigeot * We don't track the timestamps around requests, nor the average
1052*3f2dd94aSFrançois Tigeot * request length, so we do not have a good indicator that this
1053*3f2dd94aSFrançois Tigeot * request will complete within the timeout. What we do know is the
1054*3f2dd94aSFrançois Tigeot * order in which requests are executed by the engine and so we can
1055*3f2dd94aSFrançois Tigeot * tell if the request has started. If the request hasn't started yet,
1056*3f2dd94aSFrançois Tigeot * it is a fair assumption that it will not complete within our
1057*3f2dd94aSFrançois Tigeot * relatively short timeout.
1058*3f2dd94aSFrançois Tigeot */
1059*3f2dd94aSFrançois Tigeot if (!i915_seqno_passed(intel_engine_get_seqno(engine), seqno - 1))
1060*3f2dd94aSFrançois Tigeot return false;
1061*3f2dd94aSFrançois Tigeot
106287df8fc6SFrançois Tigeot /* When waiting for high frequency requests, e.g. during synchronous
106387df8fc6SFrançois Tigeot * rendering split between the CPU and GPU, the finite amount of time
106487df8fc6SFrançois Tigeot * required to set up the irq and wait upon it limits the response
106587df8fc6SFrançois Tigeot * rate. By busywaiting on the request completion for a short while we
106687df8fc6SFrançois Tigeot * can service the high frequency waits as quick as possible. However,
106787df8fc6SFrançois Tigeot * if it is a slow request, we want to sleep as quickly as possible.
106887df8fc6SFrançois Tigeot * The tradeoff between waiting and sleeping is roughly the time it
106987df8fc6SFrançois Tigeot * takes to sleep on a request, on the order of a microsecond.
107087df8fc6SFrançois Tigeot */
107187df8fc6SFrançois Tigeot
1072a85cb24fSFrançois Tigeot irq = atomic_read(&engine->irq_count);
107387df8fc6SFrançois Tigeot timeout_us += local_clock_us(&cpu);
107487df8fc6SFrançois Tigeot do {
1075*3f2dd94aSFrançois Tigeot if (i915_seqno_passed(intel_engine_get_seqno(engine), seqno))
1076*3f2dd94aSFrançois Tigeot return seqno == i915_gem_request_global_seqno(req);
107787df8fc6SFrançois Tigeot
1078a85cb24fSFrançois Tigeot /* Seqno are meant to be ordered *before* the interrupt. If
1079a85cb24fSFrançois Tigeot * we see an interrupt without a corresponding seqno advance,
1080a85cb24fSFrançois Tigeot * assume we won't see one in the near future but require
1081a85cb24fSFrançois Tigeot * the engine->seqno_barrier() to fixup coherency.
1082a85cb24fSFrançois Tigeot */
1083a85cb24fSFrançois Tigeot if (atomic_read(&engine->irq_count) != irq)
1084a85cb24fSFrançois Tigeot break;
1085a85cb24fSFrançois Tigeot
108687df8fc6SFrançois Tigeot if (signal_pending_state(state, current))
108787df8fc6SFrançois Tigeot break;
108887df8fc6SFrançois Tigeot
108987df8fc6SFrançois Tigeot if (busywait_stop(timeout_us, cpu))
109087df8fc6SFrançois Tigeot break;
109187df8fc6SFrançois Tigeot
109287df8fc6SFrançois Tigeot cpu_relax();
109387df8fc6SFrançois Tigeot } while (!need_resched());
109487df8fc6SFrançois Tigeot
109587df8fc6SFrançois Tigeot return false;
109687df8fc6SFrançois Tigeot }
109787df8fc6SFrançois Tigeot
__i915_wait_request_check_and_reset(struct drm_i915_gem_request * request)1098a85cb24fSFrançois Tigeot static bool __i915_wait_request_check_and_reset(struct drm_i915_gem_request *request)
10994be47400SFrançois Tigeot {
1100a85cb24fSFrançois Tigeot if (likely(!i915_reset_handoff(&request->i915->gpu_error)))
1101a85cb24fSFrançois Tigeot return false;
11024be47400SFrançois Tigeot
11034be47400SFrançois Tigeot __set_current_state(TASK_RUNNING);
1104*3f2dd94aSFrançois Tigeot i915_reset(request->i915, 0);
1105a85cb24fSFrançois Tigeot return true;
11064be47400SFrançois Tigeot }
11074be47400SFrançois Tigeot
110887df8fc6SFrançois Tigeot /**
110971f41f3eSFrançois Tigeot * i915_wait_request - wait until execution of request has finished
11104be47400SFrançois Tigeot * @req: the request to wait upon
11111e12ee3bSFrançois Tigeot * @flags: how to wait
11124be47400SFrançois Tigeot * @timeout: how long to wait in jiffies
111387df8fc6SFrançois Tigeot *
11144be47400SFrançois Tigeot * i915_wait_request() waits for the request to be completed, for a
11154be47400SFrançois Tigeot * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
11164be47400SFrançois Tigeot * unbounded wait).
111787df8fc6SFrançois Tigeot *
11184be47400SFrançois Tigeot * If the caller holds the struct_mutex, the caller must pass I915_WAIT_LOCKED
11194be47400SFrançois Tigeot * in via the flags, and vice versa if the struct_mutex is not held, the caller
11204be47400SFrançois Tigeot * must not specify that the wait is locked.
11214be47400SFrançois Tigeot *
11224be47400SFrançois Tigeot * Returns the remaining time (in jiffies) if the request completed, which may
11234be47400SFrançois Tigeot * be zero or -ETIME if the request is unfinished after the timeout expires.
11244be47400SFrançois Tigeot * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
11254be47400SFrançois Tigeot * pending before the request completes.
112687df8fc6SFrançois Tigeot */
i915_wait_request(struct drm_i915_gem_request * req,unsigned int flags,long timeout)11274be47400SFrançois Tigeot long i915_wait_request(struct drm_i915_gem_request *req,
11281e12ee3bSFrançois Tigeot unsigned int flags,
11294be47400SFrançois Tigeot long timeout)
113087df8fc6SFrançois Tigeot {
11311e12ee3bSFrançois Tigeot const int state = flags & I915_WAIT_INTERRUPTIBLE ?
11321e12ee3bSFrançois Tigeot TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
1133a85cb24fSFrançois Tigeot wait_queue_head_t *errq = &req->i915->gpu_error.wait_queue;
1134a85cb24fSFrançois Tigeot DEFINE_WAIT_FUNC(reset, default_wake_function);
1135a85cb24fSFrançois Tigeot DEFINE_WAIT_FUNC(exec, default_wake_function);
113687df8fc6SFrançois Tigeot struct intel_wait wait;
113787df8fc6SFrançois Tigeot
113887df8fc6SFrançois Tigeot might_sleep();
11391e12ee3bSFrançois Tigeot #if IS_ENABLED(CONFIG_LOCKDEP)
11404be47400SFrançois Tigeot GEM_BUG_ON(debug_locks &&
11414be47400SFrançois Tigeot !!lockdep_is_held(&req->i915->drm.struct_mutex) !=
11421e12ee3bSFrançois Tigeot !!(flags & I915_WAIT_LOCKED));
11431e12ee3bSFrançois Tigeot #endif
11444be47400SFrançois Tigeot GEM_BUG_ON(timeout < 0);
114587df8fc6SFrançois Tigeot
114687df8fc6SFrançois Tigeot if (i915_gem_request_completed(req))
11474be47400SFrançois Tigeot return timeout;
114887df8fc6SFrançois Tigeot
11494be47400SFrançois Tigeot if (!timeout)
115087df8fc6SFrançois Tigeot return -ETIME;
115187df8fc6SFrançois Tigeot
1152a85cb24fSFrançois Tigeot trace_i915_gem_request_wait_begin(req, flags);
115387df8fc6SFrançois Tigeot
1154a85cb24fSFrançois Tigeot add_wait_queue(&req->execute, &exec);
1155a85cb24fSFrançois Tigeot if (flags & I915_WAIT_LOCKED)
1156a85cb24fSFrançois Tigeot add_wait_queue(errq, &reset);
1157a85cb24fSFrançois Tigeot
1158a85cb24fSFrançois Tigeot intel_wait_init(&wait, req);
1159a85cb24fSFrançois Tigeot
1160a85cb24fSFrançois Tigeot restart:
1161a85cb24fSFrançois Tigeot do {
1162a85cb24fSFrançois Tigeot set_current_state(state);
1163a85cb24fSFrançois Tigeot if (intel_wait_update_request(&wait, req))
1164a85cb24fSFrançois Tigeot break;
1165a85cb24fSFrançois Tigeot
1166a85cb24fSFrançois Tigeot if (flags & I915_WAIT_LOCKED &&
1167a85cb24fSFrançois Tigeot __i915_wait_request_check_and_reset(req))
1168a85cb24fSFrançois Tigeot continue;
1169a85cb24fSFrançois Tigeot
1170a85cb24fSFrançois Tigeot if (signal_pending_state(state, current)) {
1171a85cb24fSFrançois Tigeot timeout = -ERESTARTSYS;
11724be47400SFrançois Tigeot goto complete;
11734be47400SFrançois Tigeot }
1174a85cb24fSFrançois Tigeot
1175a85cb24fSFrançois Tigeot if (!timeout) {
1176a85cb24fSFrançois Tigeot timeout = -ETIME;
1177a85cb24fSFrançois Tigeot goto complete;
1178a85cb24fSFrançois Tigeot }
1179a85cb24fSFrançois Tigeot
1180a85cb24fSFrançois Tigeot timeout = io_schedule_timeout(timeout);
1181a85cb24fSFrançois Tigeot } while (1);
1182a85cb24fSFrançois Tigeot
1183a85cb24fSFrançois Tigeot GEM_BUG_ON(!intel_wait_has_seqno(&wait));
1184a85cb24fSFrançois Tigeot GEM_BUG_ON(!i915_sw_fence_signaled(&req->submit));
118587df8fc6SFrançois Tigeot
118671f41f3eSFrançois Tigeot /* Optimistic short spin before touching IRQs */
1187*3f2dd94aSFrançois Tigeot if (__i915_spin_request(req, wait.seqno, state, 5))
118887df8fc6SFrançois Tigeot goto complete;
118987df8fc6SFrançois Tigeot
119087df8fc6SFrançois Tigeot set_current_state(state);
119187df8fc6SFrançois Tigeot if (intel_engine_add_wait(req->engine, &wait))
119287df8fc6SFrançois Tigeot /* In order to check that we haven't missed the interrupt
119387df8fc6SFrançois Tigeot * as we enabled it, we need to kick ourselves to do a
119487df8fc6SFrançois Tigeot * coherent check on the seqno before we sleep.
119587df8fc6SFrançois Tigeot */
119687df8fc6SFrançois Tigeot goto wakeup;
119787df8fc6SFrançois Tigeot
1198a85cb24fSFrançois Tigeot if (flags & I915_WAIT_LOCKED)
1199a85cb24fSFrançois Tigeot __i915_wait_request_check_and_reset(req);
1200a85cb24fSFrançois Tigeot
120187df8fc6SFrançois Tigeot for (;;) {
120287df8fc6SFrançois Tigeot if (signal_pending_state(state, current)) {
12034be47400SFrançois Tigeot timeout = -ERESTARTSYS;
120487df8fc6SFrançois Tigeot break;
120587df8fc6SFrançois Tigeot }
120687df8fc6SFrançois Tigeot
12074be47400SFrançois Tigeot if (!timeout) {
12084be47400SFrançois Tigeot timeout = -ETIME;
120987df8fc6SFrançois Tigeot break;
121087df8fc6SFrançois Tigeot }
121187df8fc6SFrançois Tigeot
12124be47400SFrançois Tigeot timeout = io_schedule_timeout(timeout);
12134be47400SFrançois Tigeot
1214a85cb24fSFrançois Tigeot if (intel_wait_complete(&wait) &&
1215a85cb24fSFrançois Tigeot intel_wait_check_request(&wait, req))
121687df8fc6SFrançois Tigeot break;
121787df8fc6SFrançois Tigeot
121887df8fc6SFrançois Tigeot set_current_state(state);
121987df8fc6SFrançois Tigeot
122087df8fc6SFrançois Tigeot wakeup:
122187df8fc6SFrançois Tigeot /* Carefully check if the request is complete, giving time
122287df8fc6SFrançois Tigeot * for the seqno to be visible following the interrupt.
122387df8fc6SFrançois Tigeot * We also have to check in case we are kicked by the GPU
122487df8fc6SFrançois Tigeot * reset in order to drop the struct_mutex.
122587df8fc6SFrançois Tigeot */
122687df8fc6SFrançois Tigeot if (__i915_request_irq_complete(req))
122787df8fc6SFrançois Tigeot break;
122887df8fc6SFrançois Tigeot
12291e12ee3bSFrançois Tigeot /* If the GPU is hung, and we hold the lock, reset the GPU
12301e12ee3bSFrançois Tigeot * and then check for completion. On a full reset, the engine's
12311e12ee3bSFrançois Tigeot * HW seqno will be advanced passed us and we are complete.
12321e12ee3bSFrançois Tigeot * If we do a partial reset, we have to wait for the GPU to
12331e12ee3bSFrançois Tigeot * resume and update the breadcrumb.
12341e12ee3bSFrançois Tigeot *
12351e12ee3bSFrançois Tigeot * If we don't hold the mutex, we can just wait for the worker
12361e12ee3bSFrançois Tigeot * to come along and update the breadcrumb (either directly
12371e12ee3bSFrançois Tigeot * itself, or indirectly by recovering the GPU).
12381e12ee3bSFrançois Tigeot */
12391e12ee3bSFrançois Tigeot if (flags & I915_WAIT_LOCKED &&
1240a85cb24fSFrançois Tigeot __i915_wait_request_check_and_reset(req))
12411e12ee3bSFrançois Tigeot continue;
12421e12ee3bSFrançois Tigeot
124387df8fc6SFrançois Tigeot /* Only spin if we know the GPU is processing this request */
1244*3f2dd94aSFrançois Tigeot if (__i915_spin_request(req, wait.seqno, state, 2))
124587df8fc6SFrançois Tigeot break;
1246a85cb24fSFrançois Tigeot
1247a85cb24fSFrançois Tigeot if (!intel_wait_check_request(&wait, req)) {
1248a85cb24fSFrançois Tigeot intel_engine_remove_wait(req->engine, &wait);
1249a85cb24fSFrançois Tigeot goto restart;
1250a85cb24fSFrançois Tigeot }
125187df8fc6SFrançois Tigeot }
125287df8fc6SFrançois Tigeot
125387df8fc6SFrançois Tigeot intel_engine_remove_wait(req->engine, &wait);
125487df8fc6SFrançois Tigeot complete:
1255a85cb24fSFrançois Tigeot __set_current_state(TASK_RUNNING);
1256a85cb24fSFrançois Tigeot if (flags & I915_WAIT_LOCKED)
1257a85cb24fSFrançois Tigeot remove_wait_queue(errq, &reset);
1258a85cb24fSFrançois Tigeot remove_wait_queue(&req->execute, &exec);
125987df8fc6SFrançois Tigeot trace_i915_gem_request_wait_end(req);
126087df8fc6SFrançois Tigeot
12614be47400SFrançois Tigeot return timeout;
126287df8fc6SFrançois Tigeot }
126387df8fc6SFrançois Tigeot
engine_retire_requests(struct intel_engine_cs * engine)12644be47400SFrançois Tigeot static void engine_retire_requests(struct intel_engine_cs *engine)
126587df8fc6SFrançois Tigeot {
126671f41f3eSFrançois Tigeot struct drm_i915_gem_request *request, *next;
1267a85cb24fSFrançois Tigeot u32 seqno = intel_engine_get_seqno(engine);
1268a85cb24fSFrançois Tigeot LINUX_LIST_HEAD(retire);
126987df8fc6SFrançois Tigeot
1270a85cb24fSFrançois Tigeot spin_lock_irq(&engine->timeline->lock);
12714be47400SFrançois Tigeot list_for_each_entry_safe(request, next,
12724be47400SFrançois Tigeot &engine->timeline->requests, link) {
1273a85cb24fSFrançois Tigeot if (!i915_seqno_passed(seqno, request->global_seqno))
1274a85cb24fSFrançois Tigeot break;
127587df8fc6SFrançois Tigeot
1276a85cb24fSFrançois Tigeot list_move_tail(&request->link, &retire);
127771f41f3eSFrançois Tigeot }
1278a85cb24fSFrançois Tigeot spin_unlock_irq(&engine->timeline->lock);
1279a85cb24fSFrançois Tigeot
1280a85cb24fSFrançois Tigeot list_for_each_entry_safe(request, next, &retire, link)
1281a85cb24fSFrançois Tigeot i915_gem_request_retire(request);
128271f41f3eSFrançois Tigeot }
128387df8fc6SFrançois Tigeot
i915_gem_retire_requests(struct drm_i915_private * dev_priv)128471f41f3eSFrançois Tigeot void i915_gem_retire_requests(struct drm_i915_private *dev_priv)
128571f41f3eSFrançois Tigeot {
128671f41f3eSFrançois Tigeot struct intel_engine_cs *engine;
12874be47400SFrançois Tigeot enum intel_engine_id id;
128887df8fc6SFrançois Tigeot
128971f41f3eSFrançois Tigeot lockdep_assert_held(&dev_priv->drm.struct_mutex);
129071f41f3eSFrançois Tigeot
12914be47400SFrançois Tigeot if (!dev_priv->gt.active_requests)
129271f41f3eSFrançois Tigeot return;
129371f41f3eSFrançois Tigeot
12944be47400SFrançois Tigeot for_each_engine(engine, dev_priv, id)
12954be47400SFrançois Tigeot engine_retire_requests(engine);
129687df8fc6SFrançois Tigeot }
1297a85cb24fSFrançois Tigeot
1298a85cb24fSFrançois Tigeot #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1299a85cb24fSFrançois Tigeot #include "selftests/mock_request.c"
1300a85cb24fSFrançois Tigeot #include "selftests/i915_gem_request.c"
1301a85cb24fSFrançois Tigeot #endif
1302