[dpdk-dev] [PATCH v2 2/2] net/virtio: support GUEST ANNOUNCE
Tiwei Bie
tiwei.bie at intel.com
Mon Dec 4 09:46:34 CET 2017
On Mon, Dec 04, 2017 at 06:02:08AM -0800, Xiao Wang wrote:
> When live migration is done, for the backup VM, either the virtio
> frontend or the vhost backend needs to send out gratuitous RARP packet
> to announce its new network location.
>
To support GUEST ANNOUNCE, do we just need to send a RARP packet?
Will it work in an IPv6-only network?
> This patch enables VIRTIO_NET_F_GUEST_ANNOUNCE feature to support live
[...]
> +
> +static int
> +virtio_dev_pause(struct rte_eth_dev *dev)
> +{
> + struct virtio_hw *hw = dev->data->dev_private;
> +
> + if (hw->started == 0)
> + return -1;
> + hw->started = 0;
> + /*
> + * Prevent the worker thread from touching queues to avoid condition,
Typo. Avoid "contention"?
> + * 1 ms should be enough for the ongoing Tx function to finish.
> + */
> + rte_delay_ms(1);
> + return 0;
> +}
> +
> +static void
> +virtio_dev_resume(struct rte_eth_dev *dev)
> +{
> + struct virtio_hw *hw = dev->data->dev_private;
> +
> + hw->started = 1;
> +}
> +
> +static void
> +generate_rarp(struct rte_eth_dev *dev)
You can give it a better name, e.g. virtio_notify_peers().
> +{
> + struct virtio_hw *hw = dev->data->dev_private;
> + struct rte_mbuf *rarp_mbuf = NULL;
> + struct virtnet_tx *txvq = dev->data->tx_queues[0];
> + struct virtnet_rx *rxvq = dev->data->rx_queues[0];
> +
> + rarp_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
> + if (rarp_mbuf == NULL) {
> + PMD_DRV_LOG(ERR, "mbuf allocate failed");
> + return;
> + }
> +
> + if (make_rarp_packet(rarp_mbuf, (struct ether_addr *)hw->mac_addr)) {
> + rte_pktmbuf_free(rarp_mbuf);
> + rarp_mbuf = NULL;
> + return;
> + }
> +
> + /* If virtio port just stopped, no need to send RARP */
> + if (virtio_dev_pause(dev) < 0)
> + return;
> +
> + virtio_inject_pkts(txvq, &rarp_mbuf, 1);
> + /* Recover the stored hw status to let worker thread continue */
> + virtio_dev_resume(dev);
> +}
> +
> +static void
> +virtnet_ack_link_announce(struct rte_eth_dev *dev)
Why use "virtnet_" prefix? I think "virtio_" would be better.
> +{
> + struct virtio_hw *hw = dev->data->dev_private;
> + struct virtio_pmd_ctrl ctrl;
> + int len;
> +
> + ctrl.hdr.class = VIRTIO_NET_CTRL_ANNOUNCE;
> + ctrl.hdr.cmd = VIRTIO_NET_CTRL_ANNOUNCE_ACK;
> + len = 0;
> +
> + virtio_send_command(hw->cvq, &ctrl, &len, 0);
> +}
> +
> /*
> - * Process Virtio Config changed interrupt and call the callback
> - * if link state changed.
> + * Process virtio config changed interrupt. Call the callback
> + * if link state changed; generate gratuitous RARP packet if
Better to replace ";" with ","
> + * the status indicates an ANNOUNCE.
> */
> void
> virtio_interrupt_handler(void *param)
> @@ -1274,6 +1391,12 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev,
> NULL, NULL);
> }
>
> + if (isr & VIRTIO_NET_S_ANNOUNCE) {
> + rte_spinlock_lock(&hw->sl);
> + generate_rarp(dev);
Just curious. Do you need to make sure that the RARP packet
would be sent successfully?
> + virtnet_ack_link_announce(dev);
> + rte_spinlock_unlock(&hw->sl);
> + }
> }
[...]
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index 3c5ce66..3cd367e 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -270,6 +270,7 @@ struct virtio_hw {
> struct virtio_pci_common_cfg *common_cfg;
> struct virtio_net_config *dev_cfg;
> void *virtio_user_dev;
> + rte_spinlock_t sl;
Some detailed comments need to be added in the code to
document the usage of this lock.
>
> struct virtqueue **vqs;
> };
[...]
> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
> index 2305d91..ed420e9 100644
> --- a/drivers/net/virtio/virtqueue.h
> +++ b/drivers/net/virtio/virtqueue.h
> @@ -158,6 +158,17 @@ struct virtio_net_ctrl_mac {
> #define VIRTIO_NET_CTRL_VLAN_ADD 0
> #define VIRTIO_NET_CTRL_VLAN_DEL 1
>
> +/*
> + * Control link announce acknowledgement
> + *
> + * The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that
> + * driver has recevied the notification; device would clear the
> + * VIRTIO_NET_S_ANNOUNCE bit in the status field after it receives
> + * this command.
> + */
> +#define VIRTIO_NET_CTRL_ANNOUNCE 3
> +#define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
You can just keep 3 and 0 in the same column.
Best regards,
Tiwei Bie
More information about the dev
mailing list