如何在Golang代码中禁用透明巨页?

huangapple go评论135阅读模式
英文:

How to Disable transparent huge page in Golang Code?

问题

有没有办法让我的进程不使用透明巨大页面,而只是更改整个操作系统(Linux)的配置?

英文:

Is there a way for my processes not to use transparent huge page instead of just changing the configuration of the entire operating system(Linux)?

答案1

得分: 1

你可以按照下面的示例进行操作。应该进行彻底的测试,以确保与Go运行时没有不良交互。

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
	"syscall"
)

const (
	// https://filippo.io/linux-syscall-table/
	PRCTL_SYSCALL = 157

	// see /usr/include/linux/prctl.h
	PR_SET_THP_DISABLE = 41
	PR_GET_THP_DISABLE = 42
)

func disableTHP() {
	_, _, errno := syscall.RawSyscall6(uintptr(PRCTL_SYSCALL), uintptr(PR_SET_THP_DISABLE), uintptr(1), 0, 0, 0, 0)
	if errno != 0 {
		log.Fatalf("禁用THP失败:%v", errno)
	}
}
func isTHPDisabled() bool {
	s, _, errno := syscall.RawSyscall6(uintptr(PRCTL_SYSCALL), uintptr(PR_GET_THP_DISABLE), 0, 0, 0, 0, 0)
	if errno != 0 {
		log.Fatalf("获取THP禁用状态失败:%v", errno)
	}
	return s == 1
}

func main() {
	if os.Getenv("X_IN_CHILD_PROC") == "" {
		runtime.LockOSThread()
		disableTHP()
		cmd := exec.Command(os.Args[0], os.Args...)
		cmd.Env = append(os.Environ(), fmt.Sprintf("X_IN_CHILD_PROC=yes"))
		cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
		_ = cmd.Run() // 错误被丢弃
		os.Exit(cmd.ProcessState.ExitCode())
	}

	// 下面的代码已禁用THP

	if !isTHPDisabled() { // 检查一下
		log.Fatal("THP未被禁用")
	}

	fmt.Println("THP已禁用")
	fmt.Println("你好,世界")
}
英文:

You can do it like shown below. You should test thoroughly to ensure there are no ill interactions with the go runtime.

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
	"syscall"
)

const (
	// https://filippo.io/linux-syscall-table/
	PRCTL_SYSCALL = 157

	// see /usr/include/linux/prctl.h
	PR_SET_THP_DISABLE = 41
	PR_GET_THP_DISABLE = 42
)

func disableTHP() {
	_, _, errno := syscall.RawSyscall6(uintptr(PRCTL_SYSCALL), uintptr(PR_SET_THP_DISABLE), uintptr(1), 0, 0, 0, 0)
	if errno != 0 {
		log.Fatalf("failed to disable THP: %v", errno)
	}
}
func isTHPDisabled() bool {
	s, _, errno := syscall.RawSyscall6(uintptr(PRCTL_SYSCALL), uintptr(PR_GET_THP_DISABLE), 0, 0, 0, 0, 0)
	if errno != 0 {
		log.Fatalf("failed get THP disable status: %v", errno)
	}
	return s == 1
}

func main() {
	if os.Getenv("X_IN_CHILD_PROC") == "" {
		runtime.LockOSThread()
		disableTHP()
		cmd := exec.Command(os.Args[0], os.Args...)
		cmd.Env = append(os.Environ(), fmt.Sprintf("X_IN_CHILD_PROC=yes"))
		cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
		_ = cmd.Run() // err discarded
		os.Exit(cmd.ProcessState.ExitCode())
	}

	// code below has THP disabled

	if !isTHPDisabled() { // sanity check
		log.Fatal("THP is somehow not disabled")
	}

	fmt.Println("THP is disabled")
	fmt.Println("hello world")
}

huangapple
  • 本文由 发表于 2022年6月30日 11:09:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/72809902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定