Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * mm/balloon_compaction.c
0004  *
0005  * Common interface for making balloon pages movable by compaction.
0006  *
0007  * Copyright (C) 2012, Red Hat, Inc.  Rafael Aquini <aquini@redhat.com>
0008  */
0009 #include <linux/mm.h>
0010 #include <linux/slab.h>
0011 #include <linux/export.h>
0012 #include <linux/balloon_compaction.h>
0013 
0014 static void balloon_page_enqueue_one(struct balloon_dev_info *b_dev_info,
0015                      struct page *page)
0016 {
0017     /*
0018      * Block others from accessing the 'page' when we get around to
0019      * establishing additional references. We should be the only one
0020      * holding a reference to the 'page' at this point. If we are not, then
0021      * memory corruption is possible and we should stop execution.
0022      */
0023     BUG_ON(!trylock_page(page));
0024     balloon_page_insert(b_dev_info, page);
0025     unlock_page(page);
0026     __count_vm_event(BALLOON_INFLATE);
0027 }
0028 
0029 /**
0030  * balloon_page_list_enqueue() - inserts a list of pages into the balloon page
0031  *               list.
0032  * @b_dev_info: balloon device descriptor where we will insert a new page to
0033  * @pages: pages to enqueue - allocated using balloon_page_alloc.
0034  *
0035  * Driver must call this function to properly enqueue balloon pages before
0036  * definitively removing them from the guest system.
0037  *
0038  * Return: number of pages that were enqueued.
0039  */
0040 size_t balloon_page_list_enqueue(struct balloon_dev_info *b_dev_info,
0041                  struct list_head *pages)
0042 {
0043     struct page *page, *tmp;
0044     unsigned long flags;
0045     size_t n_pages = 0;
0046 
0047     spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0048     list_for_each_entry_safe(page, tmp, pages, lru) {
0049         list_del(&page->lru);
0050         balloon_page_enqueue_one(b_dev_info, page);
0051         n_pages++;
0052     }
0053     spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0054     return n_pages;
0055 }
0056 EXPORT_SYMBOL_GPL(balloon_page_list_enqueue);
0057 
0058 /**
0059  * balloon_page_list_dequeue() - removes pages from balloon's page list and
0060  *               returns a list of the pages.
0061  * @b_dev_info: balloon device descriptor where we will grab a page from.
0062  * @pages: pointer to the list of pages that would be returned to the caller.
0063  * @n_req_pages: number of requested pages.
0064  *
0065  * Driver must call this function to properly de-allocate a previous enlisted
0066  * balloon pages before definitively releasing it back to the guest system.
0067  * This function tries to remove @n_req_pages from the ballooned pages and
0068  * return them to the caller in the @pages list.
0069  *
0070  * Note that this function may fail to dequeue some pages even if the balloon
0071  * isn't empty - since the page list can be temporarily empty due to compaction
0072  * of isolated pages.
0073  *
0074  * Return: number of pages that were added to the @pages list.
0075  */
0076 size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info,
0077                  struct list_head *pages, size_t n_req_pages)
0078 {
0079     struct page *page, *tmp;
0080     unsigned long flags;
0081     size_t n_pages = 0;
0082 
0083     spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0084     list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
0085         if (n_pages == n_req_pages)
0086             break;
0087 
0088         /*
0089          * Block others from accessing the 'page' while we get around to
0090          * establishing additional references and preparing the 'page'
0091          * to be released by the balloon driver.
0092          */
0093         if (!trylock_page(page))
0094             continue;
0095 
0096         if (IS_ENABLED(CONFIG_BALLOON_COMPACTION) &&
0097             PageIsolated(page)) {
0098             /* raced with isolation */
0099             unlock_page(page);
0100             continue;
0101         }
0102         balloon_page_delete(page);
0103         __count_vm_event(BALLOON_DEFLATE);
0104         list_add(&page->lru, pages);
0105         unlock_page(page);
0106         n_pages++;
0107     }
0108     spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0109 
0110     return n_pages;
0111 }
0112 EXPORT_SYMBOL_GPL(balloon_page_list_dequeue);
0113 
0114 /*
0115  * balloon_page_alloc - allocates a new page for insertion into the balloon
0116  *          page list.
0117  *
0118  * Driver must call this function to properly allocate a new balloon page.
0119  * Driver must call balloon_page_enqueue before definitively removing the page
0120  * from the guest system.
0121  *
0122  * Return: struct page for the allocated page or NULL on allocation failure.
0123  */
0124 struct page *balloon_page_alloc(void)
0125 {
0126     struct page *page = alloc_page(balloon_mapping_gfp_mask() |
0127                        __GFP_NOMEMALLOC | __GFP_NORETRY |
0128                        __GFP_NOWARN);
0129     return page;
0130 }
0131 EXPORT_SYMBOL_GPL(balloon_page_alloc);
0132 
0133 /*
0134  * balloon_page_enqueue - inserts a new page into the balloon page list.
0135  *
0136  * @b_dev_info: balloon device descriptor where we will insert a new page
0137  * @page: new page to enqueue - allocated using balloon_page_alloc.
0138  *
0139  * Drivers must call this function to properly enqueue a new allocated balloon
0140  * page before definitively removing the page from the guest system.
0141  *
0142  * Drivers must not call balloon_page_enqueue on pages that have been pushed to
0143  * a list with balloon_page_push before removing them with balloon_page_pop. To
0144  * enqueue a list of pages, use balloon_page_list_enqueue instead.
0145  */
0146 void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
0147               struct page *page)
0148 {
0149     unsigned long flags;
0150 
0151     spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0152     balloon_page_enqueue_one(b_dev_info, page);
0153     spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0154 }
0155 EXPORT_SYMBOL_GPL(balloon_page_enqueue);
0156 
0157 /*
0158  * balloon_page_dequeue - removes a page from balloon's page list and returns
0159  *            its address to allow the driver to release the page.
0160  * @b_dev_info: balloon device descriptor where we will grab a page from.
0161  *
0162  * Driver must call this function to properly dequeue a previously enqueued page
0163  * before definitively releasing it back to the guest system.
0164  *
0165  * Caller must perform its own accounting to ensure that this
0166  * function is called only if some pages are actually enqueued.
0167  *
0168  * Note that this function may fail to dequeue some pages even if there are
0169  * some enqueued pages - since the page list can be temporarily empty due to
0170  * the compaction of isolated pages.
0171  *
0172  * TODO: remove the caller accounting requirements, and allow caller to wait
0173  * until all pages can be dequeued.
0174  *
0175  * Return: struct page for the dequeued page, or NULL if no page was dequeued.
0176  */
0177 struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
0178 {
0179     unsigned long flags;
0180     LIST_HEAD(pages);
0181     int n_pages;
0182 
0183     n_pages = balloon_page_list_dequeue(b_dev_info, &pages, 1);
0184 
0185     if (n_pages != 1) {
0186         /*
0187          * If we are unable to dequeue a balloon page because the page
0188          * list is empty and there are no isolated pages, then something
0189          * went out of track and some balloon pages are lost.
0190          * BUG() here, otherwise the balloon driver may get stuck in
0191          * an infinite loop while attempting to release all its pages.
0192          */
0193         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0194         if (unlikely(list_empty(&b_dev_info->pages) &&
0195                  !b_dev_info->isolated_pages))
0196             BUG();
0197         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0198         return NULL;
0199     }
0200     return list_first_entry(&pages, struct page, lru);
0201 }
0202 EXPORT_SYMBOL_GPL(balloon_page_dequeue);
0203 
0204 #ifdef CONFIG_BALLOON_COMPACTION
0205 
0206 static bool balloon_page_isolate(struct page *page, isolate_mode_t mode)
0207 
0208 {
0209     struct balloon_dev_info *b_dev_info = balloon_page_device(page);
0210     unsigned long flags;
0211 
0212     spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0213     list_del(&page->lru);
0214     b_dev_info->isolated_pages++;
0215     spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0216 
0217     return true;
0218 }
0219 
0220 static void balloon_page_putback(struct page *page)
0221 {
0222     struct balloon_dev_info *b_dev_info = balloon_page_device(page);
0223     unsigned long flags;
0224 
0225     spin_lock_irqsave(&b_dev_info->pages_lock, flags);
0226     list_add(&page->lru, &b_dev_info->pages);
0227     b_dev_info->isolated_pages--;
0228     spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
0229 }
0230 
0231 /* move_to_new_page() counterpart for a ballooned page */
0232 static int balloon_page_migrate(struct page *newpage, struct page *page,
0233         enum migrate_mode mode)
0234 {
0235     struct balloon_dev_info *balloon = balloon_page_device(page);
0236 
0237     /*
0238      * We can not easily support the no copy case here so ignore it as it
0239      * is unlikely to be used with balloon pages. See include/linux/hmm.h
0240      * for a user of the MIGRATE_SYNC_NO_COPY mode.
0241      */
0242     if (mode == MIGRATE_SYNC_NO_COPY)
0243         return -EINVAL;
0244 
0245     VM_BUG_ON_PAGE(!PageLocked(page), page);
0246     VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
0247 
0248     return balloon->migratepage(balloon, newpage, page, mode);
0249 }
0250 
0251 const struct movable_operations balloon_mops = {
0252     .migrate_page = balloon_page_migrate,
0253     .isolate_page = balloon_page_isolate,
0254     .putback_page = balloon_page_putback,
0255 };
0256 EXPORT_SYMBOL_GPL(balloon_mops);
0257 
0258 #endif /* CONFIG_BALLOON_COMPACTION */