Line data Source code
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 : 9 : #ifndef _LINUX_PAGEVEC_H 10 : #define _LINUX_PAGEVEC_H 11 : 12 : #include <linux/xarray.h> 13 : 14 : /* 15 pointers + header align the pagevec structure to a power of two */ 15 : #define PAGEVEC_SIZE 15 16 : 17 : struct page; 18 : struct folio; 19 : struct address_space; 20 : 21 : /* Layout must match folio_batch */ 22 : struct pagevec { 23 : unsigned char nr; 24 : bool percpu_pvec_drained; 25 : struct page *pages[PAGEVEC_SIZE]; 26 : }; 27 : 28 : void __pagevec_release(struct pagevec *pvec); 29 : void __pagevec_lru_add(struct pagevec *pvec); 30 : unsigned pagevec_lookup_range(struct pagevec *pvec, 31 : struct address_space *mapping, 32 : pgoff_t *start, pgoff_t end); 33 : static inline unsigned pagevec_lookup(struct pagevec *pvec, 34 : struct address_space *mapping, 35 : pgoff_t *start) 36 : { 37 0 : return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1); 38 : } 39 : 40 : unsigned pagevec_lookup_range_tag(struct pagevec *pvec, 41 : struct address_space *mapping, pgoff_t *index, pgoff_t end, 42 : xa_mark_t tag); 43 : static inline unsigned pagevec_lookup_tag(struct pagevec *pvec, 44 : struct address_space *mapping, pgoff_t *index, xa_mark_t tag) 45 : { 46 : return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag); 47 : } 48 : 49 : static inline void pagevec_init(struct pagevec *pvec) 50 : { 51 0 : pvec->nr = 0; 52 0 : pvec->percpu_pvec_drained = false; 53 : } 54 : 55 : static inline void pagevec_reinit(struct pagevec *pvec) 56 : { 57 0 : pvec->nr = 0; 58 : } 59 : 60 : static inline unsigned pagevec_count(struct pagevec *pvec) 61 : { 62 0 : return pvec->nr; 63 : } 64 : 65 : static inline unsigned pagevec_space(struct pagevec *pvec) 66 : { 67 : return PAGEVEC_SIZE - pvec->nr; 68 : } 69 : 70 : /* 71 : * Add a page to a pagevec. Returns the number of slots still available. 72 : */ 73 : static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page) 74 : { 75 0 : pvec->pages[pvec->nr++] = page; 76 0 : return pagevec_space(pvec); 77 : } 78 : 79 : static inline void pagevec_release(struct pagevec *pvec) 80 : { 81 0 : if (pagevec_count(pvec)) 82 0 : __pagevec_release(pvec); 83 : } 84 : 85 : /** 86 : * struct folio_batch - A collection of folios. 87 : * 88 : * The folio_batch is used to amortise the cost of retrieving and 89 : * operating on a set of folios. The order of folios in the batch may be 90 : * significant (eg delete_from_page_cache_batch()). Some users of the 91 : * folio_batch store "exceptional" entries in it which can be removed 92 : * by calling folio_batch_remove_exceptionals(). 93 : */ 94 : struct folio_batch { 95 : unsigned char nr; 96 : bool percpu_pvec_drained; 97 : struct folio *folios[PAGEVEC_SIZE]; 98 : }; 99 : 100 : /* Layout must match pagevec */ 101 : static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch)); 102 : static_assert(offsetof(struct pagevec, pages) == 103 : offsetof(struct folio_batch, folios)); 104 : 105 : /** 106 : * folio_batch_init() - Initialise a batch of folios 107 : * @fbatch: The folio batch. 108 : * 109 : * A freshly initialised folio_batch contains zero folios. 110 : */ 111 : static inline void folio_batch_init(struct folio_batch *fbatch) 112 : { 113 0 : fbatch->nr = 0; 114 0 : fbatch->percpu_pvec_drained = false; 115 : } 116 : 117 : static inline unsigned int folio_batch_count(struct folio_batch *fbatch) 118 : { 119 0 : return fbatch->nr; 120 : } 121 : 122 : static inline unsigned int fbatch_space(struct folio_batch *fbatch) 123 : { 124 : return PAGEVEC_SIZE - fbatch->nr; 125 : } 126 : 127 : /** 128 : * folio_batch_add() - Add a folio to a batch. 129 : * @fbatch: The folio batch. 130 : * @folio: The folio to add. 131 : * 132 : * The folio is added to the end of the batch. 133 : * The batch must have previously been initialised using folio_batch_init(). 134 : * 135 : * Return: The number of slots still available. 136 : */ 137 : static inline unsigned folio_batch_add(struct folio_batch *fbatch, 138 : struct folio *folio) 139 : { 140 0 : fbatch->folios[fbatch->nr++] = folio; 141 0 : return fbatch_space(fbatch); 142 : } 143 : 144 : static inline void folio_batch_release(struct folio_batch *fbatch) 145 : { 146 0 : pagevec_release((struct pagevec *)fbatch); 147 : } 148 : 149 : void folio_batch_remove_exceptionals(struct folio_batch *fbatch); 150 : #endif /* _LINUX_PAGEVEC_H */