glx-multithread-clearbuffer: new test reproducing amdgpu CS thread deadlock

Submitted by Marek Olšák on July 14, 2017, 3:54 p.m.

Details

Message ID 1500047653-8120-1-git-send-email-maraeo@gmail.com
State New
Headers show
Series "glx-multithread-clearbuffer: new test reproducing amdgpu CS thread deadlock" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Marek Olšák July 14, 2017, 3:54 p.m.
From: Marek Olšák <marek.olsak@amd.com>

---
 tests/all.py                            |   1 +
 tests/glx/CMakeLists.gl.txt             |   2 +
 tests/glx/glx-multithread-clearbuffer.c | 100 ++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 tests/glx/glx-multithread-clearbuffer.c

Patch hide | download patch | download mbox

diff --git a/tests/all.py b/tests/all.py
index e08cee9..ae55425 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -659,20 +659,21 @@  with profile.test_list.group_manager(
     g(['glx-close-display'], run_concurrent=False)
     g(['glx-fbconfig-sanity'], run_concurrent=False)
     g(['glx-fbconfig-compliance'], run_concurrent=False)
     g(['glx-fbconfig-bad'], run_concurrent=False)
     g(['glx-fbo-binding'], run_concurrent=False)
     g(['glx-multi-context-front'], run_concurrent=False)
     g(['glx-multi-context-ib-1'], run_concurrent=False)
     g(['glx-multi-context-single-window'], run_concurrent=False)
     g(['glx-multi-window-single-context'], run_concurrent=False)
     g(['glx-multithread'], run_concurrent=False)
+    g(['glx-multithread-clearbuffer'], run_concurrent=False)
     g(['glx-multithread-texture'], run_concurrent=False)
     g(['glx-multithread-makecurrent-1'], run_concurrent=False)
     g(['glx-multithread-makecurrent-2'], run_concurrent=False)
     g(['glx-multithread-makecurrent-3'], run_concurrent=False)
     g(['glx-multithread-makecurrent-4'], run_concurrent=False)
     g(['glx-multithread-shader-compile'], run_concurrent=False)
     g(['glx-shader-sharing'], run_concurrent=False)
     g(['glx-swap-exchange'], run_concurrent=False)
     g(['glx-swap-event', '--event'], 'glx-swap-event_event',
       run_concurrent=False)
diff --git a/tests/glx/CMakeLists.gl.txt b/tests/glx/CMakeLists.gl.txt
index cf036f5..3d3b4da 100644
--- a/tests/glx/CMakeLists.gl.txt
+++ b/tests/glx/CMakeLists.gl.txt
@@ -31,20 +31,22 @@  IF(PIGLIT_BUILD_GLX_TESTS)
 	piglit_add_executable (glx-destroycontext-2 glx-destroycontext-2.c)
 	piglit_add_executable (glx-dont-care-mask glx-dont-care-mask.c)
 	piglit_add_executable (glx-multi-context-front glx-multi-context-front.c)
 	piglit_add_executable (glx-multi-context-ib-1 glx-multi-context-ib-1.c)
 	piglit_add_executable (glx-multi-context-single-window glx-multi-context-single-window.c)
 	piglit_add_executable (glx-multi-window-single-context glx-multi-window-single-context.c)
 	piglit_add_executable (glx-multithread glx-multithread.c)
 	target_link_libraries(glx-multithread pthread)
 	piglit_add_executable (glx-context-flush-control glx-context-flush-control.c)
 	target_link_libraries (glx-context-flush-control pthread)
+	piglit_add_executable (glx-multithread-clearbuffer glx-multithread-clearbuffer.c)
+	target_link_libraries(glx-multithread-clearbuffer pthread)
 	piglit_add_executable (glx-multithread-texture glx-multithread-texture.c)
 	target_link_libraries(glx-multithread-texture pthread)
 	piglit_add_executable (glx-multithread-makecurrent-1 glx-multithread-makecurrent-1.c)
 	target_link_libraries(glx-multithread-makecurrent-1 pthread)
 	piglit_add_executable (glx-multithread-makecurrent-2 glx-multithread-makecurrent-2.c)
 	target_link_libraries(glx-multithread-makecurrent-2 pthread)
 	piglit_add_executable (glx-multithread-makecurrent-3 glx-multithread-makecurrent-3.c)
 	target_link_libraries(glx-multithread-makecurrent-3 pthread)
 	piglit_add_executable (glx-multithread-makecurrent-4 glx-multithread-makecurrent-4.c)
 	target_link_libraries(glx-multithread-makecurrent-4 pthread)
diff --git a/tests/glx/glx-multithread-clearbuffer.c b/tests/glx/glx-multithread-clearbuffer.c
new file mode 100644
index 0000000..577fde8
--- /dev/null
+++ b/tests/glx/glx-multithread-clearbuffer.c
@@ -0,0 +1,100 @@ 
+/*
+ * Copyright (c) 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Create multiple GLX contexts and concurrently create, clear, and destroy
+ * buffers and flush the context.
+ *
+ * This reproduces a deadlock with the radeonsi command submission thread
+ * queue.
+ */
+
+#include "piglit-util-gl.h"
+#include "piglit-glx-util.h"
+#include "pthread.h"
+
+static pthread_mutex_t mutex;
+static bool dispatch_ready = false;
+
+static void *
+thread_func(void *arg)
+{
+	Display *dpy;
+	XVisualInfo *visinfo;
+	Window win;
+	unsigned i;
+
+	dpy = piglit_get_glx_display();
+	visinfo = piglit_get_glx_visual(dpy);
+	win = piglit_get_glx_window(dpy, visinfo);
+
+	GLXContext ctx;
+
+	ctx = piglit_get_glx_context(dpy, visinfo);
+	glXMakeCurrent(dpy, win, ctx);
+
+	pthread_mutex_lock(&mutex);
+	if (!dispatch_ready) {
+		piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
+		dispatch_ready = true;
+		piglit_require_gl_version(30);
+		piglit_require_extension("GL_ARB_clear_buffer_object");
+	}
+	pthread_mutex_unlock(&mutex);
+
+	for (i = 0; i < 1000; ++i) {
+		GLuint buf;
+		glGenBuffers(1, &buf);
+		glBindBuffer(GL_ARRAY_BUFFER, buf);
+		glBufferData(GL_ARRAY_BUFFER, 512, NULL, GL_STATIC_DRAW);
+		glClearBufferSubData(GL_ARRAY_BUFFER, GL_R32UI, 0, 512, GL_RED_INTEGER, GL_UNSIGNED_INT, &buf);
+		glDeleteBuffers(1, &buf);
+		glFlush();
+		piglit_check_gl_error(0);
+	}
+
+	glXDestroyContext(dpy, ctx);
+	return NULL;
+}
+
+int
+main(int argc, char **argv)
+{
+	/* Need at least 16 contexts to congest the thread queue. */
+	pthread_t thread[16];
+
+	XInitThreads();
+
+	pthread_mutex_init(&mutex, NULL);
+
+	for (int i = 0; i < ARRAY_SIZE(thread); i++)
+		pthread_create(&thread[i], NULL, thread_func, NULL);
+
+	for (int i = 0; i < ARRAY_SIZE(thread); i++)
+		pthread_join(thread[i], NULL);
+
+	pthread_mutex_destroy(&mutex);
+
+	piglit_report_result(PIGLIT_PASS);
+	return 0;
+}

Comments

Reviewed-by: Brian Paul <brianp@vmware.com>



On 07/14/2017 09:54 AM, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak@amd.com>
>
> ---
>   tests/all.py                            |   1 +
>   tests/glx/CMakeLists.gl.txt             |   2 +
>   tests/glx/glx-multithread-clearbuffer.c | 100 ++++++++++++++++++++++++++++++++
>   3 files changed, 103 insertions(+)
>   create mode 100644 tests/glx/glx-multithread-clearbuffer.c
>
> diff --git a/tests/all.py b/tests/all.py
> index e08cee9..ae55425 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -659,20 +659,21 @@ with profile.test_list.group_manager(
>       g(['glx-close-display'], run_concurrent=False)
>       g(['glx-fbconfig-sanity'], run_concurrent=False)
>       g(['glx-fbconfig-compliance'], run_concurrent=False)
>       g(['glx-fbconfig-bad'], run_concurrent=False)
>       g(['glx-fbo-binding'], run_concurrent=False)
>       g(['glx-multi-context-front'], run_concurrent=False)
>       g(['glx-multi-context-ib-1'], run_concurrent=False)
>       g(['glx-multi-context-single-window'], run_concurrent=False)
>       g(['glx-multi-window-single-context'], run_concurrent=False)
>       g(['glx-multithread'], run_concurrent=False)
> +    g(['glx-multithread-clearbuffer'], run_concurrent=False)
>       g(['glx-multithread-texture'], run_concurrent=False)
>       g(['glx-multithread-makecurrent-1'], run_concurrent=False)
>       g(['glx-multithread-makecurrent-2'], run_concurrent=False)
>       g(['glx-multithread-makecurrent-3'], run_concurrent=False)
>       g(['glx-multithread-makecurrent-4'], run_concurrent=False)
>       g(['glx-multithread-shader-compile'], run_concurrent=False)
>       g(['glx-shader-sharing'], run_concurrent=False)
>       g(['glx-swap-exchange'], run_concurrent=False)
>       g(['glx-swap-event', '--event'], 'glx-swap-event_event',
>         run_concurrent=False)
> diff --git a/tests/glx/CMakeLists.gl.txt b/tests/glx/CMakeLists.gl.txt
> index cf036f5..3d3b4da 100644
> --- a/tests/glx/CMakeLists.gl.txt
> +++ b/tests/glx/CMakeLists.gl.txt
> @@ -31,20 +31,22 @@ IF(PIGLIT_BUILD_GLX_TESTS)
>   	piglit_add_executable (glx-destroycontext-2 glx-destroycontext-2.c)
>   	piglit_add_executable (glx-dont-care-mask glx-dont-care-mask.c)
>   	piglit_add_executable (glx-multi-context-front glx-multi-context-front.c)
>   	piglit_add_executable (glx-multi-context-ib-1 glx-multi-context-ib-1.c)
>   	piglit_add_executable (glx-multi-context-single-window glx-multi-context-single-window.c)
>   	piglit_add_executable (glx-multi-window-single-context glx-multi-window-single-context.c)
>   	piglit_add_executable (glx-multithread glx-multithread.c)
>   	target_link_libraries(glx-multithread pthread)
>   	piglit_add_executable (glx-context-flush-control glx-context-flush-control.c)
>   	target_link_libraries (glx-context-flush-control pthread)
> +	piglit_add_executable (glx-multithread-clearbuffer glx-multithread-clearbuffer.c)
> +	target_link_libraries(glx-multithread-clearbuffer pthread)
>   	piglit_add_executable (glx-multithread-texture glx-multithread-texture.c)
>   	target_link_libraries(glx-multithread-texture pthread)
>   	piglit_add_executable (glx-multithread-makecurrent-1 glx-multithread-makecurrent-1.c)
>   	target_link_libraries(glx-multithread-makecurrent-1 pthread)
>   	piglit_add_executable (glx-multithread-makecurrent-2 glx-multithread-makecurrent-2.c)
>   	target_link_libraries(glx-multithread-makecurrent-2 pthread)
>   	piglit_add_executable (glx-multithread-makecurrent-3 glx-multithread-makecurrent-3.c)
>   	target_link_libraries(glx-multithread-makecurrent-3 pthread)
>   	piglit_add_executable (glx-multithread-makecurrent-4 glx-multithread-makecurrent-4.c)
>   	target_link_libraries(glx-multithread-makecurrent-4 pthread)
> diff --git a/tests/glx/glx-multithread-clearbuffer.c b/tests/glx/glx-multithread-clearbuffer.c
> new file mode 100644
> index 0000000..577fde8
> --- /dev/null
> +++ b/tests/glx/glx-multithread-clearbuffer.c
> @@ -0,0 +1,100 @@
> +/*
> + * Copyright (c) 2017 Advanced Micro Devices, Inc.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +/**
> + * Create multiple GLX contexts and concurrently create, clear, and destroy
> + * buffers and flush the context.
> + *
> + * This reproduces a deadlock with the radeonsi command submission thread
> + * queue.
> + */
> +
> +#include "piglit-util-gl.h"
> +#include "piglit-glx-util.h"
> +#include "pthread.h"
> +
> +static pthread_mutex_t mutex;
> +static bool dispatch_ready = false;
> +
> +static void *
> +thread_func(void *arg)
> +{
> +	Display *dpy;
> +	XVisualInfo *visinfo;
> +	Window win;
> +	unsigned i;
> +
> +	dpy = piglit_get_glx_display();
> +	visinfo = piglit_get_glx_visual(dpy);
> +	win = piglit_get_glx_window(dpy, visinfo);
> +
> +	GLXContext ctx;
> +
> +	ctx = piglit_get_glx_context(dpy, visinfo);
> +	glXMakeCurrent(dpy, win, ctx);
> +
> +	pthread_mutex_lock(&mutex);
> +	if (!dispatch_ready) {
> +		piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
> +		dispatch_ready = true;
> +		piglit_require_gl_version(30);
> +		piglit_require_extension("GL_ARB_clear_buffer_object");
> +	}
> +	pthread_mutex_unlock(&mutex);
> +
> +	for (i = 0; i < 1000; ++i) {
> +		GLuint buf;
> +		glGenBuffers(1, &buf);
> +		glBindBuffer(GL_ARRAY_BUFFER, buf);
> +		glBufferData(GL_ARRAY_BUFFER, 512, NULL, GL_STATIC_DRAW);
> +		glClearBufferSubData(GL_ARRAY_BUFFER, GL_R32UI, 0, 512, GL_RED_INTEGER, GL_UNSIGNED_INT, &buf);
> +		glDeleteBuffers(1, &buf);
> +		glFlush();
> +		piglit_check_gl_error(0);
> +	}
> +
> +	glXDestroyContext(dpy, ctx);
> +	return NULL;
> +}
> +
> +int
> +main(int argc, char **argv)
> +{
> +	/* Need at least 16 contexts to congest the thread queue. */
> +	pthread_t thread[16];
> +
> +	XInitThreads();
> +
> +	pthread_mutex_init(&mutex, NULL);
> +
> +	for (int i = 0; i < ARRAY_SIZE(thread); i++)
> +		pthread_create(&thread[i], NULL, thread_func, NULL);
> +
> +	for (int i = 0; i < ARRAY_SIZE(thread); i++)
> +		pthread_join(thread[i], NULL);
> +
> +	pthread_mutex_destroy(&mutex);
> +
> +	piglit_report_result(PIGLIT_PASS);
> +	return 0;
> +}
>