[Mesa-dev] [PATCH 03/10] radeonsi: add tests verifying that VM faults don't hang

Marek Olšák maraeo at gmail.com
Thu Mar 30 17:16:00 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

GFX9 hangs instead of writing VM faults to dmesg.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
 src/gallium/auxiliary/util/u_tests.c          |  9 ++++---
 src/gallium/auxiliary/util/u_tests.h          |  4 +++
 src/gallium/drivers/radeon/r600_pipe_common.c |  3 +++
 src/gallium/drivers/radeon/r600_pipe_common.h |  3 +++
 src/gallium/drivers/radeonsi/si_pipe.c        | 37 +++++++++++++++++++++++++++
 5 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
index 687e511..30eb589 100644
--- a/src/gallium/auxiliary/util/u_tests.c
+++ b/src/gallium/auxiliary/util/u_tests.c
@@ -390,35 +390,36 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
    /* Cleanup. */
    cso_destroy_context(cso);
    ctx->delete_vs_state(ctx, vs);
    ctx->delete_fs_state(ctx, fs);
    pipe_resource_reference(&cb, NULL);
 
    util_report_result_helper(pass, "%s: %s", __func__,
                              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;
    void *fs, *vs;
    bool pass = true;
    static const float zero[] = {0, 0, 0, 0};
 
    cso = cso_create_context(ctx, 0);
    cb = util_create_texture2d(ctx->screen, 256, 256,
                               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. */
    {
       static const char *text = /* I don't like ureg... */
             "FRAG\n"
             "DCL CONST[0]\n"
             "DCL OUT[0], COLOR\n"
 
             "MOV OUT[0], CONST[0]\n"
             "END\n";
@@ -495,17 +496,17 @@ null_fragment_shader(struct pipe_context *ctx)
  */
 void
 util_run_tests(struct pipe_screen *screen)
 {
    struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
 
    null_fragment_shader(ctx);
    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);
 
    puts("Done. Exiting..");
    exit(0);
 }
diff --git a/src/gallium/auxiliary/util/u_tests.h b/src/gallium/auxiliary/util/u_tests.h
index 106b0a0..5ac5d83 100644
--- a/src/gallium/auxiliary/util/u_tests.h
+++ b/src/gallium/auxiliary/util/u_tests.h
@@ -28,18 +28,22 @@
 #ifndef U_TESTS_H
 #define U_TESTS_H
 
 #include "pipe/p_compiler.h"
 
 #ifdef __cplusplus
 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
 }
 #endif
 
 #endif
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index c33b457..4607e71 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -702,20 +702,23 @@ static const struct debug_named_value common_debug_options[] = {
 	{ "tcs", DBG_TCS, "Print tessellation control shaders" },
 	{ "tes", DBG_TES, "Print tessellation evaluation shaders" },
 	{ "noir", DBG_NO_IR, "Don't print the LLVM IR"},
 	{ "notgsi", DBG_NO_TGSI, "Don't print the TGSI"},
 	{ "noasm", DBG_NO_ASM, "Don't print disassembled shaders"},
 	{ "preoptir", DBG_PREOPT_IR, "Print the LLVM IR before initial optimizations" },
 	{ "checkir", DBG_CHECK_IR, "Enable additional sanity checks on shader IR" },
 	{ "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" },
 	{ "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" },
 	/* GL uses the word INVALIDATE, gallium uses the word DISCARD */
 	{ "noinvalrange", DBG_NO_DISCARD_RANGE, "Disable handling of INVALIDATE_RANGE map flags" },
 	{ "no2d", DBG_NO_2D_TILING, "Disable 2D tiling" },
 	{ "notiling", DBG_NO_TILING, "Disable tiling" },
 	{ "switch_on_eop", DBG_SWITCH_ON_EOP, "Program WD/IA to switch on end-of-packet." },
 	{ "forcedma", DBG_FORCE_DMA, "Use asynchronous DMA for all operations when possible." },
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 6a52247..70b2836 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -100,20 +100,23 @@
 #define DBG_NO_WC		(1llu << 41)
 #define DBG_CHECK_VM		(1llu << 42)
 #define DBG_NO_DCC		(1llu << 43)
 #define DBG_NO_DCC_CLEAR	(1llu << 44)
 #define DBG_NO_RB_PLUS		(1llu << 45)
 #define DBG_SI_SCHED		(1llu << 46)
 #define DBG_MONOLITHIC_SHADERS	(1llu << 47)
 #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
 
 #define SI_MAX_VARIABLE_THREADS_PER_BLOCK 1024
 
 enum r600_coherency {
 	R600_COHERENCY_NONE, /* no cache flushes needed */
 	R600_COHERENCY_SHADER,
 	R600_COHERENCY_CB_META,
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index c32546f..3b5b111 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -22,20 +22,21 @@
  */
 
 #include "si_pipe.h"
 #include "si_public.h"
 #include "si_shader_internal.h"
 #include "sid.h"
 
 #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"
 
 #define SI_LLVM_DEFAULT_FEATURES \
 	"+DumpCode,+vgpr-spilling,-fp32-denormals,-xnack"
 
 /*
  * pipe_context
  */
 static void si_destroy_context(struct pipe_context *context)
@@ -769,20 +770,51 @@ static void si_handle_env_var_force_family(struct si_screen *sscreen)
 			/* Don't submit any IBs. */
 			setenv("RADEON_NOOP", "1", 1);
 			return;
 		}
 	}
 
 	fprintf(stderr, "radeonsi: Unknown family: %s\n", family);
 	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);
 	unsigned num_cpus, num_compiler_threads, i;
 
 	if (!sscreen) {
 		return NULL;
 	}
 
 	/* Set functions first. */
@@ -875,12 +907,17 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
 
 	for (i = 0; i < num_compiler_threads; i++)
 		sscreen->tm[i] = si_create_llvm_target_machine(sscreen);
 
 	/* Create the auxiliary context. This must be done last. */
 	sscreen->b.aux_context = sscreen->b.b.context_create(&sscreen->b.b, NULL, 0);
 
 	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;
 }
-- 
2.7.4



More information about the mesa-dev mailing list