netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 2/3] virtio net: Handle proto_down state by setting the carrier off.
@ 2015-03-22  4:06 anuradhak
  2015-03-23 20:50 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: anuradhak @ 2015-03-22  4:06 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, gospo, wkok, anuradhak

From: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>

Applications such as MLAG can detect errors in the network which results
in IFF_PROTO_DOWN being set. This patch adds support for handling
proto_down for virtio drivers by turning off the carrier and stopping
netif processing.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
---
 drivers/net/virtio_net.c |   78 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 74 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index f1ff366..e396bf4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -767,6 +767,15 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 	return received;
 }
 
+static inline bool is_virtnet_up(struct virtnet_info *vi)
+{
+	if ((vi->status & VIRTIO_NET_S_LINK_UP) &&
+	    !(vi->dev->flags & IFF_PROTO_DOWN))
+		return true;
+
+	return false;
+}
+
 #ifdef CONFIG_NET_RX_BUSY_POLL
 /* must be called with local_bh_disable()d */
 static int virtnet_busy_poll(struct napi_struct *napi)
@@ -776,7 +785,7 @@ static int virtnet_busy_poll(struct napi_struct *napi)
 	struct virtnet_info *vi = rq->vq->vdev->priv;
 	int r, received = 0, budget = 4;
 
-	if (!(vi->status & VIRTIO_NET_S_LINK_UP))
+	if (!is_virtnet_up(vi))
 		return LL_FLUSH_FAILED;
 
 	if (!napi_schedule_prep(napi))
@@ -1428,7 +1437,7 @@ static void virtnet_config_changed_work(struct work_struct *work)
 
 	vi->status = v;
 
-	if (vi->status & VIRTIO_NET_S_LINK_UP) {
+	if (is_virtnet_up(vi)) {
 		netif_carrier_on(vi->dev);
 		netif_tx_wake_all_queues(vi->dev);
 	} else {
@@ -1878,7 +1887,8 @@ static int virtnet_probe(struct virtio_device *vdev)
 		schedule_work(&vi->config_work);
 	} else {
 		vi->status = VIRTIO_NET_S_LINK_UP;
-		netif_carrier_on(dev);
+		if (is_virtnet_up(vi))
+			netif_carrier_on(dev);
 	}
 
 	pr_debug("virtnet: registered device %s with %d RX and TX vq's\n",
@@ -2027,7 +2037,67 @@ static struct virtio_driver virtio_net_driver = {
 #endif
 };
 
-module_virtio_driver(virtio_net_driver);
+/* virtio_netdev_event: handle netdev notifier chain events. */
+static int virtio_netdev_event(struct notifier_block *this,
+			       unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct virtnet_info *vi;
+
+	if (dev->netdev_ops != &virtnet_netdev)
+		return NOTIFY_DONE;
+
+	vi = netdev_priv(dev);
+
+	switch (event) {
+	case NETDEV_CHANGE:
+		/* carrier state needs to be updated based on changes to
+		 * proto_down state
+		 */
+		if (is_virtnet_up(vi)) {
+			if (!netif_carrier_ok(dev)) {
+				netif_carrier_on(dev);
+				netif_tx_wake_all_queues(vi->dev);
+			}
+		} else {
+			if (netif_carrier_ok(dev)) {
+				netif_carrier_off(dev);
+				netif_tx_stop_all_queues(dev);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block virtio_netdev_notifier = {
+	.notifier_call = virtio_netdev_event,
+};
+
+static int __init init(void)
+{
+	int ret;
+
+	ret = register_virtio_driver(&virtio_net_driver);
+	if (ret)
+		goto done;
+
+	register_netdevice_notifier(&virtio_netdev_notifier);
+
+done:
+	return ret;
+}
+module_init(init);
+
+static void __exit fini(void)
+{
+	unregister_netdevice_notifier(&virtio_netdev_notifier);
+	unregister_virtio_driver(&virtio_net_driver);
+}
+module_exit(fini);
 
 MODULE_DEVICE_TABLE(virtio, id_table);
 MODULE_DESCRIPTION("Virtio network driver");
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net-next v2 2/3] virtio net: Handle proto_down state by setting the carrier off.
  2015-03-22  4:06 [PATCH net-next v2 2/3] virtio net: Handle proto_down state by setting the carrier off anuradhak
@ 2015-03-23 20:50 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2015-03-23 20:50 UTC (permalink / raw)
  To: anuradhak; +Cc: netdev, roopa, gospo, wkok

From: anuradhak@cumulusnetworks.com
Date: Sat, 21 Mar 2015 21:06:57 -0700

> From: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
> 
> Applications such as MLAG can detect errors in the network which results
> in IFF_PROTO_DOWN being set. This patch adds support for handling
> proto_down for virtio drivers by turning off the carrier and stopping
> netif processing.
> 
> Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
> Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
> Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>

I really don't like the idea that there are potentially many drivers
that will not have to add this kind of new code.

This doesn't scale when you have dozens of software devices of various
types, and several hundred physical hardware networking drivers.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-03-23 20:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-22  4:06 [PATCH net-next v2 2/3] virtio net: Handle proto_down state by setting the carrier off anuradhak
2015-03-23 20:50 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).