balloon_compaction.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * include/linux/balloon_compaction.h
  3. *
  4. * Common interface definitions for making balloon pages movable by compaction.
  5. *
  6. * Despite being perfectly possible to perform ballooned pages migration, they
  7. * make a special corner case to compaction scans because balloon pages are not
  8. * enlisted at any LRU list like the other pages we do compact / migrate.
  9. *
  10. * As the page isolation scanning step a compaction thread does is a lockless
  11. * procedure (from a page standpoint), it might bring some racy situations while
  12. * performing balloon page compaction. In order to sort out these racy scenarios
  13. * and safely perform balloon's page compaction and migration we must, always,
  14. * ensure following these three simple rules:
  15. *
  16. * i. when updating a balloon's page ->mapping element, strictly do it under
  17. * the following lock order, independently of the far superior
  18. * locking scheme (lru_lock, balloon_lock):
  19. * +-page_lock(page);
  20. * +--spin_lock_irq(&b_dev_info->pages_lock);
  21. * ... page->mapping updates here ...
  22. *
  23. * ii. before isolating or dequeueing a balloon page from the balloon device
  24. * pages list, the page reference counter must be raised by one and the
  25. * extra refcount must be dropped when the page is enqueued back into
  26. * the balloon device page list, thus a balloon page keeps its reference
  27. * counter raised only while it is under our special handling;
  28. *
  29. * iii. after the lockless scan step have selected a potential balloon page for
  30. * isolation, re-test the page->mapping flags and the page ref counter
  31. * under the proper page lock, to ensure isolating a valid balloon page
  32. * (not yet isolated, nor under release procedure)
  33. *
  34. * The functions provided by this interface are placed to help on coping with
  35. * the aforementioned balloon page corner case, as well as to ensure the simple
  36. * set of exposed rules are satisfied while we are dealing with balloon pages
  37. * compaction / migration.
  38. *
  39. * Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com>
  40. */
  41. #ifndef _LINUX_BALLOON_COMPACTION_H
  42. #define _LINUX_BALLOON_COMPACTION_H
  43. #include <linux/pagemap.h>
  44. #include <linux/page-flags.h>
  45. #include <linux/migrate.h>
  46. #include <linux/gfp.h>
  47. #include <linux/err.h>
  48. /*
  49. * Balloon device information descriptor.
  50. * This struct is used to allow the common balloon compaction interface
  51. * procedures to find the proper balloon device holding memory pages they'll
  52. * have to cope for page compaction / migration, as well as it serves the
  53. * balloon driver as a page book-keeper for its registered balloon devices.
  54. */
  55. struct balloon_dev_info {
  56. void *balloon_device; /* balloon device descriptor */
  57. struct address_space *mapping; /* balloon special page->mapping */
  58. unsigned long isolated_pages; /* # of isolated pages for migration */
  59. spinlock_t pages_lock; /* Protection to pages list */
  60. struct list_head pages; /* Pages enqueued & handled to Host */
  61. };
  62. extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);
  63. extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);
  64. extern struct balloon_dev_info *balloon_devinfo_alloc(
  65. void *balloon_dev_descriptor);
  66. static inline void balloon_devinfo_free(struct balloon_dev_info *b_dev_info)
  67. {
  68. kfree(b_dev_info);
  69. }
  70. /*
  71. * balloon_page_free - release a balloon page back to the page free lists
  72. * @page: ballooned page to be set free
  73. *
  74. * This function must be used to properly set free an isolated/dequeued balloon
  75. * page at the end of a sucessful page migration, or at the balloon driver's
  76. * page release procedure.
  77. */
  78. static inline void balloon_page_free(struct page *page)
  79. {
  80. /*
  81. * Balloon pages always get an extra refcount before being isolated
  82. * and before being dequeued to help on sorting out fortuite colisions
  83. * between a thread attempting to isolate and another thread attempting
  84. * to release the very same balloon page.
  85. *
  86. * Before we handle the page back to Buddy, lets drop its extra refcnt.
  87. */
  88. put_page(page);
  89. __free_page(page);
  90. }
  91. #ifdef CONFIG_BALLOON_COMPACTION
  92. extern bool balloon_page_isolate(struct page *page);
  93. extern void balloon_page_putback(struct page *page);
  94. extern int balloon_page_migrate(struct page *newpage,
  95. struct page *page, enum migrate_mode mode);
  96. extern struct address_space
  97. *balloon_mapping_alloc(struct balloon_dev_info *b_dev_info,
  98. const struct address_space_operations *a_ops);
  99. static inline void balloon_mapping_free(struct address_space *balloon_mapping)
  100. {
  101. kfree(balloon_mapping);
  102. }
  103. /*
  104. * page_flags_cleared - helper to perform balloon @page ->flags tests.
  105. *
  106. * As balloon pages are obtained from buddy and we do not play with page->flags
  107. * at driver level (exception made when we get the page lock for compaction),
  108. * we can safely identify a ballooned page by checking if the
  109. * PAGE_FLAGS_CHECK_AT_PREP page->flags are all cleared. This approach also
  110. * helps us skip ballooned pages that are locked for compaction or release, thus
  111. * mitigating their racy check at balloon_page_movable()
  112. */
  113. static inline bool page_flags_cleared(struct page *page)
  114. {
  115. return !(page->flags & PAGE_FLAGS_CHECK_AT_PREP);
  116. }
  117. /*
  118. * __is_movable_balloon_page - helper to perform @page mapping->flags tests
  119. */
  120. static inline bool __is_movable_balloon_page(struct page *page)
  121. {
  122. struct address_space *mapping = page->mapping;
  123. return mapping_balloon(mapping);
  124. }
  125. /*
  126. * balloon_page_movable - test page->mapping->flags to identify balloon pages
  127. * that can be moved by compaction/migration.
  128. *
  129. * This function is used at core compaction's page isolation scheme, therefore
  130. * most pages exposed to it are not enlisted as balloon pages and so, to avoid
  131. * undesired side effects like racing against __free_pages(), we cannot afford
  132. * holding the page locked while testing page->mapping->flags here.
  133. *
  134. * As we might return false positives in the case of a balloon page being just
  135. * released under us, the page->mapping->flags need to be re-tested later,
  136. * under the proper page lock, at the functions that will be coping with the
  137. * balloon page case.
  138. */
  139. static inline bool balloon_page_movable(struct page *page)
  140. {
  141. /*
  142. * Before dereferencing and testing mapping->flags, let's make sure
  143. * this is not a page that uses ->mapping in a different way
  144. */
  145. if (page_flags_cleared(page) && !page_mapped(page) &&
  146. page_count(page) == 1)
  147. return __is_movable_balloon_page(page);
  148. return false;
  149. }
  150. /*
  151. * balloon_page_insert - insert a page into the balloon's page list and make
  152. * the page->mapping assignment accordingly.
  153. * @page : page to be assigned as a 'balloon page'
  154. * @mapping : allocated special 'balloon_mapping'
  155. * @head : balloon's device page list head
  156. *
  157. * Caller must ensure the page is locked and the spin_lock protecting balloon
  158. * pages list is held before inserting a page into the balloon device.
  159. */
  160. static inline void balloon_page_insert(struct page *page,
  161. struct address_space *mapping,
  162. struct list_head *head)
  163. {
  164. page->mapping = mapping;
  165. list_add(&page->lru, head);
  166. }
  167. /*
  168. * balloon_page_delete - delete a page from balloon's page list and clear
  169. * the page->mapping assignement accordingly.
  170. * @page : page to be released from balloon's page list
  171. *
  172. * Caller must ensure the page is locked and the spin_lock protecting balloon
  173. * pages list is held before deleting a page from the balloon device.
  174. */
  175. static inline void balloon_page_delete(struct page *page)
  176. {
  177. page->mapping = NULL;
  178. list_del(&page->lru);
  179. }
  180. /*
  181. * balloon_page_device - get the b_dev_info descriptor for the balloon device
  182. * that enqueues the given page.
  183. */
  184. static inline struct balloon_dev_info *balloon_page_device(struct page *page)
  185. {
  186. struct address_space *mapping = page->mapping;
  187. if (likely(mapping))
  188. return mapping->private_data;
  189. return NULL;
  190. }
  191. static inline gfp_t balloon_mapping_gfp_mask(void)
  192. {
  193. return GFP_HIGHUSER_MOVABLE;
  194. }
  195. static inline bool balloon_compaction_check(void)
  196. {
  197. return true;
  198. }
  199. #else /* !CONFIG_BALLOON_COMPACTION */
  200. static inline void *balloon_mapping_alloc(void *balloon_device,
  201. const struct address_space_operations *a_ops)
  202. {
  203. return ERR_PTR(-EOPNOTSUPP);
  204. }
  205. static inline void balloon_mapping_free(struct address_space *balloon_mapping)
  206. {
  207. return;
  208. }
  209. static inline void balloon_page_insert(struct page *page,
  210. struct address_space *mapping,
  211. struct list_head *head)
  212. {
  213. list_add(&page->lru, head);
  214. }
  215. static inline void balloon_page_delete(struct page *page)
  216. {
  217. list_del(&page->lru);
  218. }
  219. static inline bool balloon_page_movable(struct page *page)
  220. {
  221. return false;
  222. }
  223. static inline bool balloon_page_isolate(struct page *page)
  224. {
  225. return false;
  226. }
  227. static inline void balloon_page_putback(struct page *page)
  228. {
  229. return;
  230. }
  231. static inline int balloon_page_migrate(struct page *newpage,
  232. struct page *page, enum migrate_mode mode)
  233. {
  234. return 0;
  235. }
  236. static inline gfp_t balloon_mapping_gfp_mask(void)
  237. {
  238. return GFP_HIGHUSER;
  239. }
  240. static inline bool balloon_compaction_check(void)
  241. {
  242. return false;
  243. }
  244. #endif /* CONFIG_BALLOON_COMPACTION */
  245. #endif /* _LINUX_BALLOON_COMPACTION_H */