• L
    util: save the correct VF's info when using a dual port SRIOV NIC in single port mode · b67eaa63
    Laine Stump 提交于
    Mellanox ConnectX-3 dual port SRIOV NICs present a bit of a challenge
    when assigning one of their VFs to a guest using VFIO device
    assignment.
    
    These NICs have only a single PCI PF device, and that single PF has
    two netdevs sharing the single PCI address - one for port 1 and one
    for port 2. When a VF is created it can also have 2 netdevs, or it can
    be setup in "single port" mode, where the VF has only a single netdev,
    and that netdev is connected either to port 1 or to port 2.
    
    When the VF is created in dual port mode, you get/set the MAC
    address/vlan tag for the port 1 VF by sending a netlink message to the
    PF's port1 netdev, and you get/set the MAC address/vlan tag for the
    port 2 VF by sending a netlink message to the PF's port 2 netdev. (Of
    course libvirt doesn't have any way to describe MAC/vlan info for 2
    ports in a single hostdev interface, so that's a bit of a moot point)
    
    When the VF is created in single port mode, you can *set* the MAC/vlan
    info by sending a netlink message to *either* PF netdev - the driver
    is smart enough to understand that there's only a single netdev, and
    set the MAC/vlan for that netdev. When you want to *get* it, however,
    the driver is more accurate - it will return 00:00:00:00:00:00 for the
    MAC if you request it from the port 1 PF netdev when the VF was
    configured to be single port on port 2, or if you request if from the
    port 2 PF netdev when the VF was configured to be single port on port
    1.
    
    Based on this information, when *getting* the MAC/vlan info (to save
    the original setting prior to assignment), we determine the correct PF
    netdev by matching phys_port_id between VF and PF.
    
    (IMPORTANT NOTE: this implies that to do PCI device assignment of the
    VFs on dual port Mellanox cards using <interface type='hostdev'>
    (i.e. if you want the MAC address/vlan tag to be set), not only must
    the VFs be configured in single port mode, but also the VFs *must* be
    bound to the host VF net driver, and libvirt must use managed='yes')
    
    By the time libvirt is ready to set the new MAC/vlan tag, the VF has
    already been unbound from the host net driver and bound to
    vfio-pci. This isn't problematic though because, as stated earlier,
    when a VF is created in single port mode, commands to configure it can
    be sent to either the port 1 PF netdev or the port 2 PF netdev.
    
    When it is time to restore the original MAC/vlan tag, again the VF
    will *not* be bound to a host net driver, so it won't be possible to
    learn from sysfs whether to use the port 1 or port 2 PF netdev for the
    netlink commands. And again, it doesn't matter which netdev you
    use. However, we must keep in mind that we saved the original settings
    to a file called "${PF}_${VFNUM}". To solve this problem, we just
    check for the existence of ${PF1}_${VFNUM} and ${PF2}_${VFNUM}, and
    use whichever one we find (since we know that only one can be there)
    b67eaa63
virpci.h 9.6 KB