winsys/radeon: remove cs_queue_empty
authorChristian König <christian.koenig@amd.com>
Sat, 21 Sep 2013 13:24:55 +0000 (15:24 +0200)
committerChristian König <christian.koenig@amd.com>
Sun, 22 Sep 2013 08:33:20 +0000 (10:33 +0200)
Waiting for an empty queue is nonsense and can lead to deadlocks if we have
multiple waiters or another thread that continuously sends down new commands.

Just post the cs to the queue and immediately wait for it to finish.

This is a candidate for the stable branch.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/winsys/radeon/drm/radeon_drm_cs.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.h

index 38a92095507dac11b9989570d740854e0cd475a9..d530011be662aa2b1898f8f3b8dcfb8f2b526232 100644 (file)
@@ -560,17 +560,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, ui
             break;
         }
 
-        if (cs->ws->thread && (flags & RADEON_FLUSH_ASYNC)) {
+        if (cs->ws->thread) {
             cs->flush_started = 1;
             radeon_drm_ws_queue_cs(cs->ws, cs);
+            if (!(flags & RADEON_FLUSH_ASYNC))
+                radeon_drm_cs_sync_flush(rcs);
         } else {
-            pipe_mutex_lock(cs->ws->cs_stack_lock);
-            if (cs->ws->thread) {
-                while (p_atomic_read(&cs->ws->ncs)) {
-                    pipe_condvar_wait(cs->ws->cs_queue_empty, cs->ws->cs_stack_lock);
-                }
-            }
-            pipe_mutex_unlock(cs->ws->cs_stack_lock);
             radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
         }
     } else {
index 0a3b932a3af86d79cb553dc159f9eea6913c6efd..27bf3483d7de2d9d6511aebe3f71cce5b8805002 100644 (file)
@@ -431,7 +431,6 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
         pipe_thread_wait(ws->thread);
     }
     pipe_semaphore_destroy(&ws->cs_queued);
-    pipe_condvar_destroy(ws->cs_queue_empty);
 
     pipe_mutex_destroy(ws->hyperz_owner_mutex);
     pipe_mutex_destroy(ws->cmask_owner_mutex);
@@ -567,9 +566,6 @@ next:
             }
             ws->cs_stack[p_atomic_read(&ws->ncs) - 1] = NULL;
             empty_stack = p_atomic_dec_zero(&ws->ncs);
-            if (empty_stack) {
-                pipe_condvar_signal(ws->cs_queue_empty);
-            }
             pipe_mutex_unlock(ws->cs_stack_lock);
 
             pipe_semaphore_signal(&cs->flush_completed);
@@ -585,7 +581,6 @@ next:
         ws->cs_stack[i] = NULL;
     }
     p_atomic_set(&ws->ncs, 0);
-    pipe_condvar_signal(ws->cs_queue_empty);
     pipe_mutex_unlock(ws->cs_stack_lock);
     return NULL;
 }
@@ -651,7 +646,6 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
 
     p_atomic_set(&ws->ncs, 0);
     pipe_semaphore_init(&ws->cs_queued, 0);
-    pipe_condvar_init(ws->cs_queue_empty);
     if (ws->num_cpus > 1 && debug_get_option_thread())
         ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);
 
index 682479ed52c98722a5192c082b0c4a2b539a26f9..ed9019486343155584c54e7a15c4c6f2d02ee30d 100644 (file)
@@ -67,11 +67,6 @@ struct radeon_drm_winsys {
     /* rings submission thread */
     pipe_mutex cs_stack_lock;
     pipe_semaphore cs_queued;
-    /* we cannot use semaphore for empty queue because maintaining an even
-     * number of call to semaphore_wait and semaphore_signal is, to say the
-     * least, tricky
-     */
-    pipe_condvar cs_queue_empty;
     pipe_thread thread;
     int kill_thread;
     int ncs;