1 /* Public domain. */ 2 3 #ifndef _LINUXKPI_LINUX_PAGEVEC_H_ 4 #define _LINUXKPI_LINUX_PAGEVEC_H_ 5 6 #include <sys/types.h> 7 #include <sys/systm.h> 8 #include <sys/errno.h> 9 10 #include <linux/pagemap.h> 11 12 #define PAGEVEC_SIZE 15 13 14 struct pagevec { 15 uint8_t nr; 16 struct page *pages[PAGEVEC_SIZE]; 17 }; 18 19 static inline unsigned int 20 pagevec_space(struct pagevec *pvec) 21 { 22 return PAGEVEC_SIZE - pvec->nr; 23 } 24 25 static inline void 26 pagevec_init(struct pagevec *pvec) 27 { 28 pvec->nr = 0; 29 } 30 31 static inline void 32 pagevec_reinit(struct pagevec *pvec) 33 { 34 pvec->nr = 0; 35 } 36 37 static inline unsigned int 38 pagevec_count(struct pagevec *pvec) 39 { 40 return pvec->nr; 41 } 42 43 static inline unsigned int 44 pagevec_add(struct pagevec *pvec, struct page *page) 45 { 46 pvec->pages[pvec->nr++] = page; 47 return PAGEVEC_SIZE - pvec->nr; 48 } 49 50 static inline void 51 __pagevec_release(struct pagevec *pvec) 52 { 53 release_pages(pvec->pages, pagevec_count(pvec)); 54 pagevec_reinit(pvec); 55 } 56 57 static inline void 58 pagevec_release(struct pagevec *pvec) 59 { 60 if (pagevec_count(pvec)) 61 __pagevec_release(pvec); 62 } 63 64 static inline void 65 check_move_unevictable_pages(struct pagevec *pvec) 66 { 67 } 68 69 /* 70 * struct folio 71 * 72 * On Linux, `struct folio` replaces `struct page`. To manage a list of folios, 73 * there is `struct folio_batch` on top of this, which replaces `struct 74 * pagevec` above. 75 * 76 * Here is the original description when `struct folio` was added to the Linux 77 * kernel: 78 * "A struct folio is a new abstraction to replace the venerable struct page. 79 * A function which takes a struct folio argument declares that it will 80 * operate on the entire (possibly compound) page, not just PAGE_SIZE bytes. 81 * In return, the caller guarantees that the pointer it is passing does not 82 * point to a tail page. No change to generated code." 83 */ 84 85 struct folio; 86 87 struct folio_batch { 88 uint8_t nr; 89 struct folio *folios[PAGEVEC_SIZE]; 90 }; 91 92 static inline void 93 folio_batch_init(struct folio_batch *fbatch) 94 { 95 fbatch->nr = 0; 96 } 97 98 static inline void 99 folio_batch_reinit(struct folio_batch *fbatch) 100 { 101 fbatch->nr = 0; 102 } 103 104 static inline unsigned int 105 folio_batch_count(struct folio_batch *fbatch) 106 { 107 return (fbatch->nr); 108 } 109 110 static inline unsigned int 111 folio_batch_space(struct folio_batch *fbatch) 112 { 113 return (PAGEVEC_SIZE - fbatch->nr); 114 } 115 116 static inline unsigned int 117 folio_batch_add(struct folio_batch *fbatch, struct folio *folio) 118 { 119 KASSERT( 120 fbatch->nr < PAGEVEC_SIZE, 121 ("struct folio_batch %p is full", fbatch)); 122 123 fbatch->folios[fbatch->nr++] = folio; 124 125 return (folio_batch_space(fbatch)); 126 } 127 128 void __folio_batch_release(struct folio_batch *fbatch); 129 130 static inline void 131 folio_batch_release(struct folio_batch *fbatch) 132 { 133 if (folio_batch_count(fbatch)) 134 __folio_batch_release(fbatch); 135 } 136 137 #endif /* _LINUXKPI_LINUX_PAGEVEC_H_ */ 138