diff options
author | Andrew J. Bennieston <andrew.bennieston@citrix.com> | 2014-06-04 05:30:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-04 17:48:16 -0400 |
commit | 8d3d53b3e43363e79ab9a9ecc149b06c1314b25d (patch) | |
tree | 210f923600d75e52d562ee851ba57de9daaeb5b7 /drivers/net/xen-netback/interface.c | |
parent | e9ce7cb6b107407e4798e8905b18ad8b642766f6 (diff) |
xen-netback: Add support for multiple queues
Builds on the refactoring of the previous patch to implement multiple
queues between xen-netfront and xen-netback.
Writes the maximum supported number of queues into XenStore, and reads
the values written by the frontend to determine how many queues to use.
Ring references and event channels are read from XenStore on a per-queue
basis and rings are connected accordingly.
Also adds code to handle the cleanup of any already initialised queues
if the initialisation of a subsequent queue fails.
Signed-off-by: Andrew J. Bennieston <andrew.bennieston@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r-- | drivers/net/xen-netback/interface.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 6005b5d1d404..6929bcb61cf0 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -139,7 +139,6 @@ static void xenvif_wake_queue_callback(unsigned long data) | |||
139 | static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, | 139 | static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, |
140 | void *accel_priv, select_queue_fallback_t fallback) | 140 | void *accel_priv, select_queue_fallback_t fallback) |
141 | { | 141 | { |
142 | struct xenvif *vif = netdev_priv(dev); | ||
143 | unsigned int num_queues = dev->real_num_tx_queues; | 142 | unsigned int num_queues = dev->real_num_tx_queues; |
144 | u32 hash; | 143 | u32 hash; |
145 | u16 queue_index; | 144 | u16 queue_index; |
@@ -436,7 +435,12 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
436 | char name[IFNAMSIZ] = {}; | 435 | char name[IFNAMSIZ] = {}; |
437 | 436 | ||
438 | snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); | 437 | snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); |
439 | dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup, 1); | 438 | /* Allocate a netdev with the max. supported number of queues. |
439 | * When the guest selects the desired number, it will be updated | ||
440 | * via netif_set_real_num_tx_queues(). | ||
441 | */ | ||
442 | dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup, | ||
443 | xenvif_max_queues); | ||
440 | if (dev == NULL) { | 444 | if (dev == NULL) { |
441 | pr_warn("Could not allocate netdev for %s\n", name); | 445 | pr_warn("Could not allocate netdev for %s\n", name); |
442 | return ERR_PTR(-ENOMEM); | 446 | return ERR_PTR(-ENOMEM); |
@@ -706,6 +710,16 @@ void xenvif_disconnect(struct xenvif *vif) | |||
706 | } | 710 | } |
707 | } | 711 | } |
708 | 712 | ||
713 | /* Reverse the relevant parts of xenvif_init_queue(). | ||
714 | * Used for queue teardown from xenvif_free(), and on the | ||
715 | * error handling paths in xenbus.c:connect(). | ||
716 | */ | ||
717 | void xenvif_deinit_queue(struct xenvif_queue *queue) | ||
718 | { | ||
719 | free_xenballooned_pages(MAX_PENDING_REQS, queue->mmap_pages); | ||
720 | netif_napi_del(&queue->napi); | ||
721 | } | ||
722 | |||
709 | void xenvif_free(struct xenvif *vif) | 723 | void xenvif_free(struct xenvif *vif) |
710 | { | 724 | { |
711 | struct xenvif_queue *queue = NULL; | 725 | struct xenvif_queue *queue = NULL; |
@@ -729,11 +743,8 @@ void xenvif_free(struct xenvif *vif) | |||
729 | 743 | ||
730 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 744 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { |
731 | queue = &vif->queues[queue_index]; | 745 | queue = &vif->queues[queue_index]; |
732 | |||
733 | xenvif_wait_unmap_timeout(queue, worst_case_skb_lifetime); | 746 | xenvif_wait_unmap_timeout(queue, worst_case_skb_lifetime); |
734 | free_xenballooned_pages(MAX_PENDING_REQS, queue->mmap_pages); | 747 | xenvif_deinit_queue(queue); |
735 | |||
736 | netif_napi_del(&queue->napi); | ||
737 | } | 748 | } |
738 | 749 | ||
739 | /* Free the array of queues. The call below does not require | 750 | /* Free the array of queues. The call below does not require |