From 531c7f8e3f9ef97d54960d6dfab92ce2d97a3b79 Mon Sep 17 00:00:00 2001 From: Robin Lu Date: Fri, 1 Mar 2024 11:19:34 +0800 Subject: [PATCH] feat: adding support to qos level memory.low protection This patch provied the feature of memory.low protection. There are a couple of benefits about memory.low protection: 1, it provides a gradient of protection. As a cgroup's usage grows past the protected amount, the protected amount remains protected, but reclaim pressure for the excess amount gradually increases. 2, it's work-conserving - if the protected cgroup doesn't use the memory, it's available for others to use. Signed-off-by: Robin Lu --- .../app/options/qrm/memory_plugin.go | 16 ++ .../memory/dynamicpolicy/policy.go | 12 + .../memory/handlers/memprotection/const.go | 31 +++ .../memprotection/memprotection_linux.go | 162 +++++++++++++ .../memprotection/memprotection_linux_test.go | 225 ++++++++++++++++++ pkg/config/agent/qrm/memory_plugin.go | 7 + 6 files changed, 453 insertions(+) create mode 100644 pkg/agent/qrm-plugins/memory/handlers/memprotection/const.go create mode 100644 pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux.go create mode 100644 pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux_test.go diff --git a/cmd/katalyst-agent/app/options/qrm/memory_plugin.go b/cmd/katalyst-agent/app/options/qrm/memory_plugin.go index 4edb6807ce..e0ba7997a8 100644 --- a/cmd/katalyst-agent/app/options/qrm/memory_plugin.go +++ b/cmd/katalyst-agent/app/options/qrm/memory_plugin.go @@ -33,6 +33,7 @@ type MemoryOptions struct { OOMPriorityPinnedMapAbsPath string SockMemOptions + MemProtectionOptions } type SockMemOptions struct { @@ -43,6 +44,11 @@ type SockMemOptions struct { SetCgroupTCPMemRatio int } +type MemProtectionOptions struct { + EnableSettingMemProtection bool + MemSoftLimitQoSLevelConfigFile string +} + func NewMemoryOptions() *MemoryOptions { return &MemoryOptions{ PolicyName: "dynamic", @@ -56,6 +62,10 @@ func NewMemoryOptions() *MemoryOptions { SetGlobalTCPMemRatio: 20, // default: 20% * {host total memory} SetCgroupTCPMemRatio: 100, // default: 100% * {cgroup memory} }, + MemProtectionOptions: MemProtectionOptions{ + EnableSettingMemProtection: false, + MemSoftLimitQoSLevelConfigFile: "", + }, } } @@ -84,6 +94,10 @@ func (o *MemoryOptions) AddFlags(fss *cliflag.NamedFlagSets) { o.SetGlobalTCPMemRatio, "limit global max tcp memory usage") fs.IntVar(&o.SetCgroupTCPMemRatio, "qrm-memory-cgroup-tcpmem-ratio", o.SetCgroupTCPMemRatio, "limit cgroup max tcp memory usage") + fs.BoolVar(&o.EnableSettingMemProtection, "enable-setting-mem-protection", + o.EnableSettingMemProtection, "if set true, we will do memory protection in qos level") + fs.StringVar(&o.MemSoftLimitQoSLevelConfigFile, "mem-softlimit-qos-config-file", + o.MemSoftLimitQoSLevelConfigFile, "the absolute path of mem.low qos level config file") } func (o *MemoryOptions) ApplyTo(conf *qrmconfig.MemoryQRMPluginConfig) error { conf.PolicyName = o.PolicyName @@ -97,5 +111,7 @@ func (o *MemoryOptions) ApplyTo(conf *qrmconfig.MemoryQRMPluginConfig) error { conf.EnableSettingSockMem = o.EnableSettingSockMem conf.SetGlobalTCPMemRatio = o.SetGlobalTCPMemRatio conf.SetCgroupTCPMemRatio = o.SetCgroupTCPMemRatio + conf.EnableSettingMemProtection = o.EnableSettingMemProtection + conf.MemSoftLimitQoSLevelConfigFile = o.MemSoftLimitQoSLevelConfigFile return nil } diff --git a/pkg/agent/qrm-plugins/memory/dynamicpolicy/policy.go b/pkg/agent/qrm-plugins/memory/dynamicpolicy/policy.go index 737b0a97c1..dfeba9b1f8 100644 --- a/pkg/agent/qrm-plugins/memory/dynamicpolicy/policy.go +++ b/pkg/agent/qrm-plugins/memory/dynamicpolicy/policy.go @@ -39,6 +39,7 @@ import ( "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/dynamicpolicy/memoryadvisor" "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/dynamicpolicy/oom" "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/dynamicpolicy/state" + "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/handlers/memprotection" "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/handlers/sockmem" "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/util" "github.com/kubewharf/katalyst-core/pkg/agent/utilcomponent/periodicalhandler" @@ -130,6 +131,7 @@ type DynamicPolicy struct { enableSettingMemoryMigrate bool enableSettingSockMem bool + enableSettingMemProtection bool enableMemoryAdvisor bool memoryAdvisorSocketAbsPath string memoryPluginSocketAbsPath string @@ -191,6 +193,7 @@ func NewDynamicPolicy(agentCtx *agent.GenericContext, conf *config.Configuration asyncWorkers: asyncworker.NewAsyncWorkers(memoryPluginAsyncWorkersName, wrappedEmitter), enableSettingMemoryMigrate: conf.EnableSettingMemoryMigrate, enableSettingSockMem: conf.EnableSettingSockMem, + enableSettingMemProtection: conf.EnableSettingMemProtection, enableMemoryAdvisor: conf.EnableMemoryAdvisor, memoryAdvisorSocketAbsPath: conf.MemoryAdvisorSocketAbsPath, memoryPluginSocketAbsPath: conf.MemoryPluginSocketAbsPath, @@ -300,6 +303,15 @@ func (p *DynamicPolicy) Start() (err error) { } } + if p.enableSettingMemProtection { + general.Infof("setMemProtection enabled") + err := periodicalhandler.RegisterPeriodicalHandler(qrm.QRMMemoryPluginPeriodicalHandlerGroupName, + memprotection.EnableSetMemProtectionPeriodicalHandlerName, memprotection.MemProtectionTaskFunc, 60*time.Second) + if err != nil { + general.Infof("setSockMem failed, err=%v", err) + } + } + go wait.Until(func() { periodicalhandler.ReadyToStartHandlersByGroup(qrm.QRMMemoryPluginPeriodicalHandlerGroupName) }, 5*time.Second, p.stopCh) diff --git a/pkg/agent/qrm-plugins/memory/handlers/memprotection/const.go b/pkg/agent/qrm-plugins/memory/handlers/memprotection/const.go new file mode 100644 index 0000000000..d41293ba68 --- /dev/null +++ b/pkg/agent/qrm-plugins/memory/handlers/memprotection/const.go @@ -0,0 +1,31 @@ +/* +Copyright 2022 The Katalyst Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package memprotection + +const EnableSetMemProtectionPeriodicalHandlerName = "SetCGMemProtection" + +const ( + // Constants for cgroup memory statistics + cgroupMemoryLimit2G = 2147483648 + cgroupMemoryLimit128M = 134217728 + + controlKnobKeyMemSoftLimit = "mem_softlimit" +) + +const ( + metricNameMemLow = "async_handler_cgroup_memlow" +) diff --git a/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux.go b/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux.go new file mode 100644 index 0000000000..f885cd00c2 --- /dev/null +++ b/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux.go @@ -0,0 +1,162 @@ +//go:build linux +// +build linux + +/* +Copyright 2022 The Katalyst Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package memprotection + +import ( + "context" + "strconv" + + "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/commonstate" + coreconfig "github.com/kubewharf/katalyst-core/pkg/config" + dynamicconfig "github.com/kubewharf/katalyst-core/pkg/config/agent/dynamic" + "github.com/kubewharf/katalyst-core/pkg/metaserver" + "github.com/kubewharf/katalyst-core/pkg/metrics" + cgroupcm "github.com/kubewharf/katalyst-core/pkg/util/cgroup/common" + cgroupmgr "github.com/kubewharf/katalyst-core/pkg/util/cgroup/manager" + "github.com/kubewharf/katalyst-core/pkg/util/general" + "github.com/kubewharf/katalyst-core/pkg/util/native" +) + +func convertMemRatioToBytes(memLimit, memRatio uint64) uint64 { + limitInBytes := memLimit / 100 * memRatio + // Any value related to cgroup memory limitation should be aligned with the page size. + limitInBytes = general.AlignToPageSize(limitInBytes) + + return limitInBytes +} + +func getMemProtectionInBytes(memLimit, memRatio uint64) uint64 { + // Step1, convert ratio into bytes + result := convertMemRatioToBytes(memLimit, memRatio) + // Step2, performing specific operations within the memory.low + // Notice: we limited memory.low between {128M, 2G} + result = uint64(general.Clamp(float64(result), float64(cgroupMemoryLimit128M), float64(cgroupMemoryLimit2G))) + + return result +} + +func getUserSpecifiedMemoryProtectionInBytes(relCgroupPath, ratio string) int64 { + memStat, err := cgroupmgr.GetMemoryWithRelativePath(relCgroupPath) + if err != nil { + general.Warningf("getUserSpecifiedMemoryProtectionInBytes failed with err: %v", err) + return 0 + } + + memProtectionRatio, err := strconv.Atoi(ratio) + if err != nil { + general.Warningf("getUserSpecifiedMemoryProtectionInBytes failed with err: %v", err) + return 0 + } + + bytes := getMemProtectionInBytes(memStat.Limit, uint64(memProtectionRatio)) + return int64(bytes) +} + +func applyMemSoftLimitQoSLevelConfig(conf *coreconfig.Configuration, + emitter metrics.MetricEmitter, metaServer *metaserver.MetaServer) { + if conf.MemSoftLimitQoSLevelConfigFile == "" { + general.Infof("no MemSoftLimitQoSLevelConfigFile found") + return + } + + var extraControlKnobConfigs commonstate.ExtraControlKnobConfigs + if err := general.LoadJsonConfig(conf.MemSoftLimitQoSLevelConfigFile, &extraControlKnobConfigs); err != nil { + general.Errorf("MemSoftLimitQoSLevelConfigFile load failed:%v", err) + return + } + ctx := context.Background() + podList, err := metaServer.GetPodList(ctx, native.PodIsActive) + if err != nil { + general.Infof("get pod list failed: %v", err) + return + } + + for _, pod := range podList { + if pod == nil { + general.Warningf("get nil pod from metaServer") + continue + } + qosConfig := conf.QoSConfiguration + qosLevel, err := qosConfig.GetQoSLevelForPod(pod) + if err != nil { + general.Warningf("GetQoSLevelForPod failed:%v", err) + continue + } + qosLevelDefaultValue, ok := extraControlKnobConfigs[controlKnobKeyMemSoftLimit].QoSLevelToDefaultValue[qosLevel] + if !ok { + continue + } + + for _, containerStatus := range pod.Status.ContainerStatuses { + podUID, containerID := string(pod.UID), native.TrimContainerIDPrefix(containerStatus.ContainerID) + relCgPath, err := cgroupcm.GetContainerRelativeCgroupPath(podUID, containerID) + if err != nil { + general.Warningf("GetContainerRelativeCgroupPath failed, pod=%v, container=%v, err=%v", podUID, containerID, err) + continue + } + softLimit := getUserSpecifiedMemoryProtectionInBytes(relCgPath, qosLevelDefaultValue) + if softLimit == 0 { + general.Warningf("getUserSpecifiedMemoryProtectionBytes return 0") + continue + } + + var data *cgroupcm.MemoryData + data = &cgroupcm.MemoryData{SoftLimitInBytes: softLimit} + if err := cgroupmgr.ApplyMemoryWithRelativePath(relCgPath, data); err != nil { + general.Warningf("ApplyMemoryWithRelativePath failed, cgpath=%v, err=%v", relCgPath, err) + continue + } + + _ = emitter.StoreInt64(metricNameMemLow, softLimit, metrics.MetricTypeNameRaw, + metrics.ConvertMapToTags(map[string]string{ + "podUID": podUID, + "containerID": containerID, + })...) + } + } +} + +func MemProtectionTaskFunc(conf *coreconfig.Configuration, + _ interface{}, _ *dynamicconfig.DynamicAgentConfiguration, + emitter metrics.MetricEmitter, metaServer *metaserver.MetaServer) { + general.Infof("called") + + if conf == nil { + general.Errorf("nil extraConf") + return + } else if emitter == nil { + general.Errorf("nil emitter") + return + } else if metaServer == nil { + general.Errorf("nil metaServer") + return + } + + // SettingMemProtection featuregate. + if !conf.EnableSettingMemProtection { + general.Infof("EnableSettingMemProtection disabled") + return + } + + // checking qos-level memory.low configuration. + if len(conf.MemSoftLimitQoSLevelConfigFile) > 0 { + applyMemSoftLimitQoSLevelConfig(conf, emitter, metaServer) + } +} diff --git a/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux_test.go b/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux_test.go new file mode 100644 index 0000000000..57532615a2 --- /dev/null +++ b/pkg/agent/qrm-plugins/memory/handlers/memprotection/memprotection_linux_test.go @@ -0,0 +1,225 @@ +//go:build linux +// +build linux + +/* +Copyright 2022 The Katalyst Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package memprotection + +import ( + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + coreconfig "github.com/kubewharf/katalyst-core/pkg/config" + "github.com/kubewharf/katalyst-core/pkg/config/agent" + configagent "github.com/kubewharf/katalyst-core/pkg/config/agent" + dynamicconfig "github.com/kubewharf/katalyst-core/pkg/config/agent/dynamic" + "github.com/kubewharf/katalyst-core/pkg/config/agent/qrm" + "github.com/kubewharf/katalyst-core/pkg/metaserver" + metaagent "github.com/kubewharf/katalyst-core/pkg/metaserver/agent" + "github.com/kubewharf/katalyst-core/pkg/metaserver/agent/metric" + "github.com/kubewharf/katalyst-core/pkg/metaserver/agent/pod" + "github.com/kubewharf/katalyst-core/pkg/metrics" + "github.com/kubewharf/katalyst-core/pkg/util/machine" +) + +func makeMetaServer() (*metaserver.MetaServer, error) { + server := &metaserver.MetaServer{ + MetaAgent: &metaagent.MetaAgent{}, + } + + cpuTopology, err := machine.GenerateDummyCPUTopology(16, 1, 2) + if err != nil { + return nil, err + } + + server.KatalystMachineInfo = &machine.KatalystMachineInfo{ + CPUTopology: cpuTopology, + } + server.MetricsFetcher = metric.NewFakeMetricsFetcher(metrics.DummyMetrics{}) + return server, nil +} + +func TestMemProtection(t *testing.T) { + t.Parallel() + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: false, + }, + }, + }, + }, + }, + }, nil, &dynamicconfig.DynamicAgentConfiguration{}, nil, nil) + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + }, + }, + }, + }, + }, + }, nil, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, nil) + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, nil) + + metaServer, err := makeMetaServer() + assert.NoError(t, err) + metaServer.PodFetcher = &pod.PodFetcherStub{PodList: []*v1.Pod{}} + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, metaServer) + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: false, + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, metaServer) + + normalPod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + UID: "normalPod", + Name: "normalPod", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "c", + }, + }, + }, + } + + metaServer.PodFetcher = &pod.PodFetcherStub{PodList: []*v1.Pod{normalPod}} + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, metaServer) + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + MemSoftLimitQoSLevelConfigFile: "", + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, metaServer) + + MemProtectionTaskFunc(&coreconfig.Configuration{ + AgentConfiguration: &agent.AgentConfiguration{ + StaticAgentConfiguration: &configagent.StaticAgentConfiguration{ + QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ + MemoryQRMPluginConfig: &qrm.MemoryQRMPluginConfig{ + MemProtectionOptions: qrm.MemProtectionOptions{ + EnableSettingMemProtection: true, + MemSoftLimitQoSLevelConfigFile: "fake", + }, + }, + }, + }, + }, + }, metrics.DummyMetrics{}, &dynamicconfig.DynamicAgentConfiguration{}, metrics.DummyMetrics{}, metaServer) +} + +func TestGetSoftMemLimitInBytes(t *testing.T) { + t.Parallel() + // Test case where memRatio is 50% of memLimit + result := getMemProtectionInBytes(1024*1024*1024, 50) + expected := uint64(536870912) // 50% of 1GB + assert.Equal(t, expected, result, "Test case 1 failed") + + // Test case where memRatio is 75% of memLimit + result = getMemProtectionInBytes(1024*1024*1024, 75) + expected = uint64(805306368) // 75% of 1GB + assert.Equal(t, expected, result, "Test case 2 failed") + + // Test case where memRatio is 25% of memLimit + result = getMemProtectionInBytes(512*1024*1024, 25) + expected = uint64(134217728) // 25% of 512MB + assert.Equal(t, expected, result, "Test case 3 failed") + + // Test case where memRatio is 0% (minimum value) + result = getMemProtectionInBytes(1024*1024*1024, 0) + expected = uint64(134217728) // 0% should be clamped to the minimum value + assert.Equal(t, expected, result, "Test case 4 failed") +} + +func TestGetUserSpecifiedMemoryProtectionInBytes(t *testing.T) { + t.Parallel() + + result := getUserSpecifiedMemoryProtectionInBytes("fake", "15") + var expected int64 = 0 + assert.Equal(t, expected, result, "Test getUserSpecifiedMemProtectionInBytes failed") +} diff --git a/pkg/config/agent/qrm/memory_plugin.go b/pkg/config/agent/qrm/memory_plugin.go index 02004d7730..37b368bd0b 100644 --- a/pkg/config/agent/qrm/memory_plugin.go +++ b/pkg/config/agent/qrm/memory_plugin.go @@ -36,6 +36,8 @@ type MemoryQRMPluginConfig struct { // SockMemQRMPluginConfig: the configuration for sockmem limitation in cgroup and host level SockMemQRMPluginConfig + // MemProtectionOptions: the configuration for cgroup memory protection in qos level + MemProtectionOptions } type SockMemQRMPluginConfig struct { @@ -47,6 +49,11 @@ type SockMemQRMPluginConfig struct { SetCgroupTCPMemRatio int } +type MemProtectionOptions struct { + EnableSettingMemProtection bool + MemSoftLimitQoSLevelConfigFile string +} + func NewMemoryQRMPluginConfig() *MemoryQRMPluginConfig { return &MemoryQRMPluginConfig{} }