mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
hugepage fix
This commit is contained in:
@@ -144,6 +144,6 @@ func (self *SAzureGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle)
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) NeedStopForChangeSpec(guest *models.SGuest) bool {
|
||||
func (self *SAzureGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ func (self *SBaseGuestDriver) RequestAssociateEip(ctx context.Context, userCred
|
||||
return fmt.Errorf("SBaseGuestDriver: Not Implement RequestAssociateEip")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) NeedStopForChangeSpec(guest *models.SGuest) bool {
|
||||
func (self *SBaseGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -298,8 +298,9 @@ func (self *SKVMGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, gues
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) NeedStopForChangeSpec(guest *models.SGuest) bool {
|
||||
return guest.GetMetadata("hotplug_cpu_mem", nil) != "enable"
|
||||
func (self *SKVMGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
|
||||
return guest.GetMetadata("hotplug_cpu_mem", nil) != "enable" ||
|
||||
(memChanged && guest.GetMetadata("__hugepage", nil) == "native")
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
|
||||
|
||||
@@ -2230,7 +2230,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
}
|
||||
|
||||
if self.Status == api.VM_RUNNING && (cpuChanged || memChanged) && self.GetDriver().NeedStopForChangeSpec(self) {
|
||||
if self.Status == api.VM_RUNNING && (cpuChanged || memChanged) && self.GetDriver().NeedStopForChangeSpec(self, cpuChanged, memChanged) {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot change CPU/Memory spec in status %s", self.Status)
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ type IGuestDriver interface {
|
||||
ValidateCreateEip(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) error
|
||||
RequestAssociateEip(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, eip *SElasticip, task taskman.ITask) error
|
||||
|
||||
NeedStopForChangeSpec(guest *SGuest) bool
|
||||
NeedStopForChangeSpec(guest *SGuest, cpuChanged, memChanged bool) bool
|
||||
|
||||
OnGuestChangeCpuMemFailed(ctx context.Context, guest *SGuest, data *jsonutils.JSONDict, task taskman.ITask) error
|
||||
IsSupportGuestClone() bool
|
||||
|
||||
@@ -1254,6 +1254,9 @@ func (s *SKVMGuestInstance) OnResumeSyncMetadataInfo() {
|
||||
if len(s.VncPassword) > 0 {
|
||||
meta.Set("__vnc_password", jsonutils.NewString(s.VncPassword))
|
||||
}
|
||||
if options.HostOptions.HugepagesOption == "native" {
|
||||
meta.Set("__hugepage", jsonutils.NewString("native"))
|
||||
}
|
||||
if s.syncMeta != nil {
|
||||
meta.Update(s.syncMeta)
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ func (s *SKVMGuestInstance) generateStopScript(data *jsonutils.JSONDict) string
|
||||
cmd += "fi\n"
|
||||
|
||||
if options.HostOptions.HugepagesOption == "native" {
|
||||
cmd += fmt.Sprintf("if [ -f /dev/hugepages/%s ]; then\n", uuid)
|
||||
cmd += fmt.Sprintf("if [ -d /dev/hugepages/%s ]; then\n", uuid)
|
||||
cmd += fmt.Sprintf(" umount /dev/hugepages/%s\n", uuid)
|
||||
cmd += fmt.Sprintf(" rm -rf /dev/hugepages/%s\n", uuid)
|
||||
cmd += "fi\n"
|
||||
|
||||
@@ -16,6 +16,7 @@ package hostinfo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -136,7 +137,9 @@ func (h *SHostInfo) Init() error {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) parseConfig() error {
|
||||
if h.GetMemory() < 64 { // MB
|
||||
if mem, err := h.GetMemory(); err != nil {
|
||||
return err
|
||||
} else if mem < 64 { // MB
|
||||
return fmt.Errorf("Not enough memory!")
|
||||
}
|
||||
for _, n := range options.HostOptions.Networks {
|
||||
@@ -234,9 +237,13 @@ func (h *SHostInfo) prepareEnv() error {
|
||||
case "disable":
|
||||
h.DisableHugepages()
|
||||
case "native":
|
||||
if err := h.EnableNativeHugepages(); err != nil {
|
||||
size, err := h.Mem.GetHugepageTotal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if size <= 0 {
|
||||
return errors.New("invalid hugepages total size")
|
||||
}
|
||||
case "transparent":
|
||||
h.EnableTransparentHugepages()
|
||||
default:
|
||||
@@ -342,8 +349,11 @@ func (h *SHostInfo) EnableTransparentHugepages() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMemory() int {
|
||||
return h.Mem.Total // - options.reserved_memory
|
||||
func (h *SHostInfo) GetMemory() (int, error) {
|
||||
if options.HostOptions.HugepagesOption == "native" {
|
||||
return h.Mem.GetHugepageTotal()
|
||||
}
|
||||
return h.Mem.Total, nil // - options.reserved_memory
|
||||
}
|
||||
|
||||
func (h *SHostInfo) EnableNativeHugepages() error {
|
||||
@@ -359,8 +369,12 @@ func (h *SHostInfo) EnableNativeHugepages() error {
|
||||
for k, v := range kv {
|
||||
sysutils.SetSysConfig(k, v)
|
||||
}
|
||||
preAllocPagesNum := h.GetMemory()/h.Mem.GetHugepagesizeMb() + 1
|
||||
err := timeutils2.CommandWithTimeout(1, "sh", "-c", fmt.Sprintf("echo %d > /proc/sys/vm/nr_hugepages", preAllocPagesNum)).Run()
|
||||
mem, err := h.GetMemory()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
preAllocPagesNum := mem/h.Mem.GetHugepagesizeMb() + 1
|
||||
err = timeutils2.CommandWithTimeout(1, "sh", "-c", fmt.Sprintf("echo %d > /proc/sys/vm/nr_hugepages", preAllocPagesNum)).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
_, err = procutils.NewCommand("sh", "-c", "echo 0 > /proc/sys/vm/nr_hugepages").Run()
|
||||
@@ -767,7 +781,12 @@ func (h *SHostInfo) updateHostRecord(hostId string) {
|
||||
content.Set("cpu_microcode", jsonutils.NewString(h.Cpu.cpuInfoProc.Microcode))
|
||||
content.Set("cpu_mhz", jsonutils.NewInt(int64(h.Cpu.cpuInfoProc.Freq)))
|
||||
content.Set("cpu_cache", jsonutils.NewInt(int64(h.Cpu.cpuInfoProc.Cache)))
|
||||
content.Set("mem_size", jsonutils.NewInt(int64(h.Mem.MemInfo.Total)))
|
||||
memTotal, err := h.GetMemory()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
h.onFail()
|
||||
}
|
||||
content.Set("mem_size", jsonutils.NewInt(int64(memTotal)))
|
||||
content.Set("storage_driver", jsonutils.NewString(api.DISK_DRIVER_LINUX))
|
||||
content.Set("storage_type", jsonutils.NewString(h.sysinfo.StorageType))
|
||||
content.Set("storage_size", jsonutils.NewInt(int64(storageman.GetManager().GetTotalCapacity())))
|
||||
@@ -787,7 +806,6 @@ func (h *SHostInfo) updateHostRecord(hostId string) {
|
||||
|
||||
var (
|
||||
res jsonutils.JSONObject
|
||||
err error
|
||||
)
|
||||
if !isInit {
|
||||
res, err = modules.Hosts.Update(h.GetSession(), hostId, content)
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
|
||||
@@ -159,6 +160,42 @@ func DetectMemoryInfo() (*SMemory, error) {
|
||||
return smem, nil
|
||||
}
|
||||
|
||||
func (m *SMemory) GetHugepageTotal() (int, error) {
|
||||
file, err := os.Open("/proc/meminfo")
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "open meminfo")
|
||||
}
|
||||
defer file.Close()
|
||||
var (
|
||||
nrHugePage int
|
||||
sizeHugePage int
|
||||
)
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "Hugepagesize:") {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
segs := re.Split(line, -1)
|
||||
v, err := strconv.Atoi(segs[1])
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "get hugepage size")
|
||||
}
|
||||
sizeHugePage = v / 1024 // MB
|
||||
log.Debugf("Huge page size %v", sizeHugePage)
|
||||
} else if strings.HasPrefix(line, "HugePages_Total:") {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
segs := re.Split(line, -1)
|
||||
v, err := strconv.Atoi(segs[1])
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "get hugepages total")
|
||||
}
|
||||
nrHugePage = v
|
||||
log.Debugf("Huge page number %v", nrHugePage)
|
||||
}
|
||||
}
|
||||
return nrHugePage * sizeHugePage, nil
|
||||
}
|
||||
|
||||
func (m *SMemory) GetHugepagesizeMb() int {
|
||||
file, err := os.Open("/proc/meminfo")
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user