]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
Merge tag 'drm-misc-next-2018-11-21' of git://anongit.freedesktop.org/drm/drm-misc...
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_ring.c
index 93794a85f83d80e868870133e387467c2b8de4a9..5b75bdc8dc28f673957067f36268ea7fb6eae8e1 100644 (file)
@@ -135,9 +135,6 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring)
 
        if (ring->funcs->end_use)
                ring->funcs->end_use(ring);
-
-       if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ)
-               amdgpu_ring_lru_touch(ring->adev, ring);
 }
 
 /**
@@ -320,8 +317,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
        ring->max_dw = max_dw;
        ring->priority = DRM_SCHED_PRIORITY_NORMAL;
        mutex_init(&ring->priority_mutex);
-       INIT_LIST_HEAD(&ring->lru_list);
-       amdgpu_ring_lru_touch(adev, ring);
 
        for (i = 0; i < DRM_SCHED_PRIORITY_MAX; ++i)
                atomic_set(&ring->num_jobs[i], 0);
@@ -343,7 +338,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
  */
 void amdgpu_ring_fini(struct amdgpu_ring *ring)
 {
-       ring->ready = false;
+       ring->sched.ready = false;
 
        /* Not to finish a ring which is not initialized */
        if (!(ring->adev) || !(ring->adev->rings[ring->idx]))
@@ -368,99 +363,6 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
        ring->adev->rings[ring->idx] = NULL;
 }
 
-static void amdgpu_ring_lru_touch_locked(struct amdgpu_device *adev,
-                                        struct amdgpu_ring *ring)
-{
-       /* list_move_tail handles the case where ring isn't part of the list */
-       list_move_tail(&ring->lru_list, &adev->ring_lru_list);
-}
-
-static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,
-                                      int *blacklist, int num_blacklist)
-{
-       int i;
-
-       for (i = 0; i < num_blacklist; i++) {
-               if (ring->idx == blacklist[i])
-                       return true;
-       }
-
-       return false;
-}
-
-/**
- * amdgpu_ring_lru_get - get the least recently used ring for a HW IP block
- *
- * @adev: amdgpu_device pointer
- * @type: amdgpu_ring_type enum
- * @blacklist: blacklisted ring ids array
- * @num_blacklist: number of entries in @blacklist
- * @lru_pipe_order: find a ring from the least recently used pipe
- * @ring: output ring
- *
- * Retrieve the amdgpu_ring structure for the least recently used ring of
- * a specific IP block (all asics).
- * Returns 0 on success, error on failure.
- */
-int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
-                       int *blacklist, int num_blacklist,
-                       bool lru_pipe_order, struct amdgpu_ring **ring)
-{
-       struct amdgpu_ring *entry;
-
-       /* List is sorted in LRU order, find first entry corresponding
-        * to the desired HW IP */
-       *ring = NULL;
-       spin_lock(&adev->ring_lru_list_lock);
-       list_for_each_entry(entry, &adev->ring_lru_list, lru_list) {
-               if (entry->funcs->type != type)
-                       continue;
-
-               if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist))
-                       continue;
-
-               if (!*ring) {
-                       *ring = entry;
-
-                       /* We are done for ring LRU */
-                       if (!lru_pipe_order)
-                               break;
-               }
-
-               /* Move all rings on the same pipe to the end of the list */
-               if (entry->pipe == (*ring)->pipe)
-                       amdgpu_ring_lru_touch_locked(adev, entry);
-       }
-
-       /* Move the ring we found to the end of the list */
-       if (*ring)
-               amdgpu_ring_lru_touch_locked(adev, *ring);
-
-       spin_unlock(&adev->ring_lru_list_lock);
-
-       if (!*ring) {
-               DRM_ERROR("Ring LRU contains no entries for ring type:%d\n", type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/**
- * amdgpu_ring_lru_touch - mark a ring as recently being used
- *
- * @adev: amdgpu_device pointer
- * @ring: ring to touch
- *
- * Move @ring to the tail of the lru list
- */
-void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring)
-{
-       spin_lock(&adev->ring_lru_list_lock);
-       amdgpu_ring_lru_touch_locked(adev, ring);
-       spin_unlock(&adev->ring_lru_list_lock);
-}
-
 /**
  * amdgpu_ring_emit_reg_write_reg_wait_helper - ring helper
  *
@@ -481,6 +383,31 @@ void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
        amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
 }
 
+/**
+ * amdgpu_ring_soft_recovery - try to soft recover a ring lockup
+ *
+ * @ring: ring to try the recovery on
+ * @vmid: VMID we try to get going again
+ * @fence: timedout fence
+ *
+ * Tries to get a ring proceeding again when it is stuck.
+ */
+bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
+                              struct dma_fence *fence)
+{
+       ktime_t deadline = ktime_add_us(ktime_get(), 10000);
+
+       if (!ring->funcs->soft_recovery)
+               return false;
+
+       atomic_inc(&ring->adev->gpu_reset_counter);
+       while (!dma_fence_is_signaled(fence) &&
+              ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0)
+               ring->funcs->soft_recovery(ring, vmid);
+
+       return dma_fence_is_signaled(fence);
+}
+
 /*
  * Debugfs info
  */
@@ -573,3 +500,29 @@ static void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring)
        debugfs_remove(ring->ent);
 #endif
 }
+
+/**
+ * amdgpu_ring_test_helper - tests ring and set sched readiness status
+ *
+ * @ring: ring to try the recovery on
+ *
+ * Tests ring and set sched readiness status
+ *
+ * Returns 0 on success, error on failure.
+ */
+int amdgpu_ring_test_helper(struct amdgpu_ring *ring)
+{
+       struct amdgpu_device *adev = ring->adev;
+       int r;
+
+       r = amdgpu_ring_test_ring(ring);
+       if (r)
+               DRM_DEV_ERROR(adev->dev, "ring %s test failed (%d)\n",
+                             ring->name, r);
+       else
+               DRM_DEV_DEBUG(adev->dev, "ring test on %s succeeded\n",
+                             ring->name);
+
+       ring->sched.ready = !r;
+       return r;
+}
This page took 0.03657 seconds and 4 git commands to generate.