| From foo@baz Sun May 27 17:33:38 CEST 2018 |
| From: Jay Vosburgh <jay.vosburgh@canonical.com> |
| Date: Thu, 22 Mar 2018 14:42:41 +0000 |
| Subject: virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS |
| |
| From: Jay Vosburgh <jay.vosburgh@canonical.com> |
| |
| [ Upstream commit bda7fab54828bbef2164bb23c0f6b1a7d05cc718 ] |
| |
| The operstate update logic will leave an interface in the |
| default UNKNOWN operstate if the interface carrier state never changes |
| from the default carrier up state set at creation. This includes the |
| case of an explicit call to netif_carrier_on, as the carrier on to on |
| transition has no effect on operstate. |
| |
| This affects virtio-net for the case that the virtio peer does |
| not support VIRTIO_NET_F_STATUS (the feature that provides carrier state |
| updates). Without this feature, the virtio specification states that |
| "the link should be assumed active," so, logically, the operstate should |
| be UP instead of UNKNOWN. This has impact on user space applications |
| that use the operstate to make availability decisions for the interface. |
| |
| Resolve this by changing the virtio probe logic slightly to call |
| netif_carrier_off for both the "with" and "without" VIRTIO_NET_F_STATUS |
| cases, and then the existing call to netif_carrier_on for the "without" |
| case will cause an operstate transition. |
| |
| Cc: "Michael S. Tsirkin" <mst@redhat.com> |
| Cc: Jason Wang <jasowang@redhat.com> |
| Cc: Ben Hutchings <ben@decadent.org.uk> |
| Signed-off-by: Jay Vosburgh <jay.vosburgh@canonical.com> |
| Acked-by: Michael S. Tsirkin <mst@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/virtio_net.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/net/virtio_net.c |
| +++ b/drivers/net/virtio_net.c |
| @@ -1949,8 +1949,8 @@ static int virtnet_probe(struct virtio_d |
| |
| /* Assume link up if device can't report link status, |
| otherwise get link status from config. */ |
| + netif_carrier_off(dev); |
| if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { |
| - netif_carrier_off(dev); |
| schedule_work(&vi->config_work); |
| } else { |
| vi->status = VIRTIO_NET_S_LINK_UP; |