diff options
author | Konstantin Khlebnikov <k.khlebnikov@samsung.com> | 2014-10-09 18:29:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:01 -0400 |
commit | 9d1ba8056474a208ed9efb7e58cd014795d9f818 (patch) | |
tree | 0a463b12b5ed28e666570b6b15051af1b5d93934 /drivers/virtio | |
parent | d6d86c0a7f8ddc5b38cf089222cb1d9540762dc2 (diff) |
mm/balloon_compaction: remove balloon mapping and flag AS_BALLOON_MAP
Now ballooned pages are detected using PageBalloon(). Fake mapping is no
longer required. This patch links ballooned pages to balloon device using
field page->private instead of page->mapping. Also this patch embeds
balloon_dev_info directly into struct virtio_balloon.
Signed-off-by: Konstantin Khlebnikov <k.khlebnikov@samsung.com>
Cc: Rafael Aquini <aquini@redhat.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 60 |
1 files changed, 13 insertions, 47 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c3eb93fc9261..2bad7f9dd2ac 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -59,7 +59,7 @@ struct virtio_balloon | |||
59 | * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE | 59 | * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE |
60 | * to num_pages above. | 60 | * to num_pages above. |
61 | */ | 61 | */ |
62 | struct balloon_dev_info *vb_dev_info; | 62 | struct balloon_dev_info vb_dev_info; |
63 | 63 | ||
64 | /* Synchronize access/update to this struct virtio_balloon elements */ | 64 | /* Synchronize access/update to this struct virtio_balloon elements */ |
65 | struct mutex balloon_lock; | 65 | struct mutex balloon_lock; |
@@ -127,7 +127,7 @@ static void set_page_pfns(u32 pfns[], struct page *page) | |||
127 | 127 | ||
128 | static void fill_balloon(struct virtio_balloon *vb, size_t num) | 128 | static void fill_balloon(struct virtio_balloon *vb, size_t num) |
129 | { | 129 | { |
130 | struct balloon_dev_info *vb_dev_info = vb->vb_dev_info; | 130 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; |
131 | 131 | ||
132 | /* We can only do one array worth at a time. */ | 132 | /* We can only do one array worth at a time. */ |
133 | num = min(num, ARRAY_SIZE(vb->pfns)); | 133 | num = min(num, ARRAY_SIZE(vb->pfns)); |
@@ -171,7 +171,7 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) | |||
171 | static void leak_balloon(struct virtio_balloon *vb, size_t num) | 171 | static void leak_balloon(struct virtio_balloon *vb, size_t num) |
172 | { | 172 | { |
173 | struct page *page; | 173 | struct page *page; |
174 | struct balloon_dev_info *vb_dev_info = vb->vb_dev_info; | 174 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; |
175 | 175 | ||
176 | /* We can only do one array worth at a time. */ | 176 | /* We can only do one array worth at a time. */ |
177 | num = min(num, ARRAY_SIZE(vb->pfns)); | 177 | num = min(num, ARRAY_SIZE(vb->pfns)); |
@@ -353,12 +353,11 @@ static int init_vqs(struct virtio_balloon *vb) | |||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | static const struct address_space_operations virtio_balloon_aops; | ||
357 | #ifdef CONFIG_BALLOON_COMPACTION | 356 | #ifdef CONFIG_BALLOON_COMPACTION |
358 | /* | 357 | /* |
359 | * virtballoon_migratepage - perform the balloon page migration on behalf of | 358 | * virtballoon_migratepage - perform the balloon page migration on behalf of |
360 | * a compation thread. (called under page lock) | 359 | * a compation thread. (called under page lock) |
361 | * @mapping: the page->mapping which will be assigned to the new migrated page. | 360 | * @vb_dev_info: the balloon device |
362 | * @newpage: page that will replace the isolated page after migration finishes. | 361 | * @newpage: page that will replace the isolated page after migration finishes. |
363 | * @page : the isolated (old) page that is about to be migrated to newpage. | 362 | * @page : the isolated (old) page that is about to be migrated to newpage. |
364 | * @mode : compaction mode -- not used for balloon page migration. | 363 | * @mode : compaction mode -- not used for balloon page migration. |
@@ -373,17 +372,13 @@ static const struct address_space_operations virtio_balloon_aops; | |||
373 | * This function preforms the balloon page migration task. | 372 | * This function preforms the balloon page migration task. |
374 | * Called through balloon_mapping->a_ops->migratepage | 373 | * Called through balloon_mapping->a_ops->migratepage |
375 | */ | 374 | */ |
376 | static int virtballoon_migratepage(struct address_space *mapping, | 375 | static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, |
377 | struct page *newpage, struct page *page, enum migrate_mode mode) | 376 | struct page *newpage, struct page *page, enum migrate_mode mode) |
378 | { | 377 | { |
379 | struct balloon_dev_info *vb_dev_info = balloon_page_device(page); | 378 | struct virtio_balloon *vb = container_of(vb_dev_info, |
380 | struct virtio_balloon *vb; | 379 | struct virtio_balloon, vb_dev_info); |
381 | unsigned long flags; | 380 | unsigned long flags; |
382 | 381 | ||
383 | BUG_ON(!vb_dev_info); | ||
384 | |||
385 | vb = vb_dev_info->balloon_device; | ||
386 | |||
387 | /* | 382 | /* |
388 | * In order to avoid lock contention while migrating pages concurrently | 383 | * In order to avoid lock contention while migrating pages concurrently |
389 | * to leak_balloon() or fill_balloon() we just give up the balloon_lock | 384 | * to leak_balloon() or fill_balloon() we just give up the balloon_lock |
@@ -399,7 +394,7 @@ static int virtballoon_migratepage(struct address_space *mapping, | |||
399 | 394 | ||
400 | /* balloon's page migration 1st step -- inflate "newpage" */ | 395 | /* balloon's page migration 1st step -- inflate "newpage" */ |
401 | spin_lock_irqsave(&vb_dev_info->pages_lock, flags); | 396 | spin_lock_irqsave(&vb_dev_info->pages_lock, flags); |
402 | balloon_page_insert(newpage, mapping, &vb_dev_info->pages); | 397 | balloon_page_insert(vb_dev_info, newpage); |
403 | vb_dev_info->isolated_pages--; | 398 | vb_dev_info->isolated_pages--; |
404 | spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags); | 399 | spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags); |
405 | vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; | 400 | vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; |
@@ -418,18 +413,11 @@ static int virtballoon_migratepage(struct address_space *mapping, | |||
418 | 413 | ||
419 | return MIGRATEPAGE_SUCCESS; | 414 | return MIGRATEPAGE_SUCCESS; |
420 | } | 415 | } |
421 | |||
422 | /* define the balloon_mapping->a_ops callback to allow balloon page migration */ | ||
423 | static const struct address_space_operations virtio_balloon_aops = { | ||
424 | .migratepage = virtballoon_migratepage, | ||
425 | }; | ||
426 | #endif /* CONFIG_BALLOON_COMPACTION */ | 416 | #endif /* CONFIG_BALLOON_COMPACTION */ |
427 | 417 | ||
428 | static int virtballoon_probe(struct virtio_device *vdev) | 418 | static int virtballoon_probe(struct virtio_device *vdev) |
429 | { | 419 | { |
430 | struct virtio_balloon *vb; | 420 | struct virtio_balloon *vb; |
431 | struct address_space *vb_mapping; | ||
432 | struct balloon_dev_info *vb_devinfo; | ||
433 | int err; | 421 | int err; |
434 | 422 | ||
435 | vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL); | 423 | vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL); |
@@ -445,30 +433,14 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
445 | vb->vdev = vdev; | 433 | vb->vdev = vdev; |
446 | vb->need_stats_update = 0; | 434 | vb->need_stats_update = 0; |
447 | 435 | ||
448 | vb_devinfo = balloon_devinfo_alloc(vb); | 436 | balloon_devinfo_init(&vb->vb_dev_info); |
449 | if (IS_ERR(vb_devinfo)) { | 437 | #ifdef CONFIG_BALLOON_COMPACTION |
450 | err = PTR_ERR(vb_devinfo); | 438 | vb->vb_dev_info.migratepage = virtballoon_migratepage; |
451 | goto out_free_vb; | 439 | #endif |
452 | } | ||
453 | |||
454 | vb_mapping = balloon_mapping_alloc(vb_devinfo, | ||
455 | (balloon_compaction_check()) ? | ||
456 | &virtio_balloon_aops : NULL); | ||
457 | if (IS_ERR(vb_mapping)) { | ||
458 | /* | ||
459 | * IS_ERR(vb_mapping) && PTR_ERR(vb_mapping) == -EOPNOTSUPP | ||
460 | * This means !CONFIG_BALLOON_COMPACTION, otherwise we get off. | ||
461 | */ | ||
462 | err = PTR_ERR(vb_mapping); | ||
463 | if (err != -EOPNOTSUPP) | ||
464 | goto out_free_vb_devinfo; | ||
465 | } | ||
466 | |||
467 | vb->vb_dev_info = vb_devinfo; | ||
468 | 440 | ||
469 | err = init_vqs(vb); | 441 | err = init_vqs(vb); |
470 | if (err) | 442 | if (err) |
471 | goto out_free_vb_mapping; | 443 | goto out_free_vb; |
472 | 444 | ||
473 | vb->thread = kthread_run(balloon, vb, "vballoon"); | 445 | vb->thread = kthread_run(balloon, vb, "vballoon"); |
474 | if (IS_ERR(vb->thread)) { | 446 | if (IS_ERR(vb->thread)) { |
@@ -480,10 +452,6 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
480 | 452 | ||
481 | out_del_vqs: | 453 | out_del_vqs: |
482 | vdev->config->del_vqs(vdev); | 454 | vdev->config->del_vqs(vdev); |
483 | out_free_vb_mapping: | ||
484 | balloon_mapping_free(vb_mapping); | ||
485 | out_free_vb_devinfo: | ||
486 | balloon_devinfo_free(vb_devinfo); | ||
487 | out_free_vb: | 455 | out_free_vb: |
488 | kfree(vb); | 456 | kfree(vb); |
489 | out: | 457 | out: |
@@ -509,8 +477,6 @@ static void virtballoon_remove(struct virtio_device *vdev) | |||
509 | 477 | ||
510 | kthread_stop(vb->thread); | 478 | kthread_stop(vb->thread); |
511 | remove_common(vb); | 479 | remove_common(vb); |
512 | balloon_mapping_free(vb->vb_dev_info->mapping); | ||
513 | balloon_devinfo_free(vb->vb_dev_info); | ||
514 | kfree(vb); | 480 | kfree(vb); |
515 | } | 481 | } |
516 | 482 | ||