[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Make frontend features distinct from netback feature flags.
Make sure that if a feature flag is disabled by ethtool on netback that we do not gratuitously re-enabled it when we check the frontend features during ring connection. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> --- drivers/xen/netback/common.h | 15 ++++++--- drivers/xen/netback/interface.c | 68 ++++++++++++++++++++++++++++++-------- drivers/xen/netback/netback.c | 2 +- drivers/xen/netback/xenbus.c | 51 +++++++++++------------------ 4 files changed, 83 insertions(+), 53 deletions(-) diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h index 1cbc4ff..a673331 100644 --- a/drivers/xen/netback/common.h +++ b/drivers/xen/netback/common.h @@ -76,14 +76,18 @@ struct xen_netif { struct vm_struct *tx_comms_area; struct vm_struct *rx_comms_area; - /* Set of features that can be turned on in dev->features. */ - int features; + /* Flags that must not be set in dev->features */ + int features_disabled; - int smart_poll; + /* Frontend feature information. */ + u8 can_sg:1; + u8 gso:1; + u8 gso_prefix:1; + u8 csum:1; + u8 smart_poll:1; /* Internal feature information. */ u8 can_queue:1; /* can queue packets for receiver? */ - u8 gso_prefix:1; /* use a prefix segment for GSO information */ /* Allow netif_be_start_xmit() to peek ahead in the rx request * ring. This is a prediction of what rx_req_cons will be once @@ -189,6 +193,7 @@ void netif_accel_init(void); void netif_disconnect(struct xen_netif *netif); +void netif_set_features(struct xen_netif *netif); struct xen_netif *netif_alloc(struct device *parent, domid_t domid, unsigned int handle); int netif_map(struct xen_netif *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn); @@ -225,7 +230,7 @@ static inline int netbk_can_queue(struct net_device *dev) static inline int netbk_can_sg(struct net_device *dev) { struct xen_netif *netif = netdev_priv(dev); - return netif->features & NETIF_F_SG; + return netif->can_sg; } struct pending_tx_info { diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c index 172ef4c..2e8508a 100644 --- a/drivers/xen/netback/interface.c +++ b/drivers/xen/netback/interface.c @@ -121,31 +121,69 @@ static int netbk_change_mtu(struct net_device *dev, int mtu) return 0; } -static int netbk_set_sg(struct net_device *dev, u32 data) +void netif_set_features(struct xen_netif *netif) { - if (data) { - struct xen_netif *netif = netdev_priv(dev); + struct net_device *dev = netif->dev; + int features = dev->features; + + if (netif->can_sg) + features |= NETIF_F_SG; + if (netif->gso || netif->gso_prefix) + features |= NETIF_F_TSO; + if (netif->csum) + features |= NETIF_F_IP_CSUM; + + features &= ~(netif->features_disabled); - if (!(netif->features & NETIF_F_SG)) + if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) + dev->mtu = ETH_DATA_LEN; + + dev->features = features; +} + +static int netbk_set_tx_csum(struct net_device *dev, u32 data) +{ + struct xen_netif *netif = netdev_priv(dev); + if (data) { + if (!netif->csum) return -ENOSYS; + netif->features_disabled &= ~NETIF_F_IP_CSUM; + } else { + netif->features_disabled |= NETIF_F_IP_CSUM; } - if (dev->mtu > ETH_DATA_LEN) - dev->mtu = ETH_DATA_LEN; + netif_set_features(netif); + return 0; +} - return ethtool_op_set_sg(dev, data); +static int netbk_set_sg(struct net_device *dev, u32 data) +{ + struct xen_netif *netif = netdev_priv(dev); + if (data) { + if (!netif->can_sg) + return -ENOSYS; + netif->features_disabled &= ~NETIF_F_SG; + } else { + netif->features_disabled |= NETIF_F_SG; + } + + netif_set_features(netif); + return 0; } static int netbk_set_tso(struct net_device *dev, u32 data) { + struct xen_netif *netif = netdev_priv(dev); if (data) { - struct xen_netif *netif = netdev_priv(dev); - - if (!(netif->features & NETIF_F_TSO)) + if (!netif->gso && !netif->gso_prefix) return -ENOSYS; + netif->features_disabled &= ~NETIF_F_TSO; + } else { + netif->features_disabled |= NETIF_F_TSO; } - return ethtool_op_set_tso(dev, data); + netif_set_features(netif); + return 0; } static void netbk_get_drvinfo(struct net_device *dev, @@ -200,7 +238,7 @@ static struct ethtool_ops network_ethtool_ops = .get_drvinfo = netbk_get_drvinfo, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .set_tx_csum = netbk_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = netbk_set_sg, .get_tso = ethtool_op_get_tso, @@ -242,7 +280,8 @@ struct xen_netif *netif_alloc(struct device *parent, domid_t domid, unsigned int netif->domid = domid; netif->group = -1; netif->handle = handle; - netif->features = NETIF_F_SG; + netif->can_sg = 1; + netif->csum = 1; atomic_set(&netif->refcnt, 1); init_waitqueue_head(&netif->waiting_to_free); netif->dev = dev; @@ -259,8 +298,7 @@ struct xen_netif *netif_alloc(struct device *parent, domid_t domid, unsigned int init_timer(&netif->tx_queue_timeout); dev->netdev_ops = &netback_ops; - dev->features = NETIF_F_IP_CSUM|NETIF_F_SG; - + netif_set_features(netif); SET_ETHTOOL_OPS(dev, &network_ethtool_ops); dev->tx_queue_len = netbk_queue_length; diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c index 93f0686..426aada 100644 --- a/drivers/xen/netback/netback.c +++ b/drivers/xen/netback/netback.c @@ -238,7 +238,7 @@ static struct sk_buff *netbk_copy_skb(struct sk_buff *skb) static inline int netbk_max_required_rx_slots(struct xen_netif *netif) { - if (netif->features & (NETIF_F_SG|NETIF_F_TSO)) + if (netif->can_sg || netif->gso || netif->gso_prefix) return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */ return 1; /* all in one */ } diff --git a/drivers/xen/netback/xenbus.c b/drivers/xen/netback/xenbus.c index 74c035b..81b3a96 100644 --- a/drivers/xen/netback/xenbus.c +++ b/drivers/xen/netback/xenbus.c @@ -412,6 +412,7 @@ static void connect(struct backend_info *be) static int connect_rings(struct backend_info *be) { + struct xen_netif *netif = be->netif; struct xenbus_device *dev = be->dev; unsigned long tx_ring_ref, rx_ring_ref; unsigned int evtchn, rx_copy; @@ -445,61 +446,47 @@ static int connect_rings(struct backend_info *be) if (!rx_copy) return -EOPNOTSUPP; - if (be->netif->dev->tx_queue_len != 0) { + if (netif->dev->tx_queue_len != 0) { if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d", &val) < 0) val = 0; if (val) - be->netif->can_queue = 1; + netif->can_queue = 1; else /* Must be non-zero for pfifo_fast to work. */ - be->netif->dev->tx_queue_len = 1; + netif->dev->tx_queue_len = 1; } - if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0) + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", + "%d", &val) < 0) val = 0; - if (!val) { - be->netif->features &= ~NETIF_F_SG; - be->netif->dev->features &= ~NETIF_F_SG; - if (be->netif->dev->mtu > ETH_DATA_LEN) - be->netif->dev->mtu = ETH_DATA_LEN; - } + netif->can_sg = !!val; if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", - "%d", &val) < 0) + "%d", &val) < 0) val = 0; - if (val) { - be->netif->features |= NETIF_F_TSO; - be->netif->dev->features |= NETIF_F_TSO; - } + netif->gso = !!val; if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix", - "%d", &val) < 0) + "%d", &val) < 0) val = 0; - if (val) { - be->netif->features |= NETIF_F_TSO; - be->netif->dev->features |= NETIF_F_TSO; - be->netif->gso_prefix = 1; - } + netif->gso_prefix = !!val; if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload", - "%d", &val) < 0) + "%d", &val) < 0) val = 0; - if (val) { - be->netif->features &= ~NETIF_F_IP_CSUM; - be->netif->dev->features &= ~NETIF_F_IP_CSUM; - } + netif->csum = !!val; if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-smart-poll", - "%d", &val) < 0) + "%d", &val) < 0) val = 0; - if (val) - be->netif->smart_poll = 1; - else - be->netif->smart_poll = 0; + netif->smart_poll = !!val; + + /* Set dev->features */ + netif_set_features(netif); /* Map the shared frame, irq etc. */ - err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn); + err = netif_map(netif, tx_ring_ref, rx_ring_ref, evtchn); if (err) { xenbus_dev_fatal(dev, err, "mapping shared-frames %lu/%lu port %u", -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |