All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Cc: netdev@vger.kernel.org, jasowang@redhat.com,
	virtualization@lists.linux-foundation.org,
	Willem de Bruijn <willemb@google.com>
Subject: Re: [PATCH RFC 1/2] virtio_net: implement VIRTIO_CONFIG_S_NEEDS_RESET
Date: Tue, 29 Aug 2017 23:20:33 +0300	[thread overview]
Message-ID: <20170829231739-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20170829200759.13975-2-willemdebruijn.kernel@gmail.com>

On Tue, Aug 29, 2017 at 04:07:58PM -0400, Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
> 
> Implement the reset communication request defined in the VIRTIO 1.0
> specification and introduces in Linux in commit c00bbcf862896 ("virtio:
> add VIRTIO_CONFIG_S_NEEDS_RESET device status bit").
> 
> Since that patch, the virtio-net driver has added a virtnet_reset
> function that implements the requested behavior through calls to the
> power management freeze and restore functions.
> 
> That function has recently been reverted when its sole caller was
> updated. Bring it back and listen for the request from the host on
> the config channel.
> 
> Implement the feature analogous to other config requests. In
> particular, acknowledge the request in the same manner as the
> NET_S_ANNOUNCE link announce request, by responding with a new
> VIRTIO_NET_CTRL_${TYPE} command. On reception, the host must check
> the config status register for success or failure.


Pls make it clearer why do you need these interface extensions.

> The existing freeze handler verifies that no config changes are
> running concurrently. Elide this check for reset. The request is
> always handled from the config workqueue. No other config requests
> can be active or scheduled concurrently on vi->config.

You need to prevent packet TX from being in progress.

> 
> Signed-off-by: Willem de Bruijn <willemb@google.com>
> ---
>  drivers/net/virtio_net.c        | 69 +++++++++++++++++++++++++++++++++++------
>  include/uapi/linux/virtio_net.h |  4 +++

virtio dev or another virtio TC list must be Cc'd on any proposed API changes.


>  2 files changed, 64 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 52ae78ca3d38..5e349226f7c1 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1458,12 +1458,11 @@ static void virtnet_netpoll(struct net_device *dev)
>  }
>  #endif
>  
> -static void virtnet_ack_link_announce(struct virtnet_info *vi)
> +static void virtnet_ack(struct virtnet_info *vi, u8 class, u8 cmd)
>  {
>  	rtnl_lock();
> -	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_ANNOUNCE,
> -				  VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL))
> -		dev_warn(&vi->dev->dev, "Failed to ack link announce.\n");
> +	if (!virtnet_send_command(vi, class, cmd, NULL))
> +		dev_warn(&vi->dev->dev, "Failed to ack %u.%u\n", class, cmd);
>  	rtnl_unlock();
>  }
>  
> @@ -1857,13 +1856,16 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
>  	.set_link_ksettings = virtnet_set_link_ksettings,
>  };
>  
> -static void virtnet_freeze_down(struct virtio_device *vdev)
> +static void virtnet_freeze_down(struct virtio_device *vdev, bool in_reset)
>  {
>  	struct virtnet_info *vi = vdev->priv;
>  	int i;
>  
> -	/* Make sure no work handler is accessing the device */
> -	flush_work(&vi->config_work);
> +	/* Make sure no work handler is accessing the device,
> +	 * unless this call is made from the reset work handler itself.
> +	 */
> +	if (!in_reset)
> +		flush_work(&vi->config_work);
>  
>  	netif_device_detach(vi->dev);
>  	netif_tx_disable(vi->dev);
> @@ -1878,6 +1880,7 @@ static void virtnet_freeze_down(struct virtio_device *vdev)
>  }
>  
>  static int init_vqs(struct virtnet_info *vi);
> +static void remove_vq_common(struct virtnet_info *vi);
>  
>  static int virtnet_restore_up(struct virtio_device *vdev)
>  {
> @@ -1906,6 +1909,45 @@ static int virtnet_restore_up(struct virtio_device *vdev)
>  	return err;
>  }
>  
> +static int virtnet_reset(struct virtnet_info *vi)
> +{
> +	struct virtio_device *dev = vi->vdev;
> +	bool failed;
> +	int ret;
> +
> +	virtio_config_disable(dev);
> +	failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> +	virtnet_freeze_down(dev, true);
> +	remove_vq_common(vi);
> +
> +	virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
> +	virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
> +
> +	/* Restore the failed status (see virtio_device_restore). */
> +	if (failed)
> +		virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> +
> +	ret = virtio_finalize_features(dev);
> +	if (ret)
> +		goto err;
> +
> +	ret = virtnet_restore_up(dev);
> +	if (ret)
> +		goto err;
> +
> +	ret = virtnet_set_queues(vi, vi->curr_queue_pairs);
> +	if (ret)
> +		goto err;
> +
> +	virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> +	virtio_config_enable(dev);
> +	return 0;
> +
> +err:
> +	virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> +	return ret;
> +}
> +
>  static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
>  {
>  	struct scatterlist sg;
> @@ -2085,7 +2127,16 @@ static void virtnet_config_changed_work(struct work_struct *work)
>  
>  	if (v & VIRTIO_NET_S_ANNOUNCE) {
>  		netdev_notify_peers(vi->dev);
> -		virtnet_ack_link_announce(vi);
> +		virtnet_ack(vi, VIRTIO_NET_CTRL_ANNOUNCE,
> +			    VIRTIO_NET_CTRL_ANNOUNCE_ACK);
> +	}
> +
> +	if (vi->vdev->config->get_status(vi->vdev) &
> +	    VIRTIO_CONFIG_S_NEEDS_RESET) {
> +		virtnet_reset(vi);
> +		virtnet_ack(vi, VIRTIO_NET_CTRL_RESET,
> +			    VIRTIO_NET_CTRL_RESET_ACK);
> +
>  	}
>  
>  	/* Ignore unknown (future) status bits */
> @@ -2708,7 +2759,7 @@ static __maybe_unused int virtnet_freeze(struct virtio_device *vdev)
>  	struct virtnet_info *vi = vdev->priv;
>  
>  	virtnet_cpu_notif_remove(vi);
> -	virtnet_freeze_down(vdev);
> +	virtnet_freeze_down(vdev, false);
>  	remove_vq_common(vi);
>  
>  	return 0;
> diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
> index fc353b518288..188fdc528f13 100644
> --- a/include/uapi/linux/virtio_net.h
> +++ b/include/uapi/linux/virtio_net.h
> @@ -245,4 +245,8 @@ struct virtio_net_ctrl_mq {
>  #define VIRTIO_NET_CTRL_GUEST_OFFLOADS   5
>  #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
>  
> +/* Signal that the driver received and executed the reset command. */
> +#define VIRTIO_NET_CTRL_RESET			6
> +#define VIRTIO_NET_CTRL_RESET_ACK		0
> +
>  #endif /* _UAPI_LINUX_VIRTIO_NET_H */
> -- 
> 2.14.1.342.g6490525c54-goog

  parent reply	other threads:[~2017-08-29 20:20 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-29 20:07 [PATCH RFC 0/2] virtio-net: implement reset request Willem de Bruijn
2017-08-29 20:07 ` [PATCH RFC 1/2] virtio_net: implement VIRTIO_CONFIG_S_NEEDS_RESET Willem de Bruijn
2017-08-29 20:20   ` Michael S. Tsirkin
2017-08-29 20:20   ` Michael S. Tsirkin [this message]
2017-10-05 16:18     ` Willem de Bruijn
2017-10-05 16:18     ` Willem de Bruijn
2017-08-29 20:07 ` Willem de Bruijn
2017-08-29 20:07 ` [PATCH RFC 2/2] virtio_net: enable probing for NEEDS_RESET support Willem de Bruijn
2017-08-29 20:16   ` Michael S. Tsirkin
2017-08-29 20:27     ` Willem de Bruijn
2017-08-29 20:27     ` Willem de Bruijn
2017-08-29 20:38       ` Michael S. Tsirkin
2017-08-29 20:38       ` Michael S. Tsirkin
2017-08-29 21:02         ` [virtio-dev] " Willem de Bruijn
2017-08-29 21:02           ` Willem de Bruijn
2017-08-29 21:13           ` [virtio-dev] " Michael S. Tsirkin
2017-08-29 21:13             ` Michael S. Tsirkin
2017-08-29 22:38             ` Willem de Bruijn
2017-08-29 22:38             ` [virtio-dev] " Willem de Bruijn
2017-08-29 22:38               ` Willem de Bruijn
2017-08-29 21:13           ` Michael S. Tsirkin
2017-08-29 21:02         ` Willem de Bruijn
2017-08-29 20:07 ` Willem de Bruijn

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=20170829231739-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=jasowang@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=willemb@google.com \
    --cc=willemdebruijn.kernel@gmail.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.