-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for rdma cgroup introduced in Linux Kernal 4.11
Signed-off-by: flouthoc <[email protected]>
- Loading branch information
Showing
8 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// +build linux | ||
|
||
package fs | ||
|
||
import ( | ||
"github.com/opencontainers/runc/libcontainer/cgroups" | ||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon" | ||
"github.com/opencontainers/runc/libcontainer/configs" | ||
"math" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
type RdmaGroup struct { | ||
} | ||
|
||
func (s *RdmaGroup) Name() string { | ||
return "rdma" | ||
} | ||
|
||
func (s *RdmaGroup) Apply(path string, d *cgroupData) error { | ||
return join(path, d.pid) | ||
} | ||
|
||
func createCmdString(device string, limits configs.LinuxRdma) string { | ||
cmdString := device | ||
if limits.HcaHandles != nil { | ||
cmdString += " hca_handle=" + strconv.FormatUint(uint64(*limits.HcaHandles), 10) | ||
} | ||
if limits.HcaObjects != nil { | ||
cmdString += " hca_object=" + strconv.FormatUint(uint64(*limits.HcaObjects), 10) | ||
} | ||
return cmdString | ||
} | ||
|
||
func (s *RdmaGroup) Set(path string, cgroup *configs.Cgroup) error { | ||
for device, limits := range cgroup.Resources.Rdma { | ||
if err := fscommon.WriteFile(path, "rdma.max", createCmdString(device, limits)); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (s *RdmaGroup) GetStats(path string, stats *cgroups.Stats) error { | ||
if !cgroups.PathExists(path) { | ||
return nil | ||
} | ||
currentData, err := fscommon.ReadFile(path, "rdma.current") | ||
if err != nil { | ||
return err | ||
} | ||
currentPerDevices := strings.Split(currentData, "\n") | ||
maxData, err := fscommon.ReadFile(path, "rdma.max") | ||
if err != nil { | ||
return err | ||
} | ||
maxPerDevices := strings.Split(maxData, "\n") | ||
// If device got removed between reading two files, ignore returning | ||
// stats. | ||
if len(currentPerDevices) != len(maxPerDevices) { | ||
return nil | ||
} | ||
currentEntries := ConvertRdmaEntry(currentPerDevices) | ||
maxEntries := ConvertRdmaEntry(maxPerDevices) | ||
|
||
stats.RdmaStats = cgroups.RdmaStats{ | ||
RdmaLimit: maxEntries, | ||
RdmaCurrent: currentEntries, | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Following is intentionally public as it going to be used by Rdma controller in fs2 | ||
// ParseRdmaKV: parse raw string to RdmaEntry. | ||
func ParseRdmaKV(raw string, entry *cgroups.RdmaEntry) { | ||
var value uint64 | ||
var err error | ||
|
||
parts := strings.SplitN(raw, "=", 3) | ||
if len(parts) == 2 { | ||
if parts[1] == "max" { | ||
value = math.MaxUint32 | ||
} else { | ||
value, err = strconv.ParseUint(parts[1], 10, 32) | ||
if err != nil { | ||
return | ||
} | ||
} | ||
if parts[0] == "hca_handle" { | ||
entry.HcaHandles = uint32(value) | ||
} else if parts[0] == "hca_object" { | ||
entry.HcaObjects = uint32(value) | ||
} | ||
} | ||
} | ||
|
||
// Following is intentionally public as it going to be used by Rdma controller in fs2 | ||
// ConvertRdmaEntry: Converts array of rawstrings to RdmaEntries | ||
func ConvertRdmaEntry(strEntries []string) []cgroups.RdmaEntry { | ||
rdmaEntries := make([]cgroups.RdmaEntry, len(strEntries)) | ||
for i := range strEntries { | ||
parts := strings.Fields(strEntries[i]) | ||
if len(parts) == 3{ | ||
entry := new(cgroups.RdmaEntry) | ||
entry.Device = parts[0] | ||
ParseRdmaKV(parts[1], entry) | ||
ParseRdmaKV(parts[2], entry) | ||
|
||
rdmaEntries = append(rdmaEntries, *entry) | ||
} | ||
} | ||
return rdmaEntries | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// +build linux | ||
|
||
package fs2 | ||
|
||
import ( | ||
"github.com/opencontainers/runc/libcontainer/cgroups" | ||
"github.com/opencontainers/runc/libcontainer/cgroups/fs" | ||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon" | ||
"github.com/opencontainers/runc/libcontainer/configs" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
func isRdmaSet(cgroup *configs.Cgroup) bool { | ||
return len(cgroup.Resources.Rdma) > 0 | ||
} | ||
|
||
func createCmdString(device string, limits configs.LinuxRdma) string { | ||
cmdString := device | ||
if limits.HcaHandles != nil { | ||
cmdString += " hca_handle=" + strconv.FormatUint(uint64(*limits.HcaHandles), 10) | ||
} | ||
if limits.HcaObjects != nil { | ||
cmdString += " hca_object=" + strconv.FormatUint(uint64(*limits.HcaObjects), 10) | ||
} | ||
return cmdString | ||
} | ||
|
||
func setRdma(path string, cgroup *configs.Cgroup) error { | ||
if !isRdmaSet(cgroup) { | ||
return nil | ||
} | ||
for device, limits := range cgroup.Resources.Rdma { | ||
if err := fscommon.WriteFile(path, "rdma.max", createCmdString(device, limits)); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func statRdma(path string, stats *cgroups.Stats) error { | ||
if !cgroups.PathExists(path) { | ||
return nil | ||
} | ||
currentData, err := fscommon.ReadFile(path, "rdma.current") | ||
if err != nil { | ||
return err | ||
} | ||
currentPerDevices := strings.Split(currentData, "\n") | ||
maxData, err := fscommon.ReadFile(path, "rdma.max") | ||
if err != nil { | ||
return err | ||
} | ||
maxPerDevices := strings.Split(maxData, "\n") | ||
// If device got removed between reading two files, ignore returning | ||
// stats. | ||
if len(currentPerDevices) != len(maxPerDevices) { | ||
return nil | ||
} | ||
currentEntries := fs.ConvertRdmaEntry(currentPerDevices) | ||
maxEntries := fs.ConvertRdmaEntry(maxPerDevices) | ||
|
||
stats.RdmaStats = cgroups.RdmaStats{ | ||
RdmaLimit: maxEntries, | ||
RdmaCurrent: currentEntries, | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package configs | ||
|
||
// LinuxRdma for Linux cgroup 'rdma' resource management (Linux 4.11) | ||
type LinuxRdma struct { | ||
// Maximum number of HCA handles that can be opened. Default is "no limit". | ||
HcaHandles *uint32 `json:"hcaHandles,omitempty"` | ||
// Maximum number of HCA objects that can be created. Default is "no limit". | ||
HcaObjects *uint32 `json:"hcaObjects,omitempty"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters