drm/amdgpu: add a fence timeout for the IB tests v2
authorChristian König <christian.koenig@amd.com>
Tue, 5 Jul 2016 19:07:17 +0000 (21:07 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 29 Jul 2016 18:37:04 +0000 (14:37 -0400)
10ms should be enough for now.

v2: fix some typos in CIK code

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
drivers/gpu/drm/amd/amdgpu/cik_sdma.c
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c

index 02a0d19ce54cbf5e5e886b2844b458bc66322826..9d1909f08d432ccddb35a0784acf62aafdc74de4 100644 (file)
@@ -306,7 +306,7 @@ struct amdgpu_ring_funcs {
                                uint32_t oa_base, uint32_t oa_size);
        /* testing functions */
        int (*test_ring)(struct amdgpu_ring *ring);
-       int (*test_ib)(struct amdgpu_ring *ring);
+       int (*test_ib)(struct amdgpu_ring *ring, long timeout);
        /* insert NOP packets */
        void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count);
        /* pad the indirect buffer to the necessary number of dw */
@@ -2245,7 +2245,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
 #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
 #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
 #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
-#define amdgpu_ring_test_ib(r) (r)->funcs->test_ib((r))
+#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
 #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
 #define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r))
 #define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r))
index 428ebf3a43873445c8fda72e737d24034e7daa78..050062e07a448f6e96a251214b18c7ac08d3f031 100644 (file)
@@ -33,6 +33,8 @@
 #include "amdgpu.h"
 #include "atom.h"
 
+#define AMDGPU_IB_TEST_TIMEOUT msecs_to_jiffies(10)
+
 /*
  * IB
  * IBs (Indirect Buffers) and areas of GPU accessible memory where
@@ -286,7 +288,7 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
                if (!ring || !ring->ready)
                        continue;
 
-               r = amdgpu_ring_test_ib(ring);
+               r = amdgpu_ring_test_ib(ring, AMDGPU_IB_TEST_TIMEOUT);
                if (r) {
                        ring->ready = false;
 
index ef5342bd696899262d5d6b83dba1c0c17774f732..c3712498c2c272f94e9cedcc16aaceb8d4a6ded7 100644 (file)
@@ -1135,29 +1135,34 @@ void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring)
  *
  * Test if we can successfully execute an IB
  */
-int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring)
+int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
-       struct fence *fence = NULL;
-       int r;
+       struct fence *fence;
+       long r;
 
        r = amdgpu_uvd_get_create_msg(ring, 1, NULL);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get create msg (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r);
                goto error;
        }
 
        r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r);
                goto error;
        }
 
-       r = fence_wait(fence, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
-               goto error;
+       r = fence_wait_timeout(fence, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out.\n");
+               r = -ETIMEDOUT;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
+       } else {
+               DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
+               r = 0;
        }
-       DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
+
 error:
        fence_put(fence);
        return r;
index 224359e4d0b46f6efedb1b28b08520dfdb09013b..c850009602d176215b14dc2b173a0f6536a2860c 100644 (file)
@@ -37,6 +37,6 @@ void amdgpu_uvd_free_handles(struct amdgpu_device *adev,
 int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx);
 void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring);
 void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring);
-int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring);
+int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout);
 
 #endif
index 6b49d406daf6493d3017ab7bea1a0524007f6121..0afa73c82a9f0ba4eed915fe66594427a3d52109 100644 (file)
@@ -844,10 +844,10 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
  * @ring: the engine to test on
  *
  */
-int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
+int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct fence *fence = NULL;
-       int r;
+       long r;
 
        /* skip vce ring1 ib test for now, since it's not reliable */
        if (ring == &ring->adev->vce.ring[1])
@@ -855,21 +855,25 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
 
        r = amdgpu_vce_get_create_msg(ring, 1, NULL);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get create msg (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r);
                goto error;
        }
 
        r = amdgpu_vce_get_destroy_msg(ring, 1, true, &fence);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r);
                goto error;
        }
 
-       r = fence_wait(fence, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(fence, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out.\n");
+               r = -ETIMEDOUT;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
        } else {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        }
 error:
        fence_put(fence);
index fe84b80dbbeddb0be6638bba5a4ec2cbf06cdfd3..63f83d0d985c0fc981de361ee746865c079373b5 100644 (file)
@@ -39,7 +39,7 @@ void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib,
 void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
                                unsigned flags);
 int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring);
-int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring);
+int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout);
 void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring);
 void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring);
 
index c1eedc4665269063b654780f7e9c3665f95f61c5..ee6466912497b7cfc608db429e144d3a2dc3387e 100644 (file)
@@ -617,19 +617,19 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring)
  * Test a simple IB in the DMA ring (CIK).
  * Returns 0 on success, error on failure.
  */
-static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring)
+static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib ib;
        struct fence *f = NULL;
        unsigned index;
-       int r;
        u32 tmp = 0;
        u64 gpu_addr;
+       long r;
 
        r = amdgpu_wb_get(adev, &index);
        if (r) {
-               dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r);
+               dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r);
                return r;
        }
 
@@ -639,7 +639,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring)
        memset(&ib, 0, sizeof(ib));
        r = amdgpu_ib_get(adev, NULL, 256, &ib);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
                goto err0;
        }
 
@@ -654,14 +654,19 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring)
        if (r)
                goto err1;
 
-       r = fence_wait(f, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(f, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out\n");
+               r = -ETIMEDOUT;
+               goto err1;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
                goto err1;
        }
        tmp = le32_to_cpu(adev->wb.wb[index]);
        if (tmp == 0xDEADBEEF) {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        } else {
                DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
                r = -EINVAL;
index 1ac5ad01bf58df2764bc14642b0fcb2d809a115e..d869d058ef24f1324ff861db8318e5a3c12f8081 100644 (file)
@@ -2105,25 +2105,25 @@ static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
  * Provides a basic gfx ring test to verify that IBs are working.
  * Returns 0 on success, error on failure.
  */
-static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring)
+static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib ib;
        struct fence *f = NULL;
        uint32_t scratch;
        uint32_t tmp = 0;
-       int r;
+       long r;
 
        r = amdgpu_gfx_scratch_get(adev, &scratch);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get scratch reg (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r);
                return r;
        }
        WREG32(scratch, 0xCAFEDEAD);
        memset(&ib, 0, sizeof(ib));
        r = amdgpu_ib_get(adev, NULL, 256, &ib);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
                goto err1;
        }
        ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
@@ -2135,14 +2135,19 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring)
        if (r)
                goto err2;
 
-       r = fence_wait(f, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(f, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out\n");
+               r = -ETIMEDOUT;
+               goto err2;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
                goto err2;
        }
        tmp = RREG32(scratch);
        if (tmp == 0xDEADBEEF) {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        } else {
                DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
                          scratch, tmp);
index d97b962bc3de1a16c181ba5122eb02829890980f..bff8668e9e6d466e059d70f719c0a818235040dc 100644 (file)
@@ -787,25 +787,25 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring)
        return r;
 }
 
-static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring)
+static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib ib;
        struct fence *f = NULL;
        uint32_t scratch;
        uint32_t tmp = 0;
-       int r;
+       long r;
 
        r = amdgpu_gfx_scratch_get(adev, &scratch);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get scratch reg (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r);
                return r;
        }
        WREG32(scratch, 0xCAFEDEAD);
        memset(&ib, 0, sizeof(ib));
        r = amdgpu_ib_get(adev, NULL, 256, &ib);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
                goto err1;
        }
        ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
@@ -817,14 +817,19 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring)
        if (r)
                goto err2;
 
-       r = fence_wait(f, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(f, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out.\n");
+               r = -ETIMEDOUT;
+               goto err2;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
                goto err2;
        }
        tmp = RREG32(scratch);
        if (tmp == 0xDEADBEEF) {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        } else {
                DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
                          scratch, tmp);
index 9d43c6ca37e6436001c1c349295d191f7c5e4443..1351c7e834a21653a358ad3578dad91f60de9da9 100644 (file)
@@ -668,19 +668,19 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring)
  * Test a simple IB in the DMA ring (VI).
  * Returns 0 on success, error on failure.
  */
-static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring)
+static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib ib;
        struct fence *f = NULL;
        unsigned index;
-       int r;
        u32 tmp = 0;
        u64 gpu_addr;
+       long r;
 
        r = amdgpu_wb_get(adev, &index);
        if (r) {
-               dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r);
+               dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r);
                return r;
        }
 
@@ -690,7 +690,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring)
        memset(&ib, 0, sizeof(ib));
        r = amdgpu_ib_get(adev, NULL, 256, &ib);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
                goto err0;
        }
 
@@ -709,14 +709,19 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring)
        if (r)
                goto err1;
 
-       r = fence_wait(f, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(f, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out\n");
+               r = -ETIMEDOUT;
+               goto err1;
+       } else if (r) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
                goto err1;
        }
        tmp = le32_to_cpu(adev->wb.wb[index]);
        if (tmp == 0xDEADBEEF) {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        } else {
                DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
                r = -EINVAL;
index 4debd0dc47d868b22de8b5f14ddb4a8ed2325e57..653ce5ed55aef6641a83649cd1447a06fcf57437 100644 (file)
@@ -896,19 +896,19 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring)
  * Test a simple IB in the DMA ring (VI).
  * Returns 0 on success, error on failure.
  */
-static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring)
+static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib ib;
        struct fence *f = NULL;
        unsigned index;
-       int r;
        u32 tmp = 0;
        u64 gpu_addr;
+       long r;
 
        r = amdgpu_wb_get(adev, &index);
        if (r) {
-               dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r);
+               dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r);
                return r;
        }
 
@@ -918,7 +918,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring)
        memset(&ib, 0, sizeof(ib));
        r = amdgpu_ib_get(adev, NULL, 256, &ib);
        if (r) {
-               DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
                goto err0;
        }
 
@@ -937,14 +937,19 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring)
        if (r)
                goto err1;
 
-       r = fence_wait(f, false);
-       if (r) {
-               DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+       r = fence_wait_timeout(f, false, timeout);
+       if (r == 0) {
+               DRM_ERROR("amdgpu: IB test timed out\n");
+               r = -ETIMEDOUT;
+               goto err1;
+       } else if (r < 0) {
+               DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
                goto err1;
        }
        tmp = le32_to_cpu(adev->wb.wb[index]);
        if (tmp == 0xDEADBEEF) {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+               r = 0;
        } else {
                DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
                r = -EINVAL;