all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: Elias Huhsovitz <e.huhsovitz@proxmox.com>, pve-devel@lists.proxmox.com
Subject: Re: [PATCH pve-qemu-server-rs 3/9] pci: layout: add v2 PCI and PCIe layouts
Date: Mon, 28 Sep 2026 16:05:56 +0200	[thread overview]
Message-ID: <1003d008-f949-4fbf-a8de-6df87376329c@proxmox.com> (raw)
In-Reply-To: <DLQYRO18N6UT.28NS9YNTKE4B3@proxmox.com>



On 9/28/26 2:55 PM, Elias Huhsovitz wrote:
> Since the `v2` name is just a development placeholder, I will start with
> some suggestions:
> 
> * `grouped` - describing the property of the new layout.
> 
> * `per_device` | `per_kind` - since each device gets its own bridges.
> 
> * `default` - since it is the new default (might age badly if a new
> default is introduced).
> 
> On Tue Sep 22, 2026 at 12:55 PM CEST, Dominik Csapak wrote:
>> The legacy layout grew over many releases and it shows: devices of one
>> kind are spread over several buses, the bus a device lands on depends on
>> how many devices of other kinds exist, and the remaining free slots are
>> scattered. That makes it hard to raise any of the per-kind limits
>> without further scattering the types over the available addresses.
>>
>> Add a second set of layouts that gives every device kind its own set of
>> bridges instead. A device's address then only depends on its own index,
>> so raising a limit adds bridges at the end rather than shifting anything
>> that exists, and the built-in devices move to a bridge of their own to
>> keep the root bus free.
>>
>> These are not wired up to the entry points yet: they are meant for new
>> guests only, and the machine property selecting them still has to be
>> added on the qemu-server side.
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>> ---
>>   pve-qemu-server-pci/src/layout/mod.rs |   2 +
>>   pve-qemu-server-pci/src/layout/v2.rs  | 344 ++++++++++++++++++++++++++
>>   pve-qemu-server-pci/src/types/mod.rs  |   3 +
>>   3 files changed, 349 insertions(+)
>>   create mode 100644 pve-qemu-server-pci/src/layout/v2.rs
>>
>> diff --git a/pve-qemu-server-pci/src/layout/mod.rs b/pve-qemu-server-pci/src/layout/mod.rs
>> index c81d730..0b72abd 100644
>> --- a/pve-qemu-server-pci/src/layout/mod.rs
>> +++ b/pve-qemu-server-pci/src/layout/mod.rs
>> @@ -13,6 +13,8 @@ macro_rules! single_device {
>>   
>>   pub(crate) mod legacy;
>>   
>> +pub mod v2;
>> +
>>   /// Constructs a correctly sized list of bridge slots, starting at address 0x01
>>   /// because 0x00 is always taken by the bridge itself.
>>   ///
>> diff --git a/pve-qemu-server-pci/src/layout/v2.rs b/pve-qemu-server-pci/src/layout/v2.rs
>> new file mode 100644
>> index 0000000..9525492
>> --- /dev/null
>> +++ b/pve-qemu-server-pci/src/layout/v2.rs
>> @@ -0,0 +1,344 @@
>> +use crate::constants::{
>> +    BRIDGE_SLOT_NUM, MAX_HOSTPCI_DEVICES, MAX_NET_DEVICES, MAX_SCSI_DEVICES,
>> +    MAX_VIRTIO_BLK_DEVICES, MAX_VIRTIOFS_DEVICES,
>> +};
>> +use crate::layout::bridge_slots;
>> +use crate::{Bus, Device, DeviceLayout, Function, PveBridge, Slot};
>> +
>> +/// The guest's built-in devices, which all live on a bridge of their own so
>> +/// that the root bus stays free for the per-kind bridges.
>> +///
>> +/// NOTE: only append here, don't reorder. The order implies the address, which
>> +/// has to stay stable.
>> +const SYS_BRIDGE_SLOTS: [Slot; BRIDGE_SLOT_NUM] = bridge_slots(&[
> 
> nit: name: I would prefer `BUILTIN_BRIDGE_SLOTS` or
> `BUILTIN_DEVICE_SLOTS`. Since devies are usually in slots, we can also
> just shorten it to `BUILTIN_DEVICES`.
> 
>> +    single_device!(Ahci),
>> +    single_device!(Balloon),
>> +    single_device!(XhciController(0)),
>> +    single_device!(GuestAgent),
>> +    single_device!(SpiceSerial),
>> +    single_device!(Rng),
>> +    single_device!(Audio),
>> +    single_device!(Watchdog),
>> +    single_device!(Ivshmem),
>> +]);
>> +
>> +/// The layout for guests with a PCI root bus.
>> +pub static PCI_LAYOUT: DeviceLayout = DeviceLayout {
>> +    pcie: false,
>> +    root: bridge_slots(&[
>> +        Slot::Reserved,
>> +        Slot::Multi(&[
>> +            Function::Device(Device::Vga(0)),
>> +            Function::Device(Device::Vga(1)),
>> +            Function::Device(Device::Vga(2)),
>> +            Function::Device(Device::Vga(3)),
>> +            Function::Unused,
>> +            Function::Unused,
>> +            Function::Unused,
>> +            Function::Unused,
>> +        ]),
>> +        Slot::Single(Function::Device(Device::Viommu)),
>> +        Slot::Single(Function::FixedBridge(Bus::Sys(0), &SYS_BRIDGE_SLOTS)),
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::VirtioFs,
>> +            max: MAX_VIRTIOFS_DEVICES,
>> +        },
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Net,
>> +            max: MAX_NET_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Scsi,
>> +            max: MAX_SCSI_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::VirtioBlk,
>> +            max: MAX_VIRTIO_BLK_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::Unused,
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Hostpci,
>> +            max: MAX_HOSTPCI_DEVICES,
>> +        },
>> +    ]),
>> +};
>> +
>> +/// The layout for guests with a PCIe root bus.
>> +///
>> +/// Identical to [`PCI_LAYOUT`] except for the root bus type and the root ports
>> +/// for passed through PCIe devices, which a PCI machine cannot have.
>> +pub static PCIE_LAYOUT: DeviceLayout = DeviceLayout {
>> +    pcie: true,
>> +    root: bridge_slots(&[
>> +        Slot::Reserved,
>> +        Slot::Multi(&[
>> +            Function::Device(Device::Vga(0)),
>> +            Function::Device(Device::Vga(1)),
>> +            Function::Device(Device::Vga(2)),
>> +            Function::Device(Device::Vga(3)),
>> +            Function::Unused,
>> +            Function::Unused,
>> +            Function::Unused,
>> +            Function::Unused,
>> +        ]),
>> +        Slot::Single(Function::Device(Device::Viommu)),
>> +        Slot::Single(Function::FixedBridge(Bus::Sys(0), &SYS_BRIDGE_SLOTS)),
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::VirtioFs,
>> +            max: MAX_VIRTIOFS_DEVICES,
>> +        },
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Net,
>> +            max: MAX_NET_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Scsi,
>> +            max: MAX_SCSI_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::VirtioBlk,
>> +            max: MAX_VIRTIO_BLK_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::Unused,
>> +        Slot::Unused,
>> +        Slot::DynamicBridge {
>> +            kind: PveBridge::Hostpci,
>> +            max: MAX_HOSTPCI_DEVICES,
>> +        },
>> +        Slot::Unused,
>> +        Slot::Multi(&[
>> +            Function::RootPort(0, Device::Hostpcie(0)),
>> +            Function::RootPort(1, Device::Hostpcie(1)),
>> +            Function::RootPort(2, Device::Hostpcie(2)),
>> +            Function::RootPort(3, Device::Hostpcie(3)),
>> +            Function::RootPort(4, Device::Hostpcie(4)),
>> +            Function::RootPort(5, Device::Hostpcie(5)),
>> +            Function::RootPort(6, Device::Hostpcie(6)),
>> +            Function::RootPort(7, Device::Hostpcie(7)),
>> +        ]),
>> +        Slot::Multi(&[
>> +            Function::RootPort(8, Device::Hostpcie(8)),
>> +            Function::RootPort(9, Device::Hostpcie(9)),
>> +            Function::RootPort(10, Device::Hostpcie(10)),
>> +            Function::RootPort(11, Device::Hostpcie(11)),
>> +            Function::RootPort(12, Device::Hostpcie(12)),
>> +            Function::RootPort(13, Device::Hostpcie(13)),
>> +            Function::RootPort(14, Device::Hostpcie(14)),
>> +            Function::RootPort(15, Device::Hostpcie(15)),
>> +        ]),
> 
> We have 16 device slots via the dynmic bridge and 16 devices slots via
> root ports = 32 passthrough slots. But the config schema only allows
> for 16 total `hostpciN` devices.
> 
> IMO we need to add `hostpcieN` as a config key in perl and add a new
> constant.
> 
> pub const MAX_HOSTPCIE_DEVICES: u8 = 16;
> 
> OR what about removing the explicit `Device::Hostpcie` and folding in the
> placement into the enum, like this:
> 
> pub enum Device {
>      Hostpci(u8, HostpciPlacement),
> }
> 
> pub enum HostpciPlacement {
>      Bridge,
>      RootPort,
> }
> 
> Since, if I understand this correctly, we primarily care about the placement.

i tried that, but that didn't quite workout with the FromStr 
implementations.

The issue here is that a hostpciX device can be either placed
in a pci or pcie slot, depending on its own config.

but see my reply to patch 1

> 
>> +    ]),
>> +};
> 
> [snip]





  reply	other threads:[~2026-09-28 14:06 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22 10:55 [RFC proxmox-perl-rs/qemu-server/qemu-server-rs 0/9] pci-handling rewrite (part 1) Dominik Csapak
2026-09-22 10:55 ` [PATCH pve-qemu-server-rs 1/9] add pve-qemu-server-pci crate for guest PCI address generation Dominik Csapak
2026-09-28 12:53   ` Elias Huhsovitz
2026-09-28 14:00     ` Dominik Csapak
2026-09-22 10:55 ` [PATCH pve-qemu-server-rs 2/9] pci: add machine abstraction and PCI bridge generation Dominik Csapak
2026-09-28 12:55   ` Elias Huhsovitz
2026-09-28 14:04     ` Dominik Csapak
2026-09-22 10:55 ` [PATCH pve-qemu-server-rs 3/9] pci: layout: add v2 PCI and PCIe layouts Dominik Csapak
2026-09-28 12:55   ` Elias Huhsovitz
2026-09-28 14:05     ` Dominik Csapak [this message]
2026-09-22 10:55 ` [PATCH pve-qemu-server-rs 4/9] fixup! add pve-qemu-server-pci crate for guest PCI address generation Dominik Csapak
2026-09-22 10:55 ` [PATCH proxmox-perl-rs 5/9] pve: add bindings for `pve-qemu-server-pci` crate Dominik Csapak
2026-09-28 12:56   ` Elias Huhsovitz
2026-09-28 14:06     ` Dominik Csapak
2026-09-22 10:55 ` [PATCH proxmox-perl-rs 6/9] pve: pci bindings: add bindings for the `Machine` struct Dominik Csapak
2026-09-22 10:55 ` [PATCH qemu-server 7/9] pci: use PVE::RS::PCI bindings Dominik Csapak
2026-09-22 10:55 ` [PATCH qemu-server 8/9] helpers: factor out the version parts parsing Dominik Csapak
2026-09-22 10:55 ` [PATCH qemu-server 9/9] pci: bridges: use the rust `Machine` struct to pass parameters Dominik Csapak
2026-09-22 11:06 ` [RFC proxmox-perl-rs/qemu-server/qemu-server-rs 0/9] pci-handling rewrite (part 1) Dominik Csapak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1003d008-f949-4fbf-a8de-6df87376329c@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=e.huhsovitz@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal