aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs/inode.c
diff options
context:
space:
mode:
authorChen, Kenneth W <kenneth.w.chen@intel.com>2006-06-23 05:03:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:42:48 -0400
commita43a8c39bbb493c9e93f6764b350de2e33e18e92 (patch)
treea3f0042371810ce6d076751d8e403baaa3d2630e /fs/hugetlbfs/inode.c
parente8f03d02080b25f53cd6bba8dc3a297803f18c01 (diff)
[PATCH] tightening hugetlb strict accounting
Current hugetlb strict accounting for shared mapping always assume mapping starts at zero file offset and reserves pages between zero and size of the file. This assumption often reserves (or lock down) a lot more pages then necessary if application maps at none zero file offset. libhugetlbfs is one example that requires proper reservation on shared mapping starts at none zero offset. This patch extends the reservation and hugetlb strict accounting to support any arbitrary pair of (offset, len), resulting a much more robust and accurate scheme. More importantly, it won't lock down any hugetlb pages outside file mapping. Signed-off-by: Ken Chen <kenneth.w.chen@intel.com> Acked-by: Adam Litke <agl@us.ibm.com> Cc: David Gibson <david@gibson.dropbear.id.au> Cc: William Lee Irwin III <wli@holomorphy.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r--fs/hugetlbfs/inode.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 678fc72c3646..e6410d8edd0e 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -59,7 +59,6 @@ static void huge_pagevec_release(struct pagevec *pvec)
59static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) 59static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
60{ 60{
61 struct inode *inode = file->f_dentry->d_inode; 61 struct inode *inode = file->f_dentry->d_inode;
62 struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode);
63 loff_t len, vma_len; 62 loff_t len, vma_len;
64 int ret; 63 int ret;
65 64
@@ -87,9 +86,10 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
87 if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size) 86 if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
88 goto out; 87 goto out;
89 88
90 if (vma->vm_flags & VM_MAYSHARE) 89 if (vma->vm_flags & VM_MAYSHARE &&
91 if (hugetlb_extend_reservation(info, len >> HPAGE_SHIFT) != 0) 90 hugetlb_reserve_pages(inode, vma->vm_pgoff >> (HPAGE_SHIFT-PAGE_SHIFT),
92 goto out; 91 len >> HPAGE_SHIFT))
92 goto out;
93 93
94 ret = 0; 94 ret = 0;
95 hugetlb_prefault_arch_hook(vma->vm_mm); 95 hugetlb_prefault_arch_hook(vma->vm_mm);
@@ -195,12 +195,8 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
195 const pgoff_t start = lstart >> HPAGE_SHIFT; 195 const pgoff_t start = lstart >> HPAGE_SHIFT;
196 struct pagevec pvec; 196 struct pagevec pvec;
197 pgoff_t next; 197 pgoff_t next;
198 int i; 198 int i, freed = 0;
199 199
200 hugetlb_truncate_reservation(HUGETLBFS_I(inode),
201 lstart >> HPAGE_SHIFT);
202 if (!mapping->nrpages)
203 return;
204 pagevec_init(&pvec, 0); 200 pagevec_init(&pvec, 0);
205 next = start; 201 next = start;
206 while (1) { 202 while (1) {
@@ -221,10 +217,12 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
221 truncate_huge_page(page); 217 truncate_huge_page(page);
222 unlock_page(page); 218 unlock_page(page);
223 hugetlb_put_quota(mapping); 219 hugetlb_put_quota(mapping);
220 freed++;
224 } 221 }
225 huge_pagevec_release(&pvec); 222 huge_pagevec_release(&pvec);
226 } 223 }
227 BUG_ON(!lstart && mapping->nrpages); 224 BUG_ON(!lstart && mapping->nrpages);
225 hugetlb_unreserve_pages(inode, start, freed);
228} 226}
229 227
230static void hugetlbfs_delete_inode(struct inode *inode) 228static void hugetlbfs_delete_inode(struct inode *inode)
@@ -366,6 +364,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
366 inode->i_mapping->a_ops = &hugetlbfs_aops; 364 inode->i_mapping->a_ops = &hugetlbfs_aops;
367 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info; 365 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
368 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 366 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
367 INIT_LIST_HEAD(&inode->i_mapping->private_list);
369 info = HUGETLBFS_I(inode); 368 info = HUGETLBFS_I(inode);
370 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, NULL); 369 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, NULL);
371 switch (mode & S_IFMT) { 370 switch (mode & S_IFMT) {
@@ -538,7 +537,6 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
538 hugetlbfs_inc_free_inodes(sbinfo); 537 hugetlbfs_inc_free_inodes(sbinfo);
539 return NULL; 538 return NULL;
540 } 539 }
541 p->prereserved_hpages = 0;
542 return &p->vfs_inode; 540 return &p->vfs_inode;
543} 541}
544 542
@@ -781,8 +779,7 @@ struct file *hugetlb_zero_setup(size_t size)
781 goto out_file; 779 goto out_file;
782 780
783 error = -ENOMEM; 781 error = -ENOMEM;
784 if (hugetlb_extend_reservation(HUGETLBFS_I(inode), 782 if (hugetlb_reserve_pages(inode, 0, size >> HPAGE_SHIFT))
785 size >> HPAGE_SHIFT) != 0)
786 goto out_inode; 783 goto out_inode;
787 784
788 d_instantiate(dentry, inode); 785 d_instantiate(dentry, inode);