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@redhat.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7460>
This commit is contained in:
Karol Herbst 2020-11-04 23:05:51 +01:00 committed by Marge Bot
parent e8a1aa9e94
commit 20a3ec2d77
4 changed files with 21 additions and 3 deletions

View File

@ -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

View File

@ -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();

View File

@ -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();
}

View File

@ -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;