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 | * folios. A folio_batch is a container which is used for that. |
7 | */ |
8 | |
9 | #ifndef _LINUX_PAGEVEC_H |
10 | #define _LINUX_PAGEVEC_H |
11 | |
12 | #include <linux/types.h> |
13 | |
14 | /* 15 pointers + header align the folio_batch structure to a power of two */ |
15 | #define PAGEVEC_SIZE 15 |
16 | |
17 | struct folio; |
18 | |
19 | /** |
20 | * struct folio_batch - A collection of folios. |
21 | * |
22 | * The folio_batch is used to amortise the cost of retrieving and |
23 | * operating on a set of folios. The order of folios in the batch may be |
24 | * significant (eg delete_from_page_cache_batch()). Some users of the |
25 | * folio_batch store "exceptional" entries in it which can be removed |
26 | * by calling folio_batch_remove_exceptionals(). |
27 | */ |
28 | struct folio_batch { |
29 | unsigned char nr; |
30 | bool percpu_pvec_drained; |
31 | struct folio *folios[PAGEVEC_SIZE]; |
32 | }; |
33 | |
34 | /** |
35 | * folio_batch_init() - Initialise a batch of folios |
36 | * @fbatch: The folio batch. |
37 | * |
38 | * A freshly initialised folio_batch contains zero folios. |
39 | */ |
40 | static inline void folio_batch_init(struct folio_batch *fbatch) |
41 | { |
42 | fbatch->nr = 0; |
43 | fbatch->percpu_pvec_drained = false; |
44 | } |
45 | |
46 | static inline void folio_batch_reinit(struct folio_batch *fbatch) |
47 | { |
48 | fbatch->nr = 0; |
49 | } |
50 | |
51 | static inline unsigned int folio_batch_count(struct folio_batch *fbatch) |
52 | { |
53 | return fbatch->nr; |
54 | } |
55 | |
56 | static inline unsigned int folio_batch_space(struct folio_batch *fbatch) |
57 | { |
58 | return PAGEVEC_SIZE - fbatch->nr; |
59 | } |
60 | |
61 | /** |
62 | * folio_batch_add() - Add a folio to a batch. |
63 | * @fbatch: The folio batch. |
64 | * @folio: The folio to add. |
65 | * |
66 | * The folio is added to the end of the batch. |
67 | * The batch must have previously been initialised using folio_batch_init(). |
68 | * |
69 | * Return: The number of slots still available. |
70 | */ |
71 | static inline unsigned folio_batch_add(struct folio_batch *fbatch, |
72 | struct folio *folio) |
73 | { |
74 | fbatch->folios[fbatch->nr++] = folio; |
75 | return folio_batch_space(fbatch); |
76 | } |
77 | |
78 | void __folio_batch_release(struct folio_batch *pvec); |
79 | |
80 | static inline void folio_batch_release(struct folio_batch *fbatch) |
81 | { |
82 | if (folio_batch_count(fbatch)) |
83 | __folio_batch_release(pvec: fbatch); |
84 | } |
85 | |
86 | void folio_batch_remove_exceptionals(struct folio_batch *fbatch); |
87 | #endif /* _LINUX_PAGEVEC_H */ |
88 | |