Merge tag 'mm-hotfixes-stable-2023-05-03-16-27' of git://git.kernel.org/pub/scm/linux...
[linux-block.git] / include / linux / pagevec.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
1da177e4
LT
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
78854014
DH
9#ifndef _LINUX_PAGEVEC_H
10#define _LINUX_PAGEVEC_H
11
10bbd235
MW
12#include <linux/xarray.h>
13
146500e9
MW
14/* 15 pointers + header align the pagevec structure to a power of two */
15#define PAGEVEC_SIZE 15
1da177e4
LT
16
17struct page;
10331795 18struct folio;
1da177e4
LT
19struct address_space;
20
10331795 21/* Layout must match folio_batch */
1da177e4 22struct pagevec {
146500e9 23 unsigned char nr;
7f0b5fb9 24 bool percpu_pvec_drained;
1da177e4
LT
25 struct page *pages[PAGEVEC_SIZE];
26};
27
28void __pagevec_release(struct pagevec *pvec);
1da177e4 29
86679820 30static inline void pagevec_init(struct pagevec *pvec)
1da177e4
LT
31{
32 pvec->nr = 0;
7f0b5fb9 33 pvec->percpu_pvec_drained = false;
1da177e4
LT
34}
35
36static inline void pagevec_reinit(struct pagevec *pvec)
37{
38 pvec->nr = 0;
39}
40
41static inline unsigned pagevec_count(struct pagevec *pvec)
42{
43 return pvec->nr;
44}
45
46static inline unsigned pagevec_space(struct pagevec *pvec)
47{
48 return PAGEVEC_SIZE - pvec->nr;
49}
50
51/*
52 * Add a page to a pagevec. Returns the number of slots still available.
53 */
54static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page)
55{
56 pvec->pages[pvec->nr++] = page;
57 return pagevec_space(pvec);
58}
59
1da177e4
LT
60static inline void pagevec_release(struct pagevec *pvec)
61{
62 if (pagevec_count(pvec))
63 __pagevec_release(pvec);
64}
65
10331795
MWO
66/**
67 * struct folio_batch - A collection of folios.
68 *
69 * The folio_batch is used to amortise the cost of retrieving and
70 * operating on a set of folios. The order of folios in the batch may be
71 * significant (eg delete_from_page_cache_batch()). Some users of the
72 * folio_batch store "exceptional" entries in it which can be removed
73 * by calling folio_batch_remove_exceptionals().
74 */
75struct folio_batch {
76 unsigned char nr;
77 bool percpu_pvec_drained;
78 struct folio *folios[PAGEVEC_SIZE];
79};
80
81/* Layout must match pagevec */
82static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch));
83static_assert(offsetof(struct pagevec, pages) ==
84 offsetof(struct folio_batch, folios));
85
86/**
87 * folio_batch_init() - Initialise a batch of folios
88 * @fbatch: The folio batch.
89 *
90 * A freshly initialised folio_batch contains zero folios.
91 */
92static inline void folio_batch_init(struct folio_batch *fbatch)
93{
94 fbatch->nr = 0;
6840f909 95 fbatch->percpu_pvec_drained = false;
10331795
MWO
96}
97
81156128
LS
98static inline void folio_batch_reinit(struct folio_batch *fbatch)
99{
100 fbatch->nr = 0;
101}
102
10331795
MWO
103static inline unsigned int folio_batch_count(struct folio_batch *fbatch)
104{
105 return fbatch->nr;
106}
107
108static inline unsigned int fbatch_space(struct folio_batch *fbatch)
109{
110 return PAGEVEC_SIZE - fbatch->nr;
111}
112
113/**
114 * folio_batch_add() - Add a folio to a batch.
115 * @fbatch: The folio batch.
116 * @folio: The folio to add.
117 *
118 * The folio is added to the end of the batch.
119 * The batch must have previously been initialised using folio_batch_init().
120 *
121 * Return: The number of slots still available.
122 */
123static inline unsigned folio_batch_add(struct folio_batch *fbatch,
124 struct folio *folio)
125{
126 fbatch->folios[fbatch->nr++] = folio;
127 return fbatch_space(fbatch);
128}
129
130static inline void folio_batch_release(struct folio_batch *fbatch)
131{
132 pagevec_release((struct pagevec *)fbatch);
133}
134
1613fac9 135void folio_batch_remove_exceptionals(struct folio_batch *fbatch);
78854014 136#endif /* _LINUX_PAGEVEC_H */