Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP4:Update
kubevirt
0012-TSC-frequencies-add-250PPM-tolerance.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0012-TSC-frequencies-add-250PPM-tolerance.patch of Package kubevirt
From c4e1f26193bd9bf83cff0881b790def2f3ba111c Mon Sep 17 00:00:00 2001 From: Jed Lejosne <jed@redhat.com> Date: Thu, 20 Apr 2023 16:45:47 -0400 Subject: [PATCH] TSC frequencies: add 250PPM tolerance It is possible to migrate VMs to nodes that have a TSC frequency within 250PPM of theirs. This adds support for it by tagging nodes with VMI frequencies within the tolerance range. Signed-off-by: Jed Lejosne <jed@redhat.com> --- pkg/virt-controller/watch/topology/filter.go | 8 ++++++ pkg/virt-controller/watch/topology/tsc.go | 26 ++++++++++++++----- .../watch/topology/tsc_test.go | 21 ++++++++++----- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/pkg/virt-controller/watch/topology/filter.go b/pkg/virt-controller/watch/topology/filter.go index 0108f5a41..ddf05489a 100644 --- a/pkg/virt-controller/watch/topology/filter.go +++ b/pkg/virt-controller/watch/topology/filter.go @@ -1,6 +1,8 @@ package topology import ( + "math" + v1 "k8s.io/api/core/v1" virtv1 "kubevirt.io/api/core/v1" @@ -10,6 +12,7 @@ import ( const TSCFrequencyLabel = virtv1.CPUTimerLabel + "tsc-frequency" const TSCFrequencySchedulingLabel = "scheduling.node.kubevirt.io/tsc-frequency" const TSCScalableLabel = virtv1.CPUTimerLabel + "tsc-scalable" +const TSCTolerancePPM float64 = 250 type FilterPredicateFunc func(node *v1.Node) bool @@ -89,3 +92,8 @@ func FilterNodesFromCache(objs []interface{}, predicates ...FilterPredicateFunc) } return match } + +// ToleranceForFrequency returns TSCTolerancePPM parts per million of freq, rounded down to the nearest Hz +func ToleranceForFrequency(freq int64) int64 { + return int64(math.Floor(float64(freq) * (TSCTolerancePPM / 1000000))) +} diff --git a/pkg/virt-controller/watch/topology/tsc.go b/pkg/virt-controller/watch/topology/tsc.go index 71635626c..bfcc0c76c 100644 --- a/pkg/virt-controller/watch/topology/tsc.go +++ b/pkg/virt-controller/watch/topology/tsc.go @@ -70,14 +70,24 @@ func TSCFrequenciesOnNode(node *v1.Node) (frequencies []int64) { return } -func CalculateTSCLabelDiff(frequenciesInUse []int64, frequenciesOnNode []int64, nodeFrequency int64, scalable bool) (toAdd []int64, toRemove []int64) { - if scalable { - frequenciesInUse = append(frequenciesInUse, nodeFrequency) - } else { - frequenciesInUse = []int64{nodeFrequency} +func distance(freq1, freq2 int64) int64 { + if freq1 > freq2 { + return freq1 - freq2 } + return freq2 - freq1 +} + +func CalculateTSCLabelDiff(frequenciesInUse []int64, frequenciesOnNode []int64, nodeFrequency int64, scalable bool) (toAdd []int64, toRemove []int64) { + frequenciesInUse = append(frequenciesInUse, nodeFrequency) + tolerance := ToleranceForFrequency(nodeFrequency) requiredMap := map[int64]struct{}{} for _, freq := range frequenciesInUse { + if !scalable && distance(freq, nodeFrequency) > tolerance { + // A non-scalable node can only accept frequencies that are within Qemu's tolerance: + // nodeFrequency*(1-0.000250) < acceptableFrequency < nodeFrequency*(1+0.000250). + // Skip the frequencies that are outside that range + continue + } requiredMap[freq] = struct{}{} } @@ -87,8 +97,10 @@ func CalculateTSCLabelDiff(frequenciesInUse []int64, frequenciesOnNode []int64, } } - for _, freq := range frequenciesInUse { - if freq <= nodeFrequency { + for freq := range requiredMap { + // For the non-scalable case, the map was already sanitized above. + // For the scalable case, a node can accept frequencies that are either lower than its own or within the tolerance range + if !scalable || freq <= nodeFrequency || distance(freq, nodeFrequency) <= tolerance { toAdd = append(toAdd, freq) } } diff --git a/pkg/virt-controller/watch/topology/tsc_test.go b/pkg/virt-controller/watch/topology/tsc_test.go index 79ea8083d..a112faa7c 100644 --- a/pkg/virt-controller/watch/topology/tsc_test.go +++ b/pkg/virt-controller/watch/topology/tsc_test.go @@ -36,8 +36,8 @@ var _ = Describe("TSC", func() { DescribeTable("should calculate the node label diff", func(frequenciesInUse []int64, frequenciesOnNode []int64, nodeFrequency int64, scalable bool, expectedToAdd []int64, expectedToRemove []int64) { toAdd, toRemove := topology.CalculateTSCLabelDiff(frequenciesInUse, frequenciesOnNode, nodeFrequency, scalable) - Expect(toAdd).To(Equal(expectedToAdd)) - Expect(toRemove).To(Equal(expectedToRemove)) + Expect(toAdd).To(ConsistOf(expectedToAdd)) + Expect(toRemove).To(ConsistOf(expectedToRemove)) }, Entry( "on a scalable node", @@ -50,15 +50,15 @@ var _ = Describe("TSC", func() { ), Entry( "on a scalable node where not all required frequencies are compatible", - []int64{1, 2, 3, 200}, + []int64{1, 2, 3, 123130, 200000}, // 123130 is above but within 250 PPM []int64{2, 4}, - int64(123), + int64(123123), true, - []int64{1, 2, 3, 123}, + []int64{1, 2, 3, 123123, 123130}, []int64{4}, ), Entry( - "on a not scalable node where only the node frequency can be set", + "on a non-scalable node where only the node frequency can be set", []int64{1, 2, 3}, []int64{2, 4}, int64(123), @@ -66,6 +66,15 @@ var _ = Describe("TSC", func() { []int64{123}, []int64{2, 4}, ), + Entry( + "on a non-scalable node where other node frequencies are close-enough", + []int64{1, 2, 123120, 123130}, // 250 PPM of 123123 is 30 + []int64{2, 4}, + int64(123123), + false, + []int64{123123, 123120, 123130}, + []int64{2, 4}, + ), ) }) -- 2.40.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor