Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit deeaf1f8 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'Enable-virtio_net-to-act-as-a-standby-for-a-passthru-device'

Sridhar Samudrala says:

====================
Enable virtio_net to act as a standby for a passthru device

The main motivation for this patch is to enable cloud service providers
to provide an accelerated datapath to virtio-net enabled VMs in a
transparent manner with no/minimal guest userspace changes. This also
enables hypervisor controlled live migration to be supported with VMs that
have direct attached SR-IOV VF devices.

Patch 1 introduces a failover module that provides a generic interface for
paravirtual drivers to listen for netdev register/unregister/link change
events from pci ethernet devices with the same MAC and takeover their
datapath. The notifier and event handling code is based on the existing
netvsc implementation.

Patch 2 refactors netvsc to use the registration/notification framework
introduced by failover module.

Patch 3 introduces a net_failover driver that provides an automated
failover mechanism to paravirtual drivers via APIs to create and destroy
a failover master netdev and mananges a primary and standby slave netdevs
that get registered via the generic failover infrastructure.

Patch 4 introduces a new feature bit VIRTIO_NET_F_STANDBY to virtio-net
that can be used by hypervisor to indicate that virtio_net interface
should act as a standby for another device with the same MAC address.

Patch 5 extends virtio_net to use alternate datapath when available and
registered. When STANDBY feature is enabled, virtio_net driver uese the
net_failover API to create an additional 'failover' netdev that acts as
a master device and controls 2 slave devices.  The original virtio_net
netdev is registered as 'standby' netdev and a passthru/vf device with
the same MAC gets registered as 'primary' netdev. Both 'standby' and
'failover' netdevs are associated with the same 'pci' device.  The user
accesses the network interface via 'failover' netdev. The 'failover'
netdev chooses 'primary' netdev as default for transmits when it is
available with link up and running.

As this patch series is initially focusing on usecases where hypervisor
fully controls the VM networking and the guest is not expected to directly
configure any hardware settings, it doesn't expose all the ndo/ethtool ops
that are supported by virtio_net at this time. To support additional usecases,
it should be possible to enable additional ops later by caching the state
in failover netdev and replaying when the 'primary' netdev gets registered.

At the time of live migration, the hypervisor needs to unplug the VF device
from the guest on the source host and reset the MAC filter of the VF to
initiate failover of datapath to virtio before starting the migration. After
the migration is completed, the destination hypervisor sets the MAC filter
on the VF and plugs it back to the guest to switch over to VF datapath.

This patch is based on the discussion initiated by Jesse on this thread.
https://marc.info/?l=linux-virtualization&m=151189725224231&w=2



v12:
- Tested live migration with virtio-net/AVF(i40evf) configured in failover
  mode while running iperf in background. Tried static ip and dhcp
  configurations using 'network' scripts and Network Manager.
- Build tested netvsc module.
Updates:
- Extended generic failover module to do common functions like setting
  FAILOVER_SLAVE flag, registering rx-handler and linking to upper dev in
  the generic register/unregister handlers.
  This required adding 3 additional failover ops pre_register, pre_unregister
  and handle_frame.  netvsc and net_failover drivers are updated to support
  these ops.

v11:
- Split net_failover module into 2 components.
  1. 'failover' module that provides generic failover infrastructure
  to register a failover instance and listen for slave events.
  2. 'net_failover' driver that provides APIs to create/destroy upper
  netdev and supports 3-netdev model used by virtio-net.
- Added documentation

v10:
- fix net_failover_open() to update failover CARRIER correctly based on
  standby and primary states.
- fix net_failover_handle_frame() to handle frames received on standby
  when primary is present.
- replace netdev_upper_dev_link with netdev_master_upper_dev_link and
  handle lower dev state changes.
- fix net_failver_create() and net_failover_register() interfaces to
  use ERR_PTR and avoid arg **
- disable setting mac address when virtio-net in STANDBY mode
- document exported symbols
- added entry to MAINTAINERS file

v9:
Select NET_FAILOVER automatically when VIRTIO_NET/HYPERV_NET
are enabled. (stephen)

v8:
- Made the failover managment routines more robust by updating the feature
  bits/other fields in the failover netdev when slave netdevs are
  registered/unregistered. (mst)
- added support for handling vlans.
- Limited the changes in netvsc to only use the notifier/event/lookups
  from the failover module. The slave register/unregister/link-change
  handlers are only updated to use the getbymac routine to get the
  upper netdev. There is no change in their functionality. (stephen)
- renamed structs/function/file names to use net_failover prefix. (mst)

v7
- Rename 'bypass/active/backup' terminology with 'failover/primary/standy'
  (jiri, mst)
- re-arranged dev_open() and dev_set_mtu() calls in the register routines
  so that they don't get called for 2-netdev model. (stephen)
- fixed select_queue() routine to do queue selection based on VF if it is
  registered as primary. (stephen)
-  minor bugfixes

v6 RFC:
  Simplified virtio_net changes by moving all the ndo_ops of the
  bypass_netdev and create/destroy of bypass_netdev to 'bypass' module.
  avoided 2 phase registration(driver + instances).
  introduced IFF_BYPASS/IFF_BYPASS_SLAVE dev->priv_flags
  replaced mutex with a spinlock

v5 RFC:
  Based on Jiri's comments, moved the common functionality to a 'bypass'
  module so that the same notifier and event handlers to handle child
  register/unregister/link change events can be shared between virtio_net
  and netvsc.
  Improved error handling based on Siwei's comments.
v4:
- Based on the review comments on the v3 version of the RFC patch and
  Jakub's suggestion for the naming issue with 3 netdev solution,
  proposed 3 netdev in-driver bonding solution for virtio-net.
v3 RFC:
- Introduced 3 netdev model and pointed out a couple of issues with
  that model and proposed 2 netdev model to avoid these issues.
- Removed broadcast/multicast optimization and only use virtio as
  backup path when VF is unplugged.
v2 RFC:
- Changed VIRTIO_NET_F_MASTER to VIRTIO_NET_F_BACKUP (mst)
- made a small change to the virtio-net xmit path to only use VF datapath
  for unicasts. Broadcasts/multicasts use virtio datapath. This avoids
  east-west broadcasts to go over the PCI link.
- added suppport for the feature bit in qemu
====================

Acked-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cb160394 ba5e4426
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

========
FAILOVER
========

Overview
========

The failover module provides a generic interface for paravirtual drivers
to register a netdev and a set of ops with a failover instance. The ops
are used as event handlers that get called to handle netdev register/
unregister/link change/name change events on slave pci ethernet devices
with the same mac address as the failover netdev.

This enables paravirtual drivers to use a VF as an accelerated low latency
datapath. It also allows live migration of VMs with direct attached VFs by
failing over to the paravirtual datapath when the VF is unplugged.
+116 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

============
NET_FAILOVER
============

Overview
========

The net_failover driver provides an automated failover mechanism via APIs
to create and destroy a failover master netdev and mananges a primary and
standby slave netdevs that get registered via the generic failover
infrastructrure.

The failover netdev acts a master device and controls 2 slave devices. The
original paravirtual interface is registered as 'standby' slave netdev and
a passthru/vf device with the same MAC gets registered as 'primary' slave
netdev. Both 'standby' and 'failover' netdevs are associated with the same
'pci' device. The user accesses the network interface via 'failover' netdev.
The 'failover' netdev chooses 'primary' netdev as default for transmits when
it is available with link up and running.

This can be used by paravirtual drivers to enable an alternate low latency
datapath. It also enables hypervisor controlled live migration of a VM with
direct attached VF by failing over to the paravirtual datapath when the VF
is unplugged.

virtio-net accelerated datapath: STANDBY mode
=============================================

net_failover enables hypervisor controlled accelerated datapath to virtio-net
enabled VMs in a transparent manner with no/minimal guest userspace chanages.

To support this, the hypervisor needs to enable VIRTIO_NET_F_STANDBY
feature on the virtio-net interface and assign the same MAC address to both
virtio-net and VF interfaces.

Here is an example XML snippet that shows such configuration.

 <interface type='network'>
   <mac address='52:54:00:00:12:53'/>
   <source network='enp66s0f0_br'/>
   <target dev='tap01'/>
   <model type='virtio'/>
   <driver name='vhost' queues='4'/>
   <link state='down'/>
   <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
 </interface>
 <interface type='hostdev' managed='yes'>
   <mac address='52:54:00:00:12:53'/>
   <source>
     <address type='pci' domain='0x0000' bus='0x42' slot='0x02' function='0x5'/>
   </source>
   <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
 </interface>

Booting a VM with the above configuration will result in the following 3
netdevs created in the VM.

4: ens10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff
    inet 192.168.12.53/24 brd 192.168.12.255 scope global dynamic ens10
       valid_lft 42482sec preferred_lft 42482sec
    inet6 fe80::97d8:db2:8c10:b6d6/64 scope link
       valid_lft forever preferred_lft forever
5: ens10nsby: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master ens10 state UP group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff
7: ens11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master ens10 state UP group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff

ens10 is the 'failover' master netdev, ens10nsby and ens11 are the slave
'standby' and 'primary' netdevs respectively.

Live Migration of a VM with SR-IOV VF & virtio-net in STANDBY mode
==================================================================

net_failover also enables hypervisor controlled live migration to be supported
with VMs that have direct attached SR-IOV VF devices by automatic failover to
the paravirtual datapath when the VF is unplugged.

Here is a sample script that shows the steps to initiate live migration on
the source hypervisor.

# cat vf_xml
<interface type='hostdev' managed='yes'>
  <mac address='52:54:00:00:12:53'/>
  <source>
    <address type='pci' domain='0x0000' bus='0x42' slot='0x02' function='0x5'/>
  </source>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
</interface>

# Source Hypervisor
#!/bin/bash

DOMAIN=fedora27-tap01
PF=enp66s0f0
VF_NUM=5
TAP_IF=tap01
VF_XML=

MAC=52:54:00:00:12:53
ZERO_MAC=00:00:00:00:00:00

virsh domif-setlink $DOMAIN $TAP_IF up
bridge fdb del $MAC dev $PF master
virsh detach-device $DOMAIN $VF_XML
ip link set $PF vf $VF_NUM mac $ZERO_MAC

virsh migrate --live $DOMAIN qemu+ssh://$REMOTE_HOST/system

# Destination Hypervisor
#!/bin/bash

virsh attach-device $DOMAIN $VF_XML
virsh domif-setlink $DOMAIN $TAP_IF down
+16 −0
Original line number Diff line number Diff line
@@ -5411,6 +5411,14 @@ S: Maintained
F:	Documentation/hwmon/f71805f
F:	drivers/hwmon/f71805f.c

FAILOVER MODULE
M:	Sridhar Samudrala <sridhar.samudrala@intel.com>
L:	netdev@vger.kernel.org
S:	Supported
F:	net/core/failover.c
F:	include/net/failover.h
F:	Documentation/networking/failover.rst

FANOTIFY
M:	Jan Kara <jack@suse.cz>
R:	Amir Goldstein <amir73il@gmail.com>
@@ -9646,6 +9654,14 @@ S: Maintained
F:	Documentation/hwmon/nct6775
F:	drivers/hwmon/nct6775.c

NET_FAILOVER MODULE
M:	Sridhar Samudrala <sridhar.samudrala@intel.com>
L:	netdev@vger.kernel.org
S:	Supported
F:	driver/net/net_failover.c
F:	include/net/net_failover.h
F:	Documentation/networking/net_failover.rst

NETEFFECT IWARP RNIC DRIVER (IW_NES)
M:	Faisal Latif <faisal.latif@intel.com>
L:	linux-rdma@vger.kernel.org
+13 −0
Original line number Diff line number Diff line
@@ -332,6 +332,7 @@ config VETH
config VIRTIO_NET
	tristate "Virtio network driver"
	depends on VIRTIO
	select NET_FAILOVER
	---help---
	  This is the virtual network driver for virtio.  It can be used with
	  QEMU based VMMs (like KVM or Xen).  Say Y or M.
@@ -510,4 +511,16 @@ config NETDEVSIM
	  To compile this driver as a module, choose M here: the module
	  will be called netdevsim.

config NET_FAILOVER
	tristate "Failover driver"
	select FAILOVER
	help
	  This provides an automated failover mechanism via APIs to create
	  and destroy a failover master netdev and manages a primary and
	  standby slave netdevs that get registered via the generic failover
	  infrastructure. This can be used by paravirtual drivers to enable
	  an alternate low latency datapath. It alsoenables live migration of
	  a VM with direct attached VF by failing over to the paravirtual
	  datapath when the VF is unplugged.

endif # NETDEVICES
+1 −0
Original line number Diff line number Diff line
@@ -78,3 +78,4 @@ obj-$(CONFIG_FUJITSU_ES) += fjes/
thunderbolt-net-y += thunderbolt.o
obj-$(CONFIG_THUNDERBOLT_NET) += thunderbolt-net.o
obj-$(CONFIG_NETDEVSIM) += netdevsim/
obj-$(CONFIG_NET_FAILOVER) += net_failover.o
Loading