mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 06:09:39 +08:00
Merge pull request #15168 from wanyaoqi/fix/hugepages
feat(region,host): hugepage optimize
This commit is contained in:
@@ -366,6 +366,8 @@ type HostSizeAttributes struct {
|
||||
MemReserved string `json:"mem_reserved"`
|
||||
// 内存超分比
|
||||
MemCmtbound *float32 `json:"mem_cmtbound"`
|
||||
// 页大小
|
||||
PageSizeKB *int `json:"page_size_kb"`
|
||||
|
||||
// 存储大小,单位Mb
|
||||
StorageSize *int `json:"storage_size"`
|
||||
|
||||
@@ -86,8 +86,9 @@ type ScheduleInput struct {
|
||||
CpuMode string `json:"cpu_mode"`
|
||||
OsArch string `json:"os_arch"`
|
||||
|
||||
SkipKernelCheck *bool `json:"skip_kernel_check"`
|
||||
TargetHostKernel string `json:"target_host_kernel"`
|
||||
HostMemPageSizeKB int `json:"host_mem_page_size"`
|
||||
SkipKernelCheck *bool `json:"skip_kernel_check"`
|
||||
TargetHostKernel string `json:"target_host_kernel"`
|
||||
|
||||
// In the migrate and create backup cases
|
||||
// we don't need reallocate network
|
||||
|
||||
@@ -508,6 +508,7 @@ func (self *SGuest) GetSchedMigrateParams(
|
||||
if host != nil {
|
||||
schedDesc.TargetHostKernel, _ = host.SysInfo.GetString("kernel_version")
|
||||
schedDesc.SkipKernelCheck = &input.SkipKernelCheck
|
||||
schedDesc.HostMemPageSizeKB = host.PageSizeKB
|
||||
}
|
||||
}
|
||||
schedDesc.ReuseNetwork = true
|
||||
|
||||
@@ -144,6 +144,8 @@ type SHost struct {
|
||||
MemReserved int `nullable:"true" default:"0" list:"domain" update:"domain" create:"domain_optional"`
|
||||
// 内存超分比
|
||||
MemCmtbound float32 `nullable:"true" default:"1" list:"domain" update:"domain" create:"domain_optional"`
|
||||
// 页大小
|
||||
PageSizeKB int `nullable:"false" default:"4" list:"domain" update:"domain" create:"domain_optional"`
|
||||
|
||||
// 存储大小,单位Mb
|
||||
StorageSize int `nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
|
||||
@@ -703,8 +705,12 @@ func (self *SHost) GetMemSize() int {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) IsHugePage() bool {
|
||||
return self.PageSizeKB > 4
|
||||
}
|
||||
|
||||
func (self *SHost) GetMemoryOvercommitBound() float32 {
|
||||
if self.MemCmtbound > 0 {
|
||||
if self.MemCmtbound > 0 && self.IsHugePage() {
|
||||
return self.MemCmtbound
|
||||
}
|
||||
return options.Options.DefaultMemoryOvercommitBound
|
||||
@@ -3648,6 +3654,10 @@ func (self *SHost) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok
|
||||
return input, errors.Wrap(err, "inputUniquenessCheck")
|
||||
}
|
||||
|
||||
if self.IsHugePage() && (input.MemReserved != "" || input.MemCmtbound != nil) {
|
||||
return input, errors.Errorf("host mem is hugepage, cannot update mem_reserved or mem_cmtbound")
|
||||
}
|
||||
|
||||
input.HostSizeAttributes, err = HostManager.ValidateSizeParams(input.HostSizeAttributes)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "ValidateSizeParams")
|
||||
|
||||
@@ -2158,7 +2158,7 @@ func (s *SKVMGuestInstance) OnResumeSyncMetadataInfo() {
|
||||
if len(s.VncPassword) > 0 {
|
||||
meta.Set("__vnc_password", jsonutils.NewString(s.VncPassword))
|
||||
}
|
||||
if options.HostOptions.HugepagesOption == "native" {
|
||||
if s.manager.host.IsHugepagesEnabled() {
|
||||
meta.Set("__hugepage", jsonutils.NewString("native"))
|
||||
}
|
||||
// not exactly
|
||||
|
||||
@@ -433,22 +433,22 @@ func (h *SHostInfo) prepareEnv() error {
|
||||
case "disable":
|
||||
h.DisableHugepages()
|
||||
case "native":
|
||||
err := h.EnableNativeHugepages(0)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "EnableNativeHugepages")
|
||||
}
|
||||
h.EnableNativeHugepages()
|
||||
hp, err := h.Mem.GetHugepages()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Mem.GetHugepages")
|
||||
}
|
||||
szlist := hp.PageSizes()
|
||||
if len(szlist) == 0 {
|
||||
return errors.Error("invalid hugepages total size")
|
||||
for i := 0; i < len(hp); i++ {
|
||||
if hp[i].SizeKb == options.HostOptions.HugepageSizeMb*1024 {
|
||||
nr := hp[i].Total
|
||||
h.sysinfo.HugepageNr = &nr
|
||||
h.sysinfo.HugepageSizeKb = hp[i].SizeKb
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(szlist) > 1 {
|
||||
return errors.Error("cannot support more than 1 type of hugepage size")
|
||||
if h.sysinfo.HugepageNr == nil || *h.sysinfo.HugepageNr == 0 {
|
||||
return errors.Errorf("hugepage %d nr 0", options.HostOptions.HugepageSizeMb)
|
||||
}
|
||||
h.sysinfo.HugepageSizeKb = szlist[0]
|
||||
case "transparent":
|
||||
h.EnableTransparentHugepages()
|
||||
default:
|
||||
@@ -600,7 +600,7 @@ func (h *SHostInfo) GetMemoryTotal() int {
|
||||
return int64(nr), nil
|
||||
} */
|
||||
|
||||
func (h *SHostInfo) EnableNativeHugepages(reservedMb int) error {
|
||||
func (h *SHostInfo) EnableNativeHugepages() {
|
||||
kv := map[string]string{
|
||||
"/sys/kernel/mm/transparent_hugepage/enabled": "never",
|
||||
"/sys/kernel/mm/transparent_hugepage/defrag": "never",
|
||||
@@ -608,43 +608,6 @@ func (h *SHostInfo) EnableNativeHugepages(reservedMb int) error {
|
||||
for k, v := range kv {
|
||||
sysutils.SetSysConfig(k, v)
|
||||
}
|
||||
// check reserved memory
|
||||
hp, err := h.Mem.GetHugepages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pgList := hp.PageSizes()
|
||||
if len(pgList) == 0 {
|
||||
// not initialized yet, manually setup, usage page_size 2MB
|
||||
} else if len(pgList) == 1 {
|
||||
// already setup, depends on the PageSize
|
||||
if pgList[0] == 2048 {
|
||||
} else {
|
||||
// readonly, cannot adjust any more
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return errors.Error("cannot support more than 1 type of hugepage sizes")
|
||||
}
|
||||
mem := h.GetMemory()
|
||||
if reservedMb > 0 {
|
||||
mem -= reservedMb
|
||||
} else {
|
||||
mem -= h.getReservedMemMb()
|
||||
}
|
||||
desiredSz := 2 // ONLY 2MB Hugepage Supported
|
||||
desiredNr := mem / desiredSz
|
||||
if desiredNr*desiredSz < mem {
|
||||
desiredNr += 1
|
||||
}
|
||||
log.Infof("Hugepage %dGB(%dMB) available Mem %dMB, to reserve %d hugepages with size %d", hp.BytesMb()/1024, hp.BytesMb(), mem, desiredNr, desiredSz)
|
||||
// not setup hugepage yet, or reserved too many hugepages
|
||||
err = timeutils2.CommandWithTimeout(1, "sh", "-c",
|
||||
fmt.Sprintf("echo %d > /sys/kernel/mm/hugepages/hugepages-%dkB/nr_hugepages", desiredNr, desiredSz*1024)).Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *SHostInfo) EnableKsm(sleepSec int) {
|
||||
@@ -1343,6 +1306,10 @@ func (h *SHostInfo) updateHostRecord(hostId string) {
|
||||
// first time create
|
||||
input.MemReserved = fmt.Sprintf("%d", h.getReservedMemMb())
|
||||
}
|
||||
if h.IsHugepagesEnabled() {
|
||||
pageSizeKb := options.HostOptions.HugepageSizeMb * 1024
|
||||
input.PageSizeKB = &pageSizeKb
|
||||
}
|
||||
input.StorageDriver = api.DISK_DRIVER_LINUX
|
||||
input.StorageType = h.sysinfo.StorageType
|
||||
storageSize := storageman.GetManager().GetTotalCapacity()
|
||||
@@ -1440,19 +1407,10 @@ func (h *SHostInfo) onUpdateHostInfoSucc(hostbody jsonutils.JSONObject) {
|
||||
h.initCgroup()
|
||||
|
||||
memReservedMb, _ := hostbody.Int("mem_reserved")
|
||||
if options.HostOptions.HugepagesOption == "native" && memReservedMb > int64(h.getReservedMemMb()) {
|
||||
err := h.EnableNativeHugepages(int(memReservedMb))
|
||||
if err != nil {
|
||||
h.onFail(err)
|
||||
return
|
||||
}
|
||||
if h.IsHugepagesEnabled() && int64(h.getReservedMemMb()) != memReservedMb {
|
||||
h.updateHostReservedMem(h.getReservedMemMb())
|
||||
}
|
||||
|
||||
reserved := h.getReportedReservedMemMb()
|
||||
if reserved != int(memReservedMb) {
|
||||
h.updateHostReservedMem(reserved)
|
||||
return
|
||||
}
|
||||
h.getNetworkInfo()
|
||||
}
|
||||
|
||||
@@ -1493,16 +1451,12 @@ func (h *SHostInfo) getOSReservedMemMb() int {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) getReservedMemMb() int {
|
||||
return h.getOSReservedMemMb() + h.getKubeReservedMemMb()
|
||||
}
|
||||
|
||||
func (h *SHostInfo) getReportedReservedMemMb() int {
|
||||
if options.HostOptions.HugepagesOption == "native" {
|
||||
// return total minus mem in huagepage pool
|
||||
if h.IsHugepagesEnabled() {
|
||||
hp, _ := h.Mem.GetHugepages()
|
||||
return h.GetMemory() - int(hp.BytesMb())
|
||||
} else {
|
||||
return h.getOSReservedMemMb() + h.getKubeReservedMemMb()
|
||||
}
|
||||
return h.getReservedMemMb()
|
||||
}
|
||||
|
||||
func (h *SHostInfo) PutHostOnline() error {
|
||||
|
||||
@@ -321,6 +321,7 @@ type SSysInfo struct {
|
||||
|
||||
HugepagesOption string `json:"hugepages_option"`
|
||||
HugepageSizeKb int `json:"hugepage_size_kb"`
|
||||
HugepageNr *int `json:"hugepage_nr"`
|
||||
|
||||
Topology *hostapi.HostTopology `json:"topology"`
|
||||
CPUInfo *hostapi.HostCPUInfo `json:"cpu_info"`
|
||||
|
||||
@@ -86,6 +86,7 @@ type SHostOptions struct {
|
||||
BlockIoScheduler string `help:"Block IO scheduler, deadline or cfq" default:"deadline"`
|
||||
EnableKsm bool `help:"Enable Kernel Same Page Merging"`
|
||||
HugepagesOption string `help:"Hugepages option: disable|native|transparent" default:"transparent"`
|
||||
HugepageSizeMb int `help:"hugepage size mb default 1G" default:"1024"`
|
||||
|
||||
PrivatePrefixes []string `help:"IPv4 private prefixes"`
|
||||
LocalImagePath []string `help:"Local image storage paths"`
|
||||
|
||||
@@ -36,6 +36,7 @@ const (
|
||||
ErrHostIsSpecifiedForMigration = `host_id specified for migration`
|
||||
ErrHostCpuModelIsNotMatchForLiveMigrate = `host cpu mode not match for live migrate`
|
||||
ErrHostCpuMicrocodeNotMatchForLiveMigrate = `host cpu microcode not match for live migrate`
|
||||
ErrHostMemPageSizeNotMatchForLiveMigrate = `host mem page size not match for live migrate`
|
||||
ErrHostKernelNotMatchForLiveMigrate = `host kernel not match for live migrate`
|
||||
ErrMoreThanOneSizeUnspecificSplit = `more than 1 size unspecific split`
|
||||
ErrNoMoreSpaceForUnspecificSplit = `no more space for an unspecific split`
|
||||
|
||||
@@ -51,6 +51,13 @@ func (p *MigratePredicate) Execute(ctx context.Context, u *core.Unit, c core.Can
|
||||
// live migrate check
|
||||
if schedData.LiveMigrate {
|
||||
host := c.Getter().Host()
|
||||
|
||||
// target host mem page size check
|
||||
if schedData.HostMemPageSizeKB != host.PageSizeKB {
|
||||
h.Exclude(predicates.ErrHostMemPageSizeNotMatchForLiveMigrate)
|
||||
return h.GetResult()
|
||||
}
|
||||
|
||||
// target host cpu check
|
||||
if schedData.CpuMode != compute.CPU_MODE_QEMU && (schedData.SkipCpuCheck == nil || *schedData.SkipCpuCheck == false) {
|
||||
if schedData.CpuDesc != host.CpuDesc {
|
||||
@@ -67,7 +74,7 @@ func (p *MigratePredicate) Execute(ctx context.Context, u *core.Unit, c core.Can
|
||||
if schedData.SkipKernelCheck != nil && !*schedData.SkipKernelCheck {
|
||||
kv, _ := host.SysInfo.GetString("kernel_version")
|
||||
if schedData.TargetHostKernel != "" && schedData.TargetHostKernel != kv {
|
||||
h.Exclude2(predicates.ErrHostCpuMicrocodeNotMatchForLiveMigrate, kv, schedData.TargetHostKernel)
|
||||
h.Exclude2(predicates.ErrHostKernelNotMatchForLiveMigrate, kv, schedData.TargetHostKernel)
|
||||
return h.GetResult()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user