diff options
Diffstat (limited to 'drivers/virtio/virtio_balloon.c')
| -rw-r--r-- | drivers/virtio/virtio_balloon.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 95aeedf198f8..958e5129c601 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
| @@ -367,29 +367,45 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev) | |||
| 367 | #ifdef CONFIG_PM | 367 | #ifdef CONFIG_PM |
| 368 | static int virtballoon_freeze(struct virtio_device *vdev) | 368 | static int virtballoon_freeze(struct virtio_device *vdev) |
| 369 | { | 369 | { |
| 370 | struct virtio_balloon *vb = vdev->priv; | ||
| 371 | |||
| 370 | /* | 372 | /* |
| 371 | * The kthread is already frozen by the PM core before this | 373 | * The kthread is already frozen by the PM core before this |
| 372 | * function is called. | 374 | * function is called. |
| 373 | */ | 375 | */ |
| 374 | 376 | ||
| 377 | while (vb->num_pages) | ||
| 378 | leak_balloon(vb, vb->num_pages); | ||
| 379 | update_balloon_size(vb); | ||
| 380 | |||
| 375 | /* Ensure we don't get any more requests from the host */ | 381 | /* Ensure we don't get any more requests from the host */ |
| 376 | vdev->config->reset(vdev); | 382 | vdev->config->reset(vdev); |
| 377 | vdev->config->del_vqs(vdev); | 383 | vdev->config->del_vqs(vdev); |
| 378 | return 0; | 384 | return 0; |
| 379 | } | 385 | } |
| 380 | 386 | ||
| 387 | static int restore_common(struct virtio_device *vdev) | ||
| 388 | { | ||
| 389 | struct virtio_balloon *vb = vdev->priv; | ||
| 390 | int ret; | ||
| 391 | |||
| 392 | ret = init_vqs(vdev->priv); | ||
| 393 | if (ret) | ||
| 394 | return ret; | ||
| 395 | |||
| 396 | fill_balloon(vb, towards_target(vb)); | ||
| 397 | update_balloon_size(vb); | ||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | |||
| 381 | static int virtballoon_thaw(struct virtio_device *vdev) | 401 | static int virtballoon_thaw(struct virtio_device *vdev) |
| 382 | { | 402 | { |
| 383 | return init_vqs(vdev->priv); | 403 | return restore_common(vdev); |
| 384 | } | 404 | } |
| 385 | 405 | ||
| 386 | static int virtballoon_restore(struct virtio_device *vdev) | 406 | static int virtballoon_restore(struct virtio_device *vdev) |
| 387 | { | 407 | { |
| 388 | struct virtio_balloon *vb = vdev->priv; | 408 | 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 | 409 | ||
| 394 | /* | 410 | /* |
| 395 | * If a request wasn't complete at the time of freezing, this | 411 | * If a request wasn't complete at the time of freezing, this |
| @@ -397,12 +413,7 @@ static int virtballoon_restore(struct virtio_device *vdev) | |||
| 397 | */ | 413 | */ |
| 398 | vb->need_stats_update = 0; | 414 | vb->need_stats_update = 0; |
| 399 | 415 | ||
| 400 | /* We don't have these pages in the balloon anymore! */ | 416 | return restore_common(vdev); |
| 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 | } | 417 | } |
| 407 | #endif | 418 | #endif |
| 408 | 419 | ||
