diff options
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 49 | 
1 files changed, 11 insertions, 38 deletions
| diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 852da34b8961..9e97c7ca0ddd 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -137,32 +137,11 @@ static void xenvif_wake_queue_callback(unsigned long data) | |||
| 137 | } | 137 | } | 
| 138 | } | 138 | } | 
| 139 | 139 | ||
| 140 | static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, | ||
| 141 | void *accel_priv, select_queue_fallback_t fallback) | ||
| 142 | { | ||
| 143 | unsigned int num_queues = dev->real_num_tx_queues; | ||
| 144 | u32 hash; | ||
| 145 | u16 queue_index; | ||
| 146 | |||
| 147 | /* First, check if there is only one queue to optimise the | ||
| 148 | * single-queue or old frontend scenario. | ||
| 149 | */ | ||
| 150 | if (num_queues == 1) { | ||
| 151 | queue_index = 0; | ||
| 152 | } else { | ||
| 153 | /* Use skb_get_hash to obtain an L4 hash if available */ | ||
| 154 | hash = skb_get_hash(skb); | ||
| 155 | queue_index = hash % num_queues; | ||
| 156 | } | ||
| 157 | |||
| 158 | return queue_index; | ||
| 159 | } | ||
| 160 | |||
| 161 | static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | 140 | static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | 
| 162 | { | 141 | { | 
| 163 | struct xenvif *vif = netdev_priv(dev); | 142 | struct xenvif *vif = netdev_priv(dev); | 
| 164 | struct xenvif_queue *queue = NULL; | 143 | struct xenvif_queue *queue = NULL; | 
| 165 | unsigned int num_queues = dev->real_num_tx_queues; | 144 | unsigned int num_queues = vif->num_queues; | 
| 166 | u16 index; | 145 | u16 index; | 
| 167 | int min_slots_needed; | 146 | int min_slots_needed; | 
| 168 | 147 | ||
| @@ -225,7 +204,7 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev) | |||
| 225 | { | 204 | { | 
| 226 | struct xenvif *vif = netdev_priv(dev); | 205 | struct xenvif *vif = netdev_priv(dev); | 
| 227 | struct xenvif_queue *queue = NULL; | 206 | struct xenvif_queue *queue = NULL; | 
| 228 | unsigned int num_queues = dev->real_num_tx_queues; | 207 | unsigned int num_queues = vif->num_queues; | 
| 229 | unsigned long rx_bytes = 0; | 208 | unsigned long rx_bytes = 0; | 
| 230 | unsigned long rx_packets = 0; | 209 | unsigned long rx_packets = 0; | 
| 231 | unsigned long tx_bytes = 0; | 210 | unsigned long tx_bytes = 0; | 
| @@ -256,7 +235,7 @@ out: | |||
| 256 | static void xenvif_up(struct xenvif *vif) | 235 | static void xenvif_up(struct xenvif *vif) | 
| 257 | { | 236 | { | 
| 258 | struct xenvif_queue *queue = NULL; | 237 | struct xenvif_queue *queue = NULL; | 
| 259 | unsigned int num_queues = vif->dev->real_num_tx_queues; | 238 | unsigned int num_queues = vif->num_queues; | 
| 260 | unsigned int queue_index; | 239 | unsigned int queue_index; | 
| 261 | 240 | ||
| 262 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 241 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 
| @@ -272,7 +251,7 @@ static void xenvif_up(struct xenvif *vif) | |||
| 272 | static void xenvif_down(struct xenvif *vif) | 251 | static void xenvif_down(struct xenvif *vif) | 
| 273 | { | 252 | { | 
| 274 | struct xenvif_queue *queue = NULL; | 253 | struct xenvif_queue *queue = NULL; | 
| 275 | unsigned int num_queues = vif->dev->real_num_tx_queues; | 254 | unsigned int num_queues = vif->num_queues; | 
| 276 | unsigned int queue_index; | 255 | unsigned int queue_index; | 
| 277 | 256 | ||
| 278 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 257 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 
| @@ -379,7 +358,7 @@ static void xenvif_get_ethtool_stats(struct net_device *dev, | |||
| 379 | struct ethtool_stats *stats, u64 * data) | 358 | struct ethtool_stats *stats, u64 * data) | 
| 380 | { | 359 | { | 
| 381 | struct xenvif *vif = netdev_priv(dev); | 360 | struct xenvif *vif = netdev_priv(dev); | 
| 382 | unsigned int num_queues = dev->real_num_tx_queues; | 361 | unsigned int num_queues = vif->num_queues; | 
| 383 | int i; | 362 | int i; | 
| 384 | unsigned int queue_index; | 363 | unsigned int queue_index; | 
| 385 | struct xenvif_stats *vif_stats; | 364 | struct xenvif_stats *vif_stats; | 
| @@ -424,7 +403,6 @@ static const struct net_device_ops xenvif_netdev_ops = { | |||
| 424 | .ndo_fix_features = xenvif_fix_features, | 403 | .ndo_fix_features = xenvif_fix_features, | 
| 425 | .ndo_set_mac_address = eth_mac_addr, | 404 | .ndo_set_mac_address = eth_mac_addr, | 
| 426 | .ndo_validate_addr = eth_validate_addr, | 405 | .ndo_validate_addr = eth_validate_addr, | 
| 427 | .ndo_select_queue = xenvif_select_queue, | ||
| 428 | }; | 406 | }; | 
| 429 | 407 | ||
| 430 | struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | 408 | struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | 
| @@ -438,7 +416,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
| 438 | snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); | 416 | snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); | 
| 439 | /* Allocate a netdev with the max. supported number of queues. | 417 | /* Allocate a netdev with the max. supported number of queues. | 
| 440 | * When the guest selects the desired number, it will be updated | 418 | * When the guest selects the desired number, it will be updated | 
| 441 | * via netif_set_real_num_tx_queues(). | 419 | * via netif_set_real_num_*_queues(). | 
| 442 | */ | 420 | */ | 
| 443 | dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup, | 421 | dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup, | 
| 444 | xenvif_max_queues); | 422 | xenvif_max_queues); | 
| @@ -458,11 +436,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
| 458 | vif->dev = dev; | 436 | vif->dev = dev; | 
| 459 | vif->disabled = false; | 437 | vif->disabled = false; | 
| 460 | 438 | ||
| 461 | /* Start out with no queues. The call below does not require | 439 | /* Start out with no queues. */ | 
| 462 | * rtnl_lock() as it happens before register_netdev(). | ||
| 463 | */ | ||
| 464 | vif->queues = NULL; | 440 | vif->queues = NULL; | 
| 465 | netif_set_real_num_tx_queues(dev, 0); | 441 | vif->num_queues = 0; | 
| 466 | 442 | ||
| 467 | dev->netdev_ops = &xenvif_netdev_ops; | 443 | dev->netdev_ops = &xenvif_netdev_ops; | 
| 468 | dev->hw_features = NETIF_F_SG | | 444 | dev->hw_features = NETIF_F_SG | | 
| @@ -677,7 +653,7 @@ static void xenvif_wait_unmap_timeout(struct xenvif_queue *queue, | |||
| 677 | void xenvif_disconnect(struct xenvif *vif) | 653 | void xenvif_disconnect(struct xenvif *vif) | 
| 678 | { | 654 | { | 
| 679 | struct xenvif_queue *queue = NULL; | 655 | struct xenvif_queue *queue = NULL; | 
| 680 | unsigned int num_queues = vif->dev->real_num_tx_queues; | 656 | unsigned int num_queues = vif->num_queues; | 
| 681 | unsigned int queue_index; | 657 | unsigned int queue_index; | 
| 682 | 658 | ||
| 683 | if (netif_carrier_ok(vif->dev)) | 659 | if (netif_carrier_ok(vif->dev)) | 
| @@ -724,7 +700,7 @@ void xenvif_deinit_queue(struct xenvif_queue *queue) | |||
| 724 | void xenvif_free(struct xenvif *vif) | 700 | void xenvif_free(struct xenvif *vif) | 
| 725 | { | 701 | { | 
| 726 | struct xenvif_queue *queue = NULL; | 702 | struct xenvif_queue *queue = NULL; | 
| 727 | unsigned int num_queues = vif->dev->real_num_tx_queues; | 703 | unsigned int num_queues = vif->num_queues; | 
| 728 | unsigned int queue_index; | 704 | unsigned int queue_index; | 
| 729 | /* Here we want to avoid timeout messages if an skb can be legitimately | 705 | /* Here we want to avoid timeout messages if an skb can be legitimately | 
| 730 | * stuck somewhere else. Realistically this could be an another vif's | 706 | * stuck somewhere else. Realistically this could be an another vif's | 
| @@ -748,12 +724,9 @@ void xenvif_free(struct xenvif *vif) | |||
| 748 | xenvif_deinit_queue(queue); | 724 | xenvif_deinit_queue(queue); | 
| 749 | } | 725 | } | 
| 750 | 726 | ||
| 751 | /* Free the array of queues. The call below does not require | ||
| 752 | * rtnl_lock() because it happens after unregister_netdev(). | ||
| 753 | */ | ||
| 754 | netif_set_real_num_tx_queues(vif->dev, 0); | ||
| 755 | vfree(vif->queues); | 727 | vfree(vif->queues); | 
| 756 | vif->queues = NULL; | 728 | vif->queues = NULL; | 
| 729 | vif->num_queues = 0; | ||
| 757 | 730 | ||
| 758 | free_netdev(vif->dev); | 731 | free_netdev(vif->dev); | 
| 759 | 732 | ||
