XenevaOS
Loading...
Searching...
No Matches
XenevaOS
BaseHdr
linux
pagemap.h
Go to the documentation of this file.
1
#ifndef __LINUX_PAGEMAP_H__
2
#define __LINUX_PAGEMAP_H__
3
4
/*
5
* DCL <linux/pagemap.h> -- the eight page primitives virtio_console.c uses.
6
*
7
* mainline's is 50 KB and its first include is <linux/mm.h>, which is the
8
* whole memory-management subsystem (rmap, page tables, compaction, the NUMA
9
* balancing state reached through gfp.h). The driver's entire contact with
10
* the page model is:
11
*
12
* alloc_page(GFP_KERNEL) :875 splice fallback buffer
13
* page_address(page) :888 destination of the copy
14
* kmap_local_page / kunmap :887 source window over pipe_buffer.page
15
* get_page / put_page :868 refcount, and free_buf()'s release loop
16
* lock_page / unlock_page :869 taken around the steal
17
* sg_page / sg_set_page :354 <linux/scatterlist.h>, which is DCL's own
18
* PAGE_SIZE / PAGE_MASK :884 <Mm/vmmngr.h>, Xeneva's native geometry
19
*
20
* so this header defines exactly that and nothing else.
21
*
22
* The page *contents* live inside struct page itself. DCL has no buddy-to-
23
* struct-page array and no virtual-address lookup, and splice is not routed
24
* by the devfs bridge yet (see <linux/splice.h>), so the honest shape for a
25
* page here is one kmalloc'd block that is both the descriptor and the
26
* storage. alloc_page() therefore returns a block whose ->data is what
27
* page_address() hands out, which is an ordinary kernel heap pointer -- the
28
* same kind of pointer that sg_init_one() already feeds to the virtio queue,
29
* so the DMA translation in DCL/virtio_shim.c needs no new case for it.
30
*/
31
32
#include <
linux/gfp.h
>
33
#include <
linux/types.h
>
34
#include <
linux/mm.h
>
/* DCL's hub header: uaccess (copy_*_user),
35
* register_chrdev, min/ARRAY_SIZE, PAGE_SIZE */
36
#include <
Mm/vmmngr.h
>
/* PAGE_SHIFT, PAGE_SIZE, PAGE_MASK */
37
38
struct
page
{
39
unsigned
int
refcount
;
40
char
data
[
PAGE_SIZE
];
41
};
42
43
/*
44
* page_address(page) -- the data block of a struct page.
45
*
46
* It used to be spelled `((page)->data)`, which is right for every call that
47
* passes a `struct page *` and wrong the moment anything else does: a member
48
* reference through a `void *` argument is a hard error (one `->` on a void
49
* base), and virtio_console.c:887 passes `buf->page` from <linux/splice.h>,
50
* where the field is `void *` because DCL's pipe_buffer has no page array
51
* behind it. Adding the offset instead of dereferencing answers both forms
52
* with one expression, and it answers them the same way -- __builtin_offsetof
53
* needs no <stddef.h> and gives the exact displacement the `->` did.
54
*
55
* The argument is still read as a struct page pointer, which is what it is:
56
* the alternative (treating it as a raw buffer) would silently shift a real
57
* page by the refcount's four bytes.
58
*/
59
/*
60
* The parameter is named `p`, not `page`: a macro argument replaces every
61
* token that spells it, including the one in `struct page` two lines down,
62
* and `__builtin_offsetof(struct p, data)` is a diagnostic about an expected
63
* comma at an expression that was never meant to hold one.
64
*/
65
#define page_address(p) \
66
((void*)((char*)(void*)(p) + __builtin_offsetof(struct page, data)))
67
#define lowmem_page_address(page) page_address(page)
68
69
/*
70
* kmap_local_page / kunmap_local -- mainline maps the page into the caller's
71
* address space for the duration of the statement. DCL's kernel is a single
72
* flat higher-half mapping, so a page's address is already its address: the
73
* map is the identity and the unmap is a statement that has to stay, because
74
* the driver writes it and it has to parse.
75
*/
76
#define kmap_local_page(page) page_address(page)
77
#define kunmap_local(addr) ((void)(addr))
78
79
void
*
alloc_page
(
gfp_t
gfp);
80
81
/*
82
* Refcounts are real: alloc_page() starts at 1, get_page() adds one,
83
* put_page() drops one and frees at zero, which is the contract free_buf()
84
* relies on at :350-357 (it walks sgpages and releases each page exactly
85
* once).
86
*/
87
void
get_page
(
struct
page
*
page
);
88
void
put_page
(
struct
page
*
page
);
89
90
/*
91
* lock_page / unlock_page -- no-ops, deliberately. The only pair in the
92
* driver is :868-869, inside pipe_to_sg(), which runs only when splice is
93
* actually routed, and the devfs bridge does not route it yet. Making them
94
* real would mean a per-page waitqueue for a path that cannot be entered;
95
* a no-op here is the same class of decision as device_find_child() ->
96
* NULL and pm_runtime_enabled() -> 0. If splice is ever wired up, this is
97
* the one line in this file that has to change.
98
*/
99
void
lock_page
(
struct
page
*
page
);
100
void
unlock_page
(
struct
page
*
page
);
101
102
#endif
/* __LINUX_PAGEMAP_H__ */
vmmngr.h
PAGE_SIZE
#define PAGE_SIZE
Definition
vmmngr.h:92
types.h
gfp.h
gfp_t
unsigned int gfp_t
Definition
kernel.h:56
mm.h
lock_page
void lock_page(struct page *page)
get_page
void get_page(struct page *page)
alloc_page
void * alloc_page(gfp_t gfp)
unlock_page
void unlock_page(struct page *page)
put_page
void put_page(struct page *page)
page
Definition
pagemap.h:38
page::data
char data[PAGE_SIZE]
Definition
pagemap.h:40
page::refcount
unsigned int refcount
Definition
pagemap.h:39
Generated by
1.9.8