aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 12:04:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 12:04:48 -0400
commit95211279c5ad00a317c98221d7e4365e02f20836 (patch)
tree2ddc8625378d2915b8c96392f3cf6663b705ed55 /fs/hugetlbfs
parent5375871d432ae9fc581014ac117b96aaee3cd0c7 (diff)
parent12724850e8064f64b6223d26d78c0597c742c65a (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge first batch of patches from Andrew Morton: "A few misc things and all the MM queue" * emailed from Andrew Morton <akpm@linux-foundation.org>: (92 commits) memcg: avoid THP split in task migration thp: add HPAGE_PMD_* definitions for !CONFIG_TRANSPARENT_HUGEPAGE memcg: clean up existing move charge code mm/memcontrol.c: remove unnecessary 'break' in mem_cgroup_read() mm/memcontrol.c: remove redundant BUG_ON() in mem_cgroup_usage_unregister_event() mm/memcontrol.c: s/stealed/stolen/ memcg: fix performance of mem_cgroup_begin_update_page_stat() memcg: remove PCG_FILE_MAPPED memcg: use new logic for page stat accounting memcg: remove PCG_MOVE_LOCK flag from page_cgroup memcg: simplify move_account() check memcg: remove EXPORT_SYMBOL(mem_cgroup_update_page_stat) memcg: kill dead prev_priority stubs memcg: remove PCG_CACHE page_cgroup flag memcg: let css_get_next() rely upon rcu_read_lock() cgroup: revert ss_id_lock to spinlock idr: make idr_get_next() good for rcu_read_lock() memcg: remove unnecessary thp check in page stat accounting memcg: remove redundant returns memcg: enum lru_list lru ...
Diffstat (limited to 'fs/hugetlbfs')
-rw-r--r--fs/hugetlbfs/inode.c138
1 files changed, 77 insertions, 61 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 81932fa1861a..ea251749d9d5 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -41,6 +41,25 @@ const struct file_operations hugetlbfs_file_operations;
41static const struct inode_operations hugetlbfs_dir_inode_operations; 41static const struct inode_operations hugetlbfs_dir_inode_operations;
42static const struct inode_operations hugetlbfs_inode_operations; 42static const struct inode_operations hugetlbfs_inode_operations;
43 43
44struct hugetlbfs_config {
45 uid_t uid;
46 gid_t gid;
47 umode_t mode;
48 long nr_blocks;
49 long nr_inodes;
50 struct hstate *hstate;
51};
52
53struct hugetlbfs_inode_info {
54 struct shared_policy policy;
55 struct inode vfs_inode;
56};
57
58static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode)
59{
60 return container_of(inode, struct hugetlbfs_inode_info, vfs_inode);
61}
62
44static struct backing_dev_info hugetlbfs_backing_dev_info = { 63static struct backing_dev_info hugetlbfs_backing_dev_info = {
45 .name = "hugetlbfs", 64 .name = "hugetlbfs",
46 .ra_pages = 0, /* No readahead */ 65 .ra_pages = 0, /* No readahead */
@@ -154,10 +173,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
154 return addr; 173 return addr;
155 } 174 }
156 175
157 start_addr = mm->free_area_cache; 176 if (len > mm->cached_hole_size)
158 177 start_addr = mm->free_area_cache;
159 if (len <= mm->cached_hole_size) 178 else {
160 start_addr = TASK_UNMAPPED_BASE; 179 start_addr = TASK_UNMAPPED_BASE;
180 mm->cached_hole_size = 0;
181 }
161 182
162full_search: 183full_search:
163 addr = ALIGN(start_addr, huge_page_size(h)); 184 addr = ALIGN(start_addr, huge_page_size(h));
@@ -171,13 +192,18 @@ full_search:
171 */ 192 */
172 if (start_addr != TASK_UNMAPPED_BASE) { 193 if (start_addr != TASK_UNMAPPED_BASE) {
173 start_addr = TASK_UNMAPPED_BASE; 194 start_addr = TASK_UNMAPPED_BASE;
195 mm->cached_hole_size = 0;
174 goto full_search; 196 goto full_search;
175 } 197 }
176 return -ENOMEM; 198 return -ENOMEM;
177 } 199 }
178 200
179 if (!vma || addr + len <= vma->vm_start) 201 if (!vma || addr + len <= vma->vm_start) {
202 mm->free_area_cache = addr + len;
180 return addr; 203 return addr;
204 }
205 if (addr + mm->cached_hole_size < vma->vm_start)
206 mm->cached_hole_size = vma->vm_start - addr;
181 addr = ALIGN(vma->vm_end, huge_page_size(h)); 207 addr = ALIGN(vma->vm_end, huge_page_size(h));
182 } 208 }
183} 209}
@@ -238,17 +264,10 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
238 loff_t isize; 264 loff_t isize;
239 ssize_t retval = 0; 265 ssize_t retval = 0;
240 266
241 mutex_lock(&inode->i_mutex);
242
243 /* validate length */ 267 /* validate length */
244 if (len == 0) 268 if (len == 0)
245 goto out; 269 goto out;
246 270
247 isize = i_size_read(inode);
248 if (!isize)
249 goto out;
250
251 end_index = (isize - 1) >> huge_page_shift(h);
252 for (;;) { 271 for (;;) {
253 struct page *page; 272 struct page *page;
254 unsigned long nr, ret; 273 unsigned long nr, ret;
@@ -256,18 +275,21 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
256 275
257 /* nr is the maximum number of bytes to copy from this page */ 276 /* nr is the maximum number of bytes to copy from this page */
258 nr = huge_page_size(h); 277 nr = huge_page_size(h);
278 isize = i_size_read(inode);
279 if (!isize)
280 goto out;
281 end_index = (isize - 1) >> huge_page_shift(h);
259 if (index >= end_index) { 282 if (index >= end_index) {
260 if (index > end_index) 283 if (index > end_index)
261 goto out; 284 goto out;
262 nr = ((isize - 1) & ~huge_page_mask(h)) + 1; 285 nr = ((isize - 1) & ~huge_page_mask(h)) + 1;
263 if (nr <= offset) { 286 if (nr <= offset)
264 goto out; 287 goto out;
265 }
266 } 288 }
267 nr = nr - offset; 289 nr = nr - offset;
268 290
269 /* Find the page */ 291 /* Find the page */
270 page = find_get_page(mapping, index); 292 page = find_lock_page(mapping, index);
271 if (unlikely(page == NULL)) { 293 if (unlikely(page == NULL)) {
272 /* 294 /*
273 * We have a HOLE, zero out the user-buffer for the 295 * We have a HOLE, zero out the user-buffer for the
@@ -279,17 +301,18 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
279 else 301 else
280 ra = 0; 302 ra = 0;
281 } else { 303 } else {
304 unlock_page(page);
305
282 /* 306 /*
283 * We have the page, copy it to user space buffer. 307 * We have the page, copy it to user space buffer.
284 */ 308 */
285 ra = hugetlbfs_read_actor(page, offset, buf, len, nr); 309 ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
286 ret = ra; 310 ret = ra;
311 page_cache_release(page);
287 } 312 }
288 if (ra < 0) { 313 if (ra < 0) {
289 if (retval == 0) 314 if (retval == 0)
290 retval = ra; 315 retval = ra;
291 if (page)
292 page_cache_release(page);
293 goto out; 316 goto out;
294 } 317 }
295 318
@@ -299,16 +322,12 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
299 index += offset >> huge_page_shift(h); 322 index += offset >> huge_page_shift(h);
300 offset &= ~huge_page_mask(h); 323 offset &= ~huge_page_mask(h);
301 324
302 if (page)
303 page_cache_release(page);
304
305 /* short read or no more work */ 325 /* short read or no more work */
306 if ((ret != nr) || (len == 0)) 326 if ((ret != nr) || (len == 0))
307 break; 327 break;
308 } 328 }
309out: 329out:
310 *ppos = ((loff_t)index << huge_page_shift(h)) + offset; 330 *ppos = ((loff_t)index << huge_page_shift(h)) + offset;
311 mutex_unlock(&inode->i_mutex);
312 return retval; 331 return retval;
313} 332}
314 333
@@ -607,9 +626,15 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
607 spin_lock(&sbinfo->stat_lock); 626 spin_lock(&sbinfo->stat_lock);
608 /* If no limits set, just report 0 for max/free/used 627 /* If no limits set, just report 0 for max/free/used
609 * blocks, like simple_statfs() */ 628 * blocks, like simple_statfs() */
610 if (sbinfo->max_blocks >= 0) { 629 if (sbinfo->spool) {
611 buf->f_blocks = sbinfo->max_blocks; 630 long free_pages;
612 buf->f_bavail = buf->f_bfree = sbinfo->free_blocks; 631
632 spin_lock(&sbinfo->spool->lock);
633 buf->f_blocks = sbinfo->spool->max_hpages;
634 free_pages = sbinfo->spool->max_hpages
635 - sbinfo->spool->used_hpages;
636 buf->f_bavail = buf->f_bfree = free_pages;
637 spin_unlock(&sbinfo->spool->lock);
613 buf->f_files = sbinfo->max_inodes; 638 buf->f_files = sbinfo->max_inodes;
614 buf->f_ffree = sbinfo->free_inodes; 639 buf->f_ffree = sbinfo->free_inodes;
615 } 640 }
@@ -625,6 +650,10 @@ static void hugetlbfs_put_super(struct super_block *sb)
625 650
626 if (sbi) { 651 if (sbi) {
627 sb->s_fs_info = NULL; 652 sb->s_fs_info = NULL;
653
654 if (sbi->spool)
655 hugepage_put_subpool(sbi->spool);
656
628 kfree(sbi); 657 kfree(sbi);
629 } 658 }
630} 659}
@@ -853,10 +882,14 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
853 sb->s_fs_info = sbinfo; 882 sb->s_fs_info = sbinfo;
854 sbinfo->hstate = config.hstate; 883 sbinfo->hstate = config.hstate;
855 spin_lock_init(&sbinfo->stat_lock); 884 spin_lock_init(&sbinfo->stat_lock);
856 sbinfo->max_blocks = config.nr_blocks;
857 sbinfo->free_blocks = config.nr_blocks;
858 sbinfo->max_inodes = config.nr_inodes; 885 sbinfo->max_inodes = config.nr_inodes;
859 sbinfo->free_inodes = config.nr_inodes; 886 sbinfo->free_inodes = config.nr_inodes;
887 sbinfo->spool = NULL;
888 if (config.nr_blocks != -1) {
889 sbinfo->spool = hugepage_new_subpool(config.nr_blocks);
890 if (!sbinfo->spool)
891 goto out_free;
892 }
860 sb->s_maxbytes = MAX_LFS_FILESIZE; 893 sb->s_maxbytes = MAX_LFS_FILESIZE;
861 sb->s_blocksize = huge_page_size(config.hstate); 894 sb->s_blocksize = huge_page_size(config.hstate);
862 sb->s_blocksize_bits = huge_page_shift(config.hstate); 895 sb->s_blocksize_bits = huge_page_shift(config.hstate);
@@ -868,38 +901,12 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
868 goto out_free; 901 goto out_free;
869 return 0; 902 return 0;
870out_free: 903out_free:
904 if (sbinfo->spool)
905 kfree(sbinfo->spool);
871 kfree(sbinfo); 906 kfree(sbinfo);
872 return -ENOMEM; 907 return -ENOMEM;
873} 908}
874 909
875int hugetlb_get_quota(struct address_space *mapping, long delta)
876{
877 int ret = 0;
878 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
879
880 if (sbinfo->free_blocks > -1) {
881 spin_lock(&sbinfo->stat_lock);
882 if (sbinfo->free_blocks - delta >= 0)
883 sbinfo->free_blocks -= delta;
884 else
885 ret = -ENOMEM;
886 spin_unlock(&sbinfo->stat_lock);
887 }
888
889 return ret;
890}
891
892void hugetlb_put_quota(struct address_space *mapping, long delta)
893{
894 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
895
896 if (sbinfo->free_blocks > -1) {
897 spin_lock(&sbinfo->stat_lock);
898 sbinfo->free_blocks += delta;
899 spin_unlock(&sbinfo->stat_lock);
900 }
901}
902
903static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type, 910static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type,
904 int flags, const char *dev_name, void *data) 911 int flags, const char *dev_name, void *data)
905{ 912{
@@ -919,8 +926,8 @@ static int can_do_hugetlb_shm(void)
919 return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); 926 return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
920} 927}
921 928
922struct file *hugetlb_file_setup(const char *name, size_t size, 929struct file *hugetlb_file_setup(const char *name, unsigned long addr,
923 vm_flags_t acctflag, 930 size_t size, vm_flags_t acctflag,
924 struct user_struct **user, int creat_flags) 931 struct user_struct **user, int creat_flags)
925{ 932{
926 int error = -ENOMEM; 933 int error = -ENOMEM;
@@ -929,6 +936,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
929 struct path path; 936 struct path path;
930 struct dentry *root; 937 struct dentry *root;
931 struct qstr quick_string; 938 struct qstr quick_string;
939 struct hstate *hstate;
940 unsigned long num_pages;
932 941
933 *user = NULL; 942 *user = NULL;
934 if (!hugetlbfs_vfsmount) 943 if (!hugetlbfs_vfsmount)
@@ -937,7 +946,11 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
937 if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { 946 if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) {
938 *user = current_user(); 947 *user = current_user();
939 if (user_shm_lock(size, *user)) { 948 if (user_shm_lock(size, *user)) {
940 printk_once(KERN_WARNING "Using mlock ulimits for SHM_HUGETLB is deprecated\n"); 949 task_lock(current);
950 printk_once(KERN_WARNING
951 "%s (%d): Using mlock ulimits for SHM_HUGETLB is deprecated\n",
952 current->comm, current->pid);
953 task_unlock(current);
941 } else { 954 } else {
942 *user = NULL; 955 *user = NULL;
943 return ERR_PTR(-EPERM); 956 return ERR_PTR(-EPERM);
@@ -958,10 +971,12 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
958 if (!inode) 971 if (!inode)
959 goto out_dentry; 972 goto out_dentry;
960 973
974 hstate = hstate_inode(inode);
975 size += addr & ~huge_page_mask(hstate);
976 num_pages = ALIGN(size, huge_page_size(hstate)) >>
977 huge_page_shift(hstate);
961 error = -ENOMEM; 978 error = -ENOMEM;
962 if (hugetlb_reserve_pages(inode, 0, 979 if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag))
963 size >> huge_page_shift(hstate_inode(inode)), NULL,
964 acctflag))
965 goto out_inode; 980 goto out_inode;
966 981
967 d_instantiate(path.dentry, inode); 982 d_instantiate(path.dentry, inode);
@@ -997,6 +1012,7 @@ static int __init init_hugetlbfs_fs(void)
997 if (error) 1012 if (error)
998 return error; 1013 return error;
999 1014
1015 error = -ENOMEM;
1000 hugetlbfs_inode_cachep = kmem_cache_create("hugetlbfs_inode_cache", 1016 hugetlbfs_inode_cachep = kmem_cache_create("hugetlbfs_inode_cache",
1001 sizeof(struct hugetlbfs_inode_info), 1017 sizeof(struct hugetlbfs_inode_info),
1002 0, 0, init_once); 1018 0, 0, init_once);
@@ -1015,10 +1031,10 @@ static int __init init_hugetlbfs_fs(void)
1015 } 1031 }
1016 1032
1017 error = PTR_ERR(vfsmount); 1033 error = PTR_ERR(vfsmount);
1034 unregister_filesystem(&hugetlbfs_fs_type);
1018 1035
1019 out: 1036 out:
1020 if (error) 1037 kmem_cache_destroy(hugetlbfs_inode_cachep);
1021 kmem_cache_destroy(hugetlbfs_inode_cachep);
1022 out2: 1038 out2:
1023 bdi_destroy(&hugetlbfs_backing_dev_info); 1039 bdi_destroy(&hugetlbfs_backing_dev_info);
1024 return error; 1040 return error;