Commit 1859d70e authored by Wez's avatar Wez Committed by Commit Bot

[fuchsia] Decommit discardable memory without relying on the VMO handle.

DiscardableSharedMemory::Purge() attempts to proactively de-commit pages
once the instance is unused, to free it quickly even if the peer is slow
to unmap it.

However, the DiscardableSharedMemoryManager (typically in the browser)
maps instances but then closes their handles - Purge() must therefore
be implemented without reference to the handle.

Bug: 1023693
Change-Id: Ic645232c0b24d85acb64e915bbef05804b25b001
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1912698
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Auto-Submit: Wez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715865}
parent 43ec9fc2
......@@ -33,7 +33,7 @@
#endif
#if defined(OS_FUCHSIA)
#include <lib/zx/vmo.h>
#include <lib/zx/vmar.h>
#include <zircon/types.h>
#include "base/fuchsia/fuchsia_logging.h"
#endif
......@@ -423,10 +423,14 @@ bool DiscardableSharedMemory::Purge(Time current_time) {
CHECK(ptr);
}
#elif defined(OS_FUCHSIA)
zx::unowned_vmo vmo = shared_memory_region_.GetPlatformHandle();
zx_status_t status =
vmo->op_range(ZX_VMO_OP_DECOMMIT, AlignToPageSize(sizeof(SharedState)),
AlignToPageSize(mapped_size_), nullptr, 0);
// De-commit via our VMAR, rather than relying on the VMO handle, since the
// handle may have been closed after the memory was mapped into this process.
uint64_t address_int = reinterpret_cast<uint64_t>(
static_cast<char*>(shared_memory_mapping_.memory()) +
AlignToPageSize(sizeof(SharedState)));
zx_status_t status = zx::vmar::root_self()->op_range(
ZX_VMO_OP_DECOMMIT, address_int, AlignToPageSize(mapped_size_), nullptr,
0);
ZX_DCHECK(status == ZX_OK, status) << "zx_vmo_op_range(ZX_VMO_OP_DECOMMIT)";
#endif // defined(OS_FUCHSIA)
......
......@@ -150,6 +150,23 @@ TEST(DiscardableSharedMemoryTest, Purge) {
ASSERT_FALSE(memory2.IsMemoryResident());
}
TEST(DiscardableSharedMemoryTest, PurgeAfterClose) {
const uint32_t kDataSize = 1024;
TestDiscardableSharedMemory memory;
bool rv = memory.CreateAndMap(kDataSize);
ASSERT_TRUE(rv);
// Unlock things so we can Purge().
memory.SetNow(Time::FromDoubleT(2));
memory.Unlock(0, 0);
// It should be safe to Purge() |memory| after Close()ing the handle.
memory.Close();
rv = memory.Purge(Time::FromDoubleT(4));
EXPECT_TRUE(rv);
}
TEST(DiscardableSharedMemoryTest, LastUsed) {
const uint32_t kDataSize = 1024;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment