From e86cb2f8a9075187607e5f49cf93fda9b75f7338 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 9 Apr 2020 17:55:13 +0200 Subject: bug: Do not schedule too large VMs on hypervisors --- .../opendc/compute/virt/service/SimpleVirtProvisioningService.kt | 4 +++- .../virt/service/allocation/ComparableAllocationPolicyLogic.kt | 6 +++++- .../compute/virt/service/allocation/RandomAllocationPolicy.kt | 6 +++++- .../kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt | 9 +++++---- 4 files changed, 18 insertions(+), 7 deletions(-) (limited to 'opendc') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt index 85bdc438..2e483db4 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt @@ -28,6 +28,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import kotlin.coroutines.Continuation import kotlin.coroutines.resume +import kotlin.math.max @OptIn(ExperimentalCoroutinesApi::class) class SimpleVirtProvisioningService( @@ -121,8 +122,9 @@ class SimpleVirtProvisioningService( for (imageInstance in imagesToBeScheduled) { val requiredMemory = (imageInstance.image as VmImage).requiredMemory val selectedHv = allocationLogic.select(availableHypervisors, imageInstance) ?: break + try { - log.info("Spawning ${imageInstance.image} on ${selectedHv.server} ${availableHypervisors.size}") + log.info("Spawning ${imageInstance.image} on ${selectedHv.server}") incomingImages -= imageInstance // Speculatively update the hypervisor view information to prevent other images in the queue from diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/ComparableAllocationPolicyLogic.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/ComparableAllocationPolicyLogic.kt index 5e41bcef..79dd95f3 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/ComparableAllocationPolicyLogic.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/ComparableAllocationPolicyLogic.kt @@ -42,7 +42,11 @@ interface ComparableAllocationPolicyLogic : AllocationPolicy.Logic { image: SimpleVirtProvisioningService.ImageView ): HypervisorView? { return hypervisors.asSequence() - .filter { it.availableMemory >= (image.image as VmImage).requiredMemory } + .filter { hv -> + val fitsMemory = hv.availableMemory >= (image.image as VmImage).requiredMemory + val fitsCpu = hv.server.flavor.cpuCount >= image.flavor.cpuCount + fitsMemory && fitsCpu + } .minWith(comparator.thenBy { it.server.uid }) } } diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/RandomAllocationPolicy.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/RandomAllocationPolicy.kt index 142846ac..07dcf1c5 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/RandomAllocationPolicy.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/allocation/RandomAllocationPolicy.kt @@ -40,7 +40,11 @@ public class RandomAllocationPolicy(val random: Random = Random(0)) : Allocation image: SimpleVirtProvisioningService.ImageView ): HypervisorView? { return hypervisors.asIterable() - .filter { it.availableMemory >= (image.image as VmImage).requiredMemory } + .filter { hv -> + val fitsMemory = hv.availableMemory >= (image.image as VmImage).requiredMemory + val fitsCpu = hv.server.flavor.cpuCount >= image.flavor.cpuCount + fitsMemory && fitsCpu + } .randomOrNull(random) } } diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt index 18cfed5f..8eeffa6b 100644 --- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt +++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt @@ -228,20 +228,21 @@ fun main(args: Array) { null } - val running = mutableSetOf() val finish = Channel(Channel.RENDEZVOUS) + var submitted = 0 + var finished = 0 val reader = Sc20TraceReader(File(traceDirectory), performanceInterferenceModel, getSelectedVmList()) while (reader.hasNext()) { val (time, workload) = reader.next() delay(max(0, time - simulationContext.clock.millis())) + submitted++ launch { chan.send(Unit) val server = scheduler.deploy( workload.image.name, workload.image, Flavor(workload.image.maxCores, workload.image.requiredMemory) ) - running += server // Monitor server events server.events .onEach { @@ -250,10 +251,10 @@ fun main(args: Array) { // Detect whether the VM has finished running if (it.server.state == ServerState.SHUTOFF) { - running -= server + finished++ } - if (running.isEmpty() && !reader.hasNext()) { + if (finished == submitted && !reader.hasNext()) { finish.send(Unit) } } -- cgit v1.2.3