Skip to content

Commit

Permalink
Fix io imits not written after workspace stop
Browse files Browse the repository at this point in the history
  • Loading branch information
Furisto committed Apr 19, 2022
1 parent 587b165 commit ae4e051
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 22 deletions.
2 changes: 1 addition & 1 deletion components/ws-daemon/pkg/cgroup/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (host *PluginHost) WorkspaceAdded(ctx context.Context, ws *dispatch.Workspa

cgroupPath, err := disp.Runtime.ContainerCGroupPath(context.Background(), ws.ContainerID)
if err != nil {
return xerrors.Errorf("cannot start governer: %w", err)
return xerrors.Errorf("cannot get cgroup path for container %s: %w", ws.ContainerID, err)
}

for _, plg := range host.Plugins {
Expand Down
50 changes: 35 additions & 15 deletions components/ws-daemon/pkg/cgroup/plugin_iolimit_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,35 @@ import (
"github.com/gitpod-io/gitpod/common-go/log"
)

type IOLimiterV2 struct {
var clearLimits = ioLimitOptions{
WriteBytesPerSecond: 0,
ReadBytesPerSecond: 0,
WriteIOPs: 0,
ReadIOPs: 0,
}

type ioLimitOptions struct {
WriteBytesPerSecond int64
ReadBytesPerSecond int64
ReadIOPs int64
WriteIOPs int64
ReadIOPs int64
}

type IOLimiterV2 struct {
limits ioLimitOptions
}

func NewIOLimiterV2(writeBytesPerSecond, readBytesPerSecond, writeIOPs, readIOPs int64) *IOLimiterV2 {
limits := ioLimitOptions{
WriteBytesPerSecond: writeBytesPerSecond,
ReadBytesPerSecond: readBytesPerSecond,
WriteIOPs: writeIOPs,
ReadIOPs: readIOPs,
}

return &IOLimiterV2{
limits: limits,
}
}

func (c *IOLimiterV2) Name() string { return "iolimiter-v2" }
Expand All @@ -39,19 +63,15 @@ func (c *IOLimiterV2) Apply(ctx context.Context, basePath, cgroupPath string) er
// Prior to shutting down though, we need to reset the IO limits to ensure we don't have
// processes stuck in the uninterruptable "D" (disk sleep) state. This would prevent the
// workspace pod from shutting down.
c.WriteBytesPerSecond = 0
c.ReadBytesPerSecond = 0
c.WriteIOPs = 0
c.ReadIOPs = 0

err := c.writeIOMax(filepath.Join(basePath, cgroupPath))
err := c.writeIOMax(filepath.Join(basePath, cgroupPath), clearLimits)
if err != nil {
log.WithError(err).WithField("cgroupPath", cgroupPath).Error("cannot write IO limits")
}
log.WithField("cgroupPath", cgroupPath).Debug("stopping io limiting")
return
case <-ticker.C:
err := c.writeIOMax(filepath.Join(basePath, cgroupPath))
err := c.writeIOMax(filepath.Join(basePath, cgroupPath), c.limits)
if err != nil {
log.WithError(err).WithField("cgroupPath", cgroupPath).Error("cannot write IO limits")
}
Expand All @@ -61,7 +81,7 @@ func (c *IOLimiterV2) Apply(ctx context.Context, basePath, cgroupPath string) er
return nil
}

func (c *IOLimiterV2) writeIOMax(loc string) error {
func (c *IOLimiterV2) writeIOMax(loc string, options ioLimitOptions) error {
iostat, err := os.ReadFile(filepath.Join(string(loc), "io.stat"))
if os.IsNotExist(err) {
// cgroup gone is ok due to the dispatch/container race
Expand All @@ -79,15 +99,15 @@ func (c *IOLimiterV2) writeIOMax(loc string) error {
devs = append(devs, fields[0])
}

cpuMaxPath := filepath.Join(string(loc), "io.max")
ioMaxPath := filepath.Join(string(loc), "io.max")
for _, dev := range devs {
err := os.WriteFile(cpuMaxPath, []byte(fmt.Sprintf(
err := os.WriteFile(ioMaxPath, []byte(fmt.Sprintf(
"%s wbps=%s rbps=%s wiops=%s riops=%s",
dev,
getLimit(c.WriteBytesPerSecond),
getLimit(c.ReadBytesPerSecond),
getLimit(c.WriteIOPs),
getLimit(c.ReadIOPs),
getLimit(options.WriteBytesPerSecond),
getLimit(options.ReadBytesPerSecond),
getLimit(options.WriteIOPs),
getLimit(options.ReadIOPs),
)), 0644)
if err != nil {
log.WithField("dev", dev).WithError(err).Warn("cannot write io.max")
Expand Down
7 changes: 1 addition & 6 deletions components/ws-daemon/pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,7 @@ func NewDaemon(config Config, reg prometheus.Registerer) (*Daemon, error) {
&cgroup.CacheReclaim{},
&cgroup.FuseDeviceEnablerV1{},
&cgroup.FuseDeviceEnablerV2{},
&cgroup.IOLimiterV2{
WriteBytesPerSecond: config.IOLimit.WriteBWPerSecond.Value(),
ReadBytesPerSecond: config.IOLimit.ReadBWPerSecond.Value(),
WriteIOPs: config.IOLimit.WriteIOPS,
ReadIOPs: config.IOLimit.ReadIOPS,
},
cgroup.NewIOLimiterV2(config.IOLimit.WriteBWPerSecond.Value(), config.IOLimit.ReadBWPerSecond.Value(), config.IOLimit.WriteIOPS, config.IOLimit.ReadIOPS),
)
if err != nil {
return nil, err
Expand Down

0 comments on commit ae4e051

Please sign in to comment.