From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 00BA493DC1 for ; Tue, 20 Sep 2022 14:51:31 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A61001BF78 for ; Tue, 20 Sep 2022 14:50:59 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 20 Sep 2022 14:50:50 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1FEF844350 for ; Tue, 20 Sep 2022 14:50:44 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Tue, 20 Sep 2022 14:50:15 +0200 Message-Id: <20220920125041.3636561-10-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220920125041.3636561-1-d.csapak@proxmox.com> References: <20220920125041.3636561-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.079 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [hardwaremap.pm] Subject: [pve-devel] [PATCH common v3 3/3] HardwareMap: add support for multiple pci device paths per mapping X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Sep 2022 12:51:31 -0000 With this, we can now tell qemu-server to choose the first avaiable devices, which makes using vGPUs and SR-IOV capable devices much easier to use, since the user does not have to hardcode the device, but can give a list of identical ones, and qemu-server chooses dynamically. note that we require the devices all to be the same vendor/device, because we don't want to group unrelated devices, but we only check the iommugroup for the first device, but there is a high chance that this also changes when somethings off since e.g. SRIOV devices are most often created at the same time, so when the any has a different group, the first one will too Signed-off-by: Dominik Csapak --- src/PVE/HardwareMap.pm | 71 ++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/PVE/HardwareMap.pm b/src/PVE/HardwareMap.pm index 31841b4..52c45e1 100644 --- a/src/PVE/HardwareMap.pm +++ b/src/PVE/HardwareMap.pm @@ -84,9 +84,11 @@ my $format = { }, path => { description => "The path to the device. If the function is omitted, the whole device is" - ." mapped. In that case use the attributes of the first device.", + ." mapped. In that case use the attributes of the first device. You can give" + ." multiple paths as a semicolon seperated list, the first available will then" + ." be chosen on guest start.", type => 'string', - pattern => "${PCI_RE}", + pattern => "(?:${PCI_RE};)*${PCI_RE}", }, mdev => { description => "The Device supports mediated devices.", @@ -213,39 +215,48 @@ sub write_hardware_map { my $pci_valid = sub { my ($cfg) = @_; - my $multifunction = 0; - if ($path !~ m/\.[a-f0-9]/i) { - # whole device, add .0 (must exist) - $path = "$path.0"; - $multifunction = 1; - } + my @paths = split(';', $cfg->{path} // ''); - my $info = PVE::SysFSTools::pci_device_info($path, 1); - die "pci device '$path' not found\n" if !defined($info); + my $idx = 0; + for my $path (@paths) { - my $correct_props = { - vendor => $info->{vendor}, - device => $info->{device}, - 'subsystem-vendor' => $info->{'subsystem_vendor'}, - 'subsystem-device' => $info->{'subsystem_device'}, - mdev => $multifunction ? undef : $info->{mdev}, # don't allow mdev for multifunction - iommugroup => $info->{iommugroup}, - }; + my $multifunction = 0; + if ($path !~ m/\.[a-f0-9]/i) { + # whole device, add .0 (must exist) + $path = "$path.0"; + $multifunction = 1; + } + + my $info = PVE::SysFSTools::pci_device_info($path, 1); + die "pci device '$path' not found\n" if !defined($info); - for my $prop (sort keys %$correct_props) { - next if !defined($correct_props->{$prop}) && !defined($cfg->{$prop}); - die "no '$prop' for device '$path'\n" - if defined($correct_props->{$prop}) && !defined($cfg->{$prop}); - die "'$prop' configured but should not be\n" - if !defined($correct_props->{$prop}) && defined($cfg->{$prop}); + my $correct_props = { + vendor => $info->{vendor}, + device => $info->{device}, + 'subsystem-vendor' => $info->{'subsystem_vendor'}, + 'subsystem-device' => $info->{'subsystem_device'}, + mdev => $multifunction ? undef : $info->{mdev}, # don't allow mdev for multifunction + iommugroup => $info->{iommugroup}, + }; + + for my $prop (sort keys %$correct_props) { + next if $prop eq 'iommugroup' && $idx > 0; # check iommu only on the first device - my $correct_prop = $correct_props->{$prop}; - $correct_prop =~ s/^0x//; - my $configured_prop = $cfg->{$prop}; - $configured_prop =~ s/^0x//; + next if !defined($correct_props->{$prop}) && !defined($cfg->{$prop}); + die "no '$prop' for device '$path'\n" + if defined($correct_props->{$prop}) && !defined($cfg->{$prop}); + die "'$prop' configured but should not be\n" + if !defined($correct_props->{$prop}) && defined($cfg->{$prop}); - die "'$prop' does not match for '$cfg->{name}' ($correct_prop != $configured_prop)\n" - if $correct_prop ne $configured_prop; + my $correct_prop = $correct_props->{$prop}; + $correct_prop =~ s/^0x//; + my $configured_prop = $cfg->{$prop}; + $configured_prop =~ s/^0x//; + + die "'$prop' does not match for '$cfg->{name}' ($correct_prop != $configured_prop)\n" + if $correct_prop ne $configured_prop; + } + $idx++; } return 1; -- 2.30.2