xref: /freebsd/sys/compat/linuxkpi/common/include/linux/pagevec.h (revision e3b16f53a6455903a7e814045584fe203d4fff64)
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
pagevec_space(struct pagevec * pvec)20 pagevec_space(struct pagevec *pvec)
21 {
22 	return PAGEVEC_SIZE - pvec->nr;
23 }
24 
25 static inline void
pagevec_init(struct pagevec * pvec)26 pagevec_init(struct pagevec *pvec)
27 {
28 	pvec->nr = 0;
29 }
30 
31 static inline void
pagevec_reinit(struct pagevec * pvec)32 pagevec_reinit(struct pagevec *pvec)
33 {
34 	pvec->nr = 0;
35 }
36 
37 static inline unsigned int
pagevec_count(struct pagevec * pvec)38 pagevec_count(struct pagevec *pvec)
39 {
40 	return pvec->nr;
41 }
42 
43 static inline unsigned int
pagevec_add(struct pagevec * pvec,struct page * page)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
__pagevec_release(struct pagevec * pvec)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
pagevec_release(struct pagevec * pvec)58 pagevec_release(struct pagevec *pvec)
59 {
60 	if (pagevec_count(pvec))
61 		__pagevec_release(pvec);
62 }
63 
64 static inline void
check_move_unevictable_pages(struct pagevec * pvec)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
folio_batch_init(struct folio_batch * fbatch)93 folio_batch_init(struct folio_batch *fbatch)
94 {
95 	fbatch->nr = 0;
96 }
97 
98 static inline void
folio_batch_reinit(struct folio_batch * fbatch)99 folio_batch_reinit(struct folio_batch *fbatch)
100 {
101 	fbatch->nr = 0;
102 }
103 
104 static inline unsigned int
folio_batch_count(struct folio_batch * fbatch)105 folio_batch_count(struct folio_batch *fbatch)
106 {
107 	return (fbatch->nr);
108 }
109 
110 static inline unsigned int
folio_batch_space(struct folio_batch * fbatch)111 folio_batch_space(struct folio_batch *fbatch)
112 {
113 	return (PAGEVEC_SIZE - fbatch->nr);
114 }
115 
116 static inline unsigned int
folio_batch_add(struct folio_batch * fbatch,struct folio * folio)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
folio_batch_release(struct folio_batch * fbatch)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