[intel][vulkan] Lock around address space allocator

A thread may be submitting on a device's queue while another thread
is releasing command buffers on the same device.

MA-565 #comment

Test:
pixelbook:go/magma-tps#L1
nuc:go/magma-tps#C0

Change-Id: Ic97a1daf682862b650a9665beecb2bea059369a0
diff --git a/src/intel/vulkan/anv_magma_connection.cc b/src/intel/vulkan/anv_magma_connection.cc
index 4384472..4ae1c49 100644
--- a/src/intel/vulkan/anv_magma_connection.cc
+++ b/src/intel/vulkan/anv_magma_connection.cc
@@ -10,6 +10,7 @@
 #include "magma_util/simple_allocator.h"
 #include <chrono>
 #include <limits.h>
+#include <mutex>
 #include <vector>
 
 #ifndef PAGE_SHIFT
@@ -95,6 +96,8 @@
 
    bool MapGpu(uint64_t page_count, uint64_t* gpu_addr_out)
    {
+      std::lock_guard<std::mutex> lock(allocator_mutex_);
+
       uint64_t length = (page_count + guard_page_count_) * PAGE_SIZE;
 
       if (length > allocator_->size())
@@ -107,7 +110,11 @@
       return true;
    }
 
-   void UnmapGpu(uint64_t gpu_addr) { allocator_->Free(gpu_addr); }
+   void UnmapGpu(uint64_t gpu_addr)
+   {
+      std::lock_guard<std::mutex> lock(allocator_mutex_);
+      allocator_->Free(gpu_addr);
+   }
 
    magma_status_t GetSysmemConnection(magma_sysmem_connection_t* sysmem_connection_out)
    {
@@ -129,6 +136,8 @@
    magma_sysmem_connection_t sysmem_connection_{};
    magma::InflightList inflight_list_;
    std::unique_ptr<magma::AddressSpaceAllocator> allocator_;
+   // Protect the allocator from simultaneous Map and Unmap from different threads
+   std::mutex allocator_mutex_;
    uint64_t guard_page_count_;
 };
 
@@ -273,12 +282,16 @@
 void AnvMagmaReleaseBuffer(anv_connection* connection, anv_magma_buffer* anv_buffer)
 {
    auto buffer = static_cast<Buffer*>(anv_buffer);
+   // Hardware mappings are released when the buffer is released.
+   // Do this before unmapping to avoid remap before release.
+   buffer->release(Connection::cast(connection)->magma_connection());
+
    std::vector<Buffer::Mapping> mappings;
    buffer->TakeMappings(&mappings);
+   // Each Unmap takes a lock, however multiple mappings per buffer is rare
    for (auto& mapping : mappings) {
       Connection::cast(connection)->UnmapGpu(mapping.addr);
    }
-   // Hardware mappings are released when the buffer is released.
-   buffer->release(Connection::cast(connection)->magma_connection());
+
    delete buffer;
 }