[llvm] [offload] Serialize queue access around launch and sync (PR #198456)

Akimasa Watanuki via llvm-commits llvm-commits at lists.llvm.org
Tue May 19 00:35:51 PDT 2026


https://github.com/Men-cotton created https://github.com/llvm/llvm-project/pull/198456

Protect each liboffload queue while launching kernels or synchronizing queued work. Serialize those paths because they share the queue's `__tgt_async_info` and plugin queue across threaded submissions.

Document that `olSyncQueue` preserves the plugin queue for later submissions.

>From 83896a922e425865c7466cadff6dc18e465f7f2d Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Tue, 19 May 2026 16:17:26 +0900
Subject: [PATCH] [offload] Serialize queue access around launch and sync

Protect each liboffload queue while launching kernels or synchronizing queued
work. Serialize those paths because they share the queue's `__tgt_async_info`
and plugin queue across threaded submissions.

Document that `olSyncQueue` preserves the plugin queue for later submissions.
---
 offload/liboffload/src/OffloadImpl.cpp | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index d4b9a62bf3bb9..0bcef789027c4 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -164,6 +164,7 @@ struct ol_queue_impl_t {
       : AsyncInfo(AsyncInfo), Device(Device), Id(IdCounter++) {}
   __tgt_async_info *AsyncInfo;
   ol_device_handle_t Device;
+  std::mutex Mutex;
   // A unique identifier for the queue
   size_t Id;
   static std::atomic<size_t> IdCounter;
@@ -767,12 +768,13 @@ Error olDestroyQueue_impl(ol_queue_handle_t Queue) {
 }
 
 Error olSyncQueue_impl(ol_queue_handle_t Queue) {
+  std::lock_guard<std::mutex> Lock(Queue->Mutex);
+
   // Host plugin doesn't have a queue set so it's not safe to call synchronize
   // on it, but we have nothing to synchronize in that situation anyway.
   if (Queue->AsyncInfo->Queue) {
-    // We don't need to release the queue and we would like the ability for
-    // other offload threads to submit work concurrently, so pass "false" here
-    // so we don't release the underlying queue object.
+    // Keep the underlying queue object available for future submissions after
+    // this synchronization completes.
     if (auto Err = Queue->Device->Device->synchronize(Queue->AsyncInfo, false))
       return Err;
   }
@@ -1064,6 +1066,10 @@ Error olLaunchKernel_impl(ol_queue_handle_t Queue, ol_device_handle_t Device,
     return createOffloadError(ErrorCode::SYMBOL_KIND,
                               "provided symbol is not a kernel");
 
+  std::unique_lock<std::mutex> QueueLock;
+  if (Queue)
+    QueueLock = std::unique_lock<std::mutex>(Queue->Mutex);
+
   auto *QueueImpl = Queue ? Queue->AsyncInfo : nullptr;
   AsyncInfoWrapperTy AsyncInfoWrapper(*DeviceImpl, QueueImpl);
   KernelArgsTy LaunchArgs{};



More information about the llvm-commits mailing list