![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0 */ 0002 /* 0003 * include/linux/balloon_compaction.h 0004 * 0005 * Common interface definitions for making balloon pages movable by compaction. 0006 * 0007 * Balloon page migration makes use of the general non-lru movable page 0008 * feature. 0009 * 0010 * page->private is used to reference the responsible balloon device. 0011 * page->mapping is used in context of non-lru page migration to reference 0012 * the address space operations for page isolation/migration/compaction. 0013 * 0014 * As the page isolation scanning step a compaction thread does is a lockless 0015 * procedure (from a page standpoint), it might bring some racy situations while 0016 * performing balloon page compaction. In order to sort out these racy scenarios 0017 * and safely perform balloon's page compaction and migration we must, always, 0018 * ensure following these simple rules: 0019 * 0020 * i. when updating a balloon's page ->mapping element, strictly do it under 0021 * the following lock order, independently of the far superior 0022 * locking scheme (lru_lock, balloon_lock): 0023 * +-page_lock(page); 0024 * +--spin_lock_irq(&b_dev_info->pages_lock); 0025 * ... page->mapping updates here ... 0026 * 0027 * ii. isolation or dequeueing procedure must remove the page from balloon 0028 * device page list under b_dev_info->pages_lock. 0029 * 0030 * The functions provided by this interface are placed to help on coping with 0031 * the aforementioned balloon page corner case, as well as to ensure the simple 0032 * set of exposed rules are satisfied while we are dealing with balloon pages 0033 * compaction / migration. 0034 * 0035 * Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com> 0036 */ 0037 #ifndef _LINUX_BALLOON_COMPACTION_H 0038 #define _LINUX_BALLOON_COMPACTION_H 0039 #include <linux/pagemap.h> 0040 #include <linux/page-flags.h> 0041 #include <linux/migrate.h> 0042 #include <linux/gfp.h> 0043 #include <linux/err.h> 0044 #include <linux/fs.h> 0045 #include <linux/list.h> 0046 0047 /* 0048 * Balloon device information descriptor. 0049 * This struct is used to allow the common balloon compaction interface 0050 * procedures to find the proper balloon device holding memory pages they'll 0051 * have to cope for page compaction / migration, as well as it serves the 0052 * balloon driver as a page book-keeper for its registered balloon devices. 0053 */ 0054 struct balloon_dev_info { 0055 unsigned long isolated_pages; /* # of isolated pages for migration */ 0056 spinlock_t pages_lock; /* Protection to pages list */ 0057 struct list_head pages; /* Pages enqueued & handled to Host */ 0058 int (*migratepage)(struct balloon_dev_info *, struct page *newpage, 0059 struct page *page, enum migrate_mode mode); 0060 }; 0061 0062 extern struct page *balloon_page_alloc(void); 0063 extern void balloon_page_enqueue(struct balloon_dev_info *b_dev_info, 0064 struct page *page); 0065 extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info); 0066 extern size_t balloon_page_list_enqueue(struct balloon_dev_info *b_dev_info, 0067 struct list_head *pages); 0068 extern size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info, 0069 struct list_head *pages, size_t n_req_pages); 0070 0071 static inline void balloon_devinfo_init(struct balloon_dev_info *balloon) 0072 { 0073 balloon->isolated_pages = 0; 0074 spin_lock_init(&balloon->pages_lock); 0075 INIT_LIST_HEAD(&balloon->pages); 0076 balloon->migratepage = NULL; 0077 } 0078 0079 #ifdef CONFIG_BALLOON_COMPACTION 0080 extern const struct movable_operations balloon_mops; 0081 0082 /* 0083 * balloon_page_insert - insert a page into the balloon's page list and make 0084 * the page->private assignment accordingly. 0085 * @balloon : pointer to balloon device 0086 * @page : page to be assigned as a 'balloon page' 0087 * 0088 * Caller must ensure the page is locked and the spin_lock protecting balloon 0089 * pages list is held before inserting a page into the balloon device. 0090 */ 0091 static inline void balloon_page_insert(struct balloon_dev_info *balloon, 0092 struct page *page) 0093 { 0094 __SetPageOffline(page); 0095 __SetPageMovable(page, &balloon_mops); 0096 set_page_private(page, (unsigned long)balloon); 0097 list_add(&page->lru, &balloon->pages); 0098 } 0099 0100 /* 0101 * balloon_page_delete - delete a page from balloon's page list and clear 0102 * the page->private assignement accordingly. 0103 * @page : page to be released from balloon's page list 0104 * 0105 * Caller must ensure the page is locked and the spin_lock protecting balloon 0106 * pages list is held before deleting a page from the balloon device. 0107 */ 0108 static inline void balloon_page_delete(struct page *page) 0109 { 0110 __ClearPageOffline(page); 0111 __ClearPageMovable(page); 0112 set_page_private(page, 0); 0113 /* 0114 * No touch page.lru field once @page has been isolated 0115 * because VM is using the field. 0116 */ 0117 if (!PageIsolated(page)) 0118 list_del(&page->lru); 0119 } 0120 0121 /* 0122 * balloon_page_device - get the b_dev_info descriptor for the balloon device 0123 * that enqueues the given page. 0124 */ 0125 static inline struct balloon_dev_info *balloon_page_device(struct page *page) 0126 { 0127 return (struct balloon_dev_info *)page_private(page); 0128 } 0129 0130 static inline gfp_t balloon_mapping_gfp_mask(void) 0131 { 0132 return GFP_HIGHUSER_MOVABLE; 0133 } 0134 0135 #else /* !CONFIG_BALLOON_COMPACTION */ 0136 0137 static inline void balloon_page_insert(struct balloon_dev_info *balloon, 0138 struct page *page) 0139 { 0140 __SetPageOffline(page); 0141 list_add(&page->lru, &balloon->pages); 0142 } 0143 0144 static inline void balloon_page_delete(struct page *page) 0145 { 0146 __ClearPageOffline(page); 0147 list_del(&page->lru); 0148 } 0149 0150 static inline gfp_t balloon_mapping_gfp_mask(void) 0151 { 0152 return GFP_HIGHUSER; 0153 } 0154 0155 #endif /* CONFIG_BALLOON_COMPACTION */ 0156 0157 /* 0158 * balloon_page_push - insert a page into a page list. 0159 * @head : pointer to list 0160 * @page : page to be added 0161 * 0162 * Caller must ensure the page is private and protect the list. 0163 */ 0164 static inline void balloon_page_push(struct list_head *pages, struct page *page) 0165 { 0166 list_add(&page->lru, pages); 0167 } 0168 0169 /* 0170 * balloon_page_pop - remove a page from a page list. 0171 * @head : pointer to list 0172 * @page : page to be added 0173 * 0174 * Caller must ensure the page is private and protect the list. 0175 */ 0176 static inline struct page *balloon_page_pop(struct list_head *pages) 0177 { 0178 struct page *page = list_first_entry_or_null(pages, struct page, lru); 0179 0180 if (!page) 0181 return NULL; 0182 0183 list_del(&page->lru); 0184 return page; 0185 } 0186 #endif /* _LINUX_BALLOON_COMPACTION_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |