From nobody Fri May 16 03:22:19 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.zohomail.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 1500132683259138.03773420234336; Sat, 15 Jul 2017 08:31:23 -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 0E766C0467C0; Sat, 15 Jul 2017 15:31:21 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 803456FF08; Sat, 15 Jul 2017 15:31:20 +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 951B71803B26; Sat, 15 Jul 2017 15:31:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v6FFVFOG006844 for ; Sat, 15 Jul 2017 11:31:15 -0400 Received: by smtp.corp.redhat.com (Postfix) id DCCC278C14; Sat, 15 Jul 2017 15:31:15 +0000 (UTC) Received: from inaba.usersys.redhat.com (ovpn-204-62.brq.redhat.com [10.40.204.62]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 10F09784D9; Sat, 15 Jul 2017 15:31:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0E766C0467C0 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.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 0E766C0467C0 From: Andrea Bolognani To: libvir-list@redhat.com Date: Sat, 15 Jul 2017 17:30:57 +0200 Message-Id: <1500132659-3658-3-git-send-email-abologna@redhat.com> In-Reply-To: <1500132659-3658-1-git-send-email-abologna@redhat.com> References: <1500132659-3658-1-git-send-email-abologna@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: laine@laine.org Subject: [libvirt] [PATCH v4 2/4] 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.31]); Sat, 15 Jul 2017 15:31:21 +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 Reviewed-by: Laine Stump --- src/conf/domain_addr.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++= +--- src/conf/domain_addr.h | 3 +++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index bb095a3..531fc68 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -369,6 +369,20 @@ virDomainPCIAddressBusIsFullyReserved(virDomainPCIAddr= essBusPtr bus) } =20 =20 +bool +virDomainPCIAddressBusIsEmpty(virDomainPCIAddressBusPtr bus) +{ + size_t i; + + for (i =3D bus->minSlot; i <=3D bus->maxSlot; i++) { + if (bus->slot[i].functions) + return false; + } + + return true; +} + + /* Ensure addr fits in the address set, by expanding it if needed * * Return value: @@ -548,7 +562,7 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressReserveAddrInternal(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - unsigned int isolationGroup ATTRIBU= TE_UNUSED, + unsigned int isolationGroup, bool fromConfig) { int ret =3D -1; @@ -586,6 +600,26 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAdd= ressSetPtr addrs, bus->slot[addr->slot].aggregate =3D true; } =20 + if (virDomainPCIAddressBusIsEmpty(bus) && !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 %u 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 %u 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, @@ -763,7 +797,7 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressGetNextAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr next_addr, virDomainPCIConnectFlags flags, - unsigned int isolationGroup ATTRIBUTE_UNUSE= D, + unsigned int isolationGroup, int function) { virPCIDeviceAddress a =3D { 0 }; @@ -779,12 +813,41 @@ 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 bus */ 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; + + /* 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 (!virDomainPCIAddressBusIsEmpty(bus) || bus->isolationGroupLock= ed) + continue; + a.slot =3D bus->minSlot; =20 if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, function, @@ -792,6 +855,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; } diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index ac6d64f..205e7cf 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -142,6 +142,9 @@ int virDomainPCIAddressBusSetModel(virDomainPCIAddressB= usPtr bus, bool virDomainPCIAddressBusIsFullyReserved(virDomainPCIAddressBusPtr bus) ATTRIBUTE_NONNULL(1); =20 +bool virDomainPCIAddressBusIsEmpty(virDomainPCIAddressBusPtr bus) + ATTRIBUTE_NONNULL(1); + bool virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); --=20 2.7.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list