drm/i915: Revert "drm/i915/gem: Asynchronous cmdparser"
authorjsg <jsg@openbsd.org>
Wed, 11 Aug 2021 03:06:57 +0000 (03:06 +0000)
committerjsg <jsg@openbsd.org>
Wed, 11 Aug 2021 03:06:57 +0000 (03:06 +0000)
From Jason Ekstrand
6976f3cf34a1a8b791c048bbaa411ebfe48666b1 in linux 5.10.y/5.10.57
c9d9fdbc108af8915d3f497bbdf3898bf8f321b8 in mainline linux

sys/dev/pci/drm/i915/gem/i915_gem_execbuffer.c
sys/dev/pci/drm/i915/i915_cmd_parser.c

index 98ab54d..ff4a691 100644 (file)
@@ -27,7 +27,6 @@
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
 #include "i915_gem_ioctls.h"
-#include "i915_sw_fence_work.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
 
@@ -1425,6 +1424,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb,
                int err;
                struct intel_engine_cs *engine = eb->engine;
 
+               /* If we need to copy for the cmdparser, we will stall anyway */
+               if (eb_use_cmdparser(eb))
+                       return ERR_PTR(-EWOULDBLOCK);
+
                if (!reloc_can_use_engine(engine)) {
                        engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0];
                        if (!engine)
@@ -2295,152 +2298,6 @@ shadow_batch_pin(struct i915_execbuffer *eb,
        return vma;
 }
 
-struct eb_parse_work {
-       struct dma_fence_work base;
-       struct intel_engine_cs *engine;
-       struct i915_vma *batch;
-       struct i915_vma *shadow;
-       struct i915_vma *trampoline;
-       unsigned long batch_offset;
-       unsigned long batch_length;
-};
-
-static int __eb_parse(struct dma_fence_work *work)
-{
-       struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
-
-       return intel_engine_cmd_parser(pw->engine,
-                                      pw->batch,
-                                      pw->batch_offset,
-                                      pw->batch_length,
-                                      pw->shadow,
-                                      pw->trampoline);
-}
-
-static void __eb_parse_release(struct dma_fence_work *work)
-{
-       struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
-
-       if (pw->trampoline)
-               i915_active_release(&pw->trampoline->active);
-       i915_active_release(&pw->shadow->active);
-       i915_active_release(&pw->batch->active);
-}
-
-static const struct dma_fence_work_ops eb_parse_ops = {
-       .name = "eb_parse",
-       .work = __eb_parse,
-       .release = __eb_parse_release,
-};
-
-static inline int
-__parser_mark_active(struct i915_vma *vma,
-                    struct intel_timeline *tl,
-                    struct dma_fence *fence)
-{
-       struct intel_gt_buffer_pool_node *node = vma->private;
-
-       return i915_active_ref(&node->active, tl->fence_context, fence);
-}
-
-static int
-parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl)
-{
-       int err;
-
-       mutex_lock(&tl->mutex);
-
-       err = __parser_mark_active(pw->shadow, tl, &pw->base.dma);
-       if (err)
-               goto unlock;
-
-       if (pw->trampoline) {
-               err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma);
-               if (err)
-                       goto unlock;
-       }
-
-unlock:
-       mutex_unlock(&tl->mutex);
-       return err;
-}
-
-static int eb_parse_pipeline(struct i915_execbuffer *eb,
-                            struct i915_vma *shadow,
-                            struct i915_vma *trampoline)
-{
-       struct eb_parse_work *pw;
-       int err;
-
-       GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset));
-       GEM_BUG_ON(overflows_type(eb->batch_len, pw->batch_length));
-
-       pw = kzalloc(sizeof(*pw), GFP_KERNEL);
-       if (!pw)
-               return -ENOMEM;
-
-       err = i915_active_acquire(&eb->batch->vma->active);
-       if (err)
-               goto err_free;
-
-       err = i915_active_acquire(&shadow->active);
-       if (err)
-               goto err_batch;
-
-       if (trampoline) {
-               err = i915_active_acquire(&trampoline->active);
-               if (err)
-                       goto err_shadow;
-       }
-
-       dma_fence_work_init(&pw->base, &eb_parse_ops);
-
-       pw->engine = eb->engine;
-       pw->batch = eb->batch->vma;
-       pw->batch_offset = eb->batch_start_offset;
-       pw->batch_length = eb->batch_len;
-       pw->shadow = shadow;
-       pw->trampoline = trampoline;
-
-       /* Mark active refs early for this worker, in case we get interrupted */
-       err = parser_mark_active(pw, eb->context->timeline);
-       if (err)
-               goto err_commit;
-
-       err = dma_resv_reserve_shared(pw->batch->resv, 1);
-       if (err)
-               goto err_commit;
-
-       /* Wait for all writes (and relocs) into the batch to complete */
-       err = i915_sw_fence_await_reservation(&pw->base.chain,
-                                             pw->batch->resv, NULL, false,
-                                             0, I915_FENCE_GFP);
-       if (err < 0)
-               goto err_commit;
-
-       /* Keep the batch alive and unwritten as we parse */
-       dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma);
-
-       /* Force execution to wait for completion of the parser */
-       dma_resv_add_excl_fence(shadow->resv, &pw->base.dma);
-
-       dma_fence_work_commit_imm(&pw->base);
-       return 0;
-
-err_commit:
-       i915_sw_fence_set_error_once(&pw->base.chain, err);
-       dma_fence_work_commit_imm(&pw->base);
-       return err;
-
-err_shadow:
-       i915_active_release(&shadow->active);
-err_batch:
-       i915_active_release(&eb->batch->vma->active);
-err_free:
-       kfree(pw);
-       return err;
-}
-
 static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i915_vma *vma)
 {
        /*
@@ -2522,13 +2379,11 @@ static int eb_parse(struct i915_execbuffer *eb)
                eb->batch_flags |= I915_DISPATCH_SECURE;
        }
 
-       batch = eb_dispatch_secure(eb, shadow);
-       if (IS_ERR(batch)) {
-               err = PTR_ERR(batch);
-               goto err_trampoline;
-       }
-
-       err = eb_parse_pipeline(eb, shadow, trampoline);
+       err = intel_engine_cmd_parser(eb->engine,
+                                     eb->batch->vma,
+                                     eb->batch_start_offset,
+                                     eb->batch_len,
+                                     shadow, trampoline);
        if (err)
                goto err_unpin_batch;
 
@@ -2550,7 +2405,6 @@ secure_batch:
 err_unpin_batch:
        if (batch)
                i915_vma_unpin(batch);
-err_trampoline:
        if (trampoline)
                i915_vma_unpin(trampoline);
 err_shadow:
index df478f4..1a74062 100644 (file)
@@ -1143,27 +1143,30 @@ find_reg(const struct intel_engine_cs *engine, u32 addr)
 /* Returns a vmap'd pointer to dst_obj, which the caller must unmap */
 static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
                       struct drm_i915_gem_object *src_obj,
-                      unsigned long offset, unsigned long length)
+                      u32 offset, u32 length)
 {
-       bool needs_clflush;
+       unsigned int src_needs_clflush;
+       unsigned int dst_needs_clflush;
        void *dst, *src;
        int ret;
 
+       ret = i915_gem_object_prepare_write(dst_obj, &dst_needs_clflush);
+       if (ret)
+               return ERR_PTR(ret);
+
        dst = i915_gem_object_pin_map(dst_obj, I915_MAP_FORCE_WB);
+       i915_gem_object_finish_access(dst_obj);
        if (IS_ERR(dst))
                return dst;
 
-       ret = i915_gem_object_pin_pages(src_obj);
+       ret = i915_gem_object_prepare_read(src_obj, &src_needs_clflush);
        if (ret) {
                i915_gem_object_unpin_map(dst_obj);
                return ERR_PTR(ret);
        }
 
-       needs_clflush =
-               !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ);
-
        src = ERR_PTR(-ENODEV);
-       if (needs_clflush && i915_has_memcpy_from_wc()) {
+       if (src_needs_clflush && i915_has_memcpy_from_wc()) {
                src = i915_gem_object_pin_map(src_obj, I915_MAP_WC);
                if (!IS_ERR(src)) {
                        i915_unaligned_memcpy_from_wc(dst,
@@ -1185,7 +1188,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
                 * validate up to the end of the batch.
                 */
                remain = length;
-               if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
+               if (dst_needs_clflush & CLFLUSH_BEFORE)
 #ifdef __linux__
                        remain = round_up(remain,
                                          boot_cpu_data.x86_clflush_size);
@@ -1200,7 +1203,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
                        int len = min(remain, PAGE_SIZE - x);
 
                        src = kmap_atomic(i915_gem_object_get_page(src_obj, n));
-                       if (needs_clflush)
+                       if (src_needs_clflush)
                                drm_clflush_virt_range(src + x, len);
                        memcpy(ptr, src + x, len);
                        kunmap_atomic(src);
@@ -1211,11 +1214,10 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
                }
        }
 
-       i915_gem_object_unpin_pages(src_obj);
+       i915_gem_object_finish_access(src_obj);
 
        memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32));
 
-       /* dst_obj is returned with vmap pinned */
        return dst;
 }
 
@@ -1422,6 +1424,7 @@ static unsigned long *alloc_whitelist(u32 batch_length)
  * Return: non-zero if the parser finds violations or otherwise fails; -EACCES
  * if the batch appears legal but should use hardware parsing
  */
+
 int intel_engine_cmd_parser(struct intel_engine_cs *engine,
                            struct i915_vma *batch,
                            unsigned long batch_offset,
@@ -1442,7 +1445,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
                                     batch->size));
        GEM_BUG_ON(!batch_length);
 
-       cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length);
+       cmd = copy_batch(shadow->obj, batch->obj,
+                        batch_offset, batch_length);
        if (IS_ERR(cmd)) {
                DRM_DEBUG("CMD: Failed to copy batch\n");
                return PTR_ERR(cmd);