/include/linux/swapops.h

https://github.com/airy09/android_kernel_sony_apq8064 · C Header · 195 lines · 128 code · 29 blank · 38 comment · 7 complexity · cb20e697154ded5742648811967db2c4 MD5 · raw file

  1. #ifndef _LINUX_SWAPOPS_H
  2. #define _LINUX_SWAPOPS_H
  3. #include <linux/radix-tree.h>
  4. #include <linux/bug.h>
  5. /*
  6. * swapcache pages are stored in the swapper_space radix tree. We want to
  7. * get good packing density in that tree, so the index should be dense in
  8. * the low-order bits.
  9. *
  10. * We arrange the `type' and `offset' fields so that `type' is at the five
  11. * high-order bits of the swp_entry_t and `offset' is right-aligned in the
  12. * remaining bits.
  13. *
  14. * swp_entry_t's are *never* stored anywhere in their arch-dependent format.
  15. */
  16. #define SWP_TYPE_SHIFT(e) (sizeof(e.val) * 8 - MAX_SWAPFILES_SHIFT)
  17. #define SWP_OFFSET_MASK(e) ((1UL << SWP_TYPE_SHIFT(e)) - 1)
  18. /*
  19. * Store a type+offset into a swp_entry_t in an arch-independent format
  20. */
  21. static inline swp_entry_t swp_entry(unsigned long type, pgoff_t offset)
  22. {
  23. swp_entry_t ret;
  24. ret.val = (type << SWP_TYPE_SHIFT(ret)) |
  25. (offset & SWP_OFFSET_MASK(ret));
  26. return ret;
  27. }
  28. /*
  29. * Extract the `type' field from a swp_entry_t. The swp_entry_t is in
  30. * arch-independent format
  31. */
  32. static inline unsigned swp_type(swp_entry_t entry)
  33. {
  34. return (entry.val >> SWP_TYPE_SHIFT(entry));
  35. }
  36. /*
  37. * Extract the `offset' field from a swp_entry_t. The swp_entry_t is in
  38. * arch-independent format
  39. */
  40. static inline pgoff_t swp_offset(swp_entry_t entry)
  41. {
  42. return entry.val & SWP_OFFSET_MASK(entry);
  43. }
  44. #ifdef CONFIG_MMU
  45. /* check whether a pte points to a swap entry */
  46. static inline int is_swap_pte(pte_t pte)
  47. {
  48. return !pte_none(pte) && !pte_present(pte) && !pte_file(pte);
  49. }
  50. #endif
  51. /*
  52. * Convert the arch-dependent pte representation of a swp_entry_t into an
  53. * arch-independent swp_entry_t.
  54. */
  55. static inline swp_entry_t pte_to_swp_entry(pte_t pte)
  56. {
  57. swp_entry_t arch_entry;
  58. BUG_ON(pte_file(pte));
  59. arch_entry = __pte_to_swp_entry(pte);
  60. return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry));
  61. }
  62. /*
  63. * Convert the arch-independent representation of a swp_entry_t into the
  64. * arch-dependent pte representation.
  65. */
  66. static inline pte_t swp_entry_to_pte(swp_entry_t entry)
  67. {
  68. swp_entry_t arch_entry;
  69. arch_entry = __swp_entry(swp_type(entry), swp_offset(entry));
  70. BUG_ON(pte_file(__swp_entry_to_pte(arch_entry)));
  71. return __swp_entry_to_pte(arch_entry);
  72. }
  73. static inline swp_entry_t radix_to_swp_entry(void *arg)
  74. {
  75. swp_entry_t entry;
  76. entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT;
  77. return entry;
  78. }
  79. static inline void *swp_to_radix_entry(swp_entry_t entry)
  80. {
  81. unsigned long value;
  82. value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT;
  83. return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY);
  84. }
  85. #ifdef CONFIG_MIGRATION
  86. static inline swp_entry_t make_migration_entry(struct page *page, int write)
  87. {
  88. BUG_ON(!PageLocked(page));
  89. return swp_entry(write ? SWP_MIGRATION_WRITE : SWP_MIGRATION_READ,
  90. page_to_pfn(page));
  91. }
  92. static inline int is_migration_entry(swp_entry_t entry)
  93. {
  94. return unlikely(swp_type(entry) == SWP_MIGRATION_READ ||
  95. swp_type(entry) == SWP_MIGRATION_WRITE);
  96. }
  97. static inline int is_write_migration_entry(swp_entry_t entry)
  98. {
  99. return unlikely(swp_type(entry) == SWP_MIGRATION_WRITE);
  100. }
  101. static inline struct page *migration_entry_to_page(swp_entry_t entry)
  102. {
  103. struct page *p = pfn_to_page(swp_offset(entry));
  104. /*
  105. * Any use of migration entries may only occur while the
  106. * corresponding page is locked
  107. */
  108. BUG_ON(!PageLocked(p));
  109. return p;
  110. }
  111. static inline void make_migration_entry_read(swp_entry_t *entry)
  112. {
  113. *entry = swp_entry(SWP_MIGRATION_READ, swp_offset(*entry));
  114. }
  115. extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
  116. unsigned long address);
  117. #else
  118. #define make_migration_entry(page, write) swp_entry(0, 0)
  119. static inline int is_migration_entry(swp_entry_t swp)
  120. {
  121. return 0;
  122. }
  123. #define migration_entry_to_page(swp) NULL
  124. static inline void make_migration_entry_read(swp_entry_t *entryp) { }
  125. static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
  126. unsigned long address) { }
  127. static inline int is_write_migration_entry(swp_entry_t entry)
  128. {
  129. return 0;
  130. }
  131. #endif
  132. #ifdef CONFIG_MEMORY_FAILURE
  133. /*
  134. * Support for hardware poisoned pages
  135. */
  136. static inline swp_entry_t make_hwpoison_entry(struct page *page)
  137. {
  138. BUG_ON(!PageLocked(page));
  139. return swp_entry(SWP_HWPOISON, page_to_pfn(page));
  140. }
  141. static inline int is_hwpoison_entry(swp_entry_t entry)
  142. {
  143. return swp_type(entry) == SWP_HWPOISON;
  144. }
  145. #else
  146. static inline swp_entry_t make_hwpoison_entry(struct page *page)
  147. {
  148. return swp_entry(0, 0);
  149. }
  150. static inline int is_hwpoison_entry(swp_entry_t swp)
  151. {
  152. return 0;
  153. }
  154. #endif
  155. #if defined(CONFIG_MEMORY_FAILURE) || defined(CONFIG_MIGRATION)
  156. static inline int non_swap_entry(swp_entry_t entry)
  157. {
  158. return swp_type(entry) >= MAX_SWAPFILES;
  159. }
  160. #else
  161. static inline int non_swap_entry(swp_entry_t entry)
  162. {
  163. return 0;
  164. }
  165. #endif
  166. #endif /* _LINUX_SWAPOPS_H */