From nobody Fri May 16 06:33:23 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1497606641197578.4391019596287; Fri, 16 Jun 2017 02:50:41 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6F0CF369CB; Fri, 16 Jun 2017 09:50:39 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3EDF083B33; Fri, 16 Jun 2017 09:50:39 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B329E6B48D; Fri, 16 Jun 2017 09:50:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v5G9oLCW031531 for ; Fri, 16 Jun 2017 05:50:21 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5089E7EEE4; Fri, 16 Jun 2017 09:50:21 +0000 (UTC) Received: from inaba.usersys.redhat.com (ovpn-12-86.pek2.redhat.com [10.72.12.86]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 737117F34E for ; Fri, 16 Jun 2017 09:50:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6F0CF369CB Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 6F0CF369CB From: Andrea Bolognani To: libvir-list@redhat.com Date: Fri, 16 Jun 2017 17:49:07 +0800 Message-Id: <1497606548-18870-24-git-send-email-abologna@redhat.com> In-Reply-To: <1497606548-18870-1-git-send-email-abologna@redhat.com> References: <1497606548-18870-1-git-send-email-abologna@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 23/24] conf: Implement isolation rules X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 16 Jun 2017 09:50:40 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" These rules will make it possible for libvirt to automatically assign PCI addresses in a way that respects any isolation constraints devices might have. Signed-off-by: Andrea Bolognani --- src/conf/domain_addr.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 48af1f5..ae1f0e0 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -534,7 +534,7 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressReserveAddrInternal(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - int isolationGroup ATTRIBUTE_UNUSED, + int isolationGroup, bool fromConfig) { int ret =3D -1; @@ -542,6 +542,8 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAddr= essSetPtr addrs, virDomainPCIAddressBusPtr bus; virErrorNumber errType =3D (fromConfig ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR= ); + bool firstDevice; + size_t slot; =20 if (!(addrStr =3D virDomainPCIAddressAsString(addr))) goto cleanup; @@ -572,6 +574,36 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAdd= ressSetPtr addrs, bus->slot[addr->slot].aggregate =3D true; } =20 + /* Figure out whether this is the first device we're plugging + * into the bus by looking at all the slots */ + firstDevice =3D true; + for (slot =3D bus->minSlot; slot <=3D bus->maxSlot; slot++) { + if (bus->slot[slot].functions) { + firstDevice =3D false; + break; + } + } + + if (firstDevice && !bus->isolationGroupLocked) { + /* The first device decides the isolation group for the + * entire bus */ + bus->isolationGroup =3D isolationGroup; + VIR_DEBUG("PCI bus %.4x:%.2x assigned isolation group %d because o= f " + "first device %s", + addr->domain, addr->bus, isolationGroup, addrStr); + } else if (bus->isolationGroup !=3D isolationGroup && fromConfig) { + /* If this is not the first function and its isolation group + * doesn't match the bus', then it should not be using this + * address. However, if the address comes from the user then + * we comply with the request and change the isolation group + * back to the default (because at that point isolation can't + * be guaranteed anymore) */ + bus->isolationGroup =3D 0; + VIR_DEBUG("PCI bus %.4x:%.2x assigned isolation group %d because o= f " + "user assigned address %s", + addr->domain, addr->bus, isolationGroup, addrStr); + } + /* mark the requested function as reserved */ bus->slot[addr->slot].functions |=3D (1 << addr->function); VIR_DEBUG("Reserving PCI address %s (aggregate=3D'%s')", addrStr, @@ -749,7 +781,7 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressGetNextAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr next_addr, virDomainPCIConnectFlags flags, - int isolationGroup ATTRIBUTE_UNUSED, + int isolationGroup, int function) { virPCIDeviceAddress a =3D { 0 }; @@ -765,12 +797,51 @@ virDomainPCIAddressGetNextAddr(virDomainPCIAddressSet= Ptr addrs, else a.function =3D function; =20 - /* "Begin at the beginning," the King said, very gravely, "and go on - * till you come to the end: then stop." */ + /* When looking for a suitable bus for the device, start by being + * very strict and ignoring all those where the isolation groups + * don't match. This ensures all devices sharing the same isolation + * group will end up on the same group */ for (a.bus =3D 0; a.bus < addrs->nbuses; a.bus++) { virDomainPCIAddressBusPtr bus =3D &addrs->buses[a.bus]; bool found =3D false; =20 + if (bus->isolationGroup !=3D isolationGroup) + continue; + + a.slot =3D bus->minSlot; + + if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, function, + flags, &found) < 0)= { + goto error; + } + + if (found) + goto success; + } + + /* We haven't been able to find a perfectly matching bus, but we + * might still be able to make this work by altering the isolation + * group for a bus that's currently empty. So let's try that */ + for (a.bus =3D 0; a.bus < addrs->nbuses; a.bus++) { + virDomainPCIAddressBusPtr bus =3D &addrs->buses[a.bus]; + bool found =3D false; + bool firstDevice =3D true; + size_t slot; + + /* Go through all the slots and see whether they are empty */ + for (slot =3D bus->minSlot; slot <=3D bus->maxSlot; slot++) { + if (bus->slot[slot].functions) { + firstDevice =3D false; + break; + } + } + + /* We can only change the isolation group for a bus when + * plugging in the first device; moreover, some buses are + * prevented from ever changing it */ + if (!firstDevice || bus->isolationGroupLocked) + continue; + a.slot =3D bus->minSlot; =20 if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, function, @@ -778,6 +849,8 @@ virDomainPCIAddressGetNextAddr(virDomainPCIAddressSetPt= r addrs, goto error; } =20 + /* The isolation group for the bus will actually be changed + * later, in virDomainPCIAddressReserveAddrInternal() */ if (found) goto success; } --=20 2.7.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list