)
func init() {
- RegisterCpuPinningSoloTests(DefaultCpuConfigurationTest, SkipCoresTest)
+ RegisterCpuPinningSoloTests(DefaultCpuConfigurationTest, MainThreadOnlyNoPinningTest, MainThreadOnlyTest, CorelistWorkersTest, RelativeMainThreadOnlyTest, RelativeAutoWorkersTest, RelativeAutoWorkersSkipCoresTest, RelativeCorelistWorkersTest, RelativeCorelistWorkersSkipCoresTest)
}
-// TODO: Add more CPU configuration tests
+/* Following test-cases verify that VPP CPU pinning configuration work as expected.
+
+Certain configuration are not tested here, as they are expected to fail in the CI environment.
+
+Assuming the vpp CI container is allocated CPUs [37 38 39]:
+Config #1: 'cpu {main-core x workers y}'
+e.g. 'cpu {main-core 37 workers 2}' will fail as workers will be assigned automatically to CPUs 1 and 2, outside the allowed cpuset
+Config #2: 'cpu {main-core x corelist-workers y skip-cores z}'
+e.g. 'cpu {main-core 37 corelist-workers 38-39 skip-cores 1}' will not behave as expected, as CPU 0 will be skipped
+*/
func DefaultCpuConfigurationTest(s *CpuPinningSuite) {
vpp := s.Containers.Vpp.VppInstance
s.AssertNil(vpp.Start())
}
-func SkipCoresTest(s *CpuPinningSuite) {
+// cpu {} (main thread is pinned on CPU that VPP launches on)
+func MainThreadOnlyNoPinningTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: false,
+ UseWorkers: false,
+ PinWorkersCorelist: false,
+ RelativeCores: false,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x}
+func MainThreadOnlyTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: false,
+ PinWorkersCorelist: false,
+ RelativeCores: false,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x corelist-workers y}
+func CorelistWorkersTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: true,
+ PinWorkersCorelist: true,
+ RelativeCores: false,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x relative}
+func RelativeMainThreadOnlyTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: false,
+ PinWorkersCorelist: false,
+ RelativeCores: true,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x workers y relative}
+func RelativeAutoWorkersTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: true,
+ PinWorkersCorelist: false,
+ RelativeCores: true,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x workers y skip-cores z relative}
+func RelativeAutoWorkersSkipCoresTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: true,
+ PinWorkersCorelist: false,
+ RelativeCores: true,
+ SkipCores: 1, /* skip 1 core */
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x corelist-workers y relative}
+func RelativeCorelistWorkersTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
+ PinMainCpu: true,
+ UseWorkers: true,
+ PinWorkersCorelist: true,
+ RelativeCores: true,
+ SkipCores: 0,
+ }
+
+ vpp := s.Containers.Vpp.VppInstance
+ vpp.CpuConfig = vppCpuConfig
+
+ s.AssertNil(vpp.Start())
+}
- skipCoresConfiguration := VppCpuConfig{
+// cpu {main-core x corelist-workers y skip-cores z relative}
+func RelativeCorelistWorkersSkipCoresTest(s *CpuPinningSuite) {
+ vppCpuConfig := VppCpuConfig{
PinMainCpu: true,
+ UseWorkers: true,
PinWorkersCorelist: true,
- SkipCores: 1,
+ RelativeCores: true,
+ SkipCores: 1, /* skip 1 core */
}
vpp := s.Containers.Vpp.VppInstance
- vpp.CpuConfig = skipCoresConfiguration
+ vpp.CpuConfig = vppCpuConfig
s.AssertNil(vpp.Start())
}
type VppCpuConfig struct {
PinMainCpu bool
+ UseWorkers bool
PinWorkersCorelist bool
+ RelativeCores bool
SkipCores int
}
func (vpp *VppInstance) setDefaultCpuConfig() {
vpp.CpuConfig.PinMainCpu = true
+ vpp.CpuConfig.UseWorkers = true
vpp.CpuConfig.PinWorkersCorelist = true
+ vpp.CpuConfig.RelativeCores = false
vpp.CpuConfig.SkipCores = 0
}
c.NewStanza("cpu")
+ if vpp.CpuConfig.RelativeCores {
+ c.Append("relative")
+ vpp.getSuite().Log("relative")
+ }
+
// If skip-cores is valid, use as start value to assign main/workers CPUs
if vpp.CpuConfig.SkipCores != 0 {
c.Append(fmt.Sprintf("skip-cores %d", vpp.CpuConfig.SkipCores))
}
if vpp.CpuConfig.PinMainCpu {
- c.Append(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
- vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+ if vpp.CpuConfig.RelativeCores {
+ c.Append(fmt.Sprintf("main-core %d", startCpu))
+ vpp.getSuite().Log(fmt.Sprintf("main-core %d", startCpu))
+ } else {
+ c.Append(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+ vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+ }
}
workers := vpp.Cpus[startCpu+1:]
+ workersRelativeCpu := startCpu + 1
- if len(workers) > 0 {
+ if len(workers) > 0 && vpp.CpuConfig.UseWorkers {
if vpp.CpuConfig.PinWorkersCorelist {
for i := 0; i < len(workers); i++ {
if i != 0 {
s = s + ", "
}
- s = s + fmt.Sprintf("%d", workers[i])
+
+ if vpp.CpuConfig.RelativeCores {
+ s = s + fmt.Sprintf("%d", workersRelativeCpu)
+ workersRelativeCpu++
+ } else {
+ s = s + fmt.Sprintf("%d", workers[i])
+ }
+
}
c.Append(fmt.Sprintf("corelist-workers %s", s))
vpp.getSuite().Log("corelist-workers " + s)