aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netfront.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r--drivers/net/xen-netfront.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 5a7872ac3566..2ccb4a02368b 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1287,7 +1287,7 @@ static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
1287 1287
1288 if (likely(netif_carrier_ok(dev) && 1288 if (likely(netif_carrier_ok(dev) &&
1289 RING_HAS_UNCONSUMED_RESPONSES(&queue->rx))) 1289 RING_HAS_UNCONSUMED_RESPONSES(&queue->rx)))
1290 napi_schedule(&queue->napi); 1290 napi_schedule(&queue->napi);
1291 1291
1292 return IRQ_HANDLED; 1292 return IRQ_HANDLED;
1293} 1293}
@@ -1437,10 +1437,11 @@ static void xennet_end_access(int ref, void *page)
1437static void xennet_disconnect_backend(struct netfront_info *info) 1437static void xennet_disconnect_backend(struct netfront_info *info)
1438{ 1438{
1439 unsigned int i = 0; 1439 unsigned int i = 0;
1440 struct netfront_queue *queue = NULL;
1441 unsigned int num_queues = info->netdev->real_num_tx_queues; 1440 unsigned int num_queues = info->netdev->real_num_tx_queues;
1442 1441
1443 for (i = 0; i < num_queues; ++i) { 1442 for (i = 0; i < num_queues; ++i) {
1443 struct netfront_queue *queue = &info->queues[i];
1444
1444 /* Stop old i/f to prevent errors whilst we rebuild the state. */ 1445 /* Stop old i/f to prevent errors whilst we rebuild the state. */
1445 spin_lock_bh(&queue->rx_lock); 1446 spin_lock_bh(&queue->rx_lock);
1446 spin_lock_irq(&queue->tx_lock); 1447 spin_lock_irq(&queue->tx_lock);
@@ -1698,8 +1699,6 @@ static int xennet_init_queue(struct netfront_queue *queue)
1698 goto exit_free_tx; 1699 goto exit_free_tx;
1699 } 1700 }
1700 1701
1701 netif_napi_add(queue->info->netdev, &queue->napi, xennet_poll, 64);
1702
1703 return 0; 1702 return 0;
1704 1703
1705 exit_free_tx: 1704 exit_free_tx:
@@ -1790,6 +1789,70 @@ error:
1790 return err; 1789 return err;
1791} 1790}
1792 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
1793/* Common code used when first setting up, and when resuming. */ 1856/* Common code used when first setting up, and when resuming. */
1794static int talk_to_netback(struct xenbus_device *dev, 1857static int talk_to_netback(struct xenbus_device *dev,
1795 struct netfront_info *info) 1858 struct netfront_info *info)
@@ -1826,42 +1889,20 @@ static int talk_to_netback(struct xenbus_device *dev,
1826 goto out; 1889 goto out;
1827 } 1890 }
1828 1891
1829 /* Allocate array of queues */ 1892 if (info->queues)
1830 info->queues = kcalloc(num_queues, sizeof(struct netfront_queue), GFP_KERNEL); 1893 xennet_destroy_queues(info);
1831 if (!info->queues) { 1894
1832 err = -ENOMEM; 1895 err = xennet_create_queues(info, num_queues);
1833 goto out; 1896 if (err < 0)
1834 } 1897 goto destroy_ring;
1835 rtnl_lock();
1836 netif_set_real_num_tx_queues(info->netdev, num_queues);
1837 rtnl_unlock();
1838 1898
1839 /* Create shared ring, alloc event channel -- for each queue */ 1899 /* Create shared ring, alloc event channel -- for each queue */
1840 for (i = 0; i < num_queues; ++i) { 1900 for (i = 0; i < num_queues; ++i) {
1841 queue = &info->queues[i]; 1901 queue = &info->queues[i];
1842 queue->id = i;
1843 queue->info = info;
1844 err = xennet_init_queue(queue);
1845 if (err) {
1846 /* xennet_init_queue() cleans up after itself on failure,
1847 * but we still have to clean up any previously initialised
1848 * queues. If i > 0, set num_queues to i, then goto
1849 * destroy_ring, which calls xennet_disconnect_backend()
1850 * to tidy up.
1851 */
1852 if (i > 0) {
1853 rtnl_lock();
1854 netif_set_real_num_tx_queues(info->netdev, i);
1855 rtnl_unlock();
1856 goto destroy_ring;
1857 } else {
1858 goto out;
1859 }
1860 }
1861 err = setup_netfront(dev, queue, feature_split_evtchn); 1902 err = setup_netfront(dev, queue, feature_split_evtchn);
1862 if (err) { 1903 if (err) {
1863 /* As for xennet_init_queue(), setup_netfront() will tidy 1904 /* setup_netfront() will tidy up the current
1864 * up the current queue on error, but we need to clean up 1905 * queue on error, but we need to clean up
1865 * those already allocated. 1906 * those already allocated.
1866 */ 1907 */
1867 if (i > 0) { 1908 if (i > 0) {