[Mesa-dev] [PATCH] util/queue: don't hang at exit
Nicolai Hähnle
nhaehnle at gmail.com
Tue Apr 18 10:56:00 UTC 2017
On 18.04.2017 03:34, Rob Clark wrote:
> So atexit() is horrible and 4aea8fe7 is probably not a good idea. But
> add an extra layer of duct-tape to the problem. Otherwise we hit a
> situation where app using an atexit() handler that runs later than ours
> doesn't hang when trying to tear down a context.
>
> (gdb) bt
> #0 util_queue_killall_and_wait (queue=queue at entry=0x52bc80) at ../../../src/util/u_queue.c:264
> #1 0x0000007fb6c380c0 in atexit_handler () at ../../../src/util/u_queue.c:51
> #2 0x0000007fb7730e2c in __run_exit_handlers () from /lib64/libc.so.6
> #3 0x0000007fb7730e5c in exit () from /lib64/libc.so.6
> #4 0x0000007fb7ce17dc in piglit_report_result (result=PIGLIT_PASS) at /home/robclark/src/piglit/tests/util/piglit-util.c:267
> #5 0x0000007fb7ef99f8 in process_next_event (x11_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:139
> #6 0x0000007fb7ef9a90 in enter_event_loop (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:153
> #7 0x0000007fb7ef8e50 in run_test (gl_fw=0x432c20, argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:88
> #8 0x0000007fb7edb890 in piglit_gl_test_run (argc=1, argv=0x7ffffff588, config=0x7ffffff400) at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:203
> #9 0x0000000000401224 in main (argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/bugs/drawbuffer-modes.c:46
> (gdb) c
> Continuing.
> [Thread 0x7fb67580c0 (LWP 3471) exited]
> ^C
> Thread 1 "drawbuffer-mode" received signal SIGINT, Interrupt.
> 0x0000007fb72dda34 in pthread_cond_wait@@GLIBC_2.17 () from /lib64/libpthread.so.0
> (gdb) bt
> #0 0x0000007fb72dda34 in pthread_cond_wait@@GLIBC_2.17 () from /lib64/libpthread.so.0
> #1 0x0000007fb6c38304 in cnd_wait (mtx=0x5bdc90, cond=0x5bdcc0) at ../../../include/c11/threads_posix.h:159
> #2 util_queue_fence_wait (fence=0x5bdc90) at ../../../src/util/u_queue.c:106
> #3 0x0000007fb6daac70 in fd_batch_sync (batch=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:233
> #4 batch_reset (batch=batch at entry=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:183
> #5 0x0000007fb6daa5e0 in batch_flush (batch=0x5bdc70) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:290
> #6 fd_batch_flush (batch=0x5bdc70, sync=<optimized out>) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch.c:308
> #7 0x0000007fb6daba2c in fd_bc_flush (cache=0x461220, ctx=0x52b920) at ../../../../../src/gallium/drivers/freedreno/freedreno_batch_cache.c:141
> #8 0x0000007fb6dac954 in fd_context_flush (pctx=0x52b920, fence=0x0, flags=<optimized out>) at ../../../../../src/gallium/drivers/freedreno/freedreno_context.c:54
> #9 0x0000007fb6b43294 in st_glFlush (ctx=<optimized out>) at ../../../src/mesa/state_tracker/st_cb_flush.c:121
> #10 0x0000007fb69a84e8 in _mesa_make_current (newCtx=newCtx at entry=0x0, drawBuffer=drawBuffer at entry=0x0, readBuffer=readBuffer at entry=0x0) at ../../../src/mesa/main/context.c:1654
> #11 0x0000007fb6b7ca58 in st_api_make_current (stapi=<optimized out>, stctxi=0x0, stdrawi=0x0, streadi=0x0) at ../../../src/mesa/state_tracker/st_manager.c:827
> #12 0x0000007fb6cc87e8 in dri_unbind_context (cPriv=<optimized out>) at ../../../../../src/gallium/state_trackers/dri/dri_context.c:217
> #13 0x0000007fb6cc80b0 in driUnbindContext (pcp=0x5271e0) at ../../../../../../src/mesa/drivers/dri/common/dri_util.c:591
> #14 0x0000007fb7d1da08 in MakeContextCurrent (dpy=0x433380, draw=0, read=0, gc_user=0x0) at ../../../src/glx/glxcurrent.c:214
> #15 0x0000007fb7a8d5e0 in glx_platform_make_current () from /lib64/libwaffle-1.so.0
> #16 0x0000007fb7a894e4 in waffle_make_current () from /lib64/libwaffle-1.so.0
> #17 0x0000007fb7ef8c60 in piglit_wfl_framework_teardown (wfl_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_wfl_framework.c:628
> #18 0x0000007fb7ef939c in piglit_winsys_framework_teardown (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:238
> #19 0x0000007fb7ef9c30 in destroy (gl_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:212
> #20 0x0000007fb7edb7c4 in destroy () at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:184
> #21 0x0000007fb7730e2c in __run_exit_handlers () from /lib64/libc.so.6
> #22 0x0000007fb7730e5c in exit () from /lib64/libc.so.6
> #23 0x0000007fb7ce17dc in piglit_report_result (result=PIGLIT_PASS) at /home/robclark/src/piglit/tests/util/piglit-util.c:267
> #24 0x0000007fb7ef99f8 in process_next_event (x11_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:139
> #25 0x0000007fb7ef9a90 in enter_event_loop (winsys_fw=0x432c20) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_x11_framework.c:153
> #26 0x0000007fb7ef8e50 in run_test (gl_fw=0x432c20, argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/util/piglit-framework-gl/piglit_winsys_framework.c:88
> #27 0x0000007fb7edb890 in piglit_gl_test_run (argc=1, argv=0x7ffffff588, config=0x7ffffff400) at /home/robclark/src/piglit/tests/util/piglit-framework-gl.c:203
> #28 0x0000000000401224 in main (argc=1, argv=0x7ffffff588) at /home/robclark/src/piglit/tests/bugs/drawbuffer-modes.c:46
> (gdb) r
OMGWTF. What a hilarious mess of atexit code running at various times.
> Fixes: 4aea8fe7 ("gallium/u_queue: fix random crashes when the app calls exit()")
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
> src/util/u_queue.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/src/util/u_queue.c b/src/util/u_queue.c
> index 0519667..8db09b0 100644
> --- a/src/util/u_queue.c
> +++ b/src/util/u_queue.c
> @@ -298,9 +298,18 @@ util_queue_add_job(struct util_queue *queue,
> struct util_queue_job *ptr;
>
> assert(fence->signalled);
> - fence->signalled = false;
>
> mtx_lock(&queue->lock);
> + if (queue->kill_threads) {
> + mtx_unlock(&queue->lock);
> + /* well no good option here, but any leaks will be
> + * short-lived as things are shutting down..
> + */
I think this comment should explicitly say something like "this should
only happen when an application makes driver calls from an atexit handler".
Since that's a pretty messed up thing to do, even if piglit does it, I
think this workaround is fine.
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> + return;
> + }
> +
> + fence->signalled = false;
> +
> assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs);
>
> /* if the queue is full, wait until there is space */
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list