Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4320

kernel-2.6.18-194.11.1.el5.src.rpm

From: Herbert Xu <herbert.xu@redhat.com>
Date: Fri, 7 Aug 2009 20:11:46 +1000
Subject: [xen] netback: call netdev_features_changed
Message-id: 20090807101146.GA6847@gondor.apana.org.au
O-Subject: [RHEL5.5 PATCH] netback: Call netdev_features_changed
Bugzilla: 493092
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>
RH-Acked-by: David Miller <davem@redhat.com>
RH-Acked-by: Thomas Graf <tgraf@redhat.com>

Hi:

RHEL5 Bugzilla #493092

netback: Call netdev_features_changed

By default, the Xen backend network device gets added to the
virtual bridge before it has completed the features negotiation
with the guest.  As such it will have all offloads set to off.
This causes the offloads on the bridge to be disabled as well.

When the guest completes negotiation, the backend device gets
the offload features but does not propagate them to the bridge.

This is usually not a problem because the host usually does not
transmit through the bridge device directly so its feature bits
are irrelevant.

However, if the topology is such that the bridge is used directly,
e.g., when netloop is not in use, then we'll lose all offload
capabilities to the guest.

This patch fixes that problem.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c
index 092d29c..ccef3e4 100644
--- a/drivers/xen/netback/interface.c
+++ b/drivers/xen/netback/interface.c
@@ -307,11 +307,9 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
 
 	netif_get(netif);
 
-	rtnl_lock();
 	netif_carrier_on(netif->dev);
 	if (netif_running(netif->dev))
 		__netif_up(netif);
-	rtnl_unlock();
 
 	return 0;
 err_hypervisor:
diff --git a/drivers/xen/netback/xenbus.c b/drivers/xen/netback/xenbus.c
index d15ce95..0e47109 100644
--- a/drivers/xen/netback/xenbus.c
+++ b/drivers/xen/netback/xenbus.c
@@ -19,6 +19,8 @@
 
 #include <stdarg.h>
 #include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
 #include <xen/xenbus.h>
 #include "common.h"
 
@@ -311,10 +313,12 @@ static void connect(struct backend_info *be)
 	int err;
 	struct xenbus_device *dev = be->dev;
 
+	rtnl_lock();
+
 	err = xen_net_read_mac(dev, be->netif->fe_dev_addr);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
-		return;
+		goto out;
 	}
 
 	xen_net_read_rate(dev, &be->netif->credit_bytes,
@@ -323,11 +327,14 @@ static void connect(struct backend_info *be)
 
 	err = connect_rings(be);
 	if (err)
-		return;
+		goto out;
 
 	/* May not get a kick from the frontend, so start the tx_queue now. */
 	if (!netbk_can_queue(be->netif->dev))
 		netif_wake_queue(be->netif->dev);
+
+out:
+	rtnl_unlock();
 }
 
 
@@ -399,6 +406,8 @@ static int connect_rings(struct backend_info *be)
 		be->netif->dev->features &= ~NETIF_F_IP_CSUM;
 	}
 
+	netdev_features_change(be->netif->dev);
+
 	/* Map the shared frame, irq etc. */
 	err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
 	if (err) {