Skip to content

Commit

Permalink
CPU templates are only available for Intel's x86_64 processors
Browse files Browse the repository at this point in the history
It doesn't work AMD's x86_64 processors sadly.

Fixes firecracker-microvm#525.

Signed-off-by: Kazuyoshi Kato <[email protected]>
  • Loading branch information
kzys committed Aug 4, 2021
1 parent ea585cf commit 6a16cc1
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 16 deletions.
7 changes: 6 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ func LoadConfig(path string) (*Config, error) {
RuncConfigPath: runcConfigPath,
},
}
if internal.SupportCPUTemplate() {

flag, err := internal.SupportCPUTemplate()
if err != nil {
return nil, err
}
if flag {
cfg.CPUTemplate = string(defaultCPUTemplate)
}

Expand Down
7 changes: 0 additions & 7 deletions internal/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"bytes"
"fmt"
"io"
"runtime"
)

const (
Expand Down Expand Up @@ -126,9 +125,3 @@ func GenerateStubContent(id string) (string, error) {

return fmt.Sprintf("%s%c%s", MagicStubBytes, byte(length), id), nil
}

// SupportCPUTemplate returns true if Firecracker supports CPU templates on
// the current architecture.
func SupportCPUTemplate() bool {
return runtime.GOARCH == "amd64"
}
73 changes: 73 additions & 0 deletions internal/cpu_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 internal

import (
"bufio"
"io"
"os"
"regexp"
"runtime"
"sync"
)

var (
isIntel bool
isIntelOnce sync.Once
)

// SupportCPUTemplate returns true if Firecracker supports CPU templates on
// the current architecture.
func SupportCPUTemplate() (bool, error) {
var err error

isIntelOnce.Do(func() {
if runtime.GOARCH == "amd64" {
isIntel, err = checkIsIntel()
} else {
isIntel = false
}
})

return isIntel, err
}

var vendorID = regexp.MustCompile(`^vendor_id\s*:\s*(.+)$`)

func checkIsIntel() (bool, error) {
f, err := os.Open("/proc/cpuinfo")
if err != nil {
return false, err
}
defer f.Close()

id, err := findFirstVendorID(f)
if err != nil {
return false, err
}

return id == "GenuineIntel", nil
}

func findFirstVendorID(r io.Reader) (string, error) {
s := bufio.NewScanner(r)
for s.Scan() {
line := s.Text()
matches := vendorID.FindStringSubmatch(line)
if len(matches) == 2 {
return matches[1], nil
}
}
return "", nil
}
41 changes: 41 additions & 0 deletions internal/cpu_template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 internal

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFindFirstVendorID(t *testing.T) {
cases := []struct {
input string
vendorID string
}{
{"vendor_id : GenuineIntel", "GenuineIntel"},
{"vendor_id : AuthenticAMD", "AuthenticAMD"},

// aarch64 doesn't have vendor IDs.
{"", ""},
}
for _, c := range cases {
r := strings.NewReader(c.input)
id, err := findFirstVendorID(r)
require.NoError(t, err)
assert.Equal(t, c.vendorID, id)
}
}
11 changes: 4 additions & 7 deletions runtime/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
models "github.com/firecracker-microvm/firecracker-go-sdk/client/models"

"github.com/firecracker-microvm/firecracker-containerd/config"
"github.com/firecracker-microvm/firecracker-containerd/internal"
"github.com/firecracker-microvm/firecracker-containerd/proto"
)

Expand All @@ -34,12 +33,10 @@ const (

func machineConfigurationFromProto(cfg *config.Config, req *proto.FirecrackerMachineConfiguration) models.MachineConfiguration {
config := models.MachineConfiguration{
VcpuCount: firecracker.Int64(defaultCPUCount),
MemSizeMib: firecracker.Int64(defaultMemSizeMb),
HtEnabled: firecracker.Bool(cfg.HtEnabled),
}
if internal.SupportCPUTemplate() {
config.CPUTemplate = models.CPUTemplate(cfg.CPUTemplate)
CPUTemplate: models.CPUTemplate(cfg.CPUTemplate),
VcpuCount: firecracker.Int64(defaultCPUCount),
MemSizeMib: firecracker.Int64(defaultMemSizeMb),
HtEnabled: firecracker.Bool(cfg.HtEnabled),
}

if req == nil {
Expand Down
7 changes: 6 additions & 1 deletion runtime/integ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ var defaultRuntimeConfig = config.Config{
}

func init() {
if internal.SupportCPUTemplate() {
flag, err := internal.SupportCPUTemplate()
if err != nil {
panic(err)
}

if flag {
defaultRuntimeConfig.CPUTemplate = "T2"
}
}
Expand Down
8 changes: 8 additions & 0 deletions runtime/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,14 @@ func (s *service) buildVMConfiguration(req *proto.CreateVMRequest) (*firecracker
VMID: s.vmID,
}

flag, err := internal.SupportCPUTemplate()
if err != nil {
return nil, err
}
if !flag {
cfg.MachineCfg.CPUTemplate = ""
}

logPath := s.shimDir.FirecrackerLogFifoPath()
if req.LogFifoPath != "" {
logPath = req.LogFifoPath
Expand Down

0 comments on commit 6a16cc1

Please sign in to comment.