Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion internal/builder/vm/lcow/sandbox_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ type SandboxOptions struct {
// Architecture is the processor architecture (e.g., "amd64", "arm64").
Architecture string

// FullyPhysicallyBacked indicates all memory allocations are backed by physical memory.
// FullyPhysicallyBacked reports whether the VM's own memory is physically
// backed (equal to !AllowOvercommit). It does not cover additional devices
// added to the running VM (e.g. file shares or mounted layer disks), whose
// physical backing is determined directly by the FullyPhysicallyBacked annotation.
FullyPhysicallyBacked bool

// ConfidentialConfig carries confidential computing fields that are not
Expand Down
12 changes: 9 additions & 3 deletions internal/builder/vm/lcow/specs.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func BuildSandboxConfig(
// When no-security-hardware is set, we still plumb the policy but use the standard HCS doc.
isConfidentialSNP := sandboxOptions.ConfidentialConfig != nil && !noSecurityHardware

// The FullyPhysicallyBacked annotation forces memory overcommit off.
fullyPhysicallyBacked := oci.ParseAnnotationsBool(ctx, spec.Annotations, shimannotations.FullyPhysicallyBacked, false)

// ================== Parse Topology (CPU, Memory, NUMA) options =================
// ===============================================================================

Expand All @@ -88,7 +91,7 @@ func BuildSandboxConfig(
}

// Parse memory configuration.
memoryConfig, err := parseMemoryOptions(ctx, opts, spec.Annotations, sandboxOptions.FullyPhysicallyBacked)
memoryConfig, err := parseMemoryOptions(ctx, opts, spec.Annotations, fullyPhysicallyBacked)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse memory parameters: %w", err)
}
Expand Down Expand Up @@ -149,7 +152,7 @@ func BuildSandboxConfig(
spec.Devices,
rootFsFullPath,
numa != nil && numaProcessors != nil, // isNumaEnabled
sandboxOptions.FullyPhysicallyBacked, // isFullyPhysicallyBacked
fullyPhysicallyBacked, // isFullyPhysicallyBacked
isConfidentialSNP, // isConfidential
)
if err != nil {
Expand Down Expand Up @@ -207,6 +210,10 @@ func BuildSandboxConfig(
memoryConfig.AllowOvercommit = false
}

// Record whether the VM's own memory is physically backed (!AllowOvercommit).
// This is VM memory backing only, not additional-device backing.
sandboxOptions.FullyPhysicallyBacked = !memoryConfig.AllowOvercommit

// ================== Parse and set Kernel Args ==================================
// ===============================================================================

Expand Down Expand Up @@ -332,7 +339,6 @@ func parseSandboxOptions(ctx context.Context, platform string, annotations map[s
sandboxOptions := &SandboxOptions{
// Extract architecture from platform string (e.g., "linux/amd64" -> "amd64")
Architecture: platform[strings.IndexByte(platform, '/')+1:],
FullyPhysicallyBacked: oci.ParseAnnotationsBool(ctx, annotations, shimannotations.FullyPhysicallyBacked, false),
PolicyBasedRouting: oci.ParseAnnotationsBool(ctx, annotations, iannotations.NetworkingPolicyBasedRouting, false),
NoWritableFileShares: oci.ParseAnnotationsBool(ctx, annotations, shimannotations.DisableWritableFileShares, false),
LiveMigrationSupportEnabled: oci.ParseAnnotationsBool(ctx, annotations, shimannotations.LiveMigrationSupportEnabled, false),
Expand Down
23 changes: 23 additions & 0 deletions internal/builder/vm/lcow/specs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,29 @@ func TestBuildSandboxConfig(t *testing.T) {
}
},
},
{
// FullyPhysicallyBacked tracks the VM's memory backing (!AllowOvercommit),
// so disabling overcommit alone (without the annotation) marks it true.
name: "overcommit off alone marks VM physically backed",
opts: &runhcsoptions.Options{
SandboxPlatform: "linux/amd64",
BootFilesRootPath: validBootFilesPath,
},
spec: &vm.Spec{
Annotations: map[string]string{
shimannotations.AllowOvercommit: "false",
},
},
validate: func(t *testing.T, doc *hcsschema.ComputeSystem, sandboxOpts *SandboxOptions) {
t.Helper()
if doc.VirtualMachine.ComputeTopology.Memory.AllowOvercommit != false {
t.Errorf("expected allow overcommit false, got %v", doc.VirtualMachine.ComputeTopology.Memory.AllowOvercommit)
}
if sandboxOpts.FullyPhysicallyBacked != true {
t.Errorf("expected fully physically backed true when overcommit off, got %v", sandboxOpts.FullyPhysicallyBacked)
}
},
},
{
name: "memory MMIO configuration",
opts: &runhcsoptions.Options{
Expand Down
16 changes: 7 additions & 9 deletions internal/controller/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,15 +530,6 @@ func (c *Controller) Stats(ctx context.Context) (*stats.VirtualMachineStatistics
return nil, fmt.Errorf("cannot get stats: VM is in incorrect state %s", c.vmState)
}

// Initialization of vmmemProcess to calculate stats properly for VA-backed UVMs.
if c.vmmemProcess == 0 {
vmmemHandle, err := vmutils.LookupVMMEM(ctx, c.uvm.RuntimeID(), &iwin.WinAPI{})
if err != nil {
return nil, fmt.Errorf("cannot get stats: %w", err)
}
c.vmmemProcess = vmmemHandle
}

s := &stats.VirtualMachineStatistics{}
props, err := c.uvm.PropertiesV2(ctx, hcsschema.PTStatistics, hcsschema.PTMemory)
if err != nil {
Expand All @@ -553,6 +544,13 @@ func (c *Controller) Stats(ctx context.Context) (*stats.VirtualMachineStatistics
// working set size for a VA-backed UVM. To work around this, we instead
// locate the vmmem process for the VM, and query that process's working set
// instead, which will be the working set for the VM.
if c.vmmemProcess == 0 {
vmmemHandle, err := vmutils.LookupVMMEM(ctx, c.uvm.RuntimeID(), &iwin.WinAPI{})
if err != nil {
return nil, fmt.Errorf("cannot get stats: %w", err)
}
c.vmmemProcess = vmmemHandle
}
memCounters, err := process.GetProcessMemoryInfo(c.vmmemProcess)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion test/parity/vm/lcow_doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func checkSandboxOptionsParity(t *testing.T, legacyOpts *uvm.OptionsLCOW, sandbo
{"NoWritableFileShares", legacyOpts.NoWritableFileShares, sandboxOpts.NoWritableFileShares},
{"EnableScratchEncryption", legacyOpts.EnableScratchEncryption, sandboxOpts.EnableScratchEncryption},
{"PolicyBasedRouting", legacyOpts.PolicyBasedRouting, sandboxOpts.PolicyBasedRouting},
{"FullyPhysicallyBacked", legacyOpts.FullyPhysicallyBacked, sandboxOpts.FullyPhysicallyBacked},
{"PhysicallyBacked", !legacyOpts.AllowOvercommit, sandboxOpts.FullyPhysicallyBacked},
}

for _, c := range checks {
Expand Down
Loading