Gates / container (push) Successful in 10s
CI / gates (push) Successful in 23m56s
Release / guard (push) Successful in 1m47s
Gates / frontend (push) Successful in 2m14s
Gates / test (push) Successful in 2m40s
Gates / test-aarch64 (push) Successful in 5m39s
Gates / package (push) Successful in 47s
Gates / container (push) Successful in 11s
Release / gates (push) Successful in 9m20s
Gates / frontend (push) Successful in 2m12s
Release / publish (push) Successful in 10m46s
Gates / test (push) Successful in 2m32s
Gates / test-aarch64 (push) Successful in 6m35s
Gates / package (push) Successful in 4m31s
42 lines
1.6 KiB
Zig
42 lines
1.6 KiB
Zig
//! Opting the process out of transparent huge pages.
|
|
//!
|
|
//! With THP set to `always`, the kernel backs any 2 MiB-aligned anonymous
|
|
//! region with a huge page on first touch. Each worker thread's stack mapping
|
|
//! qualifies, so a thread that touches a few KiB of stack can hold 2 MiB
|
|
//! resident, and `std.Io.Threaded` never retires a worker: one burst on such a
|
|
//! host left about 40 of 200 workers at 2 MiB each. nxdns's memory is sized
|
|
//! for small pages, so the whole process opts out instead of chasing each
|
|
//! mapping.
|
|
|
|
const std = @import("std");
|
|
const linux = std.os.linux;
|
|
|
|
pub const DisableError = error{
|
|
/// A kernel older than 3.15, which has no such switch.
|
|
Unsupported,
|
|
Unexpected,
|
|
};
|
|
|
|
/// Sets `PR_SET_THP_DISABLE`, which covers every mapping of the process,
|
|
/// existing and future, and is inherited across `fork`.
|
|
pub fn disable() DisableError!void {
|
|
const rc = linux.prctl(@intFromEnum(linux.PR.SET_THP_DISABLE), 1, 0, 0, 0);
|
|
switch (linux.errno(rc)) {
|
|
.SUCCESS => {},
|
|
.INVAL => return error.Unsupported,
|
|
else => return error.Unexpected,
|
|
}
|
|
}
|
|
|
|
test "disable takes effect for the process" {
|
|
disable() catch |err| switch (err) {
|
|
// qemu-user, which runs the aarch64 suite, rejects the option the way
|
|
// a pre-3.15 kernel does.
|
|
error.Unsupported => return error.SkipZigTest,
|
|
error.Unexpected => return err,
|
|
};
|
|
const rc = linux.prctl(@intFromEnum(linux.PR.GET_THP_DISABLE), 0, 0, 0, 0);
|
|
try std.testing.expectEqual(linux.E.SUCCESS, linux.errno(rc));
|
|
try std.testing.expectEqual(@as(usize, 1), rc);
|
|
}
|