shmem.c (f3f0e1d2150b2b99da2cbdfaad000089efe9bf30) shmem.c (e496cf3d782135c1cca0d154d4b924517ff58de0)
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 349 unchanged lines hidden (view full) ---

358 * disables huge on shm_mnt and all mounts, for emergency use;
359 * SHMEM_HUGE_FORCE:
360 * enables huge on shm_mnt and all mounts, w/o needing option, for testing;
361 *
362 */
363#define SHMEM_HUGE_DENY (-1)
364#define SHMEM_HUGE_FORCE (-2)
365
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 349 unchanged lines hidden (view full) ---

358 * disables huge on shm_mnt and all mounts, for emergency use;
359 * SHMEM_HUGE_FORCE:
360 * enables huge on shm_mnt and all mounts, w/o needing option, for testing;
361 *
362 */
363#define SHMEM_HUGE_DENY (-1)
364#define SHMEM_HUGE_FORCE (-2)
365
366#ifdef CONFIG_TRANSPARENT_HUGEPAGE
366#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
367/* ifdef here to avoid bloating shmem.o when not necessary */
368
369int shmem_huge __read_mostly;
370
371static int shmem_parse_huge(const char *str)
372{
373 if (!strcmp(str, "never"))
374 return SHMEM_HUGE_NEVER;

--- 26 unchanged lines hidden (view full) ---

401 case SHMEM_HUGE_FORCE:
402 return "force";
403 default:
404 VM_BUG_ON(1);
405 return "bad_val";
406 }
407}
408
367/* ifdef here to avoid bloating shmem.o when not necessary */
368
369int shmem_huge __read_mostly;
370
371static int shmem_parse_huge(const char *str)
372{
373 if (!strcmp(str, "never"))
374 return SHMEM_HUGE_NEVER;

--- 26 unchanged lines hidden (view full) ---

401 case SHMEM_HUGE_FORCE:
402 return "force";
403 default:
404 VM_BUG_ON(1);
405 return "bad_val";
406 }
407}
408
409#else /* !CONFIG_TRANSPARENT_HUGEPAGE */
409#else /* !CONFIG_TRANSPARENT_HUGE_PAGECACHE */
410
411#define shmem_huge SHMEM_HUGE_DENY
412
410
411#define shmem_huge SHMEM_HUGE_DENY
412
413#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
413#endif /* CONFIG_TRANSPARENT_HUGE_PAGECACHE */
414
415/*
416 * Like add_to_page_cache_locked, but error if expected item has gone.
417 */
418static int shmem_add_to_page_cache(struct page *page,
419 struct address_space *mapping,
420 pgoff_t index, void *expected)
421{

--- 802 unchanged lines hidden (view full) ---

1224{
1225 struct vm_area_struct pvma;
1226 struct inode *inode = &info->vfs_inode;
1227 struct address_space *mapping = inode->i_mapping;
1228 pgoff_t idx, hindex = round_down(index, HPAGE_PMD_NR);
1229 void __rcu **results;
1230 struct page *page;
1231
414
415/*
416 * Like add_to_page_cache_locked, but error if expected item has gone.
417 */
418static int shmem_add_to_page_cache(struct page *page,
419 struct address_space *mapping,
420 pgoff_t index, void *expected)
421{

--- 802 unchanged lines hidden (view full) ---

1224{
1225 struct vm_area_struct pvma;
1226 struct inode *inode = &info->vfs_inode;
1227 struct address_space *mapping = inode->i_mapping;
1228 pgoff_t idx, hindex = round_down(index, HPAGE_PMD_NR);
1229 void __rcu **results;
1230 struct page *page;
1231
1232 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
1232 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
1233 return NULL;
1234
1235 rcu_read_lock();
1236 if (radix_tree_gang_lookup_slot(&mapping->page_tree, &results, &idx,
1237 hindex, 1) && idx < hindex + HPAGE_PMD_NR) {
1238 rcu_read_unlock();
1239 return NULL;
1240 }

--- 24 unchanged lines hidden (view full) ---

1265static struct page *shmem_alloc_and_acct_page(gfp_t gfp,
1266 struct shmem_inode_info *info, struct shmem_sb_info *sbinfo,
1267 pgoff_t index, bool huge)
1268{
1269 struct page *page;
1270 int nr;
1271 int err = -ENOSPC;
1272
1233 return NULL;
1234
1235 rcu_read_lock();
1236 if (radix_tree_gang_lookup_slot(&mapping->page_tree, &results, &idx,
1237 hindex, 1) && idx < hindex + HPAGE_PMD_NR) {
1238 rcu_read_unlock();
1239 return NULL;
1240 }

--- 24 unchanged lines hidden (view full) ---

1265static struct page *shmem_alloc_and_acct_page(gfp_t gfp,
1266 struct shmem_inode_info *info, struct shmem_sb_info *sbinfo,
1267 pgoff_t index, bool huge)
1268{
1269 struct page *page;
1270 int nr;
1271 int err = -ENOSPC;
1272
1273 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
1273 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
1274 huge = false;
1275 nr = huge ? HPAGE_PMD_NR : 1;
1276
1277 if (shmem_acct_block(info->flags, nr))
1278 goto failed;
1279 if (sbinfo->max_blocks) {
1280 if (percpu_counter_compare(&sbinfo->used_blocks,
1281 sbinfo->max_blocks - nr) > 0)

--- 486 unchanged lines hidden (view full) ---

1768 unsigned long inflated_offset;
1769
1770 if (len > TASK_SIZE)
1771 return -ENOMEM;
1772
1773 get_area = current->mm->get_unmapped_area;
1774 addr = get_area(file, uaddr, len, pgoff, flags);
1775
1274 huge = false;
1275 nr = huge ? HPAGE_PMD_NR : 1;
1276
1277 if (shmem_acct_block(info->flags, nr))
1278 goto failed;
1279 if (sbinfo->max_blocks) {
1280 if (percpu_counter_compare(&sbinfo->used_blocks,
1281 sbinfo->max_blocks - nr) > 0)

--- 486 unchanged lines hidden (view full) ---

1768 unsigned long inflated_offset;
1769
1770 if (len > TASK_SIZE)
1771 return -ENOMEM;
1772
1773 get_area = current->mm->get_unmapped_area;
1774 addr = get_area(file, uaddr, len, pgoff, flags);
1775
1776 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
1776 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
1777 return addr;
1778 if (IS_ERR_VALUE(addr))
1779 return addr;
1780 if (addr & ~PAGE_MASK)
1781 return addr;
1782 if (addr > TASK_SIZE - len)
1783 return addr;
1784

--- 100 unchanged lines hidden (view full) ---

1885 spin_unlock_irq(&info->lock);
1886 return retval;
1887}
1888
1889static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
1890{
1891 file_accessed(file);
1892 vma->vm_ops = &shmem_vm_ops;
1777 return addr;
1778 if (IS_ERR_VALUE(addr))
1779 return addr;
1780 if (addr & ~PAGE_MASK)
1781 return addr;
1782 if (addr > TASK_SIZE - len)
1783 return addr;
1784

--- 100 unchanged lines hidden (view full) ---

1885 spin_unlock_irq(&info->lock);
1886 return retval;
1887}
1888
1889static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
1890{
1891 file_accessed(file);
1892 vma->vm_ops = &shmem_vm_ops;
1893 if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
1893 if (IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE) &&
1894 ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
1895 (vma->vm_end & HPAGE_PMD_MASK)) {
1896 khugepaged_enter(vma, vma->vm_flags);
1897 }
1898 return 0;
1899}
1900
1901static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,

--- 1380 unchanged lines hidden (view full) ---

3282 if (remount)
3283 continue;
3284 gid = simple_strtoul(value, &rest, 0);
3285 if (*rest)
3286 goto bad_val;
3287 sbinfo->gid = make_kgid(current_user_ns(), gid);
3288 if (!gid_valid(sbinfo->gid))
3289 goto bad_val;
1894 ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
1895 (vma->vm_end & HPAGE_PMD_MASK)) {
1896 khugepaged_enter(vma, vma->vm_flags);
1897 }
1898 return 0;
1899}
1900
1901static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,

--- 1380 unchanged lines hidden (view full) ---

3282 if (remount)
3283 continue;
3284 gid = simple_strtoul(value, &rest, 0);
3285 if (*rest)
3286 goto bad_val;
3287 sbinfo->gid = make_kgid(current_user_ns(), gid);
3288 if (!gid_valid(sbinfo->gid))
3289 goto bad_val;
3290#ifdef CONFIG_TRANSPARENT_HUGEPAGE
3290#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
3291 } else if (!strcmp(this_char, "huge")) {
3292 int huge;
3293 huge = shmem_parse_huge(value);
3294 if (huge < 0)
3295 goto bad_val;
3296 if (!has_transparent_hugepage() &&
3297 huge != SHMEM_HUGE_NEVER)
3298 goto bad_val;

--- 80 unchanged lines hidden (view full) ---

3379 if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
3380 seq_printf(seq, ",mode=%03ho", sbinfo->mode);
3381 if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
3382 seq_printf(seq, ",uid=%u",
3383 from_kuid_munged(&init_user_ns, sbinfo->uid));
3384 if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
3385 seq_printf(seq, ",gid=%u",
3386 from_kgid_munged(&init_user_ns, sbinfo->gid));
3291 } else if (!strcmp(this_char, "huge")) {
3292 int huge;
3293 huge = shmem_parse_huge(value);
3294 if (huge < 0)
3295 goto bad_val;
3296 if (!has_transparent_hugepage() &&
3297 huge != SHMEM_HUGE_NEVER)
3298 goto bad_val;

--- 80 unchanged lines hidden (view full) ---

3379 if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
3380 seq_printf(seq, ",mode=%03ho", sbinfo->mode);
3381 if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
3382 seq_printf(seq, ",uid=%u",
3383 from_kuid_munged(&init_user_ns, sbinfo->uid));
3384 if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
3385 seq_printf(seq, ",gid=%u",
3386 from_kgid_munged(&init_user_ns, sbinfo->gid));
3387#ifdef CONFIG_TRANSPARENT_HUGEPAGE
3387#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
3388 /* Rightly or wrongly, show huge mount option unmasked by shmem_huge */
3389 if (sbinfo->huge)
3390 seq_printf(seq, ",huge=%s", shmem_format_huge(sbinfo->huge));
3391#endif
3392 shmem_show_mpol(seq, sbinfo->mpol);
3393 return 0;
3394}
3395

--- 329 unchanged lines hidden (view full) ---

3725
3726 shm_mnt = kern_mount(&shmem_fs_type);
3727 if (IS_ERR(shm_mnt)) {
3728 error = PTR_ERR(shm_mnt);
3729 pr_err("Could not kern_mount tmpfs\n");
3730 goto out1;
3731 }
3732
3388 /* Rightly or wrongly, show huge mount option unmasked by shmem_huge */
3389 if (sbinfo->huge)
3390 seq_printf(seq, ",huge=%s", shmem_format_huge(sbinfo->huge));
3391#endif
3392 shmem_show_mpol(seq, sbinfo->mpol);
3393 return 0;
3394}
3395

--- 329 unchanged lines hidden (view full) ---

3725
3726 shm_mnt = kern_mount(&shmem_fs_type);
3727 if (IS_ERR(shm_mnt)) {
3728 error = PTR_ERR(shm_mnt);
3729 pr_err("Could not kern_mount tmpfs\n");
3730 goto out1;
3731 }
3732
3733#ifdef CONFIG_TRANSPARENT_HUGEPAGE
3733#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
3734 if (has_transparent_hugepage() && shmem_huge < SHMEM_HUGE_DENY)
3735 SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge;
3736 else
3737 shmem_huge = 0; /* just in case it was patched */
3738#endif
3739 return 0;
3740
3741out1:
3742 unregister_filesystem(&shmem_fs_type);
3743out2:
3744 shmem_destroy_inodecache();
3745out3:
3746 shm_mnt = ERR_PTR(error);
3747 return error;
3748}
3749
3734 if (has_transparent_hugepage() && shmem_huge < SHMEM_HUGE_DENY)
3735 SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge;
3736 else
3737 shmem_huge = 0; /* just in case it was patched */
3738#endif
3739 return 0;
3740
3741out1:
3742 unregister_filesystem(&shmem_fs_type);
3743out2:
3744 shmem_destroy_inodecache();
3745out3:
3746 shm_mnt = ERR_PTR(error);
3747 return error;
3748}
3749
3750#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_SYSFS)
3750#if defined(CONFIG_TRANSPARENT_HUGE_PAGECACHE) && defined(CONFIG_SYSFS)
3751static ssize_t shmem_enabled_show(struct kobject *kobj,
3752 struct kobj_attribute *attr, char *buf)
3753{
3754 int values[] = {
3755 SHMEM_HUGE_ALWAYS,
3756 SHMEM_HUGE_WITHIN_SIZE,
3757 SHMEM_HUGE_ADVISE,
3758 SHMEM_HUGE_NEVER,

--- 66 unchanged lines hidden (view full) ---

3825 case SHMEM_HUGE_ADVISE:
3826 /* TODO: implement fadvise() hints */
3827 return (vma->vm_flags & VM_HUGEPAGE);
3828 default:
3829 VM_BUG_ON(1);
3830 return false;
3831 }
3832}
3751static ssize_t shmem_enabled_show(struct kobject *kobj,
3752 struct kobj_attribute *attr, char *buf)
3753{
3754 int values[] = {
3755 SHMEM_HUGE_ALWAYS,
3756 SHMEM_HUGE_WITHIN_SIZE,
3757 SHMEM_HUGE_ADVISE,
3758 SHMEM_HUGE_NEVER,

--- 66 unchanged lines hidden (view full) ---

3825 case SHMEM_HUGE_ADVISE:
3826 /* TODO: implement fadvise() hints */
3827 return (vma->vm_flags & VM_HUGEPAGE);
3828 default:
3829 VM_BUG_ON(1);
3830 return false;
3831 }
3832}
3833#endif /* CONFIG_TRANSPARENT_HUGEPAGE && CONFIG_SYSFS */
3833#endif /* CONFIG_TRANSPARENT_HUGE_PAGECACHE && CONFIG_SYSFS */
3834
3835#else /* !CONFIG_SHMEM */
3836
3837/*
3838 * tiny-shmem: simple shmemfs and tmpfs using ramfs code
3839 *
3840 * This is intended for small system where the benefits of the full
3841 * shmem code (swap-backed and resource-limited) are outweighed by

--- 163 unchanged lines hidden (view full) ---

4005 if (IS_ERR(file))
4006 return PTR_ERR(file);
4007
4008 if (vma->vm_file)
4009 fput(vma->vm_file);
4010 vma->vm_file = file;
4011 vma->vm_ops = &shmem_vm_ops;
4012
3834
3835#else /* !CONFIG_SHMEM */
3836
3837/*
3838 * tiny-shmem: simple shmemfs and tmpfs using ramfs code
3839 *
3840 * This is intended for small system where the benefits of the full
3841 * shmem code (swap-backed and resource-limited) are outweighed by

--- 163 unchanged lines hidden (view full) ---

4005 if (IS_ERR(file))
4006 return PTR_ERR(file);
4007
4008 if (vma->vm_file)
4009 fput(vma->vm_file);
4010 vma->vm_file = file;
4011 vma->vm_ops = &shmem_vm_ops;
4012
4013 if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
4013 if (IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE) &&
4014 ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
4015 (vma->vm_end & HPAGE_PMD_MASK)) {
4016 khugepaged_enter(vma, vma->vm_flags);
4017 }
4018
4019 return 0;
4020}
4021

--- 39 unchanged lines hidden ---
4014 ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
4015 (vma->vm_end & HPAGE_PMD_MASK)) {
4016 khugepaged_enter(vma, vma->vm_flags);
4017 }
4018
4019 return 0;
4020}
4021

--- 39 unchanged lines hidden ---