Browse code

Fix scaling of NanoCPUs on Hyper-V containers

Signed-off-by: Darren Stahl <darst@microsoft.com>

Darren Stahl authored on 2017/04/13 08:54:27
Showing 2 changed files
... ...
@@ -146,6 +146,17 @@ func verifyContainerResources(resources *containertypes.Resources, isHyperv bool
146 146
 		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())
147 147
 	}
148 148
 
149
+	osv := system.GetOSVersion()
150
+	if resources.NanoCPUs > 0 && isHyperv && osv.Build < 16175 {
151
+		leftoverNanoCPUs := resources.NanoCPUs % 1e9
152
+		if leftoverNanoCPUs != 0 && resources.NanoCPUs > 1e9 {
153
+			resources.NanoCPUs = ((resources.NanoCPUs + 1e9/2) / 1e9) * 1e9
154
+			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)
155
+			warnings = append(warnings, warningString)
156
+			logrus.Warn(warningString)
157
+		}
158
+	}
159
+
149 160
 	if len(resources.BlkioDeviceReadBps) > 0 {
150 161
 		return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadBps")
151 162
 	}
... ...
@@ -81,10 +81,19 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
81 81
 	// @darrenstahlmsft implement these resources
82 82
 	cpuShares := uint16(c.HostConfig.CPUShares)
83 83
 	cpuPercent := uint8(c.HostConfig.CPUPercent)
84
+	cpuCount := uint64(c.HostConfig.CPUCount)
84 85
 	if c.HostConfig.NanoCPUs > 0 {
85
-		cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9)
86
+		if isHyperV {
87
+			cpuCount = uint64(c.HostConfig.NanoCPUs / 1e9)
88
+			leftoverNanoCPUs := c.HostConfig.NanoCPUs % 1e9
89
+			if leftoverNanoCPUs != 0 {
90
+				cpuCount++
91
+				cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(cpuCount) / 1e9)
92
+			}
93
+		} else {
94
+			cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9)
95
+		}
86 96
 	}
87
-	cpuCount := uint64(c.HostConfig.CPUCount)
88 97
 	memoryLimit := uint64(c.HostConfig.Memory)
89 98
 	s.Windows.Resources = &specs.WindowsResources{
90 99
 		CPU: &specs.WindowsCPUResources{