summaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/include/linux/pagevec.h
blob: 0a952e965b5a6f282e408f006f4707dfdaa592f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* Public domain. */

#ifndef	_LINUXKPI_LINUX_PAGEVEC_H_
#define	_LINUXKPI_LINUX_PAGEVEC_H_

#include <sys/types.h>
#include <sys/systm.h>
#include <sys/errno.h>

#include <linux/pagemap.h>

#define PAGEVEC_SIZE 15

struct pagevec {
	uint8_t	nr;
	struct page *pages[PAGEVEC_SIZE];
};

static inline unsigned int
pagevec_space(struct pagevec *pvec)
{
	return PAGEVEC_SIZE - pvec->nr;
}

static inline void
pagevec_init(struct pagevec *pvec)
{
	pvec->nr = 0;
}

static inline void
pagevec_reinit(struct pagevec *pvec)
{
	pvec->nr = 0;
}

static inline unsigned int
pagevec_count(struct pagevec *pvec)
{
	return pvec->nr;
}

static inline unsigned int
pagevec_add(struct pagevec *pvec, struct page *page)
{
	pvec->pages[pvec->nr++] = page;
	return PAGEVEC_SIZE - pvec->nr;
}

static inline void
__pagevec_release(struct pagevec *pvec)
{
	release_pages(pvec->pages, pagevec_count(pvec));
	pagevec_reinit(pvec);
}

static inline void
pagevec_release(struct pagevec *pvec)
{
	if (pagevec_count(pvec))
		__pagevec_release(pvec);
}

static inline void
check_move_unevictable_pages(struct pagevec *pvec)
{
}

/*
 * struct folio
 *
 * On Linux, `struct folio` replaces `struct page`. To manage a list of folios,
 * there is `struct folio_batch` on top of this, which replaces `struct
 * pagevec` above.
 *
 * Here is the original description when `struct folio` was added to the Linux
 * kernel:
 *   "A struct folio is a new abstraction to replace the venerable struct page.
 *   A function which takes a struct folio argument declares that it will
 *   operate on the entire (possibly compound) page, not just PAGE_SIZE bytes.
 *   In return, the caller guarantees that the pointer it is passing does not
 *   point to a tail page.  No change to generated code."
 */

struct folio;

struct folio_batch {
	uint8_t	nr;
	struct folio *folios[PAGEVEC_SIZE];
};

static inline void
folio_batch_init(struct folio_batch *fbatch)
{
	fbatch->nr = 0;
}

static inline void
folio_batch_reinit(struct folio_batch *fbatch)
{
	fbatch->nr = 0;
}

static inline unsigned int
folio_batch_count(struct folio_batch *fbatch)
{
	return (fbatch->nr);
}

static inline unsigned int
folio_batch_space(struct folio_batch *fbatch)
{
	return (PAGEVEC_SIZE - fbatch->nr);
}

static inline unsigned int
folio_batch_add(struct folio_batch *fbatch, struct folio *folio)
{
	KASSERT(
	    fbatch->nr < PAGEVEC_SIZE,
	    ("struct folio_batch %p is full", fbatch));

	fbatch->folios[fbatch->nr++] = folio;

	return (folio_batch_space(fbatch));
}

void __folio_batch_release(struct folio_batch *fbatch);

static inline void
folio_batch_release(struct folio_batch *fbatch)
{
	if (folio_batch_count(fbatch))
		__folio_batch_release(fbatch);
}

#endif	/* _LINUXKPI_LINUX_PAGEVEC_H_ */