cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pagevec.h (3892B)


      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 * pages.  A pagevec is a multipage container which is used for that.
      7 */
      8
      9#ifndef _LINUX_PAGEVEC_H
     10#define _LINUX_PAGEVEC_H
     11
     12#include <linux/xarray.h>
     13
     14/* 15 pointers + header align the pagevec structure to a power of two */
     15#define PAGEVEC_SIZE	15
     16
     17struct page;
     18struct folio;
     19struct address_space;
     20
     21/* Layout must match folio_batch */
     22struct pagevec {
     23	unsigned char nr;
     24	bool percpu_pvec_drained;
     25	struct page *pages[PAGEVEC_SIZE];
     26};
     27
     28void __pagevec_release(struct pagevec *pvec);
     29void __pagevec_lru_add(struct pagevec *pvec);
     30unsigned pagevec_lookup_range(struct pagevec *pvec,
     31			      struct address_space *mapping,
     32			      pgoff_t *start, pgoff_t end);
     33static inline unsigned pagevec_lookup(struct pagevec *pvec,
     34				      struct address_space *mapping,
     35				      pgoff_t *start)
     36{
     37	return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1);
     38}
     39
     40unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
     41		struct address_space *mapping, pgoff_t *index, pgoff_t end,
     42		xa_mark_t tag);
     43static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
     44		struct address_space *mapping, pgoff_t *index, xa_mark_t tag)
     45{
     46	return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag);
     47}
     48
     49static inline void pagevec_init(struct pagevec *pvec)
     50{
     51	pvec->nr = 0;
     52	pvec->percpu_pvec_drained = false;
     53}
     54
     55static inline void pagevec_reinit(struct pagevec *pvec)
     56{
     57	pvec->nr = 0;
     58}
     59
     60static inline unsigned pagevec_count(struct pagevec *pvec)
     61{
     62	return pvec->nr;
     63}
     64
     65static inline unsigned pagevec_space(struct pagevec *pvec)
     66{
     67	return PAGEVEC_SIZE - pvec->nr;
     68}
     69
     70/*
     71 * Add a page to a pagevec.  Returns the number of slots still available.
     72 */
     73static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page)
     74{
     75	pvec->pages[pvec->nr++] = page;
     76	return pagevec_space(pvec);
     77}
     78
     79static inline void pagevec_release(struct pagevec *pvec)
     80{
     81	if (pagevec_count(pvec))
     82		__pagevec_release(pvec);
     83}
     84
     85/**
     86 * struct folio_batch - A collection of folios.
     87 *
     88 * The folio_batch is used to amortise the cost of retrieving and
     89 * operating on a set of folios.  The order of folios in the batch may be
     90 * significant (eg delete_from_page_cache_batch()).  Some users of the
     91 * folio_batch store "exceptional" entries in it which can be removed
     92 * by calling folio_batch_remove_exceptionals().
     93 */
     94struct folio_batch {
     95	unsigned char nr;
     96	bool percpu_pvec_drained;
     97	struct folio *folios[PAGEVEC_SIZE];
     98};
     99
    100/* Layout must match pagevec */
    101static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch));
    102static_assert(offsetof(struct pagevec, pages) ==
    103		offsetof(struct folio_batch, folios));
    104
    105/**
    106 * folio_batch_init() - Initialise a batch of folios
    107 * @fbatch: The folio batch.
    108 *
    109 * A freshly initialised folio_batch contains zero folios.
    110 */
    111static inline void folio_batch_init(struct folio_batch *fbatch)
    112{
    113	fbatch->nr = 0;
    114	fbatch->percpu_pvec_drained = false;
    115}
    116
    117static inline unsigned int folio_batch_count(struct folio_batch *fbatch)
    118{
    119	return fbatch->nr;
    120}
    121
    122static inline unsigned int fbatch_space(struct folio_batch *fbatch)
    123{
    124	return PAGEVEC_SIZE - fbatch->nr;
    125}
    126
    127/**
    128 * folio_batch_add() - Add a folio to a batch.
    129 * @fbatch: The folio batch.
    130 * @folio: The folio to add.
    131 *
    132 * The folio is added to the end of the batch.
    133 * The batch must have previously been initialised using folio_batch_init().
    134 *
    135 * Return: The number of slots still available.
    136 */
    137static inline unsigned folio_batch_add(struct folio_batch *fbatch,
    138		struct folio *folio)
    139{
    140	fbatch->folios[fbatch->nr++] = folio;
    141	return fbatch_space(fbatch);
    142}
    143
    144static inline void folio_batch_release(struct folio_batch *fbatch)
    145{
    146	pagevec_release((struct pagevec *)fbatch);
    147}
    148
    149void folio_batch_remove_exceptionals(struct folio_batch *fbatch);
    150#endif /* _LINUX_PAGEVEC_H */