Blame view

include/linux/highmem.h 5.42 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  #ifndef _LINUX_HIGHMEM_H
  #define _LINUX_HIGHMEM_H
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
  #include <linux/fs.h>
597781f3e   Cesar Eduardo Barros   kmap_atomic: make...
4
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
  #include <linux/mm.h>
ad76fb6b5   Peter Zijlstra   [PATCH] mm: k{,um...
6
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
  
  #include <asm/cacheflush.h>
03beb0766   James Bottomley   [PATCH] Add API f...
9
  #ifndef ARCH_HAS_FLUSH_ANON_PAGE
a6f36be32   Russell King   [ARM] pass vma fo...
10
  static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
03beb0766   James Bottomley   [PATCH] Add API f...
11
12
13
  {
  }
  #endif
5a3a5a98b   James Bottomley   [PATCH] Add flush...
14
15
16
17
  #ifndef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
  static inline void flush_kernel_dcache_page(struct page *page)
  {
  }
9df5f7419   James Bottomley   mm: add coherence...
18
19
20
21
22
23
  static inline void flush_kernel_vmap_range(void *vaddr, int size)
  {
  }
  static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
  {
  }
5a3a5a98b   James Bottomley   [PATCH] Add flush...
24
  #endif
3688e07f8   Kumar Gala   Fix highmem PPC b...
25
  #include <asm/kmap_types.h>
ff3d58c22   Akinobu Mita   highmem: remove u...
26
  #ifdef CONFIG_DEBUG_HIGHMEM
3688e07f8   Kumar Gala   Fix highmem PPC b...
27
28
29
30
  
  void debug_kmap_atomic(enum km_type type);
  
  #else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

3688e07f8   Kumar Gala   Fix highmem PPC b...
32
33
34
35
36
37
38
  static inline void debug_kmap_atomic(enum km_type type)
  {
  }
  
  #endif
  
  #ifdef CONFIG_HIGHMEM
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
  #include <asm/highmem.h>
  
  /* declarations for linux/mm/highmem.c */
  unsigned int nr_free_highpages(void);
c1f60a5a4   Christoph Lameter   [PATCH] reduce MA...
43
  extern unsigned long totalhigh_pages;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

ce6234b52   Jeremy Fitzhardinge   [PATCH] i386: PAR...
45
  void kmap_flush_unused(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
  #else /* CONFIG_HIGHMEM */
  
  static inline unsigned int nr_free_highpages(void) { return 0; }
4b529401c   Andreas Fenkart   mm: make totalhig...
49
  #define totalhigh_pages 0UL
c1f60a5a4   Christoph Lameter   [PATCH] reduce MA...
50

a6ca1b99e   James Bottomley   [PATCH] update to...
51
  #ifndef ARCH_HAS_KMAP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
56
  static inline void *kmap(struct page *page)
  {
  	might_sleep();
  	return page_address(page);
  }
31c911329   Matthew Wilcox   mm: check the arg...
57
58
59
  static inline void kunmap(struct page *page)
  {
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60

254f9c5cd   Geert Uytterhoeven   Convert non-highm...
61
62
63
64
65
  static inline void *kmap_atomic(struct page *page, enum km_type idx)
  {
  	pagefault_disable();
  	return page_address(page);
  }
ce6234b52   Jeremy Fitzhardinge   [PATCH] i386: PAR...
66
  #define kmap_atomic_prot(page, idx, prot)	kmap_atomic(page, idx)
254f9c5cd   Geert Uytterhoeven   Convert non-highm...
67

4e60c86bd   Andi Kleen   gcc-4.6: mm: fix ...
68
69
70
71
  static inline void kunmap_atomic_notypecheck(void *addr, enum km_type idx)
  {
  	pagefault_enable();
  }
ad76fb6b5   Peter Zijlstra   [PATCH] mm: k{,um...
72
  #define kmap_atomic_pfn(pfn, idx)	kmap_atomic(pfn_to_page(pfn), (idx))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  #define kmap_atomic_to_page(ptr)	virt_to_page(ptr)
ce6234b52   Jeremy Fitzhardinge   [PATCH] i386: PAR...
74
75
  
  #define kmap_flush_unused()	do {} while(0)
a6ca1b99e   James Bottomley   [PATCH] update to...
76
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  
  #endif /* CONFIG_HIGHMEM */
597781f3e   Cesar Eduardo Barros   kmap_atomic: make...
79
80
81
82
83
84
  /* Prevent people trying to call kunmap_atomic() as if it were kunmap() */
  /* kunmap_atomic() should get the return value of kmap_atomic, not the page. */
  #define kunmap_atomic(addr, idx) do { \
  		BUILD_BUG_ON(__same_type((addr), struct page *)); \
  		kunmap_atomic_notypecheck((addr), (idx)); \
  	} while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
487ff3208   Russell King   Allow architectur...
86
  #ifndef clear_user_highpage
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
  static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
  {
  	void *addr = kmap_atomic(page, KM_USER0);
  	clear_user_page(addr, vaddr, page);
  	kunmap_atomic(addr, KM_USER0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  }
487ff3208   Russell King   Allow architectur...
93
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  
  #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
769848c03   Mel Gorman   Add __GFP_MOVABLE...
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  /**
   * __alloc_zeroed_user_highpage - Allocate a zeroed HIGHMEM page for a VMA with caller-specified movable GFP flags
   * @movableflags: The GFP flags related to the pages future ability to move like __GFP_MOVABLE
   * @vma: The VMA the page is to be allocated for
   * @vaddr: The virtual address the page will be inserted into
   *
   * This function will allocate a page for a VMA but the caller is expected
   * to specify via movableflags whether the page will be movable in the
   * future or not
   *
   * An architecture may override this function by defining
   * __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE and providing their own
   * implementation.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  static inline struct page *
769848c03   Mel Gorman   Add __GFP_MOVABLE...
111
112
113
  __alloc_zeroed_user_highpage(gfp_t movableflags,
  			struct vm_area_struct *vma,
  			unsigned long vaddr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  {
769848c03   Mel Gorman   Add __GFP_MOVABLE...
115
116
  	struct page *page = alloc_page_vma(GFP_HIGHUSER | movableflags,
  			vma, vaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
122
123
  
  	if (page)
  		clear_user_highpage(page, vaddr);
  
  	return page;
  }
  #endif
769848c03   Mel Gorman   Add __GFP_MOVABLE...
124
  /**
769848c03   Mel Gorman   Add __GFP_MOVABLE...
125
126
127
128
129
130
131
132
133
134
135
136
137
   * alloc_zeroed_user_highpage_movable - Allocate a zeroed HIGHMEM page for a VMA that the caller knows can move
   * @vma: The VMA the page is to be allocated for
   * @vaddr: The virtual address the page will be inserted into
   *
   * This function will allocate a page for a VMA that the caller knows will
   * be able to migrate in the future using move_pages() or reclaimed
   */
  static inline struct page *
  alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
  					unsigned long vaddr)
  {
  	return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
141
142
143
  static inline void clear_highpage(struct page *page)
  {
  	void *kaddr = kmap_atomic(page, KM_USER0);
  	clear_page(kaddr);
  	kunmap_atomic(kaddr, KM_USER0);
  }
eebd2aa35   Christoph Lameter   Pagecache zeroing...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  static inline void zero_user_segments(struct page *page,
  	unsigned start1, unsigned end1,
  	unsigned start2, unsigned end2)
  {
  	void *kaddr = kmap_atomic(page, KM_USER0);
  
  	BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE);
  
  	if (end1 > start1)
  		memset(kaddr + start1, 0, end1 - start1);
  
  	if (end2 > start2)
  		memset(kaddr + start2, 0, end2 - start2);
  
  	kunmap_atomic(kaddr, KM_USER0);
  	flush_dcache_page(page);
  }
  
  static inline void zero_user_segment(struct page *page,
  	unsigned start, unsigned end)
  {
  	zero_user_segments(page, start, end, 0, 0);
  }
  
  static inline void zero_user(struct page *page,
  	unsigned start, unsigned size)
  {
  	zero_user_segments(page, start, start + size, 0, 0);
  }
01f2705da   Nate Diller   fs: convert core ...
173

f37bc2712   Nate Diller   fs: deprecate mem...
174
  static inline void __deprecated memclear_highpage_flush(struct page *page,
01f2705da   Nate Diller   fs: convert core ...
175
  			unsigned int offset, unsigned int size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  {
eebd2aa35   Christoph Lameter   Pagecache zeroing...
177
  	zero_user(page, offset, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
  }
77fff4ae2   Atsushi Nemoto   [PATCH] Fix COW D...
179
  #ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
9de455b20   Atsushi Nemoto   [PATCH] Pass vma ...
180
181
  static inline void copy_user_highpage(struct page *to, struct page *from,
  	unsigned long vaddr, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
185
186
187
188
189
  {
  	char *vfrom, *vto;
  
  	vfrom = kmap_atomic(from, KM_USER0);
  	vto = kmap_atomic(to, KM_USER1);
  	copy_user_page(vto, vfrom, vaddr, to);
  	kunmap_atomic(vfrom, KM_USER0);
  	kunmap_atomic(vto, KM_USER1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  }
77fff4ae2   Atsushi Nemoto   [PATCH] Fix COW D...
191
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
196
197
198
199
200
201
202
203
  static inline void copy_highpage(struct page *to, struct page *from)
  {
  	char *vfrom, *vto;
  
  	vfrom = kmap_atomic(from, KM_USER0);
  	vto = kmap_atomic(to, KM_USER1);
  	copy_page(vto, vfrom);
  	kunmap_atomic(vfrom, KM_USER0);
  	kunmap_atomic(vto, KM_USER1);
  }
  
  #endif /* _LINUX_HIGHMEM_H */