* [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline @ 2017-04-12 12:48 Chris Wilson 2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson ` (10 more replies) 0 siblings, 11 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx; +Cc: Daniel Vetter 2 clflushes on two different objects are not ordered, and so do not belong to the same timeline (context). Either we use a unique context for each, or we reserve a special global context to mean unordered. Ideally, we would reserve 0 to mean unordered (DMA_FENCE_NO_CONTEXT) to have the same semantics everywhere. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_clflush.c | 8 +------- drivers/gpu/drm/i915/i915_gem_clflush.h | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1af4e6f5410c..9ff399fdf92b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1511,6 +1511,8 @@ struct i915_gem_mm { /** LRU list of objects with fence regs on them. */ struct list_head fence_list; + u64 unordered_timeline; + /* the indicator for dispatch video commands on two BSD rings */ atomic_t bsd_engine_dispatch_index; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 33fb11cc5acc..68c0a1c3bf77 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4746,7 +4746,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->drm.struct_mutex); - i915_gem_clflush_init(dev_priv); + dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1); if (!i915.enable_execlists) { dev_priv->gt.resume = intel_legacy_submission_resume; diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c index ffd01e02fe94..ffac7a1f0caf 100644 --- a/drivers/gpu/drm/i915/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/i915_gem_clflush.c @@ -27,7 +27,6 @@ #include "i915_gem_clflush.h" static DEFINE_SPINLOCK(clflush_lock); -static u64 clflush_context; struct clflush { struct dma_fence dma; /* Must be first for dma_fence_free() */ @@ -157,7 +156,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, dma_fence_init(&clflush->dma, &i915_clflush_ops, &clflush_lock, - clflush_context, + to_i915(obj->base.dev)->mm.unordered_timeline, 0); i915_sw_fence_init(&clflush->wait, i915_clflush_notify); @@ -182,8 +181,3 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU); } } - -void i915_gem_clflush_init(struct drm_i915_private *i915) -{ - clflush_context = dma_fence_context_alloc(1); -} diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.h b/drivers/gpu/drm/i915/i915_gem_clflush.h index b62d61a2d15f..2455a7820937 100644 --- a/drivers/gpu/drm/i915/i915_gem_clflush.h +++ b/drivers/gpu/drm/i915/i915_gem_clflush.h @@ -28,7 +28,6 @@ struct drm_i915_private; struct drm_i915_gem_object; -void i915_gem_clflush_init(struct drm_i915_private *i915); void i915_gem_clflush_object(struct drm_i915_gem_object *obj, unsigned int flags); #define I915_CLFLUSH_FORCE BIT(0) -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson ` (9 subsequent siblings) 10 siblings, 0 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx Currently we filter out repeated use of the same timeline in the low level i915_gem_request_await_request(), after having added the dependency on the old request. However, we can lift this to i915_gem_request_await_dma_fence() (before the dependency is added) using the observation that requests along the same timeline are explicitly ordered via i915_add_request (along with the dependencies). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem_request.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 313cdff7c6dd..31874a38752e 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -663,6 +663,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, int ret; GEM_BUG_ON(to == from); + GEM_BUG_ON(to->timeline == from->timeline); if (to->engine->schedule) { ret = i915_priotree_add_dependency(to->i915, @@ -672,9 +673,6 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, return ret; } - if (to->timeline == from->timeline) - return 0; - if (to->engine == from->engine) { ret = i915_sw_fence_await_sw_fence_gfp(&to->submit, &from->submit, @@ -723,6 +721,13 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return 0; + /* Requests on the same timeline are explicitly ordered, along with + * their dependencies, by i915_add_request() which ensures that requests + * are submitted in-order through each ring. + */ + if (fence->context == req->fence.context) + return 0; + if (dma_fence_is_i915(fence)) return i915_gem_request_await_request(req, to_request(fence)); -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson 2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson ` (8 subsequent siblings) 10 siblings, 0 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx ptr_unpack_bits() is a function-like macro, as such it is meant to be replaceable by a function. In this case, we should be passing in the out-param as a pointer. Bizarrely this does affect code generation: function old new delta i915_gem_object_pin_map 409 389 -20 An improvement(?) in this case, but one can't help wonder what strict-aliasing optimisations we are preventing. The generated code looks identical in using ptr_unpack_bits (no extra motions to stack, the pointer and bits appear to be kept in registers), the difference appears to be code ordering and with a reorder it is able to use smaller forward jumps. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 68c0a1c3bf77..d993a3cc8f97 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2612,7 +2612,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, } GEM_BUG_ON(!obj->mm.pages); - ptr = ptr_unpack_bits(obj->mm.mapping, has_type); + ptr = ptr_unpack_bits(obj->mm.mapping, &has_type); if (ptr && has_type != type) { if (pinned) { ret = -EBUSY; diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index c5455d36b617..aca11aad5da7 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -77,7 +77,7 @@ #define ptr_unpack_bits(ptr, bits) ({ \ unsigned long __v = (unsigned long)(ptr); \ - (bits) = __v & ~PAGE_MASK; \ + *(bits) = __v & ~PAGE_MASK; \ (typeof(ptr))(__v & PAGE_MASK); \ }) -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson 2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson 2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson ` (7 subsequent siblings) 10 siblings, 0 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx Rebrand the current (pointer | bits) pack/unpack utility macros as explicit bit twiddling for PAGE_SIZE so that we can use the more flexible underlying macros for different bits. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_cmd_parser.c | 2 +- drivers/gpu/drm/i915/i915_gem.c | 6 +++--- drivers/gpu/drm/i915/i915_utils.h | 19 +++++++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 2a1a3347495a..f0cb22cc0dd6 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1284,7 +1284,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, if (*cmd == MI_BATCH_BUFFER_END) { if (needs_clflush_after) { - void *ptr = ptr_mask_bits(shadow_batch_obj->mm.mapping); + void *ptr = page_mask_bits(shadow_batch_obj->mm.mapping); drm_clflush_virt_range(ptr, (void *)(cmd + 1) - ptr); } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d993a3cc8f97..e5f943ca5216 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2280,7 +2280,7 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, if (obj->mm.mapping) { void *ptr; - ptr = ptr_mask_bits(obj->mm.mapping); + ptr = page_mask_bits(obj->mm.mapping); if (is_vmalloc_addr(ptr)) vunmap(ptr); else @@ -2612,7 +2612,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, } GEM_BUG_ON(!obj->mm.pages); - ptr = ptr_unpack_bits(obj->mm.mapping, &has_type); + ptr = page_unpack_bits(obj->mm.mapping, &has_type); if (ptr && has_type != type) { if (pinned) { ret = -EBUSY; @@ -2634,7 +2634,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, goto err_unpin; } - obj->mm.mapping = ptr_pack_bits(ptr, type); + obj->mm.mapping = page_pack_bits(ptr, type); } out_unlock: diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index aca11aad5da7..f0500c65726d 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -70,20 +70,27 @@ #define overflows_type(x, T) \ (sizeof(x) > sizeof(T) && (x) >> (sizeof(T) * BITS_PER_BYTE)) -#define ptr_mask_bits(ptr) ({ \ +#define ptr_mask_bits(ptr, n) ({ \ unsigned long __v = (unsigned long)(ptr); \ - (typeof(ptr))(__v & PAGE_MASK); \ + (typeof(ptr))(__v & -BIT(n)); \ }) -#define ptr_unpack_bits(ptr, bits) ({ \ +#define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1)) + +#define ptr_unpack_bits(ptr, bits, n) ({ \ unsigned long __v = (unsigned long)(ptr); \ - *(bits) = __v & ~PAGE_MASK; \ - (typeof(ptr))(__v & PAGE_MASK); \ + *(bits) = __v & (BIT(n) - 1); \ + (typeof(ptr))(__v & -BIT(n)); \ }) -#define ptr_pack_bits(ptr, bits) \ +#define ptr_pack_bits(ptr, bits, n) \ ((typeof(ptr))((unsigned long)(ptr) | (bits))) +#define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) +#define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) +#define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT) +#define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT) + #define ptr_offset(ptr, member) offsetof(typeof(*(ptr)), member) #define fetch_and_zero(ptr) ({ \ -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (2 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 14:24 ` [PATCH v3] " Chris Wilson 2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson ` (6 subsequent siblings) 10 siblings, 1 reply; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx Track the latest fence waited upon on each context, and only add a new asynchronous wait if the new fence is more recent than the recorded fence for that context. This requires us to filter out unordered timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the absence of a universal identifier, we have to use our own i915->mm.unordered_timeline token. v2: Throw around the debug crutches v3: Inline the likely case of the pre-allocation cache being full. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem_request.c | 72 ++++--- drivers/gpu/drm/i915/i915_gem_timeline.c | 217 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_timeline.h | 34 ++++ drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 127 ++++++++++++ .../gpu/drm/i915/selftests/i915_mock_selftests.h | 1 + 5 files changed, 424 insertions(+), 27 deletions(-) create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 31874a38752e..6e68387aa097 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -714,9 +714,7 @@ int i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, struct dma_fence *fence) { - struct dma_fence_array *array; int ret; - int i; if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return 0; @@ -728,39 +726,59 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, if (fence->context == req->fence.context) return 0; - if (dma_fence_is_i915(fence)) - return i915_gem_request_await_request(req, to_request(fence)); + /* Squash repeated waits to the same timelines, picking the latest */ + if (fence->context != req->i915->mm.unordered_timeline) { + if (intel_timeline_sync_get(req->timeline, + fence->context, + fence->seqno)) + return 0; - if (!dma_fence_is_array(fence)) { + ret = intel_timeline_sync_reserve(req->timeline); + if (unlikely(ret)) + return ret; + } + + if (dma_fence_is_i915(fence)) { + ret = i915_gem_request_await_request(req, to_request(fence)); + if (ret < 0) + return ret; + } else if (!dma_fence_is_array(fence)) { ret = i915_sw_fence_await_dma_fence(&req->submit, fence, I915_FENCE_TIMEOUT, GFP_KERNEL); - return ret < 0 ? ret : 0; - } - - /* Note that if the fence-array was created in signal-on-any mode, - * we should *not* decompose it into its individual fences. However, - * we don't currently store which mode the fence-array is operating - * in. Fortunately, the only user of signal-on-any is private to - * amdgpu and we should not see any incoming fence-array from - * sync-file being in signal-on-any mode. - */ - - array = to_dma_fence_array(fence); - for (i = 0; i < array->num_fences; i++) { - struct dma_fence *child = array->fences[i]; - - if (dma_fence_is_i915(child)) - ret = i915_gem_request_await_request(req, - to_request(child)); - else - ret = i915_sw_fence_await_dma_fence(&req->submit, - child, I915_FENCE_TIMEOUT, - GFP_KERNEL); if (ret < 0) return ret; + } else { + struct dma_fence_array *array = to_dma_fence_array(fence); + int i; + + /* Note that if the fence-array was created in signal-on-any mode, + * we should *not* decompose it into its individual fences. However, + * we don't currently store which mode the fence-array is operating + * in. Fortunately, the only user of signal-on-any is private to + * amdgpu and we should not see any incoming fence-array from + * sync-file being in signal-on-any mode. + */ + + for (i = 0; i < array->num_fences; i++) { + struct dma_fence *child = array->fences[i]; + + if (dma_fence_is_i915(child)) + ret = i915_gem_request_await_request(req, + to_request(child)); + else + ret = i915_sw_fence_await_dma_fence(&req->submit, + child, I915_FENCE_TIMEOUT, + GFP_KERNEL); + if (ret < 0) + return ret; + } } + if (fence->context != req->i915->mm.unordered_timeline) + intel_timeline_sync_set(req->timeline, + fence->context, fence->seqno); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c index b596ca7ee058..c25edfde4833 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/i915_gem_timeline.c @@ -24,6 +24,217 @@ #include "i915_drv.h" +#define SHIFT ilog2(NSEQMAP) +#define MASK (NSEQMAP - 1) + +static void seqmap_free_layers(struct seqmap_layer *p) +{ + unsigned int i; + + if (p->height) { + for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i) + seqmap_free_layers(p->slot[i - 1]); + } + + kfree(p); +} + +static void seqmap_free(struct seqmap *seqmap) +{ + if (seqmap->top) + seqmap_free_layers(seqmap->top); + + while (seqmap->freed) { + struct seqmap_layer *p; + + p = ptr_mask_bits(seqmap->freed, SEQMAP_COUNT_BITS); + seqmap->freed = p->parent; + kfree(p); + } +} + +__malloc static struct seqmap_layer * +seqmap_alloc_layer(struct seqmap *shared) +{ + struct seqmap_layer *p; + + GEM_BUG_ON(!shared->freed); + + p = ptr_mask_bits(shared->freed, SEQMAP_COUNT_BITS); + shared->freed = p->parent; + + return p; +} + +static int layer_idx(const struct seqmap_layer *p, u64 id) +{ + return (id >> p->height) & MASK; +} + +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct seqmap *shared = &tl->sync; + struct seqmap_layer *p; + unsigned int idx; + + p = shared->hint; + if (!p) + return false; + + if ((id >> SHIFT) == p->prefix) + goto found; + + p = shared->top; + do { + if ((id >> p->height >> SHIFT) != p->prefix) + return false; + + if (!p->height) + break; + + p = p->slot[layer_idx(p, id)]; + if (!p) + return false; + } while (1); + + shared->hint = p; +found: + idx = id & MASK; + if (!(p->bitmap & BIT(idx))) + return false; + + return i915_seqno_passed((uintptr_t)p->slot[idx], seqno); +} + +void intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct seqmap *shared = &tl->sync; + struct seqmap_layer *p, *cur; + unsigned int idx; + + /* We expect to be called in sequence following a _get(id), which + * should have preloaded the ->hint for us. + */ + p = shared->hint; + if (likely(p && (id >> SHIFT) == p->prefix)) + goto found_layer; + + if (!p) { + GEM_BUG_ON(shared->top); + cur = seqmap_alloc_layer(shared); + cur->parent = NULL; + shared->top = cur; + goto new_layer; + } + + /* No shortcut, we have to descend the tree to find the right layer + * containing this fence. + * + * Each layer in the tree holds 16 (NSEQMAP) pointers, either fences + * or lower layers. Leaf nodes (height = 0) contain the fences, all + * other nodes (height > 0) are internal layers that point to a lower + * node. Each internal layer has at least 2 descendents. + * + * Starting at the top, we check whether the current prefix matches. If + * it doesn't, we have gone passed our layer and need to insert a join + * into the tree, and a new leaf node as a descendent as well as the + * original layer. + * + * The matching prefix means we are still following the right branch + * of the tree. If it has height 0, we have found our leaf and just + * need to replace the fence slot with ourselves. If the height is + * not zero, our slot contains the next layer in the tree (unless + * it is empty, in which case we can add ourselves as a new leaf). + * As descend the tree the prefix grows (and height decreases). + */ + p = shared->top; + do { + if ((id >> p->height >> SHIFT) != p->prefix) { + /* insert a join above the current layer */ + cur = seqmap_alloc_layer(shared); + cur->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix), + SHIFT) + p->height; + cur->prefix = id >> cur->height >> SHIFT; + + if (p->parent) + p->parent->slot[layer_idx(p->parent, id)] = cur; + else + shared->top = cur; + cur->parent = p->parent; + + idx = p->prefix >> (cur->height - p->height - SHIFT) & MASK; + cur->slot[idx] = p; + cur->bitmap |= BIT(idx); + p->parent = cur; + } else if (!p->height) { + /* matching base layer */ + shared->hint = p; + goto found_layer; + } else { + /* descend into the next layer */ + idx = layer_idx(p, id); + cur = p->slot[idx]; + if (unlikely(!cur)) { + cur = seqmap_alloc_layer(shared); + p->slot[idx] = cur; + p->bitmap |= BIT(idx); + cur->parent = p; + goto new_layer; + } + } + + p = cur; + } while (1); + +found_layer: + GEM_BUG_ON(p->height); + GEM_BUG_ON(p->prefix != id >> SHIFT); + idx = id & MASK; + p->slot[idx] = (void *)(uintptr_t)seqno; + p->bitmap |= BIT(idx); + GEM_BUG_ON(shared->hint != p); + return; + +new_layer: + GEM_BUG_ON(cur->height); + cur->prefix = id >> SHIFT; + idx = id & MASK; + cur->slot[idx] = (void *)(uintptr_t)seqno; + cur->bitmap = BIT(idx); + shared->hint = cur; + return; +} + +int __intel_timeline_sync_reserve(struct intel_timeline *tl) +{ + struct seqmap *shared = &tl->sync; + int count; + + might_sleep(); + + /* To guarantee being able to replace a fence in the radixtree, + * we need at most 2 layers: one to create a join in the tree, + * and one to contain the fence. Typically we expect to reuse + * a layer and so avoid any insertions. + * + * We use the low bits of the freed list to track its length + * since we only need a couple of bits. + */ + count = ptr_unmask_bits(shared->freed, SEQMAP_COUNT_BITS); + while (count++ < 2) { + struct seqmap_layer *p; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + + p->parent = shared->freed; + shared->freed = ptr_pack_bits(p, count, SEQMAP_COUNT_BITS); + } + + return 0; +} + static int __i915_gem_timeline_init(struct drm_i915_private *i915, struct i915_gem_timeline *timeline, const char *name, @@ -91,8 +302,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline) struct intel_timeline *tl = &timeline->engine[i]; GEM_BUG_ON(!list_empty(&tl->requests)); + + seqmap_free(&tl->sync); } list_del(&timeline->link); kfree(timeline->name); } + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/i915_gem_timeline.c" +#endif diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h index 6c53e14cab2a..4cb597401803 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.h +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h @@ -26,11 +26,30 @@ #define I915_GEM_TIMELINE_H #include <linux/list.h> +#include <linux/radix-tree.h> +#include "i915_utils.h" #include "i915_gem_request.h" struct i915_gem_timeline; +#define NSEQMAP 16 + +struct seqmap_layer { + u64 prefix; + unsigned int height; + unsigned int bitmap; + struct seqmap_layer *parent; + void *slot[NSEQMAP]; +}; + +struct seqmap { + struct seqmap_layer *hint; + struct seqmap_layer *top; + struct seqmap_layer *freed; +#define SEQMAP_COUNT_BITS 2 +}; + struct intel_timeline { u64 fence_context; u32 seqno; @@ -55,6 +74,8 @@ struct intel_timeline { * struct_mutex. */ struct i915_gem_active last_request; + + struct seqmap sync; u32 sync_seqno[I915_NUM_ENGINES]; struct i915_gem_timeline *common; @@ -75,4 +96,17 @@ int i915_gem_timeline_init(struct drm_i915_private *i915, int i915_gem_timeline_init__global(struct drm_i915_private *i915); void i915_gem_timeline_fini(struct i915_gem_timeline *tl); +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno); + +int __intel_timeline_sync_reserve(struct intel_timeline *tl); +static inline int intel_timeline_sync_reserve(struct intel_timeline *tl) +{ + if (likely(ptr_unmask_bits(tl->sync.freed, SEQMAP_COUNT_BITS) == 2)) + return 0; + + return __intel_timeline_sync_reserve(tl); +} + +void intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno); + #endif diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c new file mode 100644 index 000000000000..15e2b2e63081 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c @@ -0,0 +1,127 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "../i915_selftest.h" +#include "mock_gem_device.h" + +static int igt_seqmap(void *arg) +{ + struct drm_i915_private *i915 = arg; + const struct { + const char *name; + u32 seqno; + bool expected; + bool set; + } pass[] = { + { "unset", 0, false, false }, + { "new", 0, false, true }, + { "0a", 0, true, true }, + { "1a", 1, false, true }, + { "1b", 1, true, true }, + { "0b", 0, true, false }, + { "2a", 2, false, true }, + { "4", 4, false, true }, + { "INT_MAX", INT_MAX, false, true }, + { "INT_MAX-1", INT_MAX-1, true, false }, + { "INT_MAX+1", (u32)INT_MAX+1, false, true }, + { "INT_MAX", INT_MAX, true, false }, + { "UINT_MAX", UINT_MAX, false, true }, + { "wrap", 0, false, true }, + { "unwrap", UINT_MAX, true, false }, + {}, + }, *p; + struct intel_timeline *tl; + int order, offset; + int ret; + + tl = &i915->gt.global_timeline.engine[RCS]; + for (p = pass; p->name; p++) { + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_reserve(tl); + if (ret) + return ret; + + intel_timeline_sync_set(tl, ctx, p->seqno); + } + } + } + } + + tl = &i915->gt.global_timeline.engine[BCS]; + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + for (p = pass; p->name; p++) { + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_reserve(tl); + if (ret) + return ret; + + intel_timeline_sync_set(tl, ctx, p->seqno); + } + } + } + } + + return 0; +} + +int i915_gem_timeline_mock_selftests(void) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_seqmap), + }; + struct drm_i915_private *i915; + int err; + + i915 = mock_gem_device(); + if (!i915) + return -ENOMEM; + + err = i915_subtests(tests, i915); + drm_dev_unref(&i915->drm); + + return err; +} diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h index be9a9ebf5692..8d0f50c25df8 100644 --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h @@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */ selftest(scatterlist, scatterlist_mock_selftests) selftest(uncore, intel_uncore_mock_selftests) selftest(breadcrumbs, intel_breadcrumbs_mock_selftests) +selftest(timelines, i915_gem_timeline_mock_selftests) selftest(requests, i915_gem_request_mock_selftests) selftest(objects, i915_gem_object_mock_selftests) selftest(dmabuf, i915_gem_dmabuf_mock_selftests) -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3] drm/i915: Squash repeated awaits on the same fence 2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson @ 2017-04-12 14:24 ` Chris Wilson 2017-04-12 15:39 ` [PATCH v4] " Chris Wilson 0 siblings, 1 reply; 19+ messages in thread From: Chris Wilson @ 2017-04-12 14:24 UTC (permalink / raw) To: intel-gfx Track the latest fence waited upon on each context, and only add a new asynchronous wait if the new fence is more recent than the recorded fence for that context. This requires us to filter out unordered timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the absence of a universal identifier, we have to use our own i915->mm.unordered_timeline token. v2: Throw around the debug crutches v3: Inline the likely case of the pre-allocation cache being full. v4: Drop the pre-allocation support, we can lose the most recent fence in case of allocation failure -- it just means we may emit more awaits than strictly necessary but will not break. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem_request.c | 66 ++++--- drivers/gpu/drm/i915/i915_gem_timeline.c | 194 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_timeline.h | 18 ++ drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 123 +++++++++++++ .../gpu/drm/i915/selftests/i915_mock_selftests.h | 1 + 5 files changed, 375 insertions(+), 27 deletions(-) create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 31874a38752e..f679c16aa5c6 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -714,9 +714,7 @@ int i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, struct dma_fence *fence) { - struct dma_fence_array *array; int ret; - int i; if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return 0; @@ -728,39 +726,53 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, if (fence->context == req->fence.context) return 0; - if (dma_fence_is_i915(fence)) - return i915_gem_request_await_request(req, to_request(fence)); + /* Squash repeated waits to the same timelines, picking the latest */ + if (fence->context != req->i915->mm.unordered_timeline && + intel_timeline_sync_get(req->timeline, + fence->context, fence->seqno)) + return 0; - if (!dma_fence_is_array(fence)) { + if (dma_fence_is_i915(fence)) { + ret = i915_gem_request_await_request(req, to_request(fence)); + if (ret < 0) + return ret; + } else if (!dma_fence_is_array(fence)) { ret = i915_sw_fence_await_dma_fence(&req->submit, fence, I915_FENCE_TIMEOUT, GFP_KERNEL); - return ret < 0 ? ret : 0; - } - - /* Note that if the fence-array was created in signal-on-any mode, - * we should *not* decompose it into its individual fences. However, - * we don't currently store which mode the fence-array is operating - * in. Fortunately, the only user of signal-on-any is private to - * amdgpu and we should not see any incoming fence-array from - * sync-file being in signal-on-any mode. - */ - - array = to_dma_fence_array(fence); - for (i = 0; i < array->num_fences; i++) { - struct dma_fence *child = array->fences[i]; - - if (dma_fence_is_i915(child)) - ret = i915_gem_request_await_request(req, - to_request(child)); - else - ret = i915_sw_fence_await_dma_fence(&req->submit, - child, I915_FENCE_TIMEOUT, - GFP_KERNEL); if (ret < 0) return ret; + } else { + struct dma_fence_array *array = to_dma_fence_array(fence); + int i; + + /* Note that if the fence-array was created in signal-on-any mode, + * we should *not* decompose it into its individual fences. However, + * we don't currently store which mode the fence-array is operating + * in. Fortunately, the only user of signal-on-any is private to + * amdgpu and we should not see any incoming fence-array from + * sync-file being in signal-on-any mode. + */ + + for (i = 0; i < array->num_fences; i++) { + struct dma_fence *child = array->fences[i]; + + if (dma_fence_is_i915(child)) + ret = i915_gem_request_await_request(req, + to_request(child)); + else + ret = i915_sw_fence_await_dma_fence(&req->submit, + child, I915_FENCE_TIMEOUT, + GFP_KERNEL); + if (ret < 0) + return ret; + } } + if (fence->context != req->i915->mm.unordered_timeline) + intel_timeline_sync_set(req->timeline, + fence->context, fence->seqno); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c index b596ca7ee058..446eefa70e6d 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/i915_gem_timeline.c @@ -24,6 +24,194 @@ #include "i915_drv.h" +#define SHIFT ilog2(NSEQMAP) +#define MASK (NSEQMAP - 1) + +static void __seqmap_free(struct seqmap *p) +{ + unsigned int i; + + if (p->height) { + for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i) + __seqmap_free(p->slot[i - 1]); + } + + kfree(p); +} + +static void seqmap_free(struct seqmap *seqmap) +{ + if (!seqmap) + return; + + while (seqmap->parent) + seqmap = seqmap->parent; + + __seqmap_free(seqmap); +} + +static int layer_idx(const struct seqmap *p, u64 id) +{ + return (id >> p->height) & MASK; +} + +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct seqmap *p; + unsigned int idx; + + p = tl->sync; + if (!p) + return false; + + if ((id >> SHIFT) == p->prefix) + goto found; + + /* First climb the tree back to a parent branch */ + do { + p = p->parent; + if (!p) + return false; + + if ((id >> p->height >> SHIFT) == p->prefix) + break; + } while (1); + + /* And then descend again until we find our leaf */ + do { + if (!p->height) + break; + + p = p->slot[layer_idx(p, id)]; + if (!p) + return false; + + if ((id >> p->height >> SHIFT) != p->prefix) + return false; + } while (1); + + tl->sync = p; +found: + idx = id & MASK; + if (!(p->bitmap & BIT(idx))) + return false; + + return i915_seqno_passed((uintptr_t)p->slot[idx], seqno); +} + +int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct seqmap *p; + unsigned int idx; + + /* We expect to be called in sequence following a _get(id), which + * should have preloaded the tl->sync hint for us. + */ + p = tl->sync; + if (likely(p && (id >> SHIFT) == p->prefix)) + goto set; + + if (!p) { + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + + p->prefix = id >> SHIFT; + goto found; + } + + /* Climb back up the tree until we find a common prefix */ + do { + if (!p->parent) + break; + + p = p->parent; + + if ((id >> p->height >> SHIFT) == p->prefix) + break; + } while (1); + + /* No shortcut, we have to descend the tree to find the right layer + * containing this fence. + * + * Each layer in the tree holds 16 (NSEQMAP) pointers, either fences + * or lower layers. Leaf nodes (height = 0) contain the fences, all + * other nodes (height > 0) are internal layers that point to a lower + * node. Each internal layer has at least 2 descendents. + * + * Starting at the top, we check whether the current prefix matches. If + * it doesn't, we have gone passed our layer and need to insert a join + * into the tree, and a new leaf node as a descendent as well as the + * original layer. + * + * The matching prefix means we are still following the right branch + * of the tree. If it has height 0, we have found our leaf and just + * need to replace the fence slot with ourselves. If the height is + * not zero, our slot contains the next layer in the tree (unless + * it is empty, in which case we can add ourselves as a new leaf). + * As descend the tree the prefix grows (and height decreases). + */ + do { + struct seqmap *next; + + if ((id >> p->height >> SHIFT) != p->prefix) { + /* insert a join above the current layer */ + next = kzalloc(sizeof(*next), GFP_KERNEL); + if (unlikely(!next)) + return -ENOMEM; + + next->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix), + SHIFT) + p->height; + next->prefix = id >> next->height >> SHIFT; + + if (p->parent) + p->parent->slot[layer_idx(p->parent, id)] = next; + next->parent = p->parent; + + idx = p->prefix >> (next->height - p->height - SHIFT) & MASK; + next->slot[idx] = p; + next->bitmap |= BIT(idx); + p->parent = next; + + /* ascend to the join */ + p = next; + } else { + if (!p->height) + break; + } + + /* descend into the next layer */ + GEM_BUG_ON(!p->height); + idx = layer_idx(p, id); + next = p->slot[idx]; + if (unlikely(!next)) { + next = kzalloc(sizeof(*next), GFP_KERNEL); + if (unlikely(!next)) + return -ENOMEM; + + p->slot[idx] = next; + p->bitmap |= BIT(idx); + next->parent = p; + next->prefix = id >> SHIFT; + + p = next; + break; + } + + p = next; + } while (1); + +found: + GEM_BUG_ON(p->height); + GEM_BUG_ON(p->prefix != id >> SHIFT); + tl->sync = p; +set: + idx = id & MASK; + p->slot[idx] = (void *)(uintptr_t)seqno; + p->bitmap |= BIT(idx); + return 0; +} + static int __i915_gem_timeline_init(struct drm_i915_private *i915, struct i915_gem_timeline *timeline, const char *name, @@ -91,8 +279,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline) struct intel_timeline *tl = &timeline->engine[i]; GEM_BUG_ON(!list_empty(&tl->requests)); + + seqmap_free(tl->sync); } list_del(&timeline->link); kfree(timeline->name); } + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/i915_gem_timeline.c" +#endif diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h index 6c53e14cab2a..64bad92320de 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.h +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h @@ -26,11 +26,23 @@ #define I915_GEM_TIMELINE_H #include <linux/list.h> +#include <linux/radix-tree.h> +#include "i915_utils.h" #include "i915_gem_request.h" struct i915_gem_timeline; +#define NSEQMAP 16 + +struct seqmap { + u64 prefix; + unsigned int height; + unsigned int bitmap; + struct seqmap *parent; + void *slot[NSEQMAP]; +}; + struct intel_timeline { u64 fence_context; u32 seqno; @@ -55,6 +67,8 @@ struct intel_timeline { * struct_mutex. */ struct i915_gem_active last_request; + + struct seqmap *sync; u32 sync_seqno[I915_NUM_ENGINES]; struct i915_gem_timeline *common; @@ -75,4 +89,8 @@ int i915_gem_timeline_init(struct drm_i915_private *i915, int i915_gem_timeline_init__global(struct drm_i915_private *i915); void i915_gem_timeline_fini(struct i915_gem_timeline *tl); +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno); + +int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno); + #endif diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c new file mode 100644 index 000000000000..c0bb8ecac93b --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c @@ -0,0 +1,123 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "../i915_selftest.h" +#include "mock_gem_device.h" + +static int igt_seqmap(void *arg) +{ + struct drm_i915_private *i915 = arg; + const struct { + const char *name; + u32 seqno; + bool expected; + bool set; + } pass[] = { + { "unset", 0, false, false }, + { "new", 0, false, true }, + { "0a", 0, true, true }, + { "1a", 1, false, true }, + { "1b", 1, true, true }, + { "0b", 0, true, false }, + { "2a", 2, false, true }, + { "4", 4, false, true }, + { "INT_MAX", INT_MAX, false, true }, + { "INT_MAX-1", INT_MAX-1, true, false }, + { "INT_MAX+1", (u32)INT_MAX+1, false, true }, + { "INT_MAX", INT_MAX, true, false }, + { "UINT_MAX", UINT_MAX, false, true }, + { "wrap", 0, false, true }, + { "unwrap", UINT_MAX, true, false }, + {}, + }, *p; + struct intel_timeline *tl; + int order, offset; + int ret; + + tl = &i915->gt.global_timeline.engine[RCS]; + for (p = pass; p->name; p++) { + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_set(tl, ctx, p->seqno); + if (ret) + return ret; + } + } + } + } + + tl = &i915->gt.global_timeline.engine[BCS]; + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + for (p = pass; p->name; p++) { + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_set(tl, ctx, p->seqno); + if (ret) + return ret; + } + } + } + } + + return 0; +} + +int i915_gem_timeline_mock_selftests(void) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_seqmap), + }; + struct drm_i915_private *i915; + int err; + + i915 = mock_gem_device(); + if (!i915) + return -ENOMEM; + + err = i915_subtests(tests, i915); + drm_dev_unref(&i915->drm); + + return err; +} diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h index be9a9ebf5692..8d0f50c25df8 100644 --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h @@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */ selftest(scatterlist, scatterlist_mock_selftests) selftest(uncore, intel_uncore_mock_selftests) selftest(breadcrumbs, intel_breadcrumbs_mock_selftests) +selftest(timelines, i915_gem_timeline_mock_selftests) selftest(requests, i915_gem_request_mock_selftests) selftest(objects, i915_gem_object_mock_selftests) selftest(dmabuf, i915_gem_dmabuf_mock_selftests) -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v4] drm/i915: Squash repeated awaits on the same fence 2017-04-12 14:24 ` [PATCH v3] " Chris Wilson @ 2017-04-12 15:39 ` Chris Wilson 0 siblings, 0 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 15:39 UTC (permalink / raw) To: intel-gfx Track the latest fence waited upon on each context, and only add a new asynchronous wait if the new fence is more recent than the recorded fence for that context. This requires us to filter out unordered timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the absence of a universal identifier, we have to use our own i915->mm.unordered_timeline token. v2: Throw around the debug crutches v3: Inline the likely case of the pre-allocation cache being full. v4: Drop the pre-allocation support, we can lose the most recent fence in case of allocation failure -- it just means we may emit more awaits than strictly necessary but will not break. v5: Trim allocation size for leaf nodes, they only need an array of u32 not pointers. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem_request.c | 66 ++++--- drivers/gpu/drm/i915/i915_gem_timeline.c | 215 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_timeline.h | 8 + drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 123 ++++++++++++ .../gpu/drm/i915/selftests/i915_mock_selftests.h | 1 + 5 files changed, 386 insertions(+), 27 deletions(-) create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 31874a38752e..f679c16aa5c6 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -714,9 +714,7 @@ int i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, struct dma_fence *fence) { - struct dma_fence_array *array; int ret; - int i; if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return 0; @@ -728,39 +726,53 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, if (fence->context == req->fence.context) return 0; - if (dma_fence_is_i915(fence)) - return i915_gem_request_await_request(req, to_request(fence)); + /* Squash repeated waits to the same timelines, picking the latest */ + if (fence->context != req->i915->mm.unordered_timeline && + intel_timeline_sync_get(req->timeline, + fence->context, fence->seqno)) + return 0; - if (!dma_fence_is_array(fence)) { + if (dma_fence_is_i915(fence)) { + ret = i915_gem_request_await_request(req, to_request(fence)); + if (ret < 0) + return ret; + } else if (!dma_fence_is_array(fence)) { ret = i915_sw_fence_await_dma_fence(&req->submit, fence, I915_FENCE_TIMEOUT, GFP_KERNEL); - return ret < 0 ? ret : 0; - } - - /* Note that if the fence-array was created in signal-on-any mode, - * we should *not* decompose it into its individual fences. However, - * we don't currently store which mode the fence-array is operating - * in. Fortunately, the only user of signal-on-any is private to - * amdgpu and we should not see any incoming fence-array from - * sync-file being in signal-on-any mode. - */ - - array = to_dma_fence_array(fence); - for (i = 0; i < array->num_fences; i++) { - struct dma_fence *child = array->fences[i]; - - if (dma_fence_is_i915(child)) - ret = i915_gem_request_await_request(req, - to_request(child)); - else - ret = i915_sw_fence_await_dma_fence(&req->submit, - child, I915_FENCE_TIMEOUT, - GFP_KERNEL); if (ret < 0) return ret; + } else { + struct dma_fence_array *array = to_dma_fence_array(fence); + int i; + + /* Note that if the fence-array was created in signal-on-any mode, + * we should *not* decompose it into its individual fences. However, + * we don't currently store which mode the fence-array is operating + * in. Fortunately, the only user of signal-on-any is private to + * amdgpu and we should not see any incoming fence-array from + * sync-file being in signal-on-any mode. + */ + + for (i = 0; i < array->num_fences; i++) { + struct dma_fence *child = array->fences[i]; + + if (dma_fence_is_i915(child)) + ret = i915_gem_request_await_request(req, + to_request(child)); + else + ret = i915_sw_fence_await_dma_fence(&req->submit, + child, I915_FENCE_TIMEOUT, + GFP_KERNEL); + if (ret < 0) + return ret; + } } + if (fence->context != req->i915->mm.unordered_timeline) + intel_timeline_sync_set(req->timeline, + fence->context, fence->seqno); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c index b596ca7ee058..15ff9f37b6dc 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/i915_gem_timeline.c @@ -24,6 +24,215 @@ #include "i915_drv.h" +#define NSYNC 16 +#define SHIFT ilog2(NSYNC) +#define MASK (NSYNC - 1) + +struct intel_timeline_sync { + u64 prefix; + unsigned int height; + unsigned int bitmap; + struct intel_timeline_sync *parent; +}; + +static inline u32 *__sync_seqno(struct intel_timeline_sync *p) +{ + return (u32 *)(p + 1); +} + +static inline struct intel_timeline_sync ** +__sync_child(struct intel_timeline_sync *p) +{ + return (struct intel_timeline_sync **)(p + 1); +} + +static void __sync_free(struct intel_timeline_sync *p) +{ + unsigned int i; + + if (p->height) { + for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i) + __sync_free(__sync_child(p)[i - 1]); + } + + kfree(p); +} + +static void sync_free(struct intel_timeline_sync *sync) +{ + if (!sync) + return; + + while (sync->parent) + sync = sync->parent; + + __sync_free(sync); +} + +static int layer_idx(const struct intel_timeline_sync *p, u64 id) +{ + return (id >> p->height) & MASK; +} + +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct intel_timeline_sync *p; + unsigned int idx; + + p = tl->sync; + if (!p) + return false; + + if ((id >> SHIFT) == p->prefix) + goto found; + + /* First climb the tree back to a parent branch */ + do { + p = p->parent; + if (!p) + return false; + + if ((id >> p->height >> SHIFT) == p->prefix) + break; + } while (1); + + /* And then descend again until we find our leaf */ + do { + if (!p->height) + break; + + p = __sync_child(p)[layer_idx(p, id)]; + if (!p) + return false; + + if ((id >> p->height >> SHIFT) != p->prefix) + return false; + } while (1); + + tl->sync = p; +found: + idx = id & MASK; + if (!(p->bitmap & BIT(idx))) + return false; + + return i915_seqno_passed(__sync_seqno(p)[idx], seqno); +} + +int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno) +{ + struct intel_timeline_sync *p; + unsigned int idx; + + /* We expect to be called in sequence following a _get(id), which + * should have preloaded the tl->sync hint for us. + */ + p = tl->sync; + if (likely(p && (id >> SHIFT) == p->prefix)) + goto set; + + if (!p) { + p = kzalloc(sizeof(*p) + NSYNC * sizeof(seqno), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + + p->prefix = id >> SHIFT; + goto found; + } + + /* Climb back up the tree until we find a common prefix */ + do { + if (!p->parent) + break; + + p = p->parent; + + if ((id >> p->height >> SHIFT) == p->prefix) + break; + } while (1); + + /* No shortcut, we have to descend the tree to find the right layer + * containing this fence. + * + * Each layer in the tree holds 16 (NSYNC) pointers, either fences + * or lower layers. Leaf nodes (height = 0) contain the fences, all + * other nodes (height > 0) are internal layers that point to a lower + * node. Each internal layer has at least 2 descendents. + * + * Starting at the top, we check whether the current prefix matches. If + * it doesn't, we have gone passed our layer and need to insert a join + * into the tree, and a new leaf node as a descendent as well as the + * original layer. + * + * The matching prefix means we are still following the right branch + * of the tree. If it has height 0, we have found our leaf and just + * need to replace the fence slot with ourselves. If the height is + * not zero, our slot contains the next layer in the tree (unless + * it is empty, in which case we can add ourselves as a new leaf). + * As descend the tree the prefix grows (and height decreases). + */ + do { + struct intel_timeline_sync *next; + + if ((id >> p->height >> SHIFT) != p->prefix) { + /* insert a join above the current layer */ + next = kzalloc(sizeof(*next) + NSYNC * sizeof(next), + GFP_KERNEL); + if (unlikely(!next)) + return -ENOMEM; + + next->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix), + SHIFT) + p->height; + next->prefix = id >> next->height >> SHIFT; + + if (p->parent) + __sync_child(p->parent)[layer_idx(p->parent, id)] = next; + next->parent = p->parent; + + idx = p->prefix >> (next->height - p->height - SHIFT) & MASK; + __sync_child(next)[idx] = p; + next->bitmap |= BIT(idx); + p->parent = next; + + /* ascend to the join */ + p = next; + } else { + if (!p->height) + break; + } + + /* descend into the next layer */ + GEM_BUG_ON(!p->height); + idx = layer_idx(p, id); + next = __sync_child(p)[idx]; + if (unlikely(!next)) { + next = kzalloc(sizeof(*next) + NSYNC * sizeof(seqno), + GFP_KERNEL); + if (unlikely(!next)) + return -ENOMEM; + + __sync_child(p)[idx] = next; + p->bitmap |= BIT(idx); + next->parent = p; + next->prefix = id >> SHIFT; + + p = next; + break; + } + + p = next; + } while (1); + +found: + GEM_BUG_ON(p->height); + GEM_BUG_ON(p->prefix != id >> SHIFT); + tl->sync = p; +set: + idx = id & MASK; + __sync_seqno(p)[idx] = seqno; + p->bitmap |= BIT(idx); + return 0; +} + static int __i915_gem_timeline_init(struct drm_i915_private *i915, struct i915_gem_timeline *timeline, const char *name, @@ -91,8 +300,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline) struct intel_timeline *tl = &timeline->engine[i]; GEM_BUG_ON(!list_empty(&tl->requests)); + + sync_free(tl->sync); } list_del(&timeline->link); kfree(timeline->name); } + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/i915_gem_timeline.c" +#endif diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h index 6c53e14cab2a..22a80daa6efa 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.h +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h @@ -26,10 +26,13 @@ #define I915_GEM_TIMELINE_H #include <linux/list.h> +#include <linux/radix-tree.h> +#include "i915_utils.h" #include "i915_gem_request.h" struct i915_gem_timeline; +struct intel_timeline_sync; struct intel_timeline { u64 fence_context; @@ -55,6 +58,8 @@ struct intel_timeline { * struct_mutex. */ struct i915_gem_active last_request; + + struct intel_timeline_sync *sync; u32 sync_seqno[I915_NUM_ENGINES]; struct i915_gem_timeline *common; @@ -75,4 +80,7 @@ int i915_gem_timeline_init(struct drm_i915_private *i915, int i915_gem_timeline_init__global(struct drm_i915_private *i915); void i915_gem_timeline_fini(struct i915_gem_timeline *tl); +bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno); +int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno); + #endif diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c new file mode 100644 index 000000000000..c0bb8ecac93b --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c @@ -0,0 +1,123 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "../i915_selftest.h" +#include "mock_gem_device.h" + +static int igt_seqmap(void *arg) +{ + struct drm_i915_private *i915 = arg; + const struct { + const char *name; + u32 seqno; + bool expected; + bool set; + } pass[] = { + { "unset", 0, false, false }, + { "new", 0, false, true }, + { "0a", 0, true, true }, + { "1a", 1, false, true }, + { "1b", 1, true, true }, + { "0b", 0, true, false }, + { "2a", 2, false, true }, + { "4", 4, false, true }, + { "INT_MAX", INT_MAX, false, true }, + { "INT_MAX-1", INT_MAX-1, true, false }, + { "INT_MAX+1", (u32)INT_MAX+1, false, true }, + { "INT_MAX", INT_MAX, true, false }, + { "UINT_MAX", UINT_MAX, false, true }, + { "wrap", 0, false, true }, + { "unwrap", UINT_MAX, true, false }, + {}, + }, *p; + struct intel_timeline *tl; + int order, offset; + int ret; + + tl = &i915->gt.global_timeline.engine[RCS]; + for (p = pass; p->name; p++) { + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_set(tl, ctx, p->seqno); + if (ret) + return ret; + } + } + } + } + + tl = &i915->gt.global_timeline.engine[BCS]; + for (order = 1; order < 64; order++) { + for (offset = -1; offset <= (order > 1); offset++) { + u64 ctx = BIT_ULL(order) + offset; + + for (p = pass; p->name; p++) { + if (intel_timeline_sync_get(tl, + ctx, + p->seqno) != p->expected) { + pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n", + p->name, ctx, p->seqno, yesno(p->expected)); + return -EINVAL; + } + + if (p->set) { + ret = intel_timeline_sync_set(tl, ctx, p->seqno); + if (ret) + return ret; + } + } + } + } + + return 0; +} + +int i915_gem_timeline_mock_selftests(void) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_seqmap), + }; + struct drm_i915_private *i915; + int err; + + i915 = mock_gem_device(); + if (!i915) + return -ENOMEM; + + err = i915_subtests(tests, i915); + drm_dev_unref(&i915->drm); + + return err; +} diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h index be9a9ebf5692..8d0f50c25df8 100644 --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h @@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */ selftest(scatterlist, scatterlist_mock_selftests) selftest(uncore, intel_uncore_mock_selftests) selftest(breadcrumbs, intel_breadcrumbs_mock_selftests) +selftest(timelines, i915_gem_timeline_mock_selftests) selftest(requests, i915_gem_request_mock_selftests) selftest(objects, i915_gem_object_mock_selftests) selftest(dmabuf, i915_gem_dmabuf_mock_selftests) -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (3 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-13 10:49 ` Joonas Lahtinen 2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson ` (5 subsequent siblings) 10 siblings, 1 reply; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx With the addition of the inter-context intel_time.sync map, having a very similar sync_seqno[] is confusing. Aide the reader by denoting that this a pre-allocated array for storing semaphore sync points wrt to the global seqno. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_gem_request.c | 8 ++++---- drivers/gpu/drm/i915/i915_gem_timeline.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 6e68387aa097..87ca3453140a 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -218,8 +218,8 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno) tl->seqno = seqno; list_for_each_entry(timeline, &i915->gt.timelines, link) - memset(timeline->engine[id].sync_seqno, 0, - sizeof(timeline->engine[id].sync_seqno)); + memset(timeline->engine[id].global_sync, 0, + sizeof(timeline->engine[id].global_sync)); } return 0; @@ -688,7 +688,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, return ret < 0 ? ret : 0; } - if (seqno <= to->timeline->sync_seqno[from->engine->id]) + if (seqno <= to->timeline->global_sync[from->engine->id]) return 0; trace_i915_gem_ring_sync_to(to, from); @@ -706,7 +706,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, return ret; } - to->timeline->sync_seqno[from->engine->id] = seqno; + to->timeline->global_sync[from->engine->id] = seqno; return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h index 4cb597401803..48437612bb4b 100644 --- a/drivers/gpu/drm/i915/i915_gem_timeline.h +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h @@ -76,7 +76,7 @@ struct intel_timeline { struct i915_gem_active last_request; struct seqmap sync; - u32 sync_seqno[I915_NUM_ENGINES]; + u32 global_sync[I915_NUM_ENGINES]; struct i915_gem_timeline *common; }; -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] 2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson @ 2017-04-13 10:49 ` Joonas Lahtinen 0 siblings, 0 replies; 19+ messages in thread From: Joonas Lahtinen @ 2017-04-13 10:49 UTC (permalink / raw) To: Chris Wilson, intel-gfx On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote: > With the addition of the inter-context intel_time.sync map, having a intel_timeline.sync? > very similar sync_seqno[] is confusing. Aide the reader by denoting that > this a pre-allocated array for storing semaphore sync points wrt to the > global seqno. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Regards, Joonas -- Joonas Lahtinen Open Source Technology Center Intel Corporation _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (4 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 16:31 ` Michał Winiarski 2017-04-13 10:46 ` Joonas Lahtinen 2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson ` (4 subsequent siblings) 10 siblings, 2 replies; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx Although we do check the completion-status of the request before actually adding a wait on it (either to its submit fence or its completion dma-fence), we currently do not check before adding it to the dependency lists. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_gem_request.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 87ca3453140a..436693b12bae 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -665,6 +665,9 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, GEM_BUG_ON(to == from); GEM_BUG_ON(to->timeline == from->timeline); + if (i915_gem_request_completed(from)) + return 0; + if (to->engine->schedule) { ret = i915_priotree_add_dependency(to->i915, &to->priotree, -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await 2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson @ 2017-04-12 16:31 ` Michał Winiarski 2017-04-13 10:46 ` Joonas Lahtinen 1 sibling, 0 replies; 19+ messages in thread From: Michał Winiarski @ 2017-04-12 16:31 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx On Wed, Apr 12, 2017 at 01:48:23PM +0100, Chris Wilson wrote: > Although we do check the completion-status of the request before > actually adding a wait on it (either to its submit fence or its > completion dma-fence), we currently do not check before adding it to the > dependency lists. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> -Michał > --- > drivers/gpu/drm/i915/i915_gem_request.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c > index 87ca3453140a..436693b12bae 100644 > --- a/drivers/gpu/drm/i915/i915_gem_request.c > +++ b/drivers/gpu/drm/i915/i915_gem_request.c > @@ -665,6 +665,9 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, > GEM_BUG_ON(to == from); > GEM_BUG_ON(to->timeline == from->timeline); > > + if (i915_gem_request_completed(from)) > + return 0; > + > if (to->engine->schedule) { > ret = i915_priotree_add_dependency(to->i915, > &to->priotree, > -- > 2.11.0 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await 2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson 2017-04-12 16:31 ` Michał Winiarski @ 2017-04-13 10:46 ` Joonas Lahtinen 1 sibling, 0 replies; 19+ messages in thread From: Joonas Lahtinen @ 2017-04-13 10:46 UTC (permalink / raw) To: Chris Wilson, intel-gfx On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote: > Although we do check the completion-status of the request before > actually adding a wait on it (either to its submit fence or its > completion dma-fence), we currently do not check before adding it to the > dependency lists. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Well, it's not going to hurt. Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Regards, Joonas -- Joonas Lahtinen Open Source Technology Center Intel Corporation _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (5 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 16:54 ` Michał Winiarski 2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson ` (3 subsequent siblings) 10 siblings, 1 reply; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx As we may unwind the requests, even though the request we are awaiting has a global_seqno that seqno may be revoked during the await and so we can not reliably use it as a barrier for all future awaits on the same timeline. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michał Winiarski <michal.winiarski@intel.com> --- drivers/gpu/drm/i915/i915_gem_request.c | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 436693b12bae..17feeb68cdff 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -684,33 +684,31 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, } seqno = i915_gem_request_global_seqno(from); - if (!seqno) { - ret = i915_sw_fence_await_dma_fence(&to->submit, - &from->fence, 0, - GFP_KERNEL); - return ret < 0 ? ret : 0; - } + if (!seqno) + goto await_dma_fence; - if (seqno <= to->timeline->global_sync[from->engine->id]) - return 0; - - trace_i915_gem_ring_sync_to(to, from); if (!i915.semaphores) { - if (!i915_spin_request(from, TASK_INTERRUPTIBLE, 2)) { - ret = i915_sw_fence_await_dma_fence(&to->submit, - &from->fence, 0, - GFP_KERNEL); - if (ret < 0) - return ret; - } + if (!__i915_spin_request(from, seqno, TASK_INTERRUPTIBLE, 2)) + goto await_dma_fence; } else { + if (seqno <= to->timeline->global_sync[from->engine->id]) + return 0; + + trace_i915_gem_ring_sync_to(to, from); ret = to->engine->semaphore.sync_to(to, from); if (ret) return ret; + + to->timeline->global_sync[from->engine->id] = seqno; } - to->timeline->global_sync[from->engine->id] = seqno; return 0; + +await_dma_fence: + ret = i915_sw_fence_await_dma_fence(&to->submit, + &from->fence, 0, + GFP_KERNEL); + return ret < 0 ? ret : 0; } int -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await 2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson @ 2017-04-12 16:54 ` Michał Winiarski 0 siblings, 0 replies; 19+ messages in thread From: Michał Winiarski @ 2017-04-12 16:54 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx On Wed, Apr 12, 2017 at 01:48:24PM +0100, Chris Wilson wrote: > As we may unwind the requests, even though the request we are awaiting > has a global_seqno that seqno may be revoked during the await and so we > can not reliably use it as a barrier for all future awaits on the same > timeline. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Michał Winiarski <michal.winiarski@intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> -Michał > --- > drivers/gpu/drm/i915/i915_gem_request.c | 34 ++++++++++++++++----------------- > 1 file changed, 16 insertions(+), 18 deletions(-) _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (6 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson @ 2017-04-12 12:48 ` Chris Wilson 2017-04-12 14:41 ` Joonas Lahtinen 2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork ` (2 subsequent siblings) 10 siblings, 1 reply; 19+ messages in thread From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw) To: intel-gfx Rather than use a global modparam, we can just check to see if the engine has semaphores configured upon it. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_gem_request.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 17feeb68cdff..38307079bd35 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -687,10 +687,12 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, if (!seqno) goto await_dma_fence; - if (!i915.semaphores) { + if (!to->engine->semaphore.sync_to) { if (!__i915_spin_request(from, seqno, TASK_INTERRUPTIBLE, 2)) goto await_dma_fence; } else { + GEM_BUG_ON(!from->engine->semaphore.signal); + if (seqno <= to->timeline->global_sync[from->engine->id]) return 0; -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate 2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson @ 2017-04-12 14:41 ` Joonas Lahtinen 0 siblings, 0 replies; 19+ messages in thread From: Joonas Lahtinen @ 2017-04-12 14:41 UTC (permalink / raw) To: Chris Wilson, intel-gfx On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote: > Rather than use a global modparam, we can just check to see if the > engine has semaphores configured upon it. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Should be good. Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Regars, Joonas -- Joonas Lahtinen Open Source Technology Center Intel Corporation _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (7 preceding siblings ...) 2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson @ 2017-04-12 13:20 ` Patchwork 2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork 2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork 10 siblings, 0 replies; 19+ messages in thread From: Patchwork @ 2017-04-12 13:20 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx == Series Details == Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline URL : https://patchwork.freedesktop.org/series/22924/ State : success == Summary == Series 22924v1 Series without cover letter https://patchwork.freedesktop.org/api/1.0/series/22924/revisions/1/mbox/ Test gem_exec_fence: Subgroup await-hang-default: incomplete -> PASS (fi-hsw-4770) fdo#99726 Test gem_exec_flush: Subgroup basic-batch-kernel-default-uc: fail -> PASS (fi-snb-2600) fdo#100007 fdo#99726 https://bugs.freedesktop.org/show_bug.cgi?id=99726 fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007 fi-bdw-5557u total:278 pass:267 dwarn:0 dfail:0 fail:0 skip:11 time:431s fi-bdw-gvtdvm total:278 pass:256 dwarn:8 dfail:0 fail:0 skip:14 time:425s fi-bsw-n3050 total:278 pass:242 dwarn:0 dfail:0 fail:0 skip:36 time:575s fi-bxt-j4205 total:278 pass:259 dwarn:0 dfail:0 fail:0 skip:19 time:507s fi-byt-j1900 total:278 pass:254 dwarn:0 dfail:0 fail:0 skip:24 time:487s fi-byt-n2820 total:278 pass:250 dwarn:0 dfail:0 fail:0 skip:28 time:487s fi-hsw-4770 total:278 pass:262 dwarn:0 dfail:0 fail:0 skip:16 time:603s fi-hsw-4770r total:278 pass:262 dwarn:0 dfail:0 fail:0 skip:16 time:403s fi-ilk-650 total:278 pass:228 dwarn:0 dfail:0 fail:0 skip:50 time:424s fi-ivb-3520m total:278 pass:260 dwarn:0 dfail:0 fail:0 skip:18 time:490s fi-ivb-3770 total:278 pass:260 dwarn:0 dfail:0 fail:0 skip:18 time:463s fi-kbl-7500u total:278 pass:260 dwarn:0 dfail:0 fail:0 skip:18 time:455s fi-kbl-7560u total:278 pass:268 dwarn:0 dfail:0 fail:0 skip:10 time:567s fi-skl-6260u total:278 pass:268 dwarn:0 dfail:0 fail:0 skip:10 time:453s fi-skl-6700hq total:278 pass:261 dwarn:0 dfail:0 fail:0 skip:17 time:570s fi-skl-6700k total:278 pass:256 dwarn:4 dfail:0 fail:0 skip:18 time:457s fi-skl-6770hq total:278 pass:268 dwarn:0 dfail:0 fail:0 skip:10 time:496s fi-skl-gvtdvm total:278 pass:265 dwarn:0 dfail:0 fail:0 skip:13 time:434s fi-snb-2520m total:278 pass:250 dwarn:0 dfail:0 fail:0 skip:28 time:527s fi-snb-2600 total:278 pass:249 dwarn:0 dfail:0 fail:0 skip:29 time:410s 53b9521a6f113b5fcfd8c6a1f2ba3194e2d21381 drm-tip: 2017y-04m-12d-12h-39m-39s UTC integration manifest d00ced5 drm/i915: Switch the global i915.semaphores check to a local predicate ee45627 drm/i915: Do not record a successful syncpoint for a dma-await a3ec281 drm/i915: Confirm the request is still active before adding it to the await 4132e6e drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] 77635c1 drm/i915: Squash repeated awaits on the same fence 037170d drm/i915: Redefine ptr_pack_bits() and friends a06b39f drm/i915: Make ptr_unpack_bits() more function-like 0ed32ff drm/i915: Lift timeline ordering to await_dma_fence 0547c98 drm/i915: Mark up clflushes as belonging to an unordered timeline == Logs == For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4492/ _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (8 preceding siblings ...) 2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork @ 2017-04-12 15:01 ` Patchwork 2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork 10 siblings, 0 replies; 19+ messages in thread From: Patchwork @ 2017-04-12 15:01 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx == Series Details == Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) URL : https://patchwork.freedesktop.org/series/22924/ State : failure == Summary == scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_perf.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_perf.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/opregion.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/opregion.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp_aux_backlight.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dp_aux_backlight.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_tfp410.o' failed make[4]: *** [drivers/gpu/drm/i915/dvo_tfp410.o] Error 1 LD net/ipv6/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dsi_pll.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dsi_pll.o] Error 1 LD drivers/video/console/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/sched_policy.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/sched_policy.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_bios.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_bios.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_panel.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_panel.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dvo.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dvo.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/display.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/display.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cmd_parser.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/cmd_parser.o] Error 1 LD drivers/video/fbdev/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/firmware.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/firmware.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_cdclk.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_cdclk.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_ch7xxx.o' failed make[4]: *** [drivers/gpu/drm/i915/dvo_ch7xxx.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dsi_vbt.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dsi_vbt.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lspcon.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_lspcon.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_opregion.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_opregion.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_sdvo.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_sdvo.o] Error 1 LD drivers/video/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_sprite.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_sprite.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/render.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/render.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/handlers.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/handlers.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lpe_audio.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_lpe_audio.o] Error 1 LD drivers/usb/gadget/udc/udc-core.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/mmio.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/mmio.o] Error 1 LD drivers/usb/gadget/udc/built-in.o LD drivers/usb/gadget/built-in.o LD drivers/scsi/scsi_mod.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_display.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_display.o] Error 1 LD drivers/pci/built-in.o LD net/ipv4/built-in.o scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm/i915' failed make[3]: *** [drivers/gpu/drm/i915] Error 2 make[3]: *** Waiting for unfinished jobs.... LD drivers/tty/serial/8250/8250_base.o LD drivers/tty/serial/8250/built-in.o LD drivers/tty/serial/built-in.o LD [M] drivers/net/ethernet/intel/e1000/e1000.o scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm' failed make[2]: *** [drivers/gpu/drm] Error 2 scripts/Makefile.build:553: recipe for target 'drivers/gpu' failed make[1]: *** [drivers/gpu] Error 2 make[1]: *** Waiting for unfinished jobs.... LD fs/btrfs/btrfs.o CC arch/x86/kernel/cpu/capflags.o LD arch/x86/kernel/cpu/built-in.o LD drivers/usb/core/usbcore.o LD drivers/scsi/sd_mod.o LD arch/x86/kernel/built-in.o LD drivers/scsi/built-in.o LD drivers/usb/core/built-in.o LD fs/btrfs/built-in.o LD arch/x86/built-in.o LD drivers/tty/vt/built-in.o LD drivers/tty/built-in.o LD [M] drivers/net/ethernet/intel/igb/igb.o LD drivers/usb/host/xhci-hcd.o LD drivers/md/md-mod.o LD drivers/md/built-in.o LD net/core/built-in.o LD net/built-in.o LD fs/ext4/ext4.o LD fs/ext4/built-in.o LD fs/built-in.o LD drivers/usb/host/built-in.o LD drivers/usb/built-in.o LD [M] drivers/net/ethernet/intel/e1000e/e1000e.o LD drivers/net/ethernet/built-in.o LD drivers/net/built-in.o Makefile:1002: recipe for target 'drivers' failed make: *** [drivers] Error 2 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
* ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson ` (9 preceding siblings ...) 2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork @ 2017-04-12 17:00 ` Patchwork 10 siblings, 0 replies; 19+ messages in thread From: Patchwork @ 2017-04-12 17:00 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx == Series Details == Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) URL : https://patchwork.freedesktop.org/series/22924/ State : failure == Summary == scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cfg_space.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/cfg_space.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_modes.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_modes.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_cdclk.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_cdclk.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gem_gtt.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_gem_gtt.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_ns2501.o' failed make[4]: *** [drivers/gpu/drm/i915/dvo_ns2501.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_vgpu.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_vgpu.o] Error 1 LD net/ipv6/ipv6.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/edid.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/edid.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/render.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/render.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lvds.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_lvds.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dp.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/vgpu.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/vgpu.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/mmio.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/mmio.o] Error 1 LD [M] drivers/net/ethernet/intel/igbvf/igbvf.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gem.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_gem.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_i2c.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_i2c.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/sched_policy.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/sched_policy.o] Error 1 LD drivers/usb/gadget/udc/udc-core.o LD net/ipv6/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp_mst.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_dp_mst.o] Error 1 LD drivers/usb/gadget/udc/built-in.o LD drivers/usb/gadget/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_opregion.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_opregion.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/aperture_gm.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/aperture_gm.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_display.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_display.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_oa_hsw.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_oa_hsw.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/gtt.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/gtt.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cmd_parser.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/cmd_parser.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gpu_error.o' failed make[4]: *** [drivers/gpu/drm/i915/i915_gpu_error.o] Error 1 scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_gvt.o' failed make[4]: *** [drivers/gpu/drm/i915/intel_gvt.o] Error 1 LD drivers/gpu/drm/drm.o LD [M] drivers/net/ethernet/intel/e1000/e1000.o LD drivers/tty/serial/8250/8250_base.o LD drivers/tty/serial/8250/built-in.o LD fs/btrfs/btrfs.o LD drivers/tty/serial/built-in.o scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/handlers.o' failed make[4]: *** [drivers/gpu/drm/i915/gvt/handlers.o] Error 1 scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm/i915' failed make[3]: *** [drivers/gpu/drm/i915] Error 2 scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm' failed make[2]: *** [drivers/gpu/drm] Error 2 scripts/Makefile.build:553: recipe for target 'drivers/gpu' failed make[1]: *** [drivers/gpu] Error 2 make[1]: *** Waiting for unfinished jobs.... LD fs/btrfs/built-in.o LD drivers/tty/vt/built-in.o CC arch/x86/kernel/cpu/capflags.o LD drivers/tty/built-in.o LD arch/x86/kernel/cpu/built-in.o LD drivers/md/md-mod.o LD drivers/md/built-in.o LD arch/x86/kernel/built-in.o AR lib/lib.a EXPORTS lib/lib-ksyms.o LD lib/built-in.o LD drivers/usb/core/usbcore.o LD drivers/usb/core/built-in.o LD arch/x86/built-in.o LD [M] drivers/net/ethernet/intel/igb/igb.o LD [M] drivers/net/ethernet/intel/e1000e/e1000e.o LD drivers/usb/host/xhci-hcd.o LD net/ipv4/built-in.o LD drivers/usb/host/built-in.o LD drivers/usb/built-in.o LD fs/ext4/ext4.o LD fs/ext4/built-in.o LD fs/built-in.o LD net/core/built-in.o LD net/built-in.o LD drivers/net/ethernet/built-in.o LD drivers/net/built-in.o Makefile:1002: recipe for target 'drivers' failed make: *** [drivers] Error 2 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2017-04-13 10:49 UTC | newest] Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson 2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson 2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson 2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson 2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson 2017-04-12 14:24 ` [PATCH v3] " Chris Wilson 2017-04-12 15:39 ` [PATCH v4] " Chris Wilson 2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson 2017-04-13 10:49 ` Joonas Lahtinen 2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson 2017-04-12 16:31 ` Michał Winiarski 2017-04-13 10:46 ` Joonas Lahtinen 2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson 2017-04-12 16:54 ` Michał Winiarski 2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson 2017-04-12 14:41 ` Joonas Lahtinen 2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork 2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork 2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.