Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
mount: Fix hugepages support
Browse files Browse the repository at this point in the history
Mount hugepage directories and configure the requested number of hugepages
dynamically by writing to sysfs files

Fixes: #871

Signed-off-by: Pradipta Banerjee <pradipta.banerjee@gmail.com>
  • Loading branch information
bpradipt committed Feb 7, 2021
1 parent 25d7471 commit 78b307b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 6 deletions.
9 changes: 9 additions & 0 deletions grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,15 @@ func (a *agentGRPC) UpdateContainer(ctx context.Context, req *pb.UpdateContainer
resources.MemorySwap = req.Resources.Memory.Swap
}

if len(req.Resources.HugepageLimits) > 0 {
for _, l := range req.Resources.HugepageLimits {
resources.HugetlbLimit = append(resources.HugetlbLimit, &configs.HugepageLimit{
Pagesize: l.Pagesize,
Limit: l.Limit,
})
}
}

if req.Resources.Pids != nil {
resources.PidsLimit = req.Resources.Pids.Limit
}
Expand Down
66 changes: 60 additions & 6 deletions mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"bufio"
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
Expand All @@ -26,12 +27,14 @@ import (
)

const (
type9pFs = "9p"
typeVirtioFS = "virtiofs"
typeRootfs = "rootfs"
typeTmpFs = "tmpfs"
procMountStats = "/proc/self/mountstats"
mountPerm = os.FileMode(0755)
type9pFs = "9p"
typeVirtioFS = "virtiofs"
typeRootfs = "rootfs"
typeTmpFs = "tmpfs"
typeHugeTlbfs = "hugetlbfs"
procMountStats = "/proc/self/mountstats"
mountPerm = os.FileMode(0755)
sysfsHugepagesPrefix = "/sys/kernel/mm/hugepages"
)

var flagList = map[string]int{
Expand Down Expand Up @@ -111,6 +114,15 @@ func mount(source, destination, fsType string, flags int, options string) error
absSource = source
case typeTmpFs:
absSource = source
case typeHugeTlbfs:
absSource = source
//Allocate hugepages before mount
///sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
///sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
//options eg "pagesize=2048,size=107374182"
if err = allocateHugePages(options); err != nil {
return grpcStatus.Errorf(codes.Internal, "Could not mount hugepages: %v", err)
}
default:
absSource, err = filepath.EvalSymlinks(source)
if err != nil {
Expand All @@ -132,6 +144,48 @@ func mount(source, destination, fsType string, flags int, options string) error
return nil
}

// Parse filesystem options string to retrieve hugepage details
func getPagesizeAndSizeFromOpt(options string) (string, string) {
//options eg "pagesize=2048,size=107374182"
var pagesizeStr, sizeStr string
fsOpts := strings.Split(options, ",")
for _, opt := range fsOpts {
if strings.HasPrefix(opt, "pagesize=") {
pagesizeStr = strings.TrimPrefix(opt, "pagesize=")
}
if strings.HasPrefix(opt, "size=") {
sizeStr = strings.TrimPrefix(opt, "size=")
}
}
return pagesizeStr, sizeStr
}

// Allocate hugepages by writing to sysfs
func allocateHugePages(options string) error {

agentLog.WithField("HugePagesOption", options).Info("HugePages option string")

pagesizeStr, sizeStr := getPagesizeAndSizeFromOpt(options)
pagesize, err := strconv.ParseInt(pagesizeStr, 10, 64)
if err != nil {
return err
}
//sysfs entry is always of the form hugepages-${size}kB
//Ref: https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
sysfsHugepagesPath := filepath.Join(sysfsHugepagesPrefix, fmt.Sprintf("hugepages-%skB", strconv.FormatInt((pagesize/1024), 10)), "nr_hugepages")

size, err := strconv.ParseInt(sizeStr, 10, 64)
if err != nil {
return err
}
numpages := strconv.FormatInt((size / pagesize), 10)
if err := ioutil.WriteFile(sysfsHugepagesPath, []byte(numpages), 0200); err != nil {
return err
}

return nil
}

// ensureDestinationExists will recursively create a given mountpoint. If directories
// are created, their permissions are initialized to mountPerm
func ensureDestinationExists(source, destination string, fsType string) error {
Expand Down
26 changes: 26 additions & 0 deletions mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,29 @@ func TestGetMountFSType(t *testing.T) {
assert.Equal(d.expectedResult, result, msg)
}
}

func TestGetPagesizeAndSizeFromOpt(t *testing.T) {
assert := assert.New(t)

data := []string{
"size=107374182,pagesize=2048",
"pagesize=2048,size=107374182",
"foo=bar,pagesize=2048,size=107374182",
"foo=bar,pagesize=2048,foo1=bar1,size=107374182",
"pagesize=2048,foo1=bar1,foo=bar,size=107374182",
"foo=bar,pagesize=2048,foo1=bar1,size=107374182,foo2=bar2",
"foo=bar,size=107374182,foo1=bar1,pagesize=2048",
}

resPagesizeStr := "2048"
resSizeStr := "107374182"

for i, opt := range data {
msg := fmt.Sprintf("test[%d]: %+v\n", i, opt)

pagesizeStr, sizeStr := getPagesizeAndSizeFromOpt(opt)

assert.Equal(resPagesizeStr, pagesizeStr, msg)
assert.Equal(resSizeStr, sizeStr, msg)
}
}

0 comments on commit 78b307b

Please sign in to comment.