diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 44 |
1 files changed, 12 insertions, 32 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 13d0a8bc8bf3..d75256bd1a6a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -123,9 +123,6 @@ struct virtnet_info { | |||
123 | /* Host can handle any s/g split between our header and packet data */ | 123 | /* Host can handle any s/g split between our header and packet data */ |
124 | bool any_header_sg; | 124 | bool any_header_sg; |
125 | 125 | ||
126 | /* enable config space updates */ | ||
127 | bool config_enable; | ||
128 | |||
129 | /* Active statistics */ | 126 | /* Active statistics */ |
130 | struct virtnet_stats __percpu *stats; | 127 | struct virtnet_stats __percpu *stats; |
131 | 128 | ||
@@ -135,9 +132,6 @@ struct virtnet_info { | |||
135 | /* Work struct for config space updates */ | 132 | /* Work struct for config space updates */ |
136 | struct work_struct config_work; | 133 | struct work_struct config_work; |
137 | 134 | ||
138 | /* Lock for config space updates */ | ||
139 | struct mutex config_lock; | ||
140 | |||
141 | /* Does the affinity hint is set for virtqueues? */ | 135 | /* Does the affinity hint is set for virtqueues? */ |
142 | bool affinity_hint_set; | 136 | bool affinity_hint_set; |
143 | 137 | ||
@@ -1414,13 +1408,9 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1414 | container_of(work, struct virtnet_info, config_work); | 1408 | container_of(work, struct virtnet_info, config_work); |
1415 | u16 v; | 1409 | u16 v; |
1416 | 1410 | ||
1417 | mutex_lock(&vi->config_lock); | ||
1418 | if (!vi->config_enable) | ||
1419 | goto done; | ||
1420 | |||
1421 | if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS, | 1411 | if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS, |
1422 | struct virtio_net_config, status, &v) < 0) | 1412 | struct virtio_net_config, status, &v) < 0) |
1423 | goto done; | 1413 | return; |
1424 | 1414 | ||
1425 | if (v & VIRTIO_NET_S_ANNOUNCE) { | 1415 | if (v & VIRTIO_NET_S_ANNOUNCE) { |
1426 | netdev_notify_peers(vi->dev); | 1416 | netdev_notify_peers(vi->dev); |
@@ -1431,7 +1421,7 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1431 | v &= VIRTIO_NET_S_LINK_UP; | 1421 | v &= VIRTIO_NET_S_LINK_UP; |
1432 | 1422 | ||
1433 | if (vi->status == v) | 1423 | if (vi->status == v) |
1434 | goto done; | 1424 | return; |
1435 | 1425 | ||
1436 | vi->status = v; | 1426 | vi->status = v; |
1437 | 1427 | ||
@@ -1442,8 +1432,6 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1442 | netif_carrier_off(vi->dev); | 1432 | netif_carrier_off(vi->dev); |
1443 | netif_tx_stop_all_queues(vi->dev); | 1433 | netif_tx_stop_all_queues(vi->dev); |
1444 | } | 1434 | } |
1445 | done: | ||
1446 | mutex_unlock(&vi->config_lock); | ||
1447 | } | 1435 | } |
1448 | 1436 | ||
1449 | static void virtnet_config_changed(struct virtio_device *vdev) | 1437 | static void virtnet_config_changed(struct virtio_device *vdev) |
@@ -1764,8 +1752,6 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1764 | u64_stats_init(&virtnet_stats->rx_syncp); | 1752 | u64_stats_init(&virtnet_stats->rx_syncp); |
1765 | } | 1753 | } |
1766 | 1754 | ||
1767 | mutex_init(&vi->config_lock); | ||
1768 | vi->config_enable = true; | ||
1769 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); | 1755 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); |
1770 | 1756 | ||
1771 | /* If we can receive ANY GSO packets, we must allocate large ones. */ | 1757 | /* If we can receive ANY GSO packets, we must allocate large ones. */ |
@@ -1813,6 +1799,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1813 | goto free_vqs; | 1799 | goto free_vqs; |
1814 | } | 1800 | } |
1815 | 1801 | ||
1802 | virtio_device_ready(vdev); | ||
1803 | |||
1816 | /* Last of all, set up some receive buffers. */ | 1804 | /* Last of all, set up some receive buffers. */ |
1817 | for (i = 0; i < vi->curr_queue_pairs; i++) { | 1805 | for (i = 0; i < vi->curr_queue_pairs; i++) { |
1818 | try_fill_recv(&vi->rq[i], GFP_KERNEL); | 1806 | try_fill_recv(&vi->rq[i], GFP_KERNEL); |
@@ -1849,6 +1837,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1849 | return 0; | 1837 | return 0; |
1850 | 1838 | ||
1851 | free_recv_bufs: | 1839 | free_recv_bufs: |
1840 | vi->vdev->config->reset(vdev); | ||
1841 | |||
1852 | free_receive_bufs(vi); | 1842 | free_receive_bufs(vi); |
1853 | unregister_netdev(dev); | 1843 | unregister_netdev(dev); |
1854 | free_vqs: | 1844 | free_vqs: |
@@ -1882,17 +1872,13 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
1882 | 1872 | ||
1883 | unregister_hotcpu_notifier(&vi->nb); | 1873 | unregister_hotcpu_notifier(&vi->nb); |
1884 | 1874 | ||
1885 | /* Prevent config work handler from accessing the device. */ | 1875 | /* Make sure no work handler is accessing the device. */ |
1886 | mutex_lock(&vi->config_lock); | 1876 | flush_work(&vi->config_work); |
1887 | vi->config_enable = false; | ||
1888 | mutex_unlock(&vi->config_lock); | ||
1889 | 1877 | ||
1890 | unregister_netdev(vi->dev); | 1878 | unregister_netdev(vi->dev); |
1891 | 1879 | ||
1892 | remove_vq_common(vi); | 1880 | remove_vq_common(vi); |
1893 | 1881 | ||
1894 | flush_work(&vi->config_work); | ||
1895 | |||
1896 | free_percpu(vi->stats); | 1882 | free_percpu(vi->stats); |
1897 | free_netdev(vi->dev); | 1883 | free_netdev(vi->dev); |
1898 | } | 1884 | } |
@@ -1905,10 +1891,8 @@ static int virtnet_freeze(struct virtio_device *vdev) | |||
1905 | 1891 | ||
1906 | unregister_hotcpu_notifier(&vi->nb); | 1892 | unregister_hotcpu_notifier(&vi->nb); |
1907 | 1893 | ||
1908 | /* Prevent config work handler from accessing the device */ | 1894 | /* Make sure no work handler is accessing the device */ |
1909 | mutex_lock(&vi->config_lock); | 1895 | flush_work(&vi->config_work); |
1910 | vi->config_enable = false; | ||
1911 | mutex_unlock(&vi->config_lock); | ||
1912 | 1896 | ||
1913 | netif_device_detach(vi->dev); | 1897 | netif_device_detach(vi->dev); |
1914 | cancel_delayed_work_sync(&vi->refill); | 1898 | cancel_delayed_work_sync(&vi->refill); |
@@ -1923,8 +1907,6 @@ static int virtnet_freeze(struct virtio_device *vdev) | |||
1923 | 1907 | ||
1924 | remove_vq_common(vi); | 1908 | remove_vq_common(vi); |
1925 | 1909 | ||
1926 | flush_work(&vi->config_work); | ||
1927 | |||
1928 | return 0; | 1910 | return 0; |
1929 | } | 1911 | } |
1930 | 1912 | ||
@@ -1937,6 +1919,8 @@ static int virtnet_restore(struct virtio_device *vdev) | |||
1937 | if (err) | 1919 | if (err) |
1938 | return err; | 1920 | return err; |
1939 | 1921 | ||
1922 | virtio_device_ready(vdev); | ||
1923 | |||
1940 | if (netif_running(vi->dev)) { | 1924 | if (netif_running(vi->dev)) { |
1941 | for (i = 0; i < vi->curr_queue_pairs; i++) | 1925 | for (i = 0; i < vi->curr_queue_pairs; i++) |
1942 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) | 1926 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) |
@@ -1948,10 +1932,6 @@ static int virtnet_restore(struct virtio_device *vdev) | |||
1948 | 1932 | ||
1949 | netif_device_attach(vi->dev); | 1933 | netif_device_attach(vi->dev); |
1950 | 1934 | ||
1951 | mutex_lock(&vi->config_lock); | ||
1952 | vi->config_enable = true; | ||
1953 | mutex_unlock(&vi->config_lock); | ||
1954 | |||
1955 | rtnl_lock(); | 1935 | rtnl_lock(); |
1956 | virtnet_set_queues(vi, vi->curr_queue_pairs); | 1936 | virtnet_set_queues(vi, vi->curr_queue_pairs); |
1957 | rtnl_unlock(); | 1937 | rtnl_unlock(); |