diff --git a/pkg/pillar/cmd/zedmanager/memorysizemgmt.go b/pkg/pillar/cmd/zedmanager/memorysizemgmt.go index 6915355103..6ce4f30993 100644 --- a/pkg/pillar/cmd/zedmanager/memorysizemgmt.go +++ b/pkg/pillar/cmd/zedmanager/memorysizemgmt.go @@ -11,6 +11,30 @@ import ( "github.com/lf-edge/eve/pkg/pillar/vault" ) +// getMemoryReservedForEveInBytes returns the amount of memory reserved for eve +// in bytes. There are two sources for this value: +// 1. Global config value `EveMemoryLimitInBytes` +// 2. Global config value `EveMemoryLimitInMiB` +// The first onve is the legacy config, as it does not support values more than 4GB. +// But we still support it for backward compatibility. If it's set to valid value, +// we use it. If it's set to 0 (which means the value set might be too high), +// we fallback to the second one. +func getMemoryReservedForEveInBytes(ctxPtr *zedmanagerContext) (uint64, error) { + // First, check the legacy config + memoryReservedForEveInBytes := ctxPtr.globalConfig.GlobalValueInt(types.EveMemoryLimitInBytes) + if memoryReservedForEveInBytes != 0 { + return uint64(memoryReservedForEveInBytes), nil + } + // If the legacy config is not set, or contains 0 (which means the value set might be too high), + // fallback to the new config + memoryReservedForEveInMiB := ctxPtr.globalConfig.GlobalValueInt(types.EveMemoryLimitInMiB) + if memoryReservedForEveInMiB != 0 { + return uint64(memoryReservedForEveInMiB) << 20, nil + } + return 0, fmt.Errorf("memoryReservedForEveInMiB is not set") + +} + // getRemainingMemory returns how many bytes remain for app instance usage // which is based on the running and about to run app instances. // It also returns a count for the app instances which are not in those @@ -41,7 +65,10 @@ func getRemainingMemory(ctxPtr *zedmanagerContext) (uint64, uint64, uint64, erro latentMemorySize += mem } } - memoryReservedForEve := uint64(ctxPtr.globalConfig.GlobalValueInt(types.EveMemoryLimitInBytes)) + memoryReservedForEve, err := getMemoryReservedForEveInBytes(ctxPtr) + if err != nil { + return 0, 0, 0, fmt.Errorf("getMemoryReservedForEveInBytes failed: %v", err) + } if vault.ReadPersistType() == types.PersistZFS { zfsArcMaxLimit, err := types.GetZFSArcMaxSizeInBytes() if err != nil { diff --git a/pkg/pillar/types/global.go b/pkg/pillar/types/global.go index f9d02d9ca3..40ff3c12f4 100644 --- a/pkg/pillar/types/global.go +++ b/pkg/pillar/types/global.go @@ -225,7 +225,12 @@ const ( VgaAccess GlobalSettingKey = "debug.enable.vga" // AllowAppVnc global setting key AllowAppVnc GlobalSettingKey = "app.allow.vnc" - // EveMemoryLimitInBytes global setting key + // EveMemoryLimitInMiB global setting key, memory limit for EVE in MiB + EveMemoryLimitInMiB GlobalSettingKey = "memory.eve.limit.MiB" + // EveMemoryLimitInBytes global setting key, memory limit for EVE in bytes + // Deprecated: Use EveMemoryLimitInMiB. This config is limited to 4GB + // as it is stored as uint32. Nevertheles, for backward compatibility, + // this config is still supported and has higher priority than EveMemoryLimitInMiB. EveMemoryLimitInBytes GlobalSettingKey = "memory.eve.limit.bytes" // How much memory overhead is allowed for VMM needs VmmMemoryLimitInMiB GlobalSettingKey = "memory.vmm.limit.MiB" @@ -805,6 +810,8 @@ func NewConfigItemSpecMap() ConfigItemSpecMap { if err != nil { logrus.Errorf("getEveMemoryLimitInBytes failed: %v", err) } + // Round up to the nearest MiB + eveMemoryLimitInMiB := uint32((eveMemoryLimitInBytes + 1024*1024 - 1) / (1024 * 1024)) var configItemSpecMap ConfigItemSpecMap configItemSpecMap.GlobalSettings = make(map[GlobalSettingKey]ConfigItemSpec) configItemSpecMap.AgentSettings = make(map[AgentSettingKey]ConfigItemSpec) @@ -869,6 +876,8 @@ func NewConfigItemSpecMap() ConfigItemSpecMap { // configItemSpecMap.AddIntItem(EveMemoryLimitInBytes, uint32(eveMemoryLimitInBytes), uint32(eveMemoryLimitInBytes), 0xFFFFFFFF) + configItemSpecMap.AddIntItem(EveMemoryLimitInMiB, eveMemoryLimitInMiB, + eveMemoryLimitInMiB, 0xFFFFFFFF) // Limit manual vmm overhead override to 1 PiB configItemSpecMap.AddIntItem(VmmMemoryLimitInMiB, 0, 0, uint32(1024*1024*1024)) // LogRemainToSendMBytes - Default is 2 Gbytes, minimum is 10 Mbytes diff --git a/pkg/pillar/types/global_test.go b/pkg/pillar/types/global_test.go index 6ff3353675..e7c4d6d5c9 100644 --- a/pkg/pillar/types/global_test.go +++ b/pkg/pillar/types/global_test.go @@ -187,6 +187,7 @@ func TestNewConfigItemSpecMap(t *testing.T) { GOGCForcedGrowthMemInMiB, GOGCForcedGrowthMemPerc, EveMemoryLimitInBytes, + EveMemoryLimitInMiB, VmmMemoryLimitInMiB, IgnoreMemoryCheckForApps, IgnoreDiskCheckForApps,