[Mesa-dev] [PATCH 2/2] winsys/radeon: use the common job queue for multithreaded command submission

Marek Olšák maraeo at gmail.com
Mon Jun 13 17:34:55 UTC 2016


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

---
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c     | 22 ++++----
 src/gallium/winsys/radeon/drm/radeon_drm_cs.h     |  4 +-
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 63 ++---------------------
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 12 ++---
 4 files changed, 19 insertions(+), 82 deletions(-)

diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index e9ab53d..d735612 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -177,7 +177,7 @@ radeon_drm_cs_create(struct radeon_winsys_ctx *ctx,
     if (!cs) {
         return NULL;
     }
-    pipe_semaphore_init(&cs->flush_completed, 1);
+    util_queue_event_init(&cs->flush_completed);
 
     cs->ws = ws;
     cs->flush_cs = flush;
@@ -427,8 +427,9 @@ static unsigned radeon_drm_cs_get_buffer_list(struct radeon_winsys_cs *rcs,
     return cs->csc->crelocs;
 }
 
-void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_drm_cs *cs, struct radeon_cs_context *csc)
+void radeon_drm_cs_emit_ioctl_oneshot(void *job)
 {
+    struct radeon_cs_context *csc = ((struct radeon_drm_cs*)job)->cst;
     unsigned i;
     int r;
 
@@ -463,11 +464,9 @@ void radeon_drm_cs_sync_flush(struct radeon_winsys_cs *rcs)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
 
-    /* Wait for any pending ioctl to complete. */
-    if (cs->ws->thread) {
-        pipe_semaphore_wait(&cs->flush_completed);
-        pipe_semaphore_signal(&cs->flush_completed);
-    }
+    /* Wait for any pending ioctl of this CS to complete. */
+    if (util_queue_is_initialized(&cs->ws->cs_queue))
+        util_queue_job_wait(&cs->flush_completed);
 }
 
 DEBUG_GET_ONCE_BOOL_OPTION(noop, "RADEON_NOOP", FALSE)
@@ -586,13 +585,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
             break;
         }
 
-        if (cs->ws->thread) {
-            pipe_semaphore_wait(&cs->flush_completed);
-            radeon_drm_ws_queue_cs(cs->ws, cs);
+        if (util_queue_is_initialized(&cs->ws->cs_queue)) {
+            util_queue_add_job(&cs->ws->cs_queue, cs, &cs->flush_completed);
             if (!(flags & RADEON_FLUSH_ASYNC))
                 radeon_drm_cs_sync_flush(rcs);
         } else {
-            radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
+            radeon_drm_cs_emit_ioctl_oneshot(cs);
         }
     } else {
         radeon_cs_context_cleanup(cs->cst);
@@ -610,7 +608,7 @@ static void radeon_drm_cs_destroy(struct radeon_winsys_cs *rcs)
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
 
     radeon_drm_cs_sync_flush(rcs);
-    pipe_semaphore_destroy(&cs->flush_completed);
+    util_queue_event_destroy(&cs->flush_completed);
     radeon_cs_context_cleanup(&cs->csc1);
     radeon_cs_context_cleanup(&cs->csc2);
     p_atomic_dec(&cs->ws->num_cs);
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index 8056e72..5a0b56b 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -78,7 +78,7 @@ struct radeon_drm_cs {
     void (*flush_cs)(void *ctx, unsigned flags, struct pipe_fence_handle **fence);
     void *flush_data;
 
-    pipe_semaphore flush_completed;
+    struct util_queue_event flush_completed;
 };
 
 int radeon_lookup_buffer(struct radeon_cs_context *csc, struct radeon_bo *bo);
@@ -122,6 +122,6 @@ radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo)
 
 void radeon_drm_cs_sync_flush(struct radeon_winsys_cs *rcs);
 void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws);
-void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_drm_cs *cs, struct radeon_cs_context *csc);
+void radeon_drm_cs_emit_ioctl_oneshot(void *job);
 
 #endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 5c85c8f..1f296f4 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -534,16 +534,11 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
 
-    if (ws->thread) {
-        ws->kill_thread = 1;
-        pipe_semaphore_signal(&ws->cs_queued);
-        pipe_thread_wait(ws->thread);
-    }
-    pipe_semaphore_destroy(&ws->cs_queued);
+    if (util_queue_is_initialized(&ws->cs_queue))
+        util_queue_destroy(&ws->cs_queue);
 
     pipe_mutex_destroy(ws->hyperz_owner_mutex);
     pipe_mutex_destroy(ws->cmask_owner_mutex);
-    pipe_mutex_destroy(ws->cs_stack_lock);
 
     pb_cache_deinit(&ws->bo_cache);
 
@@ -686,55 +681,7 @@ static int compare_fd(void *key1, void *key2)
            stat1.st_rdev != stat2.st_rdev;
 }
 
-void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs)
-{
-retry:
-    pipe_mutex_lock(ws->cs_stack_lock);
-    if (ws->ncs >= RING_LAST) {
-        /* no room left for a flush */
-        pipe_mutex_unlock(ws->cs_stack_lock);
-        goto retry;
-    }
-    ws->cs_stack[ws->ncs++] = cs;
-    pipe_mutex_unlock(ws->cs_stack_lock);
-    pipe_semaphore_signal(&ws->cs_queued);
-}
-
-static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
-{
-    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)param;
-    struct radeon_drm_cs *cs;
-    unsigned i;
-
-    while (1) {
-        pipe_semaphore_wait(&ws->cs_queued);
-        if (ws->kill_thread)
-            break;
-
-        pipe_mutex_lock(ws->cs_stack_lock);
-        cs = ws->cs_stack[0];
-        for (i = 1; i < ws->ncs; i++)
-            ws->cs_stack[i - 1] = ws->cs_stack[i];
-        ws->cs_stack[--ws->ncs] = NULL;
-        pipe_mutex_unlock(ws->cs_stack_lock);
-
-        if (cs) {
-            radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
-            pipe_semaphore_signal(&cs->flush_completed);
-        }
-    }
-    pipe_mutex_lock(ws->cs_stack_lock);
-    for (i = 0; i < ws->ncs; i++) {
-        pipe_semaphore_signal(&ws->cs_stack[i]->flush_completed);
-        ws->cs_stack[i] = NULL;
-    }
-    ws->ncs = 0;
-    pipe_mutex_unlock(ws->cs_stack_lock);
-    return 0;
-}
-
 DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE)
-static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param);
 
 static bool radeon_winsys_unref(struct radeon_winsys *ws)
 {
@@ -823,7 +770,6 @@ radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
 
     pipe_mutex_init(ws->hyperz_owner_mutex);
     pipe_mutex_init(ws->cmask_owner_mutex);
-    pipe_mutex_init(ws->cs_stack_lock);
 
     ws->bo_names = util_hash_table_create(handle_hash, handle_compare);
     ws->bo_handles = util_hash_table_create(handle_hash, handle_compare);
@@ -836,10 +782,9 @@ radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
     /* TTM aligns the BO size to the CPU page size */
     ws->info.gart_page_size = sysconf(_SC_PAGESIZE);
 
-    ws->ncs = 0;
-    pipe_semaphore_init(&ws->cs_queued, 0);
     if (ws->num_cpus > 1 && debug_get_option_thread())
-        ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);
+        util_queue_init(&ws->cs_queue,
+                        radeon_drm_cs_emit_ioctl_oneshot);
 
     /* Create the screen at the end. The winsys must be initialized
      * completely.
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 80de561..c429aba 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -32,7 +32,7 @@
 
 #include "gallium/drivers/radeon/radeon_winsys.h"
 #include "pipebuffer/pb_cache.h"
-#include "os/os_thread.h"
+#include "util/u_queue.h"
 #include "util/list.h"
 #include <radeon_drm.h>
 
@@ -101,13 +101,8 @@ struct radeon_drm_winsys {
     struct radeon_drm_cs *cmask_owner;
     pipe_mutex cmask_owner_mutex;
 
-    /* rings submission thread */
-    pipe_mutex cs_stack_lock;
-    pipe_semaphore cs_queued;
-    pipe_thread thread;
-    int kill_thread;
-    int ncs;
-    struct radeon_drm_cs *cs_stack[RING_LAST];
+    /* multithreaded command submission */
+    struct util_queue cs_queue;
 };
 
 static inline struct radeon_drm_winsys *
@@ -116,7 +111,6 @@ radeon_drm_winsys(struct radeon_winsys *base)
     return (struct radeon_drm_winsys*)base;
 }
 
-void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs);
 void radeon_surface_init_functions(struct radeon_drm_winsys *ws);
 
 #endif
-- 
2.7.4



More information about the mesa-dev mailing list