pagevec.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * include/linux/pagevec.h
  4. *
  5. * In many places it is efficient to batch an operation up against multiple
  6. * pages. A pagevec is a multipage container which is used for that.
  7. */
  8. #ifndef _LINUX_PAGEVEC_H
  9. #define _LINUX_PAGEVEC_H
  10. #include <linux/xarray.h>
  11. /* 15 pointers + header align the pagevec structure to a power of two */
  12. #define PAGEVEC_SIZE 15
  13. struct page;
  14. struct folio;
  15. struct address_space;
  16. /* Layout must match folio_batch */
  17. struct pagevec {
  18. unsigned char nr;
  19. bool percpu_pvec_drained;
  20. struct page *pages[PAGEVEC_SIZE];
  21. };
  22. void __pagevec_release(struct pagevec *pvec);
  23. unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
  24. struct address_space *mapping, pgoff_t *index, pgoff_t end,
  25. xa_mark_t tag);
  26. static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
  27. struct address_space *mapping, pgoff_t *index, xa_mark_t tag)
  28. {
  29. return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag);
  30. }
  31. static inline void pagevec_init(struct pagevec *pvec)
  32. {
  33. pvec->nr = 0;
  34. pvec->percpu_pvec_drained = false;
  35. }
  36. static inline void pagevec_reinit(struct pagevec *pvec)
  37. {
  38. pvec->nr = 0;
  39. }
  40. static inline unsigned pagevec_count(struct pagevec *pvec)
  41. {
  42. return pvec->nr;
  43. }
  44. static inline unsigned pagevec_space(struct pagevec *pvec)
  45. {
  46. return PAGEVEC_SIZE - pvec->nr;
  47. }
  48. /*
  49. * Add a page to a pagevec. Returns the number of slots still available.
  50. */
  51. static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page)
  52. {
  53. pvec->pages[pvec->nr++] = page;
  54. return pagevec_space(pvec);
  55. }
  56. static inline void pagevec_release(struct pagevec *pvec)
  57. {
  58. if (pagevec_count(pvec))
  59. __pagevec_release(pvec);
  60. }
  61. /**
  62. * struct folio_batch - A collection of folios.
  63. *
  64. * The folio_batch is used to amortise the cost of retrieving and
  65. * operating on a set of folios. The order of folios in the batch may be
  66. * significant (eg delete_from_page_cache_batch()). Some users of the
  67. * folio_batch store "exceptional" entries in it which can be removed
  68. * by calling folio_batch_remove_exceptionals().
  69. */
  70. struct folio_batch {
  71. unsigned char nr;
  72. bool percpu_pvec_drained;
  73. struct folio *folios[PAGEVEC_SIZE];
  74. };
  75. /* Layout must match pagevec */
  76. static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch));
  77. static_assert(offsetof(struct pagevec, pages) ==
  78. offsetof(struct folio_batch, folios));
  79. /**
  80. * folio_batch_init() - Initialise a batch of folios
  81. * @fbatch: The folio batch.
  82. *
  83. * A freshly initialised folio_batch contains zero folios.
  84. */
  85. static inline void folio_batch_init(struct folio_batch *fbatch)
  86. {
  87. fbatch->nr = 0;
  88. fbatch->percpu_pvec_drained = false;
  89. }
  90. static inline unsigned int folio_batch_count(struct folio_batch *fbatch)
  91. {
  92. return fbatch->nr;
  93. }
  94. static inline unsigned int fbatch_space(struct folio_batch *fbatch)
  95. {
  96. return PAGEVEC_SIZE - fbatch->nr;
  97. }
  98. /**
  99. * folio_batch_add() - Add a folio to a batch.
  100. * @fbatch: The folio batch.
  101. * @folio: The folio to add.
  102. *
  103. * The folio is added to the end of the batch.
  104. * The batch must have previously been initialised using folio_batch_init().
  105. *
  106. * Return: The number of slots still available.
  107. */
  108. static inline unsigned folio_batch_add(struct folio_batch *fbatch,
  109. struct folio *folio)
  110. {
  111. fbatch->folios[fbatch->nr++] = folio;
  112. return fbatch_space(fbatch);
  113. }
  114. static inline void folio_batch_release(struct folio_batch *fbatch)
  115. {
  116. pagevec_release((struct pagevec *)fbatch);
  117. }
  118. void folio_batch_remove_exceptionals(struct folio_batch *fbatch);
  119. #endif /* _LINUX_PAGEVEC_H */