drm/i915: Use VMA as the primary tracker for semaphore page
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 15 Aug 2016 09:49:02 +0000 (10:49 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 15 Aug 2016 10:01:10 +0000 (11:01 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471254551-25805-23-git-send-email-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 6e7cfbaff224f533e3da1c1c8a5c1eb804abce1d..a922b78350d1b5189905a9cc1f0ca91a42f54845 100644 (file)
@@ -3189,7 +3189,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
                struct page *page;
                uint64_t *seqno;
 
-               page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
+               page = i915_gem_object_get_page(dev_priv->semaphore->obj, 0);
 
                seqno = (uint64_t *)kmap_atomic(page);
                for_each_engine_id(engine, dev_priv, id) {
index 259425d99e177486953d6c55555adf9a714beaec..50dc3613c61c5119efdb34bc53d56a103091ea0a 100644 (file)
@@ -733,7 +733,7 @@ struct drm_i915_error_state {
        u64 fence[I915_MAX_NUM_FENCES];
        struct intel_overlay_error_state *overlay;
        struct intel_display_error_state *display;
-       struct drm_i915_error_object *semaphore_obj;
+       struct drm_i915_error_object *semaphore;
 
        struct drm_i915_error_engine {
                int engine_id;
@@ -1750,7 +1750,7 @@ struct drm_i915_private {
        struct pci_dev *bridge_dev;
        struct i915_gem_context *kernel_context;
        struct intel_engine_cs engine[I915_NUM_ENGINES];
-       struct drm_i915_gem_object *semaphore_obj;
+       struct i915_vma *semaphore;
        u32 next_seqno;
 
        struct drm_dma_handle *status_page_dmah;
index c327733e673565e91af0b824f8ba2e92b602e6ff..4068630bfc682c55df30705de6c3e7bb09187d6f 100644 (file)
@@ -549,7 +549,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
                }
        }
 
-       if ((obj = error->semaphore_obj)) {
+       if ((obj = error->semaphore)) {
                err_printf(m, "Semaphore page = 0x%08x\n",
                           lower_32_bits(obj->gtt_offset));
                for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
@@ -640,7 +640,7 @@ static void i915_error_state_free(struct kref *error_ref)
                kfree(ee->waiters);
        }
 
-       i915_error_object_free(error->semaphore_obj);
+       i915_error_object_free(error->semaphore);
 
        for (i = 0; i < ARRAY_SIZE(error->active_bo); i++)
                kfree(error->active_bo[i]);
@@ -876,7 +876,7 @@ static void gen8_record_semaphore_state(struct drm_i915_error_state *error,
        struct intel_engine_cs *to;
        enum intel_engine_id id;
 
-       if (!error->semaphore_obj)
+       if (!error->semaphore)
                return;
 
        for_each_engine_id(to, dev_priv, id) {
@@ -889,7 +889,7 @@ static void gen8_record_semaphore_state(struct drm_i915_error_state *error,
 
                signal_offset =
                        (GEN8_SIGNAL_OFFSET(engine, id) & (PAGE_SIZE - 1)) / 4;
-               tmp = error->semaphore_obj->pages[0];
+               tmp = error->semaphore->pages[0];
                idx = intel_engine_sync_index(engine, to);
 
                ee->semaphore_mboxes[idx] = tmp[signal_offset];
@@ -1061,11 +1061,9 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
        struct drm_i915_gem_request *request;
        int i, count;
 
-       if (dev_priv->semaphore_obj) {
-               error->semaphore_obj =
-                       i915_error_ggtt_object_create(dev_priv,
-                                                     dev_priv->semaphore_obj);
-       }
+       error->semaphore =
+               i915_error_ggtt_object_create(dev_priv,
+                                             dev_priv->semaphore->obj);
 
        for (i = 0; i < I915_NUM_ENGINES; i++) {
                struct intel_engine_cs *engine = &dev_priv->engine[i];
index 829624571ca4922847eb76645ec40f5d840683a7..573f642a74f80394d4dd2e3b069e7b7670b2c621 100644 (file)
@@ -179,12 +179,16 @@ void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno)
                if (HAS_VEBOX(dev_priv))
                        I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
        }
-       if (dev_priv->semaphore_obj) {
-               struct drm_i915_gem_object *obj = dev_priv->semaphore_obj;
-               struct page *page = i915_gem_object_get_dirty_page(obj, 0);
-               void *semaphores = kmap(page);
+       if (dev_priv->semaphore) {
+               struct page *page = i915_vma_first_page(dev_priv->semaphore);
+               void *semaphores;
+
+               /* Semaphores are in noncoherent memory, flush to be safe */
+               semaphores = kmap(page);
                memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
                       0, I915_NUM_ENGINES * gen8_semaphore_seqno_size);
+               drm_clflush_virt_range(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
+                                      I915_NUM_ENGINES * gen8_semaphore_seqno_size);
                kunmap(page);
        }
        memset(engine->semaphore.sync_seqno, 0,
index 6008d54b9152f1134dd556844e978e15275e6644..30b066140b0ce87443c8b2857d123749ed6c4a70 100644 (file)
@@ -1257,12 +1257,14 @@ static int init_render_ring(struct intel_engine_cs *engine)
 static void render_ring_cleanup(struct intel_engine_cs *engine)
 {
        struct drm_i915_private *dev_priv = engine->i915;
+       struct i915_vma *vma;
 
-       if (dev_priv->semaphore_obj) {
-               i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj);
-               i915_gem_object_put(dev_priv->semaphore_obj);
-               dev_priv->semaphore_obj = NULL;
-       }
+       vma = fetch_and_zero(&dev_priv->semaphore);
+       if (!vma)
+               return;
+
+       i915_vma_unpin(vma);
+       i915_vma_put(vma);
 }
 
 static int gen8_rcs_signal(struct drm_i915_gem_request *req)
@@ -2523,30 +2525,30 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv,
        if (!i915.semaphores)
                return;
 
-       if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore_obj) {
+       if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore) {
+               struct i915_vma *vma;
+
                obj = i915_gem_object_create(&dev_priv->drm, 4096);
-               if (IS_ERR(obj)) {
-                       DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n");
-                       i915.semaphores = 0;
-               } else {
-                       i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
-                       ret = i915_gem_object_ggtt_pin(obj, NULL,
-                                                      0, 0, PIN_HIGH);
-                       if (ret != 0) {
-                               i915_gem_object_put(obj);
-                               DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n");
-                               i915.semaphores = 0;
-                       } else {
-                               dev_priv->semaphore_obj = obj;
-                       }
-               }
-       }
+               if (IS_ERR(obj))
+                       goto err;
 
-       if (!i915.semaphores)
-               return;
+               vma = i915_vma_create(obj, &dev_priv->ggtt.base, NULL);
+               if (IS_ERR(vma))
+                       goto err_obj;
+
+               ret = i915_gem_object_set_to_gtt_domain(obj, false);
+               if (ret)
+                       goto err_obj;
+
+               ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
+               if (ret)
+                       goto err_obj;
+
+               dev_priv->semaphore = vma;
+       }
 
        if (INTEL_GEN(dev_priv) >= 8) {
-               u64 offset = i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj);
+               u64 offset = dev_priv->semaphore->node.start;
 
                engine->semaphore.sync_to = gen8_ring_sync_to;
                engine->semaphore.signal = gen8_xcs_signal;
@@ -2613,6 +2615,14 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv,
                        engine->semaphore.mbox.signal[i] = mbox_reg;
                }
        }
+
+       return;
+
+err_obj:
+       i915_gem_object_put(obj);
+err:
+       DRM_DEBUG_DRIVER("Failed to allocate space for semaphores, disabling\n");
+       i915.semaphores = 0;
 }
 
 static void intel_ring_init_irq(struct drm_i915_private *dev_priv,
index dca84258be1667b803e486d3333f886bab0eab89..cb40785e76773414f51de7ff7d31ef7db31ba9ef 100644 (file)
@@ -57,10 +57,10 @@ struct intel_hw_status_page {
 #define GEN8_SEMAPHORE_OFFSET(__from, __to)                         \
        (((__from) * I915_NUM_ENGINES  + (__to)) * gen8_semaphore_seqno_size)
 #define GEN8_SIGNAL_OFFSET(__ring, to)                      \
-       (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+       (dev_priv->semaphore->node.start + \
         GEN8_SEMAPHORE_OFFSET((__ring)->id, (to)))
 #define GEN8_WAIT_OFFSET(__ring, from)                      \
-       (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+       (dev_priv->semaphore->node.start + \
         GEN8_SEMAPHORE_OFFSET(from, (__ring)->id))
 
 enum intel_engine_hangcheck_action {