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