Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * include/linux/pagevec.h
0004  *
0005  * In many places it is efficient to batch an operation up against multiple
0006  * pages.  A pagevec is a multipage container which is used for that.
0007  */
0008 
0009 #ifndef _LINUX_PAGEVEC_H
0010 #define _LINUX_PAGEVEC_H
0011 
0012 #include <linux/xarray.h>
0013 
0014 /* 15 pointers + header align the pagevec structure to a power of two */
0015 #define PAGEVEC_SIZE    15
0016 
0017 struct page;
0018 struct folio;
0019 struct address_space;
0020 
0021 /* Layout must match folio_batch */
0022 struct pagevec {
0023     unsigned char nr;
0024     bool percpu_pvec_drained;
0025     struct page *pages[PAGEVEC_SIZE];
0026 };
0027 
0028 void __pagevec_release(struct pagevec *pvec);
0029 unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
0030         struct address_space *mapping, pgoff_t *index, pgoff_t end,
0031         xa_mark_t tag);
0032 static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
0033         struct address_space *mapping, pgoff_t *index, xa_mark_t tag)
0034 {
0035     return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag);
0036 }
0037 
0038 static inline void pagevec_init(struct pagevec *pvec)
0039 {
0040     pvec->nr = 0;
0041     pvec->percpu_pvec_drained = false;
0042 }
0043 
0044 static inline void pagevec_reinit(struct pagevec *pvec)
0045 {
0046     pvec->nr = 0;
0047 }
0048 
0049 static inline unsigned pagevec_count(struct pagevec *pvec)
0050 {
0051     return pvec->nr;
0052 }
0053 
0054 static inline unsigned pagevec_space(struct pagevec *pvec)
0055 {
0056     return PAGEVEC_SIZE - pvec->nr;
0057 }
0058 
0059 /*
0060  * Add a page to a pagevec.  Returns the number of slots still available.
0061  */
0062 static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page)
0063 {
0064     pvec->pages[pvec->nr++] = page;
0065     return pagevec_space(pvec);
0066 }
0067 
0068 static inline void pagevec_release(struct pagevec *pvec)
0069 {
0070     if (pagevec_count(pvec))
0071         __pagevec_release(pvec);
0072 }
0073 
0074 /**
0075  * struct folio_batch - A collection of folios.
0076  *
0077  * The folio_batch is used to amortise the cost of retrieving and
0078  * operating on a set of folios.  The order of folios in the batch may be
0079  * significant (eg delete_from_page_cache_batch()).  Some users of the
0080  * folio_batch store "exceptional" entries in it which can be removed
0081  * by calling folio_batch_remove_exceptionals().
0082  */
0083 struct folio_batch {
0084     unsigned char nr;
0085     bool percpu_pvec_drained;
0086     struct folio *folios[PAGEVEC_SIZE];
0087 };
0088 
0089 /* Layout must match pagevec */
0090 static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch));
0091 static_assert(offsetof(struct pagevec, pages) ==
0092         offsetof(struct folio_batch, folios));
0093 
0094 /**
0095  * folio_batch_init() - Initialise a batch of folios
0096  * @fbatch: The folio batch.
0097  *
0098  * A freshly initialised folio_batch contains zero folios.
0099  */
0100 static inline void folio_batch_init(struct folio_batch *fbatch)
0101 {
0102     fbatch->nr = 0;
0103     fbatch->percpu_pvec_drained = false;
0104 }
0105 
0106 static inline unsigned int folio_batch_count(struct folio_batch *fbatch)
0107 {
0108     return fbatch->nr;
0109 }
0110 
0111 static inline unsigned int fbatch_space(struct folio_batch *fbatch)
0112 {
0113     return PAGEVEC_SIZE - fbatch->nr;
0114 }
0115 
0116 /**
0117  * folio_batch_add() - Add a folio to a batch.
0118  * @fbatch: The folio batch.
0119  * @folio: The folio to add.
0120  *
0121  * The folio is added to the end of the batch.
0122  * The batch must have previously been initialised using folio_batch_init().
0123  *
0124  * Return: The number of slots still available.
0125  */
0126 static inline unsigned folio_batch_add(struct folio_batch *fbatch,
0127         struct folio *folio)
0128 {
0129     fbatch->folios[fbatch->nr++] = folio;
0130     return fbatch_space(fbatch);
0131 }
0132 
0133 static inline void folio_batch_release(struct folio_batch *fbatch)
0134 {
0135     pagevec_release((struct pagevec *)fbatch);
0136 }
0137 
0138 void folio_batch_remove_exceptionals(struct folio_batch *fbatch);
0139 #endif /* _LINUX_PAGEVEC_H */