Mesa (master): clover/queue: Flush automatically if applications do not flush themselves

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 10 19:35:14 UTC 2020


Module: Mesa
Branch: master
Commit: 20a3ec2d771d7f8942018b714c64925a870a2062
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=20a3ec2d771d7f8942018b714c64925a870a2062

Author: Karol Herbst <kherbst at redhat.com>
Date:   Wed Nov  4 23:05:51 2020 +0100

clover/queue: Flush automatically if applications do not flush themselves

With the image_read_write OpenCL CTS we can get a stack overflow handling
all the events as the application itself never flushes.

We need to address this in two ways:
1. flush the queue once an abritary amoung of events piled up.
2. Drop event deps once they get a fence assigned.

Signed-off-by: Karol Herbst <kherbst at redhat.com>
Reviewed-by: Francisco Jerez <currojerez at riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7460>

---

 src/gallium/frontends/clover/core/event.cpp |  7 ++++++-
 src/gallium/frontends/clover/core/event.hpp |  2 +-
 src/gallium/frontends/clover/core/queue.cpp | 13 ++++++++++++-
 src/gallium/frontends/clover/core/queue.hpp |  2 ++
 4 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/gallium/frontends/clover/core/event.cpp b/src/gallium/frontends/clover/core/event.cpp
index 3d313ce8969..823b243b1a5 100644
--- a/src/gallium/frontends/clover/core/event.cpp
+++ b/src/gallium/frontends/clover/core/event.cpp
@@ -118,7 +118,10 @@ event::wait_signalled() const {
 
 void
 event::wait() const {
-   for (event &ev : deps)
+   std::vector<intrusive_ref<event>> evs;
+   std::swap(deps, evs);
+
+   for (event &ev : evs)
       ev.wait();
 
    wait_signalled();
@@ -203,8 +206,10 @@ hard_event::time_end() const {
 
 void
 hard_event::fence(pipe_fence_handle *fence) {
+   assert(fence);
    pipe_screen *screen = queue()->device().pipe;
    screen->fence_reference(screen, &_fence, fence);
+   deps.clear();
 }
 
 event::action
diff --git a/src/gallium/frontends/clover/core/event.hpp b/src/gallium/frontends/clover/core/event.hpp
index 03c97bcf4da..5817893d0da 100644
--- a/src/gallium/frontends/clover/core/event.hpp
+++ b/src/gallium/frontends/clover/core/event.hpp
@@ -81,7 +81,7 @@ namespace clover {
    protected:
       void chain(event &ev);
 
-      std::vector<intrusive_ref<event>> deps;
+      mutable std::vector<intrusive_ref<event>> deps;
 
    private:
       std::vector<intrusive_ref<event>> trigger_self();
diff --git a/src/gallium/frontends/clover/core/queue.cpp b/src/gallium/frontends/clover/core/queue.cpp
index c91b97ad15e..c7d08a8c6d2 100644
--- a/src/gallium/frontends/clover/core/queue.cpp
+++ b/src/gallium/frontends/clover/core/queue.cpp
@@ -65,10 +65,15 @@ command_queue::~command_queue() {
 
 void
 command_queue::flush() {
+   std::lock_guard<std::mutex> lock(queued_events_mutex);
+   flush_unlocked();
+}
+
+void
+command_queue::flush_unlocked() {
    pipe_screen *screen = device().pipe;
    pipe_fence_handle *fence = NULL;
 
-   std::lock_guard<std::mutex> lock(queued_events_mutex);
    if (!queued_events.empty()) {
       pipe->flush(pipe, &fence, 0);
 
@@ -99,4 +104,10 @@ command_queue::sequence(hard_event &ev) {
       queued_events.back()().chain(ev);
 
    queued_events.push_back(ev);
+
+   // Arbitrary threshold.
+   // The CTS tends to run a lot of subtests without flushing with the image
+   // tests, so flush regulary to prevent stack overflows.
+   if (queued_events.size() > 1000)
+      flush_unlocked();
 }
diff --git a/src/gallium/frontends/clover/core/queue.hpp b/src/gallium/frontends/clover/core/queue.hpp
index bddb86c0e4c..27f2c9b7aeb 100644
--- a/src/gallium/frontends/clover/core/queue.hpp
+++ b/src/gallium/frontends/clover/core/queue.hpp
@@ -67,6 +67,8 @@ namespace clover {
       /// Serialize a hardware event with respect to the previous ones,
       /// and push it to the pending list.
       void sequence(hard_event &ev);
+      // Use this instead of flush() if `queued_events_mutex` is acquired.
+      void flush_unlocked();
 
       cl_command_queue_properties props;
       pipe_context *pipe;



More information about the mesa-commit mailing list