diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index d58b51db6e..efe1b1f6a0 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -146,6 +146,17 @@ func verifyContainerResources(resources *containertypes.Resources, isHyperv bool return warnings, fmt.Errorf("range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", sysinfo.NumCPU(), sysinfo.NumCPU()) } + osv := system.GetOSVersion() + if resources.NanoCPUs > 0 && isHyperv && osv.Build < 16175 { + leftoverNanoCPUs := resources.NanoCPUs % 1e9 + if leftoverNanoCPUs != 0 && resources.NanoCPUs > 1e9 { + resources.NanoCPUs = ((resources.NanoCPUs + 1e9/2) / 1e9) * 1e9 + warningString := fmt.Sprintf("Your current OS version does not support Hyper-V containers with NanoCPUs greater than 1000000000 but not divisible by 1000000000. NanoCPUs rounded to %d", resources.NanoCPUs) + warnings = append(warnings, warningString) + logrus.Warn(warningString) + } + } + if len(resources.BlkioDeviceReadBps) > 0 { return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadBps") } diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go index b225d4550d..85e2a9bc14 100644 --- a/daemon/oci_windows.go +++ b/daemon/oci_windows.go @@ -81,10 +81,19 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { // @darrenstahlmsft implement these resources cpuShares := uint16(c.HostConfig.CPUShares) cpuPercent := uint8(c.HostConfig.CPUPercent) - if c.HostConfig.NanoCPUs > 0 { - cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9) - } cpuCount := uint64(c.HostConfig.CPUCount) + if c.HostConfig.NanoCPUs > 0 { + if isHyperV { + cpuCount = uint64(c.HostConfig.NanoCPUs / 1e9) + leftoverNanoCPUs := c.HostConfig.NanoCPUs % 1e9 + if leftoverNanoCPUs != 0 { + cpuCount++ + cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(cpuCount) / 1e9) + } + } else { + cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9) + } + } memoryLimit := uint64(c.HostConfig.Memory) s.Windows.Resources = &specs.WindowsResources{ CPU: &specs.WindowsCPUResources{