aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-07-24 00:27:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:17 -0400
commita5516438959d90b071ff0a484ce4f3f523dc3152 (patch)
treee356ba9364c76b93c176b4d4a262b7aca3ee8f91 /include
parentb7ba30c679ed1eb7ed3ed8f281f6493282042bd4 (diff)
hugetlb: modular state for hugetlb page size
The goal of this patchset is to support multiple hugetlb page sizes. This is achieved by introducing a new struct hstate structure, which encapsulates the important hugetlb state and constants (eg. huge page size, number of huge pages currently allocated, etc). The hstate structure is then passed around the code which requires these fields, they will do the right thing regardless of the exact hstate they are operating on. This patch adds the hstate structure, with a single global instance of it (default_hstate), and does the basic work of converting hugetlb to use the hstate. Future patches will add more hstate structures to allow for different hugetlbfs mounts to have different page sizes. [akpm@linux-foundation.org: coding-style fixes] Acked-by: Adam Litke <agl@us.ibm.com> Acked-by: Nishanth Aravamudan <nacc@us.ibm.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-ia64/hugetlb.h3
-rw-r--r--include/asm-powerpc/hugetlb.h3
-rw-r--r--include/asm-s390/hugetlb.h3
-rw-r--r--include/asm-sh/hugetlb.h3
-rw-r--r--include/asm-sparc/hugetlb.h3
-rw-r--r--include/asm-x86/hugetlb.h8
-rw-r--r--include/linux/hugetlb.h88
7 files changed, 98 insertions, 13 deletions
diff --git a/include/asm-ia64/hugetlb.h b/include/asm-ia64/hugetlb.h
index e9d1e5e2382d..da55c63728e0 100644
--- a/include/asm-ia64/hugetlb.h
+++ b/include/asm-ia64/hugetlb.h
@@ -8,7 +8,8 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
8 unsigned long end, unsigned long floor, 8 unsigned long end, unsigned long floor,
9 unsigned long ceiling); 9 unsigned long ceiling);
10 10
11int prepare_hugepage_range(unsigned long addr, unsigned long len); 11int prepare_hugepage_range(struct file *file,
12 unsigned long addr, unsigned long len);
12 13
13static inline int is_hugepage_only_range(struct mm_struct *mm, 14static inline int is_hugepage_only_range(struct mm_struct *mm,
14 unsigned long addr, 15 unsigned long addr,
diff --git a/include/asm-powerpc/hugetlb.h b/include/asm-powerpc/hugetlb.h
index 0a37aa5ecaa5..ca37c4af27b1 100644
--- a/include/asm-powerpc/hugetlb.h
+++ b/include/asm-powerpc/hugetlb.h
@@ -21,7 +21,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
21 * If the arch doesn't supply something else, assume that hugepage 21 * If the arch doesn't supply something else, assume that hugepage
22 * size aligned regions are ok without further preparation. 22 * size aligned regions are ok without further preparation.
23 */ 23 */
24static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) 24static inline int prepare_hugepage_range(struct file *file,
25 unsigned long addr, unsigned long len)
25{ 26{
26 if (len & ~HPAGE_MASK) 27 if (len & ~HPAGE_MASK)
27 return -EINVAL; 28 return -EINVAL;
diff --git a/include/asm-s390/hugetlb.h b/include/asm-s390/hugetlb.h
index 600a776f8f75..670a1d1745d2 100644
--- a/include/asm-s390/hugetlb.h
+++ b/include/asm-s390/hugetlb.h
@@ -22,7 +22,8 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
22 * If the arch doesn't supply something else, assume that hugepage 22 * If the arch doesn't supply something else, assume that hugepage
23 * size aligned regions are ok without further preparation. 23 * size aligned regions are ok without further preparation.
24 */ 24 */
25static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) 25static inline int prepare_hugepage_range(struct file *file,
26 unsigned long addr, unsigned long len)
26{ 27{
27 if (len & ~HPAGE_MASK) 28 if (len & ~HPAGE_MASK)
28 return -EINVAL; 29 return -EINVAL;
diff --git a/include/asm-sh/hugetlb.h b/include/asm-sh/hugetlb.h
index fb30018938c7..967068fb79ac 100644
--- a/include/asm-sh/hugetlb.h
+++ b/include/asm-sh/hugetlb.h
@@ -14,7 +14,8 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
14 * If the arch doesn't supply something else, assume that hugepage 14 * If the arch doesn't supply something else, assume that hugepage
15 * size aligned regions are ok without further preparation. 15 * size aligned regions are ok without further preparation.
16 */ 16 */
17static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) 17static inline int prepare_hugepage_range(struct file *file,
18 unsigned long addr, unsigned long len)
18{ 19{
19 if (len & ~HPAGE_MASK) 20 if (len & ~HPAGE_MASK)
20 return -EINVAL; 21 return -EINVAL;
diff --git a/include/asm-sparc/hugetlb.h b/include/asm-sparc/hugetlb.h
index aeb92374ca3d..177061064ee6 100644
--- a/include/asm-sparc/hugetlb.h
+++ b/include/asm-sparc/hugetlb.h
@@ -22,7 +22,8 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
22 * If the arch doesn't supply something else, assume that hugepage 22 * If the arch doesn't supply something else, assume that hugepage
23 * size aligned regions are ok without further preparation. 23 * size aligned regions are ok without further preparation.
24 */ 24 */
25static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) 25static inline int prepare_hugepage_range(struct file *file,
26 unsigned long addr, unsigned long len)
26{ 27{
27 if (len & ~HPAGE_MASK) 28 if (len & ~HPAGE_MASK)
28 return -EINVAL; 29 return -EINVAL;
diff --git a/include/asm-x86/hugetlb.h b/include/asm-x86/hugetlb.h
index 7eed6e0883bf..439a9acc132d 100644
--- a/include/asm-x86/hugetlb.h
+++ b/include/asm-x86/hugetlb.h
@@ -14,11 +14,13 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
14 * If the arch doesn't supply something else, assume that hugepage 14 * If the arch doesn't supply something else, assume that hugepage
15 * size aligned regions are ok without further preparation. 15 * size aligned regions are ok without further preparation.
16 */ 16 */
17static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) 17static inline int prepare_hugepage_range(struct file *file,
18 unsigned long addr, unsigned long len)
18{ 19{
19 if (len & ~HPAGE_MASK) 20 struct hstate *h = hstate_file(file);
21 if (len & ~huge_page_mask(h))
20 return -EINVAL; 22 return -EINVAL;
21 if (addr & ~HPAGE_MASK) 23 if (addr & ~huge_page_mask(h))
22 return -EINVAL; 24 return -EINVAL;
23 return 0; 25 return 0;
24} 26}
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index abbc187193a1..ad2271e11f9b 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -8,7 +8,6 @@
8#include <linux/mempolicy.h> 8#include <linux/mempolicy.h>
9#include <linux/shm.h> 9#include <linux/shm.h>
10#include <asm/tlbflush.h> 10#include <asm/tlbflush.h>
11#include <asm/hugetlb.h>
12 11
13struct ctl_table; 12struct ctl_table;
14 13
@@ -45,7 +44,8 @@ extern int sysctl_hugetlb_shm_group;
45 44
46/* arch callbacks */ 45/* arch callbacks */
47 46
48pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr); 47pte_t *huge_pte_alloc(struct mm_struct *mm,
48 unsigned long addr, unsigned long sz);
49pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr); 49pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr);
50int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep); 50int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep);
51struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, 51struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
@@ -80,7 +80,7 @@ static inline unsigned long hugetlb_total_pages(void)
80#define hugetlb_report_meminfo(buf) 0 80#define hugetlb_report_meminfo(buf) 0
81#define hugetlb_report_node_meminfo(n, buf) 0 81#define hugetlb_report_node_meminfo(n, buf) 0
82#define follow_huge_pmd(mm, addr, pmd, write) NULL 82#define follow_huge_pmd(mm, addr, pmd, write) NULL
83#define prepare_hugepage_range(addr,len) (-EINVAL) 83#define prepare_hugepage_range(file, addr, len) (-EINVAL)
84#define pmd_huge(x) 0 84#define pmd_huge(x) 0
85#define is_hugepage_only_range(mm, addr, len) 0 85#define is_hugepage_only_range(mm, addr, len) 0
86#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; }) 86#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; })
@@ -134,8 +134,6 @@ struct file *hugetlb_file_setup(const char *name, size_t);
134int hugetlb_get_quota(struct address_space *mapping, long delta); 134int hugetlb_get_quota(struct address_space *mapping, long delta);
135void hugetlb_put_quota(struct address_space *mapping, long delta); 135void hugetlb_put_quota(struct address_space *mapping, long delta);
136 136
137#define BLOCKS_PER_HUGEPAGE (HPAGE_SIZE / 512)
138
139static inline int is_file_hugepages(struct file *file) 137static inline int is_file_hugepages(struct file *file)
140{ 138{
141 if (file->f_op == &hugetlbfs_file_operations) 139 if (file->f_op == &hugetlbfs_file_operations)
@@ -164,4 +162,84 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
164 unsigned long flags); 162 unsigned long flags);
165#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */ 163#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
166 164
165#ifdef CONFIG_HUGETLB_PAGE
166
167/* Defines one hugetlb page size */
168struct hstate {
169 int hugetlb_next_nid;
170 unsigned int order;
171 unsigned long mask;
172 unsigned long max_huge_pages;
173 unsigned long nr_huge_pages;
174 unsigned long free_huge_pages;
175 unsigned long resv_huge_pages;
176 unsigned long surplus_huge_pages;
177 unsigned long nr_overcommit_huge_pages;
178 struct list_head hugepage_freelists[MAX_NUMNODES];
179 unsigned int nr_huge_pages_node[MAX_NUMNODES];
180 unsigned int free_huge_pages_node[MAX_NUMNODES];
181 unsigned int surplus_huge_pages_node[MAX_NUMNODES];
182};
183
184extern struct hstate default_hstate;
185
186static inline struct hstate *hstate_vma(struct vm_area_struct *vma)
187{
188 return &default_hstate;
189}
190
191static inline struct hstate *hstate_file(struct file *f)
192{
193 return &default_hstate;
194}
195
196static inline struct hstate *hstate_inode(struct inode *i)
197{
198 return &default_hstate;
199}
200
201static inline unsigned long huge_page_size(struct hstate *h)
202{
203 return (unsigned long)PAGE_SIZE << h->order;
204}
205
206static inline unsigned long huge_page_mask(struct hstate *h)
207{
208 return h->mask;
209}
210
211static inline unsigned int huge_page_order(struct hstate *h)
212{
213 return h->order;
214}
215
216static inline unsigned huge_page_shift(struct hstate *h)
217{
218 return h->order + PAGE_SHIFT;
219}
220
221static inline unsigned int pages_per_huge_page(struct hstate *h)
222{
223 return 1 << h->order;
224}
225
226static inline unsigned int blocks_per_huge_page(struct hstate *h)
227{
228 return huge_page_size(h) / 512;
229}
230
231#include <asm/hugetlb.h>
232
233#else
234struct hstate {};
235#define hstate_file(f) NULL
236#define hstate_vma(v) NULL
237#define hstate_inode(i) NULL
238#define huge_page_size(h) PAGE_SIZE
239#define huge_page_mask(h) PAGE_MASK
240#define huge_page_order(h) 0
241#define huge_page_shift(h) PAGE_SHIFT
242#define pages_per_huge_page(h) 1
243#endif
244
167#endif /* _LINUX_HUGETLB_H */ 245#endif /* _LINUX_HUGETLB_H */