Skip to content

Commit 8eca760

Browse files
committed
fix the issue that CPU quota is 0 if it's not limited by cgroup
Signed-off-by: Yang Keao <[email protected]>
1 parent 3ab8c7f commit 8eca760

File tree

2 files changed

+60
-21
lines changed

2 files changed

+60
-21
lines changed

pkg/util/cgmon/cgmon.go

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ var (
3838
ctx context.Context
3939
cancel context.CancelFunc
4040
wg sync.WaitGroup
41-
cfgMaxProcs int
42-
lastMaxProcs int
41+
lastCPU int
4342
lastMemoryLimit uint64
4443
)
4544

@@ -115,45 +114,44 @@ func refreshCgroupCPU() error {
115114
quota := runtime.NumCPU()
116115

117116
// Get CPU quota from cgroup.
118-
cpuPeriod, cpuQuota, err := cgroup.GetCPUPeriodAndQuota()
119-
if err != nil {
120-
return err
121-
}
122-
if cpuPeriod > 0 && cpuQuota > 0 {
117+
cpuPeriod, cpuQuota, err := getCgroupCPUPeriodAndQuota()
118+
if err == nil && cpuPeriod > 0 && cpuQuota > 0 {
123119
ratio := float64(cpuQuota) / float64(cpuPeriod)
124120
if ratio < float64(quota) {
125121
quota = int(math.Ceil(ratio))
126122
}
127123
}
128124

129-
if quota != lastMaxProcs {
125+
if quota != lastCPU {
130126
log.Info("set the maxprocs", zap.Int("quota", quota))
131127
metrics.MaxProcs.Set(float64(quota))
132-
lastMaxProcs = quota
133-
} else if lastMaxProcs == 0 {
134-
log.Info("set the maxprocs", zap.Int("cfgMaxProcs", cfgMaxProcs))
135-
metrics.MaxProcs.Set(float64(cfgMaxProcs))
136-
lastMaxProcs = cfgMaxProcs
128+
lastCPU = quota
137129
}
138-
return nil
130+
131+
return err
139132
}
140133

141134
func refreshCgroupMemory() error {
142-
memLimit, err := cgroup.GetMemoryLimit()
143-
if err != nil {
144-
return err
145-
}
135+
// Get the total memory limit from `procfs`
146136
vmem, err := mem.VirtualMemory()
147137
if err != nil {
148138
return err
149139
}
150-
if memLimit > vmem.Total {
151-
memLimit = vmem.Total
140+
memLimit := vmem.Total
141+
142+
// Try to update the limit from cgroup.
143+
cgroupMemLimit, err := getCgroupMemoryLimit()
144+
if err == nil && cgroupMemLimit < memLimit {
145+
memLimit = cgroupMemLimit
152146
}
147+
153148
if memLimit != lastMemoryLimit {
154149
log.Info("set the memory limit", zap.Uint64("memLimit", memLimit))
155150
metrics.MemoryLimit.Set(float64(memLimit))
156151
lastMemoryLimit = memLimit
157152
}
158-
return nil
153+
return err
159154
}
155+
156+
var getCgroupCPUPeriodAndQuota = cgroup.GetCPUPeriodAndQuota
157+
var getCgroupMemoryLimit = cgroup.GetMemoryLimit

pkg/util/cgmon/cgmon_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2022 PingCAP, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cgmon
16+
17+
import (
18+
"errors"
19+
"runtime"
20+
"testing"
21+
22+
"github.com/shirou/gopsutil/v3/mem"
23+
"github.com/stretchr/testify/require"
24+
)
25+
26+
func TestUploadDefaultValueWithoutCgroup(t *testing.T) {
27+
getCgroupCPUPeriodAndQuota = func() (period int64, quota int64, err error) {
28+
return 0, 0, errors.New("mock error")
29+
}
30+
getCgroupMemoryLimit = func() (uint64, error) {
31+
return 0, errors.New("mock error")
32+
}
33+
34+
require.Error(t, refreshCgroupCPU())
35+
require.Error(t, refreshCgroupMemory())
36+
37+
require.Equal(t, runtime.NumCPU(), lastCPU)
38+
vmem, err := mem.VirtualMemory()
39+
require.NoError(t, err)
40+
require.Equal(t, vmem.Total, lastMemoryLimit)
41+
}

0 commit comments

Comments
 (0)