diff --git a/libvirt.changes b/libvirt.changes index 1c5e4a7..adbae50 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Tue Aug 2 17:17:25 UTC 2016 - jfehlig@suse.com + +- Update patches providing support for driver_override sysfs + interface with latest upstream variant. Dropped + pci-simplify-stub.patch and updated + pci-use-driver-override-sysfs.patch + bsc#986718 + +------------------------------------------------------------------- +Sat Jul 30 17:25:38 UTC 2016 - jfehlig@suse.com + +- spec: enable numactl and numad support for aarch64 + FATE#319979, bsc#991377 + ------------------------------------------------------------------- Fri Jul 15 14:57:40 UTC 2016 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index d7d9197..0012f6c 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -77,9 +77,8 @@ %endif %endif -# numactl package has "ExclusiveArch: ia64 x86_64 ppc64 ppc64le ppc %sparc" -# We'll only use it on x86_64 ppc64 ppc64le -%ifnarch x86_64 ppc64 ppc64le +# numactl has 'ExcludeArch s390 s390x' +%ifarch s390 s390x %define with_numactl 0 %endif @@ -139,9 +138,9 @@ %define with_wireshark 0 # numad is used to manage the CPU and memory placement dynamically for -# qemu, lxc, and uml drivers. We'll only use in on x86_64 +# qemu, lxc, and uml drivers. We'll only use it on aarch64 and x86_64 %if %{with_qemu} || %{with_lxc} || %{with_uml} - %ifarch x86_64 + %ifarch aarch64 x86_64 %define with_numad 0%{!?_without_numad:1} %endif %endif @@ -301,8 +300,7 @@ Source100: %{name}-rpmlintrc Patch0: c8f08e48-systemd-notify-fix.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch -Patch101: pci-simplify-stub.patch -Patch102: pci-use-driver-override-sysfs.patch +Patch101: pci-use-driver-override-sysfs.patch # Need to go upstream Patch150: xen-pv-cdrom.patch Patch151: blockcopy-check-dst-identical-device.patch @@ -755,7 +753,6 @@ libvirt plugin for NSS for translating domain names into IP addresses. %patch0 -p1 %patch100 -p1 %patch101 -p1 -%patch102 -p1 %patch150 -p1 %patch151 -p1 %patch152 -p1 diff --git a/pci-use-driver-override-sysfs.patch b/pci-use-driver-override-sysfs.patch index 89b9563..445e7a4 100644 --- a/pci-use-driver-override-sysfs.patch +++ b/pci-use-driver-override-sysfs.patch @@ -1,191 +1,81 @@ -commit 1de627810eaba897705cf32c9f025023e34ce73a -Author: Jim Fehlig -Date: Fri Jul 8 16:25:03 2016 -0600 +From 9bd9a05b8b64489598ca4e0d241247cb99406d20 Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Mon, 1 Aug 2016 21:16:43 -0600 +Subject: [PATCH] virpci: support driver_override sysfs interface - virpci: support driver_override sysfs interface - - Currently, libvirt uses the new_id PCI sysfs interface to bind a PCI - stub driver to a PCI device. The new_id interface is known to be - buggy and racey, hence a more deterministic interface was introduced - in the 3.12 kernel - driver_override. For more details see - - https://www.redhat.com/archives/libvir-list/2016-June/msg02124.html - - This patch changes the stub binding/unbinding code to use the - driver_override interface if present. If not present, the new_id - interface will be used to provide compatibility with older kernels - lacking driver_override. - - Signed-off-by: Jim Fehlig +libvirt uses the new_id PCI sysfs interface to bind a PCI stub driver +to a PCI device. The new_id interface is known to be buggy and racey, +hence a more deterministic interface was introduced in the 3.12 kernel: +driver_override. For more details see + +https://www.redhat.com/archives/libvir-list/2016-June/msg02124.html + +This patch adds support for the driver_override interface by + +- adding new virPCIDevice{BindTo,UnbindFrom}StubWithOverride functions + that use the driver_override interface +- renames the existing virPCIDevice{BindTo,UnbindFrom}Stub functions + to virPCIDevice{BindTo,UnbindFrom}StubWithNewid to perserve existing + behavior on new_id interface +- changes virPCIDevice{BindTo,UnbindFrom}Stub function to call one of + the above depending on availability of driver_override + +The patch includes a bit of duplicate code, but allows for easily +dropping the new_id code once support for older kernels is no +longer desired. + +Signed-off-by: Jim Fehlig +--- + src/util/virpci.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 149 insertions(+), 2 deletions(-) Index: libvirt-2.0.0/src/util/virpci.c =================================================================== --- libvirt-2.0.0.orig/src/util/virpci.c +++ libvirt-2.0.0/src/util/virpci.c -@@ -1158,6 +1158,19 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP - - VIR_DEBUG("Reprobing for PCI device %s", dev->name); - -+ /* Remove driver_override if it exists */ -+ VIR_FREE(path); -+ if (!(path = virPCIFile(dev->name, "driver_override"))) -+ goto cleanup; -+ -+ if (virFileExists(path) && virFileWriteStr(path, "\n", 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to remove stub driver from " -+ "driver_override interface of PCI device '%s'"), -+ dev->name); -+ goto cleanup; -+ } -+ - /* Trigger a re-probe of the device is not in the stub's dynamic - * ID table. If the stub is available, but 'remove_id' isn't - * available, then re-probing would just cause the device to be -@@ -1193,49 +1206,13 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP - +@@ -1089,8 +1089,54 @@ virPCIDeviceUnbind(virPCIDevicePtr dev) + return ret; + } ++/* ++ * Bind a PCI device to a driver using driver_override sysfs interface. ++ * E.g. ++ * ++ * echo driver-name > /sys/bus/pci/devices/0000:03:00.0/driver_override ++ * echo 0000:03:00.0 > /sys/bus/pci/devices/0000:03:00.0/driver/unbind ++ * echo 0000:03:00.0 > /sys/bus/pci/drivers_probe ++ * ++ * An empty driverName will cause the device to be bound to its ++ * preferred driver. ++ */ static int --virPCIDeviceBindToStub(virPCIDevicePtr dev) -+virPCIDeviceBindToStubWithNewid(virPCIDevicePtr dev, -+ const char *stubDriverName) - { -- int result = -1; -- char *stubDriverPath = NULL; -- char *driverLink = NULL; -- char *path = NULL; /* reused for different purposes */ -- const char *stubDriverName = NULL; -+ int ret = -1; -+ char *path = NULL; - virErrorPtr err = NULL; - -- /* Check the device is configured to use one of the known stub drivers */ -- if (dev->stubDriver == VIR_PCI_STUB_DRIVER_NONE) { -- virReportError(VIR_ERR_INTERNAL_ERROR, -- _("No stub driver configured for PCI device %s"), -- dev->name); -- return -1; -- } else if (!(stubDriverName = virPCIStubDriverTypeToString(dev->stubDriver))) { -- virReportError(VIR_ERR_INTERNAL_ERROR, -- _("Unknown stub driver configured for PCI device %s"), -- dev->name); -- return -1; -- } -- -- if (!(stubDriverPath = virPCIDriverDir(stubDriverName)) || -- !(driverLink = virPCIFile(dev->name, "driver"))) -- goto cleanup; -- -- if (virFileExists(driverLink)) { -- if (virFileLinkPointsTo(driverLink, stubDriverPath)) { -- /* The device is already bound to the correct driver */ -- VIR_DEBUG("Device %s is already bound to %s", -- dev->name, stubDriverName); -- dev->unbind_from_stub = true; -- dev->remove_slot = true; -- result = 0; -- goto cleanup; -- } -- /* -- * If the device is bound to a driver that is not the stub, we'll -- * need to reprobe later -- */ -- dev->reprobe = true; -- } -- - /* Add the PCI device ID to the stub's dynamic ID table; - * this is needed to allow us to bind the device to the stub. - * Note: if the device is not currently bound to any driver, -@@ -1283,7 +1260,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - } - dev->unbind_from_stub = true; - -- result = 0; -+ ret = 0; - - remove_id: - err = virSaveLastError(); -@@ -1299,7 +1276,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - "cannot be probed again.", dev->id, stubDriverName); - } - dev->reprobe = false; -- result = -1; -+ ret = -1; - goto cleanup; - } - -@@ -1314,10 +1291,142 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - "cannot be probed again.", dev->id, stubDriverName); - } - dev->reprobe = false; -- result = -1; -+ ret = -1; -+ goto cleanup; -+ } -+ -+ cleanup: -+ VIR_FREE(path); -+ -+ if (err) -+ virSetError(err); -+ virFreeError(err); -+ -+ return ret; -+} -+ -+ -+static int -+virPCIDeviceBindToStubWithOverride(virPCIDevicePtr dev, -+ const char *stubDriverName) +-virPCIDeviceUnbindFromStub(virPCIDevicePtr dev) ++virPCIDeviceBindWithDriverOverride(virPCIDevicePtr dev, ++ const char *driverName) +{ + int ret = -1; -+ char *path = NULL; ++ char *path; + -+ /* -+ * Add stub to the device's driver_override, falling back to -+ * adding the device ID to the stub's dynamic ID table. -+ */ + if (!(path = virPCIFile(dev->name, "driver_override"))) + return -1; + -+ if (virFileWriteStr(path, stubDriverName, 0) < 0) { ++ if (virFileWriteStr(path, driverName, 0) < 0) { + virReportSystemError(errno, -+ _("Failed to add stub driver '%s' to " -+ "driver_override interface of PCI device '%s'"), -+ stubDriverName, dev->name); ++ _("Failed to add driver '%s' to driver_override " ++ " interface of PCI device '%s'"), ++ driverName, dev->name); + goto cleanup; + } + + if (virPCIDeviceUnbind(dev) < 0) + goto cleanup; + -+ /* Xen's pciback.ko wants you to use new_slot first */ -+ VIR_FREE(path); -+ if (!(path = virPCIDriverFile(stubDriverName, "new_slot"))) -+ goto cleanup; -+ -+ if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to add slot for " -+ "PCI device '%s' to %s"), -+ dev->name, stubDriverName); -+ goto cleanup; -+ } -+ dev->remove_slot = true; -+ + if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) { + virReportSystemError(errno, -+ _("Failed to trigger a re-probe for PCI device '%s'"), ++ _("Failed to trigger a probe for PCI device '%s'"), + dev->name); - goto cleanup; - } - -+ /* -+ * Device is now bound to the stub. Set reprobe so it will be re-bound -+ * when unbinding from the stub. -+ */ -+ dev->reprobe = true; -+ dev->unbind_from_stub = true; ++ goto cleanup; ++ } + + ret = 0; + @@ -194,15 +84,65 @@ Index: libvirt-2.0.0/src/util/virpci.c + return ret; +} + ++static int ++virPCIDeviceUnbindFromStubWithNewid(virPCIDevicePtr dev) + { + int result = -1; + char *drvdir = NULL; +@@ -1191,9 +1237,41 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP + return result; + } + ++static int ++virPCIDeviceUnbindFromStubWithOverride(virPCIDevicePtr dev) ++{ ++ if (!dev->unbind_from_stub) { ++ VIR_DEBUG("Unbind from stub skipped for PCI device %s", dev->name); ++ return 0; ++ } ++ ++ return virPCIDeviceBindWithDriverOverride(dev, "\n"); ++} + +static int -+virPCIDeviceBindToStub(virPCIDevicePtr dev) ++virPCIDeviceUnbindFromStub(virPCIDevicePtr dev) +{ -+ int result = -1; ++ int ret; ++ char *path; ++ ++ /* ++ * Prefer using the device's driver_override interface, falling back ++ * to the unpleasant new_id interface. ++ */ ++ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ return -1; ++ ++ if (virFileExists(path)) ++ ret = virPCIDeviceUnbindFromStubWithOverride(dev); ++ else ++ ret = virPCIDeviceUnbindFromStubWithNewid(dev); ++ ++ VIR_FREE(path); ++ return ret; ++} + + static int +-virPCIDeviceBindToStub(virPCIDevicePtr dev) ++virPCIDeviceBindToStubWithNewid(virPCIDevicePtr dev) + { + int result = -1; + bool reprobe = false; +@@ -1345,6 +1423,75 @@ virPCIDeviceBindToStub(virPCIDevicePtr d + return result; + } + ++static int ++virPCIDeviceBindToStubWithOverride(virPCIDevicePtr dev) ++{ ++ int ret = -1; ++ const char *stubDriverName; + char *stubDriverPath = NULL; + char *driverLink = NULL; -+ char *path = NULL; /* reused for different purposes */ -+ const char *stubDriverName = NULL; + + /* Check the device is configured to use one of the known stub drivers */ + if (dev->stubDriver == VIR_PCI_STUB_DRIVER_NONE) { @@ -226,46 +166,45 @@ Index: libvirt-2.0.0/src/util/virpci.c + /* The device is already bound to the correct driver */ + VIR_DEBUG("Device %s is already bound to %s", + dev->name, stubDriverName); -+ dev->unbind_from_stub = true; -+ dev->remove_slot = true; -+ result = 0; ++ ret = 0; + goto cleanup; + } -+ /* -+ * If the device is bound to a driver that is not the stub, we'll -+ * need to reprobe later -+ */ -+ dev->reprobe = true; + } + -+ /* -+ * Add stub to the device's driver_override, falling back to -+ * adding the device ID to the stub's dynamic ID table. -+ */ -+ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ if (virPCIDeviceBindWithDriverOverride(dev, stubDriverName) < 0) + goto cleanup; + -+ if (virFileExists(path)) { -+ if (virPCIDeviceBindToStubWithOverride(dev, stubDriverName) < 0) -+ goto cleanup; -+ } else { -+ if (virPCIDeviceBindToStubWithNewid(dev, stubDriverName) < 0) -+ goto cleanup; -+ } ++ dev->unbind_from_stub = true; ++ ret = 0; + -+ result = 0; ++ cleanup: ++ VIR_FREE(stubDriverPath); ++ VIR_FREE(driverLink); ++ return ret; ++} + - cleanup: - VIR_FREE(stubDriverPath); - VIR_FREE(driverLink); -@@ -1326,10 +1435,6 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - if (result < 0) - virPCIDeviceUnbindFromStub(dev); - -- if (err) -- virSetError(err); -- virFreeError(err); -- - return result; - } - ++static int ++virPCIDeviceBindToStub(virPCIDevicePtr dev) ++{ ++ int ret; ++ char *path; ++ ++ /* ++ * Prefer using the device's driver_override interface, falling back ++ * to the unpleasant new_id interface. ++ */ ++ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ return -1; ++ ++ if (virFileExists(path)) ++ ret = virPCIDeviceBindToStubWithOverride(dev); ++ else ++ ret = virPCIDeviceBindToStubWithNewid(dev); ++ ++ VIR_FREE(path); ++ return ret; ++} ++ + /* virPCIDeviceDetach: + * + * Detach this device from the host driver, attach it to the stub