Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/mm/balloon_compaction.c

  1 /*
  2  * mm/balloon_compaction.c
  3  *
  4  * Common interface for making balloon pages movable by compaction.
  5  *
  6  * Copyright (C) 2012, Red Hat, Inc.  Rafael Aquini <aquini@redhat.com>
  7  */
  8 #include <linux/mm.h>
  9 #include <linux/slab.h>
 10 #include <linux/export.h>
 11 #include <linux/balloon_compaction.h>
 12 
 13 /*
 14  * balloon_page_enqueue - allocates a new page and inserts it into the balloon
 15  *                        page list.
 16  * @b_dev_info: balloon device descriptor where we will insert a new page to
 17  *
 18  * Driver must call it to properly allocate a new enlisted balloon page
 19  * before definitively removing it from the guest system.
 20  * This function returns the page address for the recently enqueued page or
 21  * NULL in the case we fail to allocate a new page this turn.
 22  */
 23 struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
 24 {
 25         unsigned long flags;
 26         struct page *page = alloc_page(balloon_mapping_gfp_mask() |
 27                                         __GFP_NOMEMALLOC | __GFP_NORETRY);
 28         if (!page)
 29                 return NULL;
 30 
 31         /*
 32          * Block others from accessing the 'page' when we get around to
 33          * establishing additional references. We should be the only one
 34          * holding a reference to the 'page' at this point.
 35          */
 36         BUG_ON(!trylock_page(page));
 37         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 38         balloon_page_insert(b_dev_info, page);
 39         __count_vm_event(BALLOON_INFLATE);
 40         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 41         unlock_page(page);
 42         return page;
 43 }
 44 EXPORT_SYMBOL_GPL(balloon_page_enqueue);
 45 
 46 /*
 47  * balloon_page_dequeue - removes a page from balloon's page list and returns
 48  *                        the its address to allow the driver release the page.
 49  * @b_dev_info: balloon device decriptor where we will grab a page from.
 50  *
 51  * Driver must call it to properly de-allocate a previous enlisted balloon page
 52  * before definetively releasing it back to the guest system.
 53  * This function returns the page address for the recently dequeued page or
 54  * NULL in the case we find balloon's page list temporarily empty due to
 55  * compaction isolated pages.
 56  */
 57 struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
 58 {
 59         struct page *page, *tmp;
 60         unsigned long flags;
 61         bool dequeued_page;
 62 
 63         dequeued_page = false;
 64         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 65         list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
 66                 /*
 67                  * Block others from accessing the 'page' while we get around
 68                  * establishing additional references and preparing the 'page'
 69                  * to be released by the balloon driver.
 70                  */
 71                 if (trylock_page(page)) {
 72 #ifdef CONFIG_BALLOON_COMPACTION
 73                         if (PageIsolated(page)) {
 74                                 /* raced with isolation */
 75                                 unlock_page(page);
 76                                 continue;
 77                         }
 78 #endif
 79                         balloon_page_delete(page);
 80                         __count_vm_event(BALLOON_DEFLATE);
 81                         unlock_page(page);
 82                         dequeued_page = true;
 83                         break;
 84                 }
 85         }
 86         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 87 
 88         if (!dequeued_page) {
 89                 /*
 90                  * If we are unable to dequeue a balloon page because the page
 91                  * list is empty and there is no isolated pages, then something
 92                  * went out of track and some balloon pages are lost.
 93                  * BUG() here, otherwise the balloon driver may get stuck into
 94                  * an infinite loop while attempting to release all its pages.
 95                  */
 96                 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 97                 if (unlikely(list_empty(&b_dev_info->pages) &&
 98                              !b_dev_info->isolated_pages))
 99                         BUG();
100                 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
101                 page = NULL;
102         }
103         return page;
104 }
105 EXPORT_SYMBOL_GPL(balloon_page_dequeue);
106 
107 #ifdef CONFIG_BALLOON_COMPACTION
108 
109 bool balloon_page_isolate(struct page *page, isolate_mode_t mode)
110 
111 {
112         struct balloon_dev_info *b_dev_info = balloon_page_device(page);
113         unsigned long flags;
114 
115         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
116         list_del(&page->lru);
117         b_dev_info->isolated_pages++;
118         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
119 
120         return true;
121 }
122 
123 void balloon_page_putback(struct page *page)
124 {
125         struct balloon_dev_info *b_dev_info = balloon_page_device(page);
126         unsigned long flags;
127 
128         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
129         list_add(&page->lru, &b_dev_info->pages);
130         b_dev_info->isolated_pages--;
131         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
132 }
133 
134 
135 /* move_to_new_page() counterpart for a ballooned page */
136 int balloon_page_migrate(struct address_space *mapping,
137                 struct page *newpage, struct page *page,
138                 enum migrate_mode mode)
139 {
140         struct balloon_dev_info *balloon = balloon_page_device(page);
141 
142         VM_BUG_ON_PAGE(!PageLocked(page), page);
143         VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
144 
145         return balloon->migratepage(balloon, newpage, page, mode);
146 }
147 
148 const struct address_space_operations balloon_aops = {
149         .migratepage = balloon_page_migrate,
150         .isolate_page = balloon_page_isolate,
151         .putback_page = balloon_page_putback,
152 };
153 EXPORT_SYMBOL_GPL(balloon_aops);
154 
155 #endif /* CONFIG_BALLOON_COMPACTION */
156 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us