diff options
author | Dino Madarang <dinox.madarang@intel.com> | 2017-11-01 09:10:16 -0700 |
---|---|---|
committer | Ross Brattain <ross.b.brattain@intel.com> | 2017-12-15 06:03:26 +0000 |
commit | 6cfec77db6b95af5b31b741d513955ee3dfa3bb2 (patch) | |
tree | ba8174fdf1b328355b1d591be0a0a735feeca889 /yardstick/benchmark/contexts | |
parent | 93f53ca898891f5fd5fb5994c40932900aea1e73 (diff) |
NSB: Fix standalone.model.Libvirt SR-IOV modeling
Fixed standalone.model.Libvirt SR-IOV XML interface modeling, acording
to [1]:
- All PCI attributes now are printed in hexadecimal format.
- The PCI address is now added in the correct section, 'interface'.
network_services.utils.PciAddress was refactored to accept both 'domain:
bus:slot:function' and 'bus:slot:function' format inputs. This class is
used as input in the previous class, Libvirt, to print in XML the PCI
address of a SR-IOV interface.
network_services.utils.PciAddress.parse_address is now deprecated. Instead
the class standard instantiation must be used:
libvirt_obj = utils.PciAddress(text_with_address)
A deprecation decorator is implemented along with this patch. This
decorator is used for the first time in the previously mentioned function.
This decorator stores every decorated function name and deprecation message
and raises a logging warning message the first time this function is used.
[1] https://goo.gl/so2Mrp
Change-Id: I22e95c488e27d6e2a8fdf6c1a07faab275fa6bba
Signed-off-by: Dino Simeon Madarang <dinox.madarang@intel.com>
Reviewed-by: Alain Jebara <alain.jebara@intel.com>
Reviewed-by: Deepak S <deepak.s@linux.intel.com>
Reviewed-by: Ross Brattain <ross.b.brattain@intel.com>
Reviewed-by: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Diffstat (limited to 'yardstick/benchmark/contexts')
-rw-r--r-- | yardstick/benchmark/contexts/standalone/model.py | 105 | ||||
-rw-r--r-- | yardstick/benchmark/contexts/standalone/ovs_dpdk.py | 19 | ||||
-rw-r--r-- | yardstick/benchmark/contexts/standalone/sriov.py | 21 |
3 files changed, 95 insertions, 50 deletions
diff --git a/yardstick/benchmark/contexts/standalone/model.py b/yardstick/benchmark/contexts/standalone/model.py index 45ae3c18a..a8943c3f6 100644 --- a/yardstick/benchmark/contexts/standalone/model.py +++ b/yardstick/benchmark/contexts/standalone/model.py @@ -94,33 +94,63 @@ class Libvirt(object): cmd_template = "virsh list --name | grep -i %s" status = connection.execute(cmd_template % vm_name)[0] if status == 0: - LOG.info("VM '%s' is already present.. destroying" % vm_name) + LOG.info("VM '%s' is already present... destroying", vm_name) connection.execute("virsh destroy %s" % vm_name) @staticmethod def virsh_create_vm(connection, cfg): err = connection.execute("virsh create %s" % cfg)[0] - LOG.info("VM create status: %s" % (err)) + LOG.info("VM create status: %s", err) @staticmethod def virsh_destroy_vm(vm_name, connection): connection.execute("virsh destroy %s" % vm_name) @staticmethod - def add_interface_address(interface, pci_address): + def _add_interface_address(interface, pci_address): + """Add a PCI 'address' XML node + + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' + function='0x0'/> + + Refence: https://software.intel.com/en-us/articles/ + configure-sr-iov-network-virtual-functions-in-linux-kvm + """ vm_pci = ET.SubElement(interface, 'address') vm_pci.set('type', 'pci') - vm_pci.set('domain', '0x%s' % pci_address.domain) - vm_pci.set('bus', '0x%s' % pci_address.bus) - vm_pci.set('slot', '0x%s' % pci_address.slot) - vm_pci.set('function', '0x%s' % pci_address.function) + vm_pci.set('domain', '0x{}'.format(pci_address.domain)) + vm_pci.set('bus', '0x{}'.format(pci_address.bus)) + vm_pci.set('slot', '0x{}'.format(pci_address.slot)) + vm_pci.set('function', '0x{}'.format(pci_address.function)) return vm_pci @classmethod def add_ovs_interface(cls, vpath, port_num, vpci, vports_mac, xml): - vhost_path = '{0}/var/run/openvswitch/dpdkvhostuser{1}' + """Add a DPDK OVS 'interface' XML node in 'devices' node + + <devices> + <interface type='vhostuser'> + <mac address='00:00:00:00:00:01'/> + <source type='unix' path='/usr/local/var/run/openvswitch/ + dpdkvhostuser0' mode='client'/> + <model type='virtio'/> + <driver queues='4'> + <host mrg_rxbuf='off'/> + </driver> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' + function='0x0'/> + </interface> + ... + </devices> + + Reference: http://docs.openvswitch.org/en/latest/topics/dpdk/ + vhost-user/ + """ + + vhost_path = ('{0}/var/run/openvswitch/dpdkvhostuser{1}'. + format(vpath, port_num)) root = ET.parse(xml) - pci_address = PciAddress.parse_address(vpci.strip(), multi_line=True) + pci_address = PciAddress(vpci.strip()) device = root.find('devices') interface = ET.SubElement(device, 'interface') @@ -130,7 +160,7 @@ class Libvirt(object): source = ET.SubElement(interface, 'source') source.set('type', 'unix') - source.set('path', vhost_path.format(vpath, port_num)) + source.set('path', vhost_path) source.set('mode', 'client') model = ET.SubElement(interface, 'model') @@ -142,14 +172,35 @@ class Libvirt(object): host = ET.SubElement(driver, 'host') host.set('mrg_rxbuf', 'off') - cls.add_interface_address(interface, pci_address) + cls._add_interface_address(interface, pci_address) root.write(xml) @classmethod - def add_sriov_interfaces(cls, vm_pci, vf_pci, vfmac, xml): + def add_sriov_interfaces(cls, vm_pci, vf_pci, vf_mac, xml): + """Add a SR-IOV 'interface' XML node in 'devices' node + + <devices> + <interface type='hostdev' managed='yes'> + <source> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' + function='0x0'/> + </source> + <mac address='52:54:00:6d:90:02'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x04' + function='0x1'/> + </interface> + ... + </devices> + + Reference: https://access.redhat.com/documentation/en-us/ + red_hat_enterprise_linux/6/html/ + virtualization_host_configuration_and_guest_installation_guide/ + sect-virtualization_host_configuration_and_guest_installation_guide + -sr_iov-how_sr_iov_libvirt_works + """ + root = ET.parse(xml) - pci_address = PciAddress.parse_address(vf_pci.strip(), multi_line=True) device = root.find('devices') interface = ET.SubElement(device, 'interface') @@ -157,18 +208,15 @@ class Libvirt(object): interface.set('type', 'hostdev') mac = ET.SubElement(interface, 'mac') - mac.set('address', vfmac) - source = ET.SubElement(interface, 'source') + mac.set('address', vf_mac) - addr = ET.SubElement(source, "address") - addr.set('domain', "0x0") - addr.set('bus', "{0}".format(pci_address.bus)) - addr.set('function', "{0}".format(pci_address.function)) - addr.set('slot', "0x{0}".format(pci_address.slot)) - addr.set('type', "pci") + source = ET.SubElement(interface, 'source') + addr = ET.SubElement(source, 'address') + pci_address = PciAddress(vf_pci.strip()) + cls._add_interface_address(addr, pci_address) - pci_vm_address = PciAddress.parse_address(vm_pci.strip(), multi_line=True) - cls.add_interface_address(interface, pci_vm_address) + pci_vm_address = PciAddress(vm_pci.strip()) + cls._add_interface_address(interface, pci_vm_address) root.write(xml) @@ -192,7 +240,7 @@ class Libvirt(object): 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) + cpuset = Libvirt.pin_vcpu_for_perf(connection, hw_socket) mac = StandaloneContextHelper.get_mac_address(0x00) image = cls.create_snapshot_qemu(connection, index, @@ -216,7 +264,7 @@ class Libvirt(object): connection.execute("echo never > /sys/kernel/mm/transparent_hugepage/enabled") @classmethod - def pin_vcpu_for_perf(cls, connection, vm_name, cpu, socket="0"): + def pin_vcpu_for_perf(cls, connection, socket='0'): threads = "" sys_obj = CpuSysCores(connection) soc_cpu = sys_obj.get_core_socket() @@ -244,9 +292,6 @@ class StandaloneContextHelper(object): if connection.execute(cmd_template % pkg)[0]: connection.execute("apt-get update") connection.execute("apt-get -y install %s" % pkg) - else: - # all installed - return @staticmethod def get_kernel_module(connection, pci, driver): @@ -283,7 +328,7 @@ class StandaloneContextHelper(object): 'interface': str(interface), 'driver': driver }) - LOG.info("{0}".format(networks)) + LOG.info(networks) return networks @@ -352,7 +397,7 @@ class StandaloneContextHelper(object): while not mgmtip and times: connection.execute("fping -c 1 -g %s > /dev/null 2>&1" % cidr) out = connection.execute("ip neighbor | grep '%s'" % mac)[1] - LOG.info("fping -c 1 -g %s > /dev/null 2>&1" % cidr) + LOG.info("fping -c 1 -g %s > /dev/null 2>&1", cidr) if out.strip(): mgmtip = str(out.split(" ")[0]).strip() client = ssh.SSH.from_node(node, overrides={"ip": mgmtip}) diff --git a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py index fcb7bb66c..a6c35de53 100644 --- a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py +++ b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py @@ -118,7 +118,7 @@ class OvsDpdkContext(Context): self.connection.execute(cmd) bind_cmd = "{dpdk_nic_bind} --force -b {driver} {port}" phy_driver = "vfio-pci" - for key, port in self.networks.items(): + for _, port in self.networks.items(): vpci = port.get("phy_port") self.connection.execute(bind_cmd.format(dpdk_nic_bind=self.dpdk_nic_bind, driver=phy_driver, port=vpci)) @@ -170,7 +170,7 @@ class OvsDpdkContext(Context): ] ordered_network = OrderedDict(self.networks) - for index, (key, vnf) in enumerate(ordered_network.items()): + for index, vnf in enumerate(ordered_network.values()): if ovs_ver >= [2, 7, 0]: dpdk_args = " options:dpdk-devargs=%s" % vnf.get("phy_port") dpdk_list.append(ovs_add_port.format(br='br0', port='dpdk%s' % vnf.get("port_num", 0), @@ -263,7 +263,7 @@ class OvsDpdkContext(Context): # Bind nics back to kernel bind_cmd = "{dpdk_nic_bind} --force -b {driver} {port}" - for key, port in self.networks.items(): + for port in self.networks.values(): vpci = port.get("phy_port") phy_driver = port.get("driver") self.connection.execute(bind_cmd.format(dpdk_nic_bind=self.dpdk_nic_bind, @@ -328,17 +328,17 @@ class OvsDpdkContext(Context): def configure_nics_for_ovs_dpdk(self): portlist = OrderedDict(self.networks) - for key, ports in portlist.items(): + for key in portlist: mac = StandaloneContextHelper.get_mac_address() portlist[key].update({'mac': mac}) self.networks = portlist - LOG.info("Ports %s" % self.networks) + LOG.info("Ports %s", self.networks) def _enable_interfaces(self, index, vfs, cfg): vpath = self.ovs_properties.get("vpath", "/usr/local") vf = self.networks[vfs[0]] port_num = vf.get('port_num', 0) - vpci = PciAddress.parse_address(vf['vpci'].strip(), multi_line=True) + vpci = PciAddress(vf['vpci'].strip()) # Generate the vpci for the interfaces slot = index + port_num + 10 vf['vpci'] = \ @@ -357,9 +357,10 @@ class OvsDpdkContext(Context): # 1. Check and delete VM if already exists Libvirt.check_if_vm_exists_and_delete(vm_name, self.connection) - vcpu, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor, cfg, vm_name, index) + _, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor, + cfg, vm_name, index) # 2: Cleanup already available VMs - for idx, (vkey, vfs) in enumerate(OrderedDict(vnf["network_ports"]).items()): + for vkey, vfs in OrderedDict(vnf["network_ports"]).items(): if vkey == "mgmt": continue self._enable_interfaces(index, vfs, cfg) @@ -367,7 +368,7 @@ class OvsDpdkContext(Context): # copy xml to target... self.connection.put(cfg, cfg) - # FIXME: launch through libvirt + # NOTE: launch through libvirt LOG.info("virsh create ...") Libvirt.virsh_create_vm(self.connection, cfg) diff --git a/yardstick/benchmark/contexts/standalone/sriov.py b/yardstick/benchmark/contexts/standalone/sriov.py index 69825fbbf..9d8423b5f 100644 --- a/yardstick/benchmark/contexts/standalone/sriov.py +++ b/yardstick/benchmark/contexts/standalone/sriov.py @@ -110,7 +110,7 @@ class SriovContext(Context): Libvirt.check_if_vm_exists_and_delete(vm, self.connection) # Bind nics back to kernel - for key, ports in self.networks.items(): + for ports in self.networks.values(): # enable VFs for given... build_vfs = "echo 0 > /sys/bus/pci/devices/{0}/sriov_numvfs" self.connection.execute(build_vfs.format(ports.get('phy_port'))) @@ -170,8 +170,7 @@ class SriovContext(Context): def configure_nics_for_sriov(self): vf_cmd = "ip link set {0} vf 0 mac {1}" - for key, ports in self.networks.items(): - vf_pci = [] + for ports in self.networks.values(): host_driver = ports.get('driver') if host_driver not in self.drivers: self.connection.execute("rmmod %svf" % host_driver) @@ -187,19 +186,19 @@ class SriovContext(Context): if interface is not None: self.connection.execute(vf_cmd.format(interface, mac)) - vf_pci = self.get_vf_data('vf_pci', ports.get('phy_port'), mac, interface) + vf_pci = self._get_vf_data(ports.get('phy_port'), mac, interface) ports.update({ 'vf_pci': vf_pci, 'mac': mac }) - LOG.info("Ports %s" % self.networks) + LOG.info('Ports %s', self.networks) def _enable_interfaces(self, index, idx, vfs, cfg): vf_spoofchk = "ip link set {0} vf 0 spoofchk off" vf = self.networks[vfs[0]] - vpci = PciAddress.parse_address(vf['vpci'].strip(), multi_line=True) + vpci = PciAddress(vf['vpci'].strip()) # Generate the vpci for the interfaces slot = index + idx + 10 vf['vpci'] = \ @@ -222,7 +221,7 @@ class SriovContext(Context): # 1. Check and delete VM if already exists Libvirt.check_if_vm_exists_and_delete(vm_name, self.connection) - vcpu, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor, cfg, vm_name, index) + _, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor, cfg, vm_name, index) # 2: Cleanup already available VMs for idx, (vkey, vfs) in enumerate(OrderedDict(vnf["network_ports"]).items()): if vkey == "mgmt": @@ -232,7 +231,7 @@ class SriovContext(Context): # copy xml to target... self.connection.put(cfg, cfg) - # FIXME: launch through libvirt + # NOTE: launch through libvirt LOG.info("virsh create ...") Libvirt.virsh_create_vm(self.connection, cfg) @@ -246,15 +245,15 @@ class SriovContext(Context): return nodes - def get_vf_data(self, key, value, vfmac, pfif): + def _get_vf_data(self, value, vfmac, pfif): vf_data = { "mac": vfmac, "pf_if": pfif } vfs = StandaloneContextHelper.get_virtual_devices(self.connection, value) for k, v in vfs.items(): - m = PciAddress.parse_address(k.strip(), multi_line=True) - m1 = PciAddress.parse_address(value.strip(), multi_line=True) + m = PciAddress(k.strip()) + m1 = PciAddress(value.strip()) if m.bus == m1.bus: vf_data.update({"vf_pci": str(v)}) break |