radeonsi: add tests verifying that VM faults don't hang
authorMarek Olšák <marek.olsak@amd.com>
Mon, 27 Mar 2017 14:53:19 +0000 (16:53 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 31 Mar 2017 19:41:57 +0000 (21:41 +0200)
GFX9 hangs instead of writing VM faults to dmesg.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/auxiliary/util/u_tests.c
src/gallium/auxiliary/util/u_tests.h
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeonsi/si_pipe.c

index 687e5118d7c300d347757fa07070d73242dc0d29..30eb589b06fcf960d56dffb2956fb246dc3056b4 100644 (file)
@@ -397,8 +397,9 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
                              tgsi_texture_names[tgsi_tex_target]);
 }
 
-static void
-null_constant_buffer(struct pipe_context *ctx)
+void
+util_test_constant_buffer(struct pipe_context *ctx,
+                          struct pipe_resource *constbuf)
 {
    struct cso_context *cso;
    struct pipe_resource *cb;
@@ -411,7 +412,7 @@ null_constant_buffer(struct pipe_context *ctx)
                               PIPE_FORMAT_R8G8B8A8_UNORM);
    util_set_common_states_and_clear(cso, ctx, cb);
 
-   ctx->set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, NULL);
+   pipe_set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, constbuf);
 
    /* Fragment shader. */
    {
@@ -502,7 +503,7 @@ util_run_tests(struct pipe_screen *screen)
    tgsi_vs_window_space_position(ctx);
    null_sampler_view(ctx, TGSI_TEXTURE_2D);
    null_sampler_view(ctx, TGSI_TEXTURE_BUFFER);
-   null_constant_buffer(ctx);
+   util_test_constant_buffer(ctx, NULL);
 
    ctx->destroy(ctx);
 
index 106b0a0a9386f8f15164b7182081aa6d6d42ca0f..5ac5d8371dfc8748b68b746fdf171972df9c9639 100644 (file)
@@ -35,7 +35,11 @@ extern "C" {
 #endif
 
 struct pipe_screen;
+struct pipe_context;
+struct pipe_resource;
 
+void util_test_constant_buffer(struct pipe_context *ctx,
+                               struct pipe_resource *constbuf);
 void util_run_tests(struct pipe_screen *screen);
 
 #ifdef __cplusplus
index c33b457641652c68aa61674dc8c5541af64071f3..4607e7197f3bdd085f74b806e7335dcde9c9d0cc 100644 (file)
@@ -709,6 +709,9 @@ static const struct debug_named_value common_debug_options[] = {
        { "nooptvariant", DBG_NO_OPT_VARIANT, "Disable compiling optimized shader variants." },
 
        { "testdma", DBG_TEST_DMA, "Invoke SDMA tests and exit." },
+       { "testvmfaultcp", DBG_TEST_VMFAULT_CP, "Invoke a CP VM fault test and exit." },
+       { "testvmfaultsdma", DBG_TEST_VMFAULT_SDMA, "Invoke a SDMA VM fault test and exit." },
+       { "testvmfaultshader", DBG_TEST_VMFAULT_SHADER, "Invoke a shader VM fault test and exit." },
 
        /* features */
        { "nodma", DBG_NO_ASYNC_DMA, "Disable asynchronous DMA" },
index 6a52247d45879760d163f94b58a5e7312f504638..70b28365da42b8c64828b86ed239be1c8e360d66 100644 (file)
 #define DBG_NO_CE              (1llu << 48)
 #define DBG_UNSAFE_MATH                (1llu << 49)
 #define DBG_NO_DCC_FB          (1llu << 50)
+#define DBG_TEST_VMFAULT_CP    (1llu << 51)
+#define DBG_TEST_VMFAULT_SDMA  (1llu << 52)
+#define DBG_TEST_VMFAULT_SHADER        (1llu << 53)
 
 #define R600_MAP_BUFFER_ALIGNMENT 64
 #define R600_MAX_VIEWPORTS        16
index 1ac5fe5c35156531ef58bc514b638a9c7883f8ff..19c9a1710f7bef4d193f5e42b9780b4f7faa321f 100644 (file)
@@ -29,6 +29,7 @@
 #include "radeon/radeon_uvd.h"
 #include "util/u_memory.h"
 #include "util/u_suballoc.h"
+#include "util/u_tests.h"
 #include "vl/vl_decoder.h"
 #include "../ddebug/dd_util.h"
 
@@ -780,6 +781,37 @@ static void si_handle_env_var_force_family(struct si_screen *sscreen)
        exit(1);
 }
 
+static void si_test_vmfault(struct si_screen *sscreen)
+{
+       struct pipe_context *ctx = sscreen->b.aux_context;
+       struct si_context *sctx = (struct si_context *)ctx;
+       struct pipe_resource *buf =
+               pipe_buffer_create(&sscreen->b.b, 0, PIPE_USAGE_DEFAULT, 64);
+
+       if (!buf) {
+               puts("Buffer allocation failed.");
+               exit(1);
+       }
+
+       r600_resource(buf)->gpu_address = 0; /* cause a VM fault */
+
+       if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_CP) {
+               si_copy_buffer(sctx, buf, buf, 0, 4, 4, 0);
+               ctx->flush(ctx, NULL, 0);
+               puts("VM fault test: CP - done.");
+       }
+       if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_SDMA) {
+               sctx->b.dma_clear_buffer(ctx, buf, 0, 4, 0);
+               ctx->flush(ctx, NULL, 0);
+               puts("VM fault test: SDMA - done.");
+       }
+       if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_SHADER) {
+               util_test_constant_buffer(ctx, buf);
+               puts("VM fault test: Shader - done.");
+       }
+       exit(0);
+}
+
 struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
 {
        struct si_screen *sscreen = CALLOC_STRUCT(si_screen);
@@ -886,5 +918,10 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
        if (sscreen->b.debug_flags & DBG_TEST_DMA)
                r600_test_dma(&sscreen->b);
 
+       if (sscreen->b.debug_flags & (DBG_TEST_VMFAULT_CP |
+                                     DBG_TEST_VMFAULT_SDMA |
+                                     DBG_TEST_VMFAULT_SHADER))
+               si_test_vmfault(sscreen);
+
        return &sscreen->b.b;
 }