summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/virtio_net.c75
-rw-r--r--drivers/virtio/virtio.c42
-rw-r--r--include/linux/virtio.h4
3 files changed, 73 insertions, 48 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 3b3c5c571b6d..4cc3da1e4070 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1661,6 +1661,49 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
1661 .set_settings = virtnet_set_settings, 1661 .set_settings = virtnet_set_settings,
1662}; 1662};
1663 1663
1664static void virtnet_freeze_down(struct virtio_device *vdev)
1665{
1666 struct virtnet_info *vi = vdev->priv;
1667 int i;
1668
1669 /* Make sure no work handler is accessing the device */
1670 flush_work(&vi->config_work);
1671
1672 netif_device_detach(vi->dev);
1673 cancel_delayed_work_sync(&vi->refill);
1674
1675 if (netif_running(vi->dev)) {
1676 for (i = 0; i < vi->max_queue_pairs; i++)
1677 napi_disable(&vi->rq[i].napi);
1678 }
1679}
1680
1681static int init_vqs(struct virtnet_info *vi);
1682
1683static int virtnet_restore_up(struct virtio_device *vdev)
1684{
1685 struct virtnet_info *vi = vdev->priv;
1686 int err, i;
1687
1688 err = init_vqs(vi);
1689 if (err)
1690 return err;
1691
1692 virtio_device_ready(vdev);
1693
1694 if (netif_running(vi->dev)) {
1695 for (i = 0; i < vi->curr_queue_pairs; i++)
1696 if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL))
1697 schedule_delayed_work(&vi->refill, 0);
1698
1699 for (i = 0; i < vi->max_queue_pairs; i++)
1700 virtnet_napi_enable(&vi->rq[i]);
1701 }
1702
1703 netif_device_attach(vi->dev);
1704 return err;
1705}
1706
1664static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog) 1707static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
1665{ 1708{
1666 unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr); 1709 unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
@@ -2353,21 +2396,9 @@ static void virtnet_remove(struct virtio_device *vdev)
2353static int virtnet_freeze(struct virtio_device *vdev) 2396static int virtnet_freeze(struct virtio_device *vdev)
2354{ 2397{
2355 struct virtnet_info *vi = vdev->priv; 2398 struct virtnet_info *vi = vdev->priv;
2356 int i;
2357 2399
2358 virtnet_cpu_notif_remove(vi); 2400 virtnet_cpu_notif_remove(vi);
2359 2401 virtnet_freeze_down(vdev);
2360 /* Make sure no work handler is accessing the device */
2361 flush_work(&vi->config_work);
2362
2363 netif_device_detach(vi->dev);
2364 cancel_delayed_work_sync(&vi->refill);
2365
2366 if (netif_running(vi->dev)) {
2367 for (i = 0; i < vi->max_queue_pairs; i++)
2368 napi_disable(&vi->rq[i].napi);
2369 }
2370
2371 remove_vq_common(vi); 2402 remove_vq_common(vi);
2372 2403
2373 return 0; 2404 return 0;
@@ -2376,25 +2407,11 @@ static int virtnet_freeze(struct virtio_device *vdev)
2376static int virtnet_restore(struct virtio_device *vdev) 2407static int virtnet_restore(struct virtio_device *vdev)
2377{ 2408{
2378 struct virtnet_info *vi = vdev->priv; 2409 struct virtnet_info *vi = vdev->priv;
2379 int err, i; 2410 int err;
2380 2411
2381 err = init_vqs(vi); 2412 err = virtnet_restore_up(vdev);
2382 if (err) 2413 if (err)
2383 return err; 2414 return err;
2384
2385 virtio_device_ready(vdev);
2386
2387 if (netif_running(vi->dev)) {
2388 for (i = 0; i < vi->curr_queue_pairs; i++)
2389 if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL))
2390 schedule_delayed_work(&vi->refill, 0);
2391
2392 for (i = 0; i < vi->max_queue_pairs; i++)
2393 virtnet_napi_enable(&vi->rq[i]);
2394 }
2395
2396 netif_device_attach(vi->dev);
2397
2398 virtnet_set_queues(vi, vi->curr_queue_pairs); 2415 virtnet_set_queues(vi, vi->curr_queue_pairs);
2399 2416
2400 err = virtnet_cpu_notif_add(vi); 2417 err = virtnet_cpu_notif_add(vi);
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 7062bb0975a5..400d70b69379 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -100,11 +100,6 @@ static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
100 dev->id.device, dev->id.vendor); 100 dev->id.device, dev->id.vendor);
101} 101}
102 102
103static void add_status(struct virtio_device *dev, unsigned status)
104{
105 dev->config->set_status(dev, dev->config->get_status(dev) | status);
106}
107
108void virtio_check_driver_offered_feature(const struct virtio_device *vdev, 103void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
109 unsigned int fbit) 104 unsigned int fbit)
110{ 105{
@@ -145,14 +140,15 @@ void virtio_config_changed(struct virtio_device *dev)
145} 140}
146EXPORT_SYMBOL_GPL(virtio_config_changed); 141EXPORT_SYMBOL_GPL(virtio_config_changed);
147 142
148static void virtio_config_disable(struct virtio_device *dev) 143void virtio_config_disable(struct virtio_device *dev)
149{ 144{
150 spin_lock_irq(&dev->config_lock); 145 spin_lock_irq(&dev->config_lock);
151 dev->config_enabled = false; 146 dev->config_enabled = false;
152 spin_unlock_irq(&dev->config_lock); 147 spin_unlock_irq(&dev->config_lock);
153} 148}
149EXPORT_SYMBOL_GPL(virtio_config_disable);
154 150
155static void virtio_config_enable(struct virtio_device *dev) 151void virtio_config_enable(struct virtio_device *dev)
156{ 152{
157 spin_lock_irq(&dev->config_lock); 153 spin_lock_irq(&dev->config_lock);
158 dev->config_enabled = true; 154 dev->config_enabled = true;
@@ -161,8 +157,15 @@ static void virtio_config_enable(struct virtio_device *dev)
161 dev->config_change_pending = false; 157 dev->config_change_pending = false;
162 spin_unlock_irq(&dev->config_lock); 158 spin_unlock_irq(&dev->config_lock);
163} 159}
160EXPORT_SYMBOL_GPL(virtio_config_enable);
161
162void virtio_add_status(struct virtio_device *dev, unsigned int status)
163{
164 dev->config->set_status(dev, dev->config->get_status(dev) | status);
165}
166EXPORT_SYMBOL_GPL(virtio_add_status);
164 167
165static int virtio_finalize_features(struct virtio_device *dev) 168int virtio_finalize_features(struct virtio_device *dev)
166{ 169{
167 int ret = dev->config->finalize_features(dev); 170 int ret = dev->config->finalize_features(dev);
168 unsigned status; 171 unsigned status;
@@ -173,7 +176,7 @@ static int virtio_finalize_features(struct virtio_device *dev)
173 if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) 176 if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1))
174 return 0; 177 return 0;
175 178
176 add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); 179 virtio_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
177 status = dev->config->get_status(dev); 180 status = dev->config->get_status(dev);
178 if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) { 181 if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
179 dev_err(&dev->dev, "virtio: device refuses features: %x\n", 182 dev_err(&dev->dev, "virtio: device refuses features: %x\n",
@@ -182,6 +185,7 @@ static int virtio_finalize_features(struct virtio_device *dev)
182 } 185 }
183 return 0; 186 return 0;
184} 187}
188EXPORT_SYMBOL_GPL(virtio_finalize_features);
185 189
186static int virtio_dev_probe(struct device *_d) 190static int virtio_dev_probe(struct device *_d)
187{ 191{
@@ -193,7 +197,7 @@ static int virtio_dev_probe(struct device *_d)
193 u64 driver_features_legacy; 197 u64 driver_features_legacy;
194 198
195 /* We have a driver! */ 199 /* We have a driver! */
196 add_status(dev, VIRTIO_CONFIG_S_DRIVER); 200 virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
197 201
198 /* Figure out what features the device supports. */ 202 /* Figure out what features the device supports. */
199 device_features = dev->config->get_features(dev); 203 device_features = dev->config->get_features(dev);
@@ -247,7 +251,7 @@ static int virtio_dev_probe(struct device *_d)
247 251
248 return 0; 252 return 0;
249err: 253err:
250 add_status(dev, VIRTIO_CONFIG_S_FAILED); 254 virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
251 return err; 255 return err;
252 256
253} 257}
@@ -265,7 +269,7 @@ static int virtio_dev_remove(struct device *_d)
265 WARN_ON_ONCE(dev->config->get_status(dev)); 269 WARN_ON_ONCE(dev->config->get_status(dev));
266 270
267 /* Acknowledge the device's existence again. */ 271 /* Acknowledge the device's existence again. */
268 add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); 272 virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
269 return 0; 273 return 0;
270} 274}
271 275
@@ -316,7 +320,7 @@ int register_virtio_device(struct virtio_device *dev)
316 dev->config->reset(dev); 320 dev->config->reset(dev);
317 321
318 /* Acknowledge that we've seen the device. */ 322 /* Acknowledge that we've seen the device. */
319 add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); 323 virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
320 324
321 INIT_LIST_HEAD(&dev->vqs); 325 INIT_LIST_HEAD(&dev->vqs);
322 326
@@ -325,7 +329,7 @@ int register_virtio_device(struct virtio_device *dev)
325 err = device_register(&dev->dev); 329 err = device_register(&dev->dev);
326out: 330out:
327 if (err) 331 if (err)
328 add_status(dev, VIRTIO_CONFIG_S_FAILED); 332 virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
329 return err; 333 return err;
330} 334}
331EXPORT_SYMBOL_GPL(register_virtio_device); 335EXPORT_SYMBOL_GPL(register_virtio_device);
@@ -365,18 +369,18 @@ int virtio_device_restore(struct virtio_device *dev)
365 dev->config->reset(dev); 369 dev->config->reset(dev);
366 370
367 /* Acknowledge that we've seen the device. */ 371 /* Acknowledge that we've seen the device. */
368 add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); 372 virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
369 373
370 /* Maybe driver failed before freeze. 374 /* Maybe driver failed before freeze.
371 * Restore the failed status, for debugging. */ 375 * Restore the failed status, for debugging. */
372 if (dev->failed) 376 if (dev->failed)
373 add_status(dev, VIRTIO_CONFIG_S_FAILED); 377 virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
374 378
375 if (!drv) 379 if (!drv)
376 return 0; 380 return 0;
377 381
378 /* We have a driver! */ 382 /* We have a driver! */
379 add_status(dev, VIRTIO_CONFIG_S_DRIVER); 383 virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
380 384
381 ret = virtio_finalize_features(dev); 385 ret = virtio_finalize_features(dev);
382 if (ret) 386 if (ret)
@@ -389,14 +393,14 @@ int virtio_device_restore(struct virtio_device *dev)
389 } 393 }
390 394
391 /* Finally, tell the device we're all set */ 395 /* Finally, tell the device we're all set */
392 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); 396 virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
393 397
394 virtio_config_enable(dev); 398 virtio_config_enable(dev);
395 399
396 return 0; 400 return 0;
397 401
398err: 402err:
399 add_status(dev, VIRTIO_CONFIG_S_FAILED); 403 virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
400 return ret; 404 return ret;
401} 405}
402EXPORT_SYMBOL_GPL(virtio_device_restore); 406EXPORT_SYMBOL_GPL(virtio_device_restore);
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index d5eb5479a425..04b0d3f95043 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -132,12 +132,16 @@ static inline struct virtio_device *dev_to_virtio(struct device *_dev)
132 return container_of(_dev, struct virtio_device, dev); 132 return container_of(_dev, struct virtio_device, dev);
133} 133}
134 134
135void virtio_add_status(struct virtio_device *dev, unsigned int status);
135int register_virtio_device(struct virtio_device *dev); 136int register_virtio_device(struct virtio_device *dev);
136void unregister_virtio_device(struct virtio_device *dev); 137void unregister_virtio_device(struct virtio_device *dev);
137 138
138void virtio_break_device(struct virtio_device *dev); 139void virtio_break_device(struct virtio_device *dev);
139 140
140void virtio_config_changed(struct virtio_device *dev); 141void virtio_config_changed(struct virtio_device *dev);
142void virtio_config_disable(struct virtio_device *dev);
143void virtio_config_enable(struct virtio_device *dev);
144int virtio_finalize_features(struct virtio_device *dev);
141#ifdef CONFIG_PM_SLEEP 145#ifdef CONFIG_PM_SLEEP
142int virtio_device_freeze(struct virtio_device *dev); 146int virtio_device_freeze(struct virtio_device *dev);
143int virtio_device_restore(struct virtio_device *dev); 147int virtio_device_restore(struct virtio_device *dev);