Keep payload buffer mapped for its lifetime
This saves the cost of mapping it for every bridge command.
Change-Id: Ib536022a0cdc275339331d20b9a8615275d5c76b
diff --git a/fuchsia/msd_img_buffer.h b/fuchsia/msd_img_buffer.h
index fef1dab..b5c66ec 100644
--- a/fuchsia/msd_img_buffer.h
+++ b/fuchsia/msd_img_buffer.h
@@ -23,10 +23,25 @@
return platform_buf_.get();
}
+ bool GetPersistentCpuMap(void** data_out)
+ {
+ if (!data_)
+ {
+ if (!platform_buf_->MapCpu(&data_))
+ {
+ return DRETF(false, "Failed to map persistent");
+ }
+ }
+
+ *data_out = data_;
+ return true;
+ }
+
private:
MsdImgBuffer(std::unique_ptr<magma::PlatformBuffer> platform_buf);
std::unique_ptr<magma::PlatformBuffer> platform_buf_;
+ void* data_ = nullptr;
};
class MsdImgAbiBuffer : public msd_buffer_t
diff --git a/fuchsia/msd_img_connection.cc b/fuchsia/msd_img_connection.cc
index f7de970..4869dfc 100644
--- a/fuchsia/msd_img_connection.cc
+++ b/fuchsia/msd_img_connection.cc
@@ -108,8 +108,10 @@
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Payload buffer too small for struct");
}
void *data;
- if (!payload_buffer->platform_buffer()->MapCpu(&data))
- return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Can't map paload buffer");
+ if (!payload_buffer->GetPersistentCpuMap(&data))
+ {
+ return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Unable to make persistent map");
+ }
payload = reinterpret_cast<volatile FuchsiaImgCommandPayload *>(data);
@@ -123,12 +125,10 @@
if (remaining_buffer_size < package_out->ui32InBufferSize)
{
- payload_buffer->platform_buffer()->UnmapCpu();
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Payload buffer too small for in args");
}
if (remaining_buffer_size < package_out->ui32OutBufferSize)
{
- payload_buffer->platform_buffer()->UnmapCpu();
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Payload buffer too small for out args");
}
// Volatile isn't necessary because the bridge code will memcpy everything
@@ -155,7 +155,7 @@
ScopedSetConnection set_connection(this);
PVRSRV_ERROR eError = BridgedDispatchKM(connection_data_, &package);
- payload_buffer_->platform_buffer()->UnmapCpu();
+ payload_buffer_ = nullptr;
additional_buffer_.reset();
current_client_thread_id_ = 0;
if (eError != PVRSRV_OK)
diff --git a/test/test_msd_img_connection.cc b/test/test_msd_img_connection.cc
index 99da492..0fef6a2 100644
--- a/test/test_msd_img_connection.cc
+++ b/test/test_msd_img_connection.cc
@@ -80,12 +80,20 @@
EXPECT_EQ(payload_buf.base_ptr(), connection.payload_buffer_);
EXPECT_EQ(nullptr, connection.TakeAdditionalBuffer());
+ // Unmap to test whether the buffer was mapped persistently.
+ ASSERT_TRUE(payload_buf.base_ptr()->platform_buffer()->UnmapCpu());
+ connection.payload_buffer_ = nullptr;
+
// 2 resources are given, so the last should be used as the
// additional buffer.
system_buf->num_resources = 2;
EXPECT_EQ(MAGMA_STATUS_OK, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_EQ(additional_buf.base_ptr(), connection.TakeAdditionalBuffer());
EXPECT_EQ(nullptr, connection.TakeAdditionalBuffer());
+
+ // The parameters should be at the same address because the
+ // buffer has a persistent mapping.
+ EXPECT_EQ(payload_buf_data + 1, package.pvParamIn);
}
};