summaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio.c
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2017-02-02 22:16:01 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-07 10:05:12 -0500
commit9fe7bfce8b3e112e8e08c40deb72ee7e24c6f072 (patch)
treecb9910cfafe6c9d2cb9525fc86dfd474859d52fc /drivers/virtio/virtio.c
parent722d82830a04ccff6c7390535fcdfb1e4d69d126 (diff)
virtio_net: refactor freeze/restore logic into virtnet reset logic
For XDP we will need to reset the queues to allow for buffer headroom to be configured. In order to do this we need to essentially run the freeze()/restore() code path. Unfortunately the locking requirements between the freeze/restore and reset paths are different however so we can not simply reuse the code. This patch refactors the code path and adds a reset helper routine. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/virtio/virtio.c')
-rw-r--r--drivers/virtio/virtio.c42
1 files changed, 23 insertions, 19 deletions
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);