From: Maarten Lankhorst <maarten.lankho...@linux.intel.com>

We're starting to require the reservation lock for pinning,
so wait until we have that.

Update the selftests to handle this correctly, and ensure pin is
called in live_hwsp_rollover_user() and mock_hwsp_freelist().

Signed-off-by: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
Reported-by: kernel test robot <l...@intel.com>
Cc: Thomas Hellström <thomas.hellst...@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/intel_timeline.c      | 49 ++++++++++----
 drivers/gpu/drm/i915/gt/intel_timeline.h      |  1 +
 .../gpu/drm/i915/gt/intel_timeline_types.h    |  1 +
 drivers/gpu/drm/i915/gt/mock_engine.c         | 24 ++++++-
 drivers/gpu/drm/i915/gt/selftest_timeline.c   | 64 ++++++++++---------
 drivers/gpu/drm/i915/i915_selftest.h          |  2 +
 6 files changed, 96 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c 
b/drivers/gpu/drm/i915/gt/intel_timeline.c
index a58228d1cd3b..479eb5440bc6 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -229,13 +229,30 @@ static void cacheline_free(struct 
intel_timeline_cacheline *cl)
        i915_active_release(&cl->active);
 }
 
+I915_SELFTEST_EXPORT int
+intel_timeline_pin_map(struct intel_timeline *timeline)
+{
+       if (!timeline->hwsp_cacheline) {
+               struct drm_i915_gem_object *obj = timeline->hwsp_ggtt->obj;
+               u32 ofs = offset_in_page(timeline->hwsp_offset);
+               void *vaddr;
+
+               vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
+               if (IS_ERR(vaddr))
+                       return PTR_ERR(vaddr);
+
+               timeline->hwsp_map = vaddr;
+               timeline->hwsp_seqno = memset(vaddr + ofs, 0, CACHELINE_BYTES);
+       }
+
+       return 0;
+}
+
 static int intel_timeline_init(struct intel_timeline *timeline,
                               struct intel_gt *gt,
                               struct i915_vma *hwsp,
                               unsigned int offset)
 {
-       void *vaddr;
-
        kref_init(&timeline->kref);
        atomic_set(&timeline->pin_count, 0);
 
@@ -260,18 +277,15 @@ static int intel_timeline_init(struct intel_timeline 
*timeline,
 
                timeline->hwsp_cacheline = cl;
                timeline->hwsp_offset = cacheline * CACHELINE_BYTES;
-
-               vaddr = page_mask_bits(cl->vaddr);
+               timeline->hwsp_map = page_mask_bits(cl->vaddr);
+               timeline->hwsp_seqno =
+                       memset(timeline->hwsp_map + timeline->hwsp_offset, 0,
+                              CACHELINE_BYTES);
        } else {
                timeline->hwsp_offset = offset;
-               vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB);
-               if (IS_ERR(vaddr))
-                       return PTR_ERR(vaddr);
+               timeline->hwsp_map = NULL;
        }
 
-       timeline->hwsp_seqno =
-               memset(vaddr + timeline->hwsp_offset, 0, CACHELINE_BYTES);
-
        timeline->hwsp_ggtt = i915_vma_get(hwsp);
        GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size);
 
@@ -306,7 +320,7 @@ static void intel_timeline_fini(struct intel_timeline 
*timeline)
 
        if (timeline->hwsp_cacheline)
                cacheline_free(timeline->hwsp_cacheline);
-       else
+       else if (timeline->hwsp_map)
                i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj);
 
        i915_vma_put(timeline->hwsp_ggtt);
@@ -346,9 +360,18 @@ int intel_timeline_pin(struct intel_timeline *tl, struct 
i915_gem_ww_ctx *ww)
        if (atomic_add_unless(&tl->pin_count, 1, 0))
                return 0;
 
+       if (!tl->hwsp_cacheline) {
+               err = intel_timeline_pin_map(tl);
+               if (err)
+                       return err;
+       }
+
        err = i915_ggtt_pin(tl->hwsp_ggtt, ww, 0, PIN_HIGH);
-       if (err)
+       if (err) {
+               if (!tl->hwsp_cacheline)
+                       i915_gem_object_unpin_map(tl->hwsp_ggtt->obj);
                return err;
+       }
 
        tl->hwsp_offset =
                i915_ggtt_offset(tl->hwsp_ggtt) +
@@ -360,6 +383,8 @@ int intel_timeline_pin(struct intel_timeline *tl, struct 
i915_gem_ww_ctx *ww)
        if (atomic_fetch_inc(&tl->pin_count)) {
                cacheline_release(tl->hwsp_cacheline);
                __i915_vma_unpin(tl->hwsp_ggtt);
+               if (!tl->hwsp_cacheline)
+                       i915_gem_object_unpin_map(tl->hwsp_ggtt->obj);
        }
 
        return 0;
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h 
b/drivers/gpu/drm/i915/gt/intel_timeline.h
index 634acebd0c4b..725bae16237c 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.h
@@ -114,5 +114,6 @@ void intel_gt_show_timelines(struct intel_gt *gt,
                                                  const struct i915_request *rq,
                                                  const char *prefix,
                                                  int indent));
+I915_SELFTEST_DECLARE(int intel_timeline_pin_map(struct intel_timeline *tl));
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h 
b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
index 4474f487f589..cac7fa3dfd43 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
@@ -45,6 +45,7 @@ struct intel_timeline {
        atomic_t pin_count;
        atomic_t active_count;
 
+       void *hwsp_map;
        const u32 *hwsp_seqno;
        struct i915_vma *hwsp_ggtt;
        u32 hwsp_offset;
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c 
b/drivers/gpu/drm/i915/gt/mock_engine.c
index 2f830017c51d..016f4f345706 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -32,9 +32,22 @@
 #include "mock_engine.h"
 #include "selftests/mock_request.h"
 
-static void mock_timeline_pin(struct intel_timeline *tl)
+static int mock_timeline_pin(struct intel_timeline *tl)
 {
+       int err;
+
+       if (!tl->hwsp_cacheline) {
+               if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj)))
+                       return -EBUSY;
+
+               err = intel_timeline_pin_map(tl);
+               i915_gem_object_unlock(tl->hwsp_ggtt->obj);
+               if (err)
+                       return err;
+       }
+
        atomic_inc(&tl->pin_count);
+       return 0;
 }
 
 static void mock_timeline_unpin(struct intel_timeline *tl)
@@ -152,6 +165,8 @@ static void mock_context_destroy(struct kref *ref)
 
 static int mock_context_alloc(struct intel_context *ce)
 {
+       int err;
+
        ce->ring = mock_ring(ce->engine);
        if (!ce->ring)
                return -ENOMEM;
@@ -162,7 +177,12 @@ static int mock_context_alloc(struct intel_context *ce)
                return PTR_ERR(ce->timeline);
        }
 
-       mock_timeline_pin(ce->timeline);
+       err = mock_timeline_pin(ce->timeline);
+       if (err) {
+               intel_timeline_put(ce->timeline);
+               ce->timeline = NULL;
+               return err;
+       }
 
        return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c 
b/drivers/gpu/drm/i915/gt/selftest_timeline.c
index fa3fec049542..7435abf5a703 100644
--- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
+++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
@@ -34,7 +34,7 @@ static unsigned long hwsp_cacheline(struct intel_timeline *tl)
 {
        unsigned long address = (unsigned long)page_address(hwsp_page(tl));
 
-       return (address + tl->hwsp_offset) / CACHELINE_BYTES;
+       return (address + offset_in_page(tl->hwsp_offset)) / CACHELINE_BYTES;
 }
 
 #define CACHELINES_PER_PAGE (PAGE_SIZE / CACHELINE_BYTES)
@@ -58,6 +58,7 @@ static void __mock_hwsp_record(struct mock_hwsp_freelist 
*state,
        tl = xchg(&state->history[idx], tl);
        if (tl) {
                radix_tree_delete(&state->cachelines, hwsp_cacheline(tl));
+               intel_timeline_unpin(tl);
                intel_timeline_put(tl);
        }
 }
@@ -77,6 +78,12 @@ static int __mock_hwsp_timeline(struct mock_hwsp_freelist 
*state,
                if (IS_ERR(tl))
                        return PTR_ERR(tl);
 
+               err = intel_timeline_pin(tl, NULL);
+               if (err) {
+                       intel_timeline_put(tl);
+                       return err;
+               }
+
                cacheline = hwsp_cacheline(tl);
                err = radix_tree_insert(&state->cachelines, cacheline, tl);
                if (err) {
@@ -84,6 +91,7 @@ static int __mock_hwsp_timeline(struct mock_hwsp_freelist 
*state,
                                pr_err("HWSP cacheline %lu already used; 
duplicate allocation!\n",
                                       cacheline);
                        }
+                       intel_timeline_unpin(tl);
                        intel_timeline_put(tl);
                        return err;
                }
@@ -451,7 +459,7 @@ static int emit_ggtt_store_dw(struct i915_request *rq, u32 
addr, u32 value)
 }
 
 static struct i915_request *
-tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)
+checked_tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, 
u32 value)
 {
        struct i915_request *rq;
        int err;
@@ -462,6 +470,13 @@ tl_write(struct intel_timeline *tl, struct intel_engine_cs 
*engine, u32 value)
                goto out;
        }
 
+       if (READ_ONCE(*tl->hwsp_seqno) != tl->seqno) {
+               pr_err("Timeline created with incorrect breadcrumb, found %x, 
expected %x\n",
+                      *tl->hwsp_seqno, tl->seqno);
+               intel_timeline_unpin(tl);
+               return ERR_PTR(-EINVAL);
+       }
+
        rq = intel_engine_create_kernel_request(engine);
        if (IS_ERR(rq))
                goto out_unpin;
@@ -483,25 +498,6 @@ tl_write(struct intel_timeline *tl, struct intel_engine_cs 
*engine, u32 value)
        return rq;
 }
 
-static struct intel_timeline *
-checked_intel_timeline_create(struct intel_gt *gt)
-{
-       struct intel_timeline *tl;
-
-       tl = intel_timeline_create(gt);
-       if (IS_ERR(tl))
-               return tl;
-
-       if (READ_ONCE(*tl->hwsp_seqno) != tl->seqno) {
-               pr_err("Timeline created with incorrect breadcrumb, found %x, 
expected %x\n",
-                      *tl->hwsp_seqno, tl->seqno);
-               intel_timeline_put(tl);
-               return ERR_PTR(-EINVAL);
-       }
-
-       return tl;
-}
-
 static int live_hwsp_engine(void *arg)
 {
 #define NUM_TIMELINES 4096
@@ -534,13 +530,13 @@ static int live_hwsp_engine(void *arg)
                        struct intel_timeline *tl;
                        struct i915_request *rq;
 
-                       tl = checked_intel_timeline_create(gt);
+                       tl = intel_timeline_create(gt);
                        if (IS_ERR(tl)) {
                                err = PTR_ERR(tl);
                                break;
                        }
 
-                       rq = tl_write(tl, engine, count);
+                       rq = checked_tl_write(tl, engine, count);
                        if (IS_ERR(rq)) {
                                intel_timeline_put(tl);
                                err = PTR_ERR(rq);
@@ -607,14 +603,14 @@ static int live_hwsp_alternate(void *arg)
                        if (!intel_engine_can_store_dword(engine))
                                continue;
 
-                       tl = checked_intel_timeline_create(gt);
+                       tl = intel_timeline_create(gt);
                        if (IS_ERR(tl)) {
                                err = PTR_ERR(tl);
                                goto out;
                        }
 
                        intel_engine_pm_get(engine);
-                       rq = tl_write(tl, engine, count);
+                       rq = checked_tl_write(tl, engine, count);
                        intel_engine_pm_put(engine);
                        if (IS_ERR(rq)) {
                                intel_timeline_put(tl);
@@ -1239,8 +1235,13 @@ static int live_hwsp_rollover_user(void *arg)
                if (!tl->has_initial_breadcrumb || !tl->hwsp_cacheline)
                        goto out;
 
+               err = intel_context_pin(ce);
+               if (err)
+                       goto out;
+
                timeline_rollback(tl);
                timeline_rollback(tl);
+
                WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
 
                for (i = 0; i < ARRAY_SIZE(rq); i++) {
@@ -1249,7 +1250,7 @@ static int live_hwsp_rollover_user(void *arg)
                        this = intel_context_create_request(ce);
                        if (IS_ERR(this)) {
                                err = PTR_ERR(this);
-                               goto out;
+                               goto out_unpin;
                        }
 
                        pr_debug("%s: create fence.seqnp:%d\n",
@@ -1268,17 +1269,18 @@ static int live_hwsp_rollover_user(void *arg)
                if (i915_request_wait(rq[2], 0, HZ / 5) < 0) {
                        pr_err("Wait for timeline wrap timed out!\n");
                        err = -EIO;
-                       goto out;
+                       goto out_unpin;
                }
 
                for (i = 0; i < ARRAY_SIZE(rq); i++) {
                        if (!i915_request_completed(rq[i])) {
                                pr_err("Pre-wrap request not completed!\n");
                                err = -EINVAL;
-                               goto out;
+                               goto out_unpin;
                        }
                }
-
+out_unpin:
+               intel_context_unpin(ce);
 out:
                for (i = 0; i < ARRAY_SIZE(rq); i++)
                        i915_request_put(rq[i]);
@@ -1320,13 +1322,13 @@ static int live_hwsp_recycle(void *arg)
                        struct intel_timeline *tl;
                        struct i915_request *rq;
 
-                       tl = checked_intel_timeline_create(gt);
+                       tl = intel_timeline_create(gt);
                        if (IS_ERR(tl)) {
                                err = PTR_ERR(tl);
                                break;
                        }
 
-                       rq = tl_write(tl, engine, count);
+                       rq = checked_tl_write(tl, engine, count);
                        if (IS_ERR(rq)) {
                                intel_timeline_put(tl);
                                err = PTR_ERR(rq);
diff --git a/drivers/gpu/drm/i915/i915_selftest.h 
b/drivers/gpu/drm/i915/i915_selftest.h
index d53d207ab6eb..f54de0499be7 100644
--- a/drivers/gpu/drm/i915/i915_selftest.h
+++ b/drivers/gpu/drm/i915/i915_selftest.h
@@ -107,6 +107,7 @@ int __i915_subtests(const char *caller,
 
 #define I915_SELFTEST_DECLARE(x) x
 #define I915_SELFTEST_ONLY(x) unlikely(x)
+#define I915_SELFTEST_EXPORT
 
 #else /* !IS_ENABLED(CONFIG_DRM_I915_SELFTEST) */
 
@@ -116,6 +117,7 @@ static inline int i915_perf_selftests(struct pci_dev *pdev) 
{ return 0; }
 
 #define I915_SELFTEST_DECLARE(x)
 #define I915_SELFTEST_ONLY(x) 0
+#define I915_SELFTEST_EXPORT static
 
 #endif
 
-- 
2.26.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to