Add mprotect syscall benchmark
Specific parameters were chosen based on the frequency of their use in Android. Bug: 327496587 Test: local build and run Change-Id: Iec225109f62e1e9cde133863d3cee8103172a6c8 Signed-off-by: Carlos Galo <carlosgalo@google.com>
This commit is contained in:
parent
fb7dd9dd85
commit
f86d29cc49
2 changed files with 196 additions and 0 deletions
|
@ -50,3 +50,44 @@
|
||||||
<args>AT_MULTI_PAGE_SIZES</args>
|
<args>AT_MULTI_PAGE_SIZES</args>
|
||||||
</fn>
|
</fn>
|
||||||
|
|
||||||
|
<!-- mprotect tests -->
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_anon_mprotect_rw_to_rd</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_anon_mprotect_rw_to_none</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_anon_mprotect_rd_to_none</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_file_mprotect_rw_to_rd</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_file_mprotect_rw_to_none</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_file_mprotect_none_to_rw</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_file_mprotect_none_to_rd</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
<fn>
|
||||||
|
<name>BM_syscall_mmap_file_mprotect_rd_to_none</name>
|
||||||
|
<iterations>10</iterations>
|
||||||
|
<args>AT_All_PAGE_SIZES</args>
|
||||||
|
</fn>
|
||||||
|
|
|
@ -38,6 +38,12 @@ struct MmapParams {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MprotectParams {
|
||||||
|
int from_prot;
|
||||||
|
int to_prot;
|
||||||
|
int64_t size;
|
||||||
|
};
|
||||||
|
|
||||||
template <BenchmarkType type>
|
template <BenchmarkType type>
|
||||||
void MmapBenchmarkImpl(benchmark::State& state, const struct MmapParams& params, int fd,
|
void MmapBenchmarkImpl(benchmark::State& state, const struct MmapParams& params, int fd,
|
||||||
void* area = nullptr) {
|
void* area = nullptr) {
|
||||||
|
@ -307,3 +313,152 @@ static void BM_syscall_mmap_anon_madvise_free(benchmark::State& state) {
|
||||||
MadviseBenchmark(state, params, MADV_FREE);
|
MadviseBenchmark(state, params, MADV_FREE);
|
||||||
}
|
}
|
||||||
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_anon_madvise_free, "AT_MULTI_PAGE_SIZES");
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_anon_madvise_free, "AT_MULTI_PAGE_SIZES");
|
||||||
|
|
||||||
|
void MprotectBenchmark(benchmark::State& state, const struct MprotectParams& params, void* addr) {
|
||||||
|
for (auto _ : state) {
|
||||||
|
state.PauseTiming();
|
||||||
|
/*
|
||||||
|
* Guarantee that physical memory pages are allocated for this region to prevent
|
||||||
|
* segmentation fault when using mprotect to change permissions.
|
||||||
|
*/
|
||||||
|
if (params.from_prot & PROT_WRITE) {
|
||||||
|
MakeAllocationResident(addr, params.size, page_sz);
|
||||||
|
}
|
||||||
|
state.ResumeTiming();
|
||||||
|
|
||||||
|
if (mprotect(addr, params.size, params.to_prot) != 0) {
|
||||||
|
state.SkipWithError(android::base::StringPrintf("mprotect failed: %m"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.PauseTiming();
|
||||||
|
// Revert back to the original protection
|
||||||
|
int res = mprotect(addr, params.size, params.from_prot);
|
||||||
|
state.ResumeTiming();
|
||||||
|
if (res != 0) {
|
||||||
|
state.SkipWithError(
|
||||||
|
android::base::StringPrintf("mprotect failed to revert to original prot: %m"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MprotectBenchmarkWithMmapAnon(benchmark::State& state,
|
||||||
|
const struct MprotectParams& params) {
|
||||||
|
void* addr = mmap(nullptr, params.size, params.from_prot, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
|
if (addr == MAP_FAILED) {
|
||||||
|
state.SkipWithError(android::base::StringPrintf("mmap failed: %m"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MprotectBenchmark(state, params, addr);
|
||||||
|
|
||||||
|
if (munmap(addr, params.size) != 0)
|
||||||
|
state.SkipWithError(android::base::StringPrintf("munmap failed: %m"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_anon_mprotect_rw_to_rd(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ | PROT_WRITE,
|
||||||
|
.to_prot = PROT_READ,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapAnon(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_anon_mprotect_rw_to_rd, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_anon_mprotect_rw_to_none(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ | PROT_WRITE,
|
||||||
|
.to_prot = PROT_NONE,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapAnon(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_anon_mprotect_rw_to_none, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_anon_mprotect_rd_to_none(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ,
|
||||||
|
.to_prot = PROT_NONE,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapAnon(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_anon_mprotect_rd_to_none, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void MprotectBenchmarkWithMmapFile(benchmark::State& state,
|
||||||
|
const struct MprotectParams& params) {
|
||||||
|
TemporaryFile tf;
|
||||||
|
|
||||||
|
if (tf.fd < 0) {
|
||||||
|
state.SkipWithError(android::base::StringPrintf("failed to create a temporary file: %m"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.size > 0 && ftruncate(tf.fd, params.size)) {
|
||||||
|
state.SkipWithError(android::base::StringPrintf("ftruncate failed: %m"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* addr = mmap(nullptr, params.size, params.from_prot, MAP_PRIVATE, tf.fd, 0);
|
||||||
|
if (addr == MAP_FAILED) {
|
||||||
|
state.SkipWithError(android::base::StringPrintf("mmap failed: %m"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MprotectBenchmark(state, params, addr);
|
||||||
|
|
||||||
|
if (munmap(addr, params.size) != 0)
|
||||||
|
state.SkipWithError(android::base::StringPrintf("munmap failed: %m"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_file_mprotect_rw_to_rd(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ | PROT_WRITE,
|
||||||
|
.to_prot = PROT_READ,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapFile(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_file_mprotect_rw_to_rd, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_file_mprotect_rw_to_none(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ | PROT_WRITE,
|
||||||
|
.to_prot = PROT_NONE,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapFile(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_file_mprotect_rw_to_none, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_file_mprotect_none_to_rw(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_NONE,
|
||||||
|
.to_prot = PROT_READ | PROT_WRITE,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapFile(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_file_mprotect_none_to_rw, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_file_mprotect_none_to_rd(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_NONE,
|
||||||
|
.to_prot = PROT_READ,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapFile(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_file_mprotect_none_to_rd, "AT_All_PAGE_SIZES");
|
||||||
|
|
||||||
|
static void BM_syscall_mmap_file_mprotect_rd_to_none(benchmark::State& state) {
|
||||||
|
struct MprotectParams params = {
|
||||||
|
.from_prot = PROT_READ,
|
||||||
|
.to_prot = PROT_NONE,
|
||||||
|
.size = state.range(0),
|
||||||
|
};
|
||||||
|
MprotectBenchmarkWithMmapFile(state, params);
|
||||||
|
}
|
||||||
|
BIONIC_BENCHMARK_WITH_ARG(BM_syscall_mmap_file_mprotect_rd_to_none, "AT_All_PAGE_SIZES");
|
||||||
|
|
Loading…
Reference in a new issue