hugepage fix

This commit is contained in:
wanyaoqi
2019-11-18 16:10:47 +08:00
parent 508fd79572
commit 130c82dfd3
9 changed files with 74 additions and 15 deletions
+1 -1
View File
@@ -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
}
+1 -1
View File
@@ -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
}
+3 -2
View File
@@ -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 {
+1 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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
+3
View File
@@ -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)
}
+1 -1
View File
@@ -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"
+26 -8
View File
@@ -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)
+37
View File
@@ -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 {