From d500175a37972fe8b482672e60c238e94f34999f Mon Sep 17 00:00:00 2001 From: Deepak S Date: Mon, 16 Oct 2017 01:21:12 -0700 Subject: Adding cpu set to enable affinity for given vcpu Change-Id: If2e079966939b7faa33d2833d81caad0a3669036 Signed-off-by: Deepak S --- .../benchmark/contexts/standalone/test_model.py | 20 +++------ yardstick/benchmark/contexts/standalone/model.py | 52 +++++++--------------- .../benchmark/contexts/standalone/ovs_dpdk.py | 6 +-- yardstick/benchmark/contexts/standalone/sriov.py | 2 - 4 files changed, 24 insertions(+), 56 deletions(-) diff --git a/tests/unit/benchmark/contexts/standalone/test_model.py b/tests/unit/benchmark/contexts/standalone/test_model.py index ddbc1a4bb..6899a0af6 100644 --- a/tests/unit/benchmark/contexts/standalone/test_model.py +++ b/tests/unit/benchmark/contexts/standalone/test_model.py @@ -91,10 +91,12 @@ class ModelLibvirtTestCase(unittest.TestCase): image = Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img") self.assertEqual(image, result) + @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.pin_vcpu_for_perf") @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.create_snapshot_qemu") @mock.patch('yardstick.benchmark.contexts.standalone.model.open') @mock.patch('yardstick.benchmark.contexts.standalone.model.write_file') - def test_build_vm_xml(self, mock_open, mock_write_file, mock_create_snapshot_qemu): + def test_build_vm_xml(self, mock_open, mock_write_file, mock_create_snapshot_qemu, + mock_pin_vcpu_for_perf): result = [4] with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) @@ -102,17 +104,10 @@ class ModelLibvirtTestCase(unittest.TestCase): mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock mock_create_snapshot_qemu.return_value = "0.img" + status = Libvirt.build_vm_xml(ssh_mock, {}, "test", "vm_0", 0) self.assertEqual(status[0], result[0]) - def test_split_cpu_list(self): - result = Libvirt.split_cpu_list("1,2,3") - self.assertEqual(result, [1, 2, 3]) - - def test_get_numa_nodes(self): - result = Libvirt.get_numa_nodes() - self.assertIsNotNone(result) - def test_update_interrupts_hugepages_perf(self): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) @@ -122,17 +117,16 @@ class ModelLibvirtTestCase(unittest.TestCase): status = Libvirt.update_interrupts_hugepages_perf(ssh_mock) self.assertIsNone(status) - @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.get_numa_nodes") + @mock.patch("yardstick.benchmark.contexts.standalone.model.CpuSysCores") @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.update_interrupts_hugepages_perf") - def test_pin_vcpu_for_perf(self, mock_update_interrupts_hugepages_perf, mock_get_numa_nodes): + def test_pin_vcpu_for_perf(self, mock_update_interrupts_hugepages_perf, mock_CpuSysCores): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - mock_get_numa_nodes.return_value = {'1': [18, 19, 20, 21], '0': [0, 1, 2, 3]} status = Libvirt.pin_vcpu_for_perf(ssh_mock, "vm_0", 4) - self.assertIsNone(status) + self.assertIsNotNone(status) class StandaloneContextHelperTestCase(unittest.TestCase): diff --git a/yardstick/benchmark/contexts/standalone/model.py b/yardstick/benchmark/contexts/standalone/model.py index 4491660e0..ffd8858d9 100644 --- a/yardstick/benchmark/contexts/standalone/model.py +++ b/yardstick/benchmark/contexts/standalone/model.py @@ -16,11 +16,9 @@ from __future__ import absolute_import import os import re import time -import glob import uuid import random import logging -import itertools import errno from netaddr import IPNetwork @@ -30,6 +28,7 @@ from yardstick import ssh from yardstick.common.constants import YARDSTICK_ROOT_PATH from yardstick.common.yaml_loader import yaml_load from yardstick.network_services.utils import PciAddress +from yardstick.network_services.helpers.cpu import CpuSysCores from yardstick.common.utils import write_file LOG = logging.getLogger(__name__) @@ -43,7 +42,7 @@ VM_TEMPLATE = """ - {vcpu} + {vcpu} hvm @@ -192,6 +191,8 @@ class Libvirt(object): threads = extra_spec.get('hw:cpu_threads', '2') vcpu = int(cpu) * int(threads) numa_cpus = '0-%s' % (vcpu - 1) + hw_socket = flavor.get('hw_socket', '0') + cpuset = Libvirt.pin_vcpu_for_perf(connection, vm_name, vcpu, hw_socket) mac = StandaloneContextHelper.get_mac_address(0x00) image = cls.create_snapshot_qemu(connection, index, @@ -203,51 +204,28 @@ class Libvirt(object): memory=memory, vcpu=vcpu, cpu=cpu, numa_cpus=numa_cpus, socket=socket, threads=threads, - vm_image=image) + vm_image=image, cpuset=cpuset) write_file(cfg, vm_xml) return [vcpu, mac] - @staticmethod - def split_cpu_list(cpu_list): - if not cpu_list: - return [] - - ranges = cpu_list.split(',') - bounds = ([int(b) for b in r.split('-')] for r in ranges) - range_objects = \ - (range(bound[0], bound[1] + 1 if len(bound) == 2 - else bound[0] + 1) for bound in bounds) - - return sorted(itertools.chain.from_iterable(range_objects)) - - @classmethod - def get_numa_nodes(cls): - nodes_sysfs = glob.iglob("/sys/devices/system/node/node*") - nodes = {} - for node_sysfs in nodes_sysfs: - num = os.path.basename(node_sysfs).replace("node", "") - with open(os.path.join(node_sysfs, "cpulist")) as cpulist_file: - cpulist = cpulist_file.read().strip() - nodes[num] = cls.split_cpu_list(cpulist) - LOG.info("nodes: {0}".format(nodes)) - return nodes - @staticmethod def update_interrupts_hugepages_perf(connection): connection.execute("echo 1 > /sys/module/kvm/parameters/allow_unsafe_assigned_interrupts") connection.execute("echo never > /sys/kernel/mm/transparent_hugepage/enabled") @classmethod - def pin_vcpu_for_perf(cls, connection, vm_name, cpu): - nodes = cls.get_numa_nodes() - num_nodes = len(nodes) - vcpi_pin_template = "virsh vcpupin {0} {1} {2}" - for i in range(0, int(cpu)): - core = nodes[str(num_nodes - 1)][i % len(nodes[str(num_nodes - 1)])] - connection.execute(vcpi_pin_template.format(vm_name, i, core)) - cls.update_interrupts_hugepages_perf(connection) + def pin_vcpu_for_perf(cls, connection, vm_name, cpu, socket="0"): + threads = "" + sys_obj = CpuSysCores(connection) + soc_cpu = sys_obj.get_core_socket() + sys_cpu = int(soc_cpu["cores_per_socket"]) + cores = "%s-%s" % (soc_cpu[socket][0], soc_cpu[socket][sys_cpu - 1]) + if int(soc_cpu["thread_per_core"]): + threads = "%s-%s" % (soc_cpu[socket][sys_cpu], soc_cpu[socket][-1]) + cpuset = "%s,%s" % (cores, threads) + return cpuset class StandaloneContextHelper(object): diff --git a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py index 833c3fb80..e990e46f5 100644 --- a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py +++ b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py @@ -164,7 +164,7 @@ class OvsDpdkContext(Context): cmd_dpdk_list = [ "ovs-vsctl del-br br0", - "rm -rf /usr/local/var/run/openvswitch/dpdkvhostuser*", + "rm -rf {0}/var/run/openvswitch/dpdkvhostuser*".format(vpath), "ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev", ] @@ -175,7 +175,7 @@ class OvsDpdkContext(Context): dpdk_list.append(ovs_add_port.format(br='br0', port='dpdk%s' % vnf.get("port_num", 0), type_='dpdk', dpdk_args=dpdk_args)) dpdk_list.append(ovs_add_queue.format(port='dpdk%s' % vnf.get("port_num", 0), - queue=self.ovs_properties.get("queues", 4))) + queue=self.ovs_properties.get("queues", 1))) # Sorting the array to make sure we execute dpdk0... in the order list.sort(dpdk_list) @@ -370,8 +370,6 @@ class OvsDpdkContext(Context): LOG.info("virsh create ...") Libvirt.virsh_create_vm(self.connection, cfg) - # 5: Tunning for better performace - Libvirt.pin_vcpu_for_perf(self.connection, vm_name, vcpu) self.vm_names.append(vm_name) # build vnf node details diff --git a/yardstick/benchmark/contexts/standalone/sriov.py b/yardstick/benchmark/contexts/standalone/sriov.py index 55d7057a9..7c95f555d 100644 --- a/yardstick/benchmark/contexts/standalone/sriov.py +++ b/yardstick/benchmark/contexts/standalone/sriov.py @@ -233,8 +233,6 @@ class SriovContext(Context): LOG.info("virsh create ...") Libvirt.virsh_create_vm(self.connection, cfg) - # 5: Tunning for better performace - Libvirt.pin_vcpu_for_perf(self.connection, vm_name, vcpu) self.vm_names.append(vm_name) # build vnf node details -- cgit 1.2.3-korg