aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2014-06-18 05:47:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-21 19:14:26 -0400
commitce58725fec6e609eee162e6af848bd57107b97af (patch)
tree0c2b20bc313a7e0b292904e2352b7ac72719044a
parent765418694bc99d91e71ede6d2889a6328da137fe (diff)
xen-netfront: recreate queues correctly when reconnecting
When reconnecting to the backend (after a resume/migration, for example), a different number of queues may be required (since the guest may have moved to a different host with different capabilities). During the reconnection the old queues are torn down and new ones created. Introduce xennet_create_queues() and xennet_destroy_queues() that fixes three bugs during the reconnection. - The old info->queues was leaked. - The old queue's napi instances were not deleted. - The new queue's napi instances were left disabled (which meant no packets could be received). The xennet_destroy_queues() calls is deferred until the reconnection instead of the disconnection (in xennet_disconnect_backend()) because napi_disable() might sleep. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Wei Liu <wei.liu2@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netfront.c104
1 files changed, 72 insertions, 32 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index daaf1e56e41e..2ccb4a02368b 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1699,8 +1699,6 @@ static int xennet_init_queue(struct netfront_queue *queue)
1699 goto exit_free_tx; 1699 goto exit_free_tx;
1700 } 1700 }
1701 1701
1702 netif_napi_add(queue->info->netdev, &queue->napi, xennet_poll, 64);
1703
1704 return 0; 1702 return 0;
1705 1703
1706 exit_free_tx: 1704 exit_free_tx:
@@ -1791,6 +1789,70 @@ error:
1791 return err; 1789 return err;
1792} 1790}
1793 1791
1792static void xennet_destroy_queues(struct netfront_info *info)
1793{
1794 unsigned int i;
1795
1796 rtnl_lock();
1797
1798 for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
1799 struct netfront_queue *queue = &info->queues[i];
1800
1801 if (netif_running(info->netdev))
1802 napi_disable(&queue->napi);
1803 netif_napi_del(&queue->napi);
1804 }
1805
1806 rtnl_unlock();
1807
1808 kfree(info->queues);
1809 info->queues = NULL;
1810}
1811
1812static int xennet_create_queues(struct netfront_info *info,
1813 unsigned int num_queues)
1814{
1815 unsigned int i;
1816 int ret;
1817
1818 info->queues = kcalloc(num_queues, sizeof(struct netfront_queue),
1819 GFP_KERNEL);
1820 if (!info->queues)
1821 return -ENOMEM;
1822
1823 rtnl_lock();
1824
1825 for (i = 0; i < num_queues; i++) {
1826 struct netfront_queue *queue = &info->queues[i];
1827
1828 queue->id = i;
1829 queue->info = info;
1830
1831 ret = xennet_init_queue(queue);
1832 if (ret < 0) {
1833 dev_warn(&info->netdev->dev, "only created %d queues\n",
1834 num_queues);
1835 num_queues = i;
1836 break;
1837 }
1838
1839 netif_napi_add(queue->info->netdev, &queue->napi,
1840 xennet_poll, 64);
1841 if (netif_running(info->netdev))
1842 napi_enable(&queue->napi);
1843 }
1844
1845 netif_set_real_num_tx_queues(info->netdev, num_queues);
1846
1847 rtnl_unlock();
1848
1849 if (num_queues == 0) {
1850 dev_err(&info->netdev->dev, "no queues\n");
1851 return -EINVAL;
1852 }
1853 return 0;
1854}
1855
1794/* Common code used when first setting up, and when resuming. */ 1856/* Common code used when first setting up, and when resuming. */
1795static int talk_to_netback(struct xenbus_device *dev, 1857static int talk_to_netback(struct xenbus_device *dev,
1796 struct netfront_info *info) 1858 struct netfront_info *info)
@@ -1827,42 +1889,20 @@ static int talk_to_netback(struct xenbus_device *dev,
1827 goto out; 1889 goto out;
1828 } 1890 }
1829 1891
1830 /* Allocate array of queues */ 1892 if (info->queues)
1831 info->queues = kcalloc(num_queues, sizeof(struct netfront_queue), GFP_KERNEL); 1893 xennet_destroy_queues(info);
1832 if (!info->queues) { 1894
1833 err = -ENOMEM; 1895 err = xennet_create_queues(info, num_queues);
1834 goto out; 1896 if (err < 0)
1835 } 1897 goto destroy_ring;
1836 rtnl_lock();
1837 netif_set_real_num_tx_queues(info->netdev, num_queues);
1838 rtnl_unlock();
1839 1898
1840 /* Create shared ring, alloc event channel -- for each queue */ 1899 /* Create shared ring, alloc event channel -- for each queue */
1841 for (i = 0; i < num_queues; ++i) { 1900 for (i = 0; i < num_queues; ++i) {
1842 queue = &info->queues[i]; 1901 queue = &info->queues[i];
1843 queue->id = i;
1844 queue->info = info;
1845 err = xennet_init_queue(queue);
1846 if (err) {
1847 /* xennet_init_queue() cleans up after itself on failure,
1848 * but we still have to clean up any previously initialised
1849 * queues. If i > 0, set num_queues to i, then goto
1850 * destroy_ring, which calls xennet_disconnect_backend()
1851 * to tidy up.
1852 */
1853 if (i > 0) {
1854 rtnl_lock();
1855 netif_set_real_num_tx_queues(info->netdev, i);
1856 rtnl_unlock();
1857 goto destroy_ring;
1858 } else {
1859 goto out;
1860 }
1861 }
1862 err = setup_netfront(dev, queue, feature_split_evtchn); 1902 err = setup_netfront(dev, queue, feature_split_evtchn);
1863 if (err) { 1903 if (err) {
1864 /* As for xennet_init_queue(), setup_netfront() will tidy 1904 /* setup_netfront() will tidy up the current
1865 * up the current queue on error, but we need to clean up 1905 * queue on error, but we need to clean up
1866 * those already allocated. 1906 * those already allocated.
1867 */ 1907 */
1868 if (i > 0) { 1908 if (i > 0) {