With THP 'always' journald's mmapped journal files sit in 2 MiB folios, so each small journal write dirties and writes back 2 MiB; on the control node that saturated the root mirror holding the bus store and the store, and the controller lost its lease. The module sets the mode from a per-machine setting (default always, the kernel's own, so assigning it changes nothing until a machine sets madvise), verifies it took, rotates the journal once so new files are mapped under the new mode, gives back what it found when stopped, and serves kernel_huge_pages to measure file_thp per unit.
51 lines
2.0 KiB
Go
51 lines
2.0 KiB
Go
// The kernel module's tools bundle (novox/hq to-be 42 Phase 1 row 11, issue 746).
|
|
//
|
|
// Served by the node's runtime over MCP on stdio through the Go SDK (ADR 0188, ADR 0193). It only reads:
|
|
// the transparent huge pages the kernel runs with, and which units hold file pages in huge folios, which
|
|
// is what a small write to a mapped file costs a whole huge page of writeback for (issue 746).
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
// binaryName is what the build names this bundle's executable: the manifest's `binary`.
|
|
const binaryName = "kernel-tools"
|
|
|
|
func main() {
|
|
// An empty name serves as the module the runtime names (MESH_SERVED_MODULE): kernel.
|
|
if err := stdio.Serve("", tools(ThisMachine())); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func tools(m *Machine) []stdio.Tool {
|
|
return []stdio.Tool{
|
|
{
|
|
Name: "kernel_huge_pages",
|
|
Description: "Transparent huge pages on this machine: the mode in force (always, madvise or never) and defrag, " +
|
|
"each per-size control with what inherit resolves to, the machine's huge pages by kind (anonymous, " +
|
|
"shared memory, file, file mapped at 2 MiB) from /proc/meminfo, and the units holding the most file " +
|
|
"pages in huge folios (memory.stat file_thp) with their dirty and writeback bytes and the bytes their " +
|
|
"cgroup has written (io.stat, the most any one device saw). A unit with file_thp that writes far more " +
|
|
"than its files grow is paying a whole huge page of writeback per small write (novox/hq issue 746). " +
|
|
"Replaces cat /sys/kernel/mm/transparent_hugepage/enabled, grep Huge /proc/meminfo and reading " +
|
|
"memory.stat by hand. (r)",
|
|
Input: schema(map[string]any{
|
|
"units": map[string]any{"type": "integer", "description": "how many units to name, the most file_thp first (default 10, 0 for none, at most 100)"},
|
|
}),
|
|
Run: func(args map[string]any) (any, error) {
|
|
n, err := whole(args, "units", 10, 0, 100)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return m.HugePages(n)
|
|
},
|
|
},
|
|
}
|
|
}
|