[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V7 net-next 4/7] xen-netback: Correctly clean up after queue initialisation error.
From: "Andrew J. Bennieston" <andrew.bennieston@xxxxxxxxxx> Multiple queues were introduced in the previous patch, but if the initialisation of a queue failed, earlier queues would not be cleaned up. This patch adds cleanup logic for this scenario, making use of code from the regular teardown sequence. Signed-off-by: Andrew J. Bennieston <andrew.bennieston@xxxxxxxxxx> --- drivers/net/xen-netback/common.h | 1 + drivers/net/xen-netback/interface.c | 15 +++++++++++---- drivers/net/xen-netback/xenbus.c | 25 +++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 50efc29..16d6a05 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -237,6 +237,7 @@ struct xenvif *xenvif_alloc(struct device *parent, unsigned int handle); int xenvif_init_queue(struct xenvif_queue *queue); +void xenvif_deinit_queue(struct xenvif_queue *queue); int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int tx_evtchn, diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 0eb6941..3ded8e5 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -733,6 +733,16 @@ void xenvif_disconnect(struct xenvif *vif) } } +/* Reverse the relevant parts of xenvif_init_queue(). + * Used for queue teardown from xenvif_free(), and on the + * error handling paths in xenbus.c:connect(). + */ +void xenvif_deinit_queue(struct xenvif_queue *queue) +{ + free_xenballooned_pages(MAX_PENDING_REQS, queue->mmap_pages); + netif_napi_del(&queue->napi); +} + void xenvif_free(struct xenvif *vif) { struct xenvif_queue *queue = NULL; @@ -756,11 +766,8 @@ void xenvif_free(struct xenvif *vif) for (queue_index = 0; queue_index < num_queues; ++queue_index) { queue = &vif->queues[queue_index]; - xenvif_wait_unmap_timeout(queue, worst_case_skb_lifetime); - free_xenballooned_pages(MAX_PENDING_REQS, queue->mmap_pages); - - netif_napi_del(&queue->napi); + xenvif_deinit_queue(queue); } /* Free the array of queues. The call below does not require diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 9632e7a..96c63dc2 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -539,14 +539,33 @@ static void connect(struct backend_info *be) be->vif->dev->name, queue->id); err = xenvif_init_queue(queue); - if (err) + if (err) { + /* xenvif_init_queue() cleans up after itself on + * failure, but we need to clean up any previously + * initialised queues. Set num_queues to i so that + * earlier queues can be destroyed using the regular + * disconnect logic. + */ + rtnl_lock(); + netif_set_real_num_tx_queues(be->vif->dev, queue_index); + rtnl_unlock(); goto err; + } queue->remaining_credit = credit_bytes; err = connect_rings(be, queue); - if (err) + if (err) { + /* connect_rings() cleans up after itself on failure, + * but we need to clean up after xenvif_init_queue() here, + * and also clean up any previously initialised queues. + */ + xenvif_deinit_queue(queue); + rtnl_lock(); + netif_set_real_num_tx_queues(be->vif->dev, queue_index); + rtnl_unlock(); goto err; + } } xenvif_carrier_on(be->vif); @@ -563,6 +582,8 @@ static void connect(struct backend_info *be) return; err: + if (be->vif->dev->real_num_tx_queues > 0) + xenvif_disconnect(be->vif); /* Clean up existing queues */ vfree(be->vif->queues); be->vif->queues = NULL; rtnl_lock(); -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |