aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_balloon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_balloon.c')
-rw-r--r--drivers/virtio/virtio_balloon.c108
1 files changed, 84 insertions, 24 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 94fd738a7741..95aeedf198f8 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -1,4 +1,5 @@
1/* Virtio balloon implementation, inspired by Dor Loar and Marcelo 1/*
2 * Virtio balloon implementation, inspired by Dor Laor and Marcelo
2 * Tosatti's implementations. 3 * Tosatti's implementations.
3 * 4 *
4 * Copyright 2008 Rusty Russell IBM Corporation 5 * Copyright 2008 Rusty Russell IBM Corporation
@@ -17,7 +18,7 @@
17 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 20 */
20//#define DEBUG 21
21#include <linux/virtio.h> 22#include <linux/virtio.h>
22#include <linux/virtio_balloon.h> 23#include <linux/virtio_balloon.h>
23#include <linux/swap.h> 24#include <linux/swap.h>
@@ -87,7 +88,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
87 init_completion(&vb->acked); 88 init_completion(&vb->acked);
88 89
89 /* We should always be able to add one buffer to an empty queue. */ 90 /* We should always be able to add one buffer to an empty queue. */
90 if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) 91 if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0)
91 BUG(); 92 BUG();
92 virtqueue_kick(vq); 93 virtqueue_kick(vq);
93 94
@@ -149,7 +150,6 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
149 vb->num_pages--; 150 vb->num_pages--;
150 } 151 }
151 152
152
153 /* 153 /*
154 * Note that if 154 * Note that if
155 * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); 155 * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
@@ -220,7 +220,7 @@ static void stats_handle_request(struct virtio_balloon *vb)
220 220
221 vq = vb->stats_vq; 221 vq = vb->stats_vq;
222 sg_init_one(&sg, vb->stats, sizeof(vb->stats)); 222 sg_init_one(&sg, vb->stats, sizeof(vb->stats));
223 if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) 223 if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0)
224 BUG(); 224 BUG();
225 virtqueue_kick(vq); 225 virtqueue_kick(vq);
226} 226}
@@ -275,32 +275,21 @@ static int balloon(void *_vballoon)
275 return 0; 275 return 0;
276} 276}
277 277
278static int virtballoon_probe(struct virtio_device *vdev) 278static int init_vqs(struct virtio_balloon *vb)
279{ 279{
280 struct virtio_balloon *vb;
281 struct virtqueue *vqs[3]; 280 struct virtqueue *vqs[3];
282 vq_callback_t *callbacks[] = { balloon_ack, balloon_ack, stats_request }; 281 vq_callback_t *callbacks[] = { balloon_ack, balloon_ack, stats_request };
283 const char *names[] = { "inflate", "deflate", "stats" }; 282 const char *names[] = { "inflate", "deflate", "stats" };
284 int err, nvqs; 283 int err, nvqs;
285 284
286 vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL); 285 /*
287 if (!vb) { 286 * We expect two virtqueues: inflate and deflate, and
288 err = -ENOMEM; 287 * optionally stat.
289 goto out; 288 */
290 }
291
292 INIT_LIST_HEAD(&vb->pages);
293 vb->num_pages = 0;
294 init_waitqueue_head(&vb->config_change);
295 vb->vdev = vdev;
296 vb->need_stats_update = 0;
297
298 /* We expect two virtqueues: inflate and deflate,
299 * and optionally stat. */
300 nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2; 289 nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2;
301 err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names); 290 err = vb->vdev->config->find_vqs(vb->vdev, nvqs, vqs, callbacks, names);
302 if (err) 291 if (err)
303 goto out_free_vb; 292 return err;
304 293
305 vb->inflate_vq = vqs[0]; 294 vb->inflate_vq = vqs[0];
306 vb->deflate_vq = vqs[1]; 295 vb->deflate_vq = vqs[1];
@@ -313,10 +302,34 @@ static int virtballoon_probe(struct virtio_device *vdev)
313 * use it to signal us later. 302 * use it to signal us later.
314 */ 303 */
315 sg_init_one(&sg, vb->stats, sizeof vb->stats); 304 sg_init_one(&sg, vb->stats, sizeof vb->stats);
316 if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb) < 0) 305 if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb, GFP_KERNEL)
306 < 0)
317 BUG(); 307 BUG();
318 virtqueue_kick(vb->stats_vq); 308 virtqueue_kick(vb->stats_vq);
319 } 309 }
310 return 0;
311}
312
313static int virtballoon_probe(struct virtio_device *vdev)
314{
315 struct virtio_balloon *vb;
316 int err;
317
318 vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
319 if (!vb) {
320 err = -ENOMEM;
321 goto out;
322 }
323
324 INIT_LIST_HEAD(&vb->pages);
325 vb->num_pages = 0;
326 init_waitqueue_head(&vb->config_change);
327 vb->vdev = vdev;
328 vb->need_stats_update = 0;
329
330 err = init_vqs(vb);
331 if (err)
332 goto out_free_vb;
320 333
321 vb->thread = kthread_run(balloon, vb, "vballoon"); 334 vb->thread = kthread_run(balloon, vb, "vballoon");
322 if (IS_ERR(vb->thread)) { 335 if (IS_ERR(vb->thread)) {
@@ -351,6 +364,48 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev)
351 kfree(vb); 364 kfree(vb);
352} 365}
353 366
367#ifdef CONFIG_PM
368static int virtballoon_freeze(struct virtio_device *vdev)
369{
370 /*
371 * The kthread is already frozen by the PM core before this
372 * function is called.
373 */
374
375 /* Ensure we don't get any more requests from the host */
376 vdev->config->reset(vdev);
377 vdev->config->del_vqs(vdev);
378 return 0;
379}
380
381static int virtballoon_thaw(struct virtio_device *vdev)
382{
383 return init_vqs(vdev->priv);
384}
385
386static int virtballoon_restore(struct virtio_device *vdev)
387{
388 struct virtio_balloon *vb = vdev->priv;
389 struct page *page, *page2;
390
391 /* We're starting from a clean slate */
392 vb->num_pages = 0;
393
394 /*
395 * If a request wasn't complete at the time of freezing, this
396 * could have been set.
397 */
398 vb->need_stats_update = 0;
399
400 /* We don't have these pages in the balloon anymore! */
401 list_for_each_entry_safe(page, page2, &vb->pages, lru) {
402 list_del(&page->lru);
403 totalram_pages++;
404 }
405 return init_vqs(vdev->priv);
406}
407#endif
408
354static unsigned int features[] = { 409static unsigned int features[] = {
355 VIRTIO_BALLOON_F_MUST_TELL_HOST, 410 VIRTIO_BALLOON_F_MUST_TELL_HOST,
356 VIRTIO_BALLOON_F_STATS_VQ, 411 VIRTIO_BALLOON_F_STATS_VQ,
@@ -365,6 +420,11 @@ static struct virtio_driver virtio_balloon_driver = {
365 .probe = virtballoon_probe, 420 .probe = virtballoon_probe,
366 .remove = __devexit_p(virtballoon_remove), 421 .remove = __devexit_p(virtballoon_remove),
367 .config_changed = virtballoon_changed, 422 .config_changed = virtballoon_changed,
423#ifdef CONFIG_PM
424 .freeze = virtballoon_freeze,
425 .restore = virtballoon_restore,
426 .thaw = virtballoon_thaw,
427#endif
368}; 428};
369 429
370static int __init init(void) 430static int __init init(void)