aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r--fs/hugetlbfs/inode.c90
1 files changed, 71 insertions, 19 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 45e34908bdb5..2640d88b0e63 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -48,9 +48,10 @@ struct hugetlbfs_config {
48 kuid_t uid; 48 kuid_t uid;
49 kgid_t gid; 49 kgid_t gid;
50 umode_t mode; 50 umode_t mode;
51 long nr_blocks; 51 long max_hpages;
52 long nr_inodes; 52 long nr_inodes;
53 struct hstate *hstate; 53 struct hstate *hstate;
54 long min_hpages;
54}; 55};
55 56
56struct hugetlbfs_inode_info { 57struct hugetlbfs_inode_info {
@@ -68,7 +69,7 @@ int sysctl_hugetlb_shm_group;
68enum { 69enum {
69 Opt_size, Opt_nr_inodes, 70 Opt_size, Opt_nr_inodes,
70 Opt_mode, Opt_uid, Opt_gid, 71 Opt_mode, Opt_uid, Opt_gid,
71 Opt_pagesize, 72 Opt_pagesize, Opt_min_size,
72 Opt_err, 73 Opt_err,
73}; 74};
74 75
@@ -79,6 +80,7 @@ static const match_table_t tokens = {
79 {Opt_uid, "uid=%u"}, 80 {Opt_uid, "uid=%u"},
80 {Opt_gid, "gid=%u"}, 81 {Opt_gid, "gid=%u"},
81 {Opt_pagesize, "pagesize=%s"}, 82 {Opt_pagesize, "pagesize=%s"},
83 {Opt_min_size, "min_size=%s"},
82 {Opt_err, NULL}, 84 {Opt_err, NULL},
83}; 85};
84 86
@@ -729,14 +731,38 @@ static const struct super_operations hugetlbfs_ops = {
729 .show_options = generic_show_options, 731 .show_options = generic_show_options,
730}; 732};
731 733
734enum { NO_SIZE, SIZE_STD, SIZE_PERCENT };
735
736/*
737 * Convert size option passed from command line to number of huge pages
738 * in the pool specified by hstate. Size option could be in bytes
739 * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
740 */
741static long long
742hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
743 int val_type)
744{
745 if (val_type == NO_SIZE)
746 return -1;
747
748 if (val_type == SIZE_PERCENT) {
749 size_opt <<= huge_page_shift(h);
750 size_opt *= h->max_huge_pages;
751 do_div(size_opt, 100);
752 }
753
754 size_opt >>= huge_page_shift(h);
755 return size_opt;
756}
757
732static int 758static int
733hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) 759hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
734{ 760{
735 char *p, *rest; 761 char *p, *rest;
736 substring_t args[MAX_OPT_ARGS]; 762 substring_t args[MAX_OPT_ARGS];
737 int option; 763 int option;
738 unsigned long long size = 0; 764 unsigned long long max_size_opt = 0, min_size_opt = 0;
739 enum { NO_SIZE, SIZE_STD, SIZE_PERCENT } setsize = NO_SIZE; 765 int max_val_type = NO_SIZE, min_val_type = NO_SIZE;
740 766
741 if (!options) 767 if (!options)
742 return 0; 768 return 0;
@@ -774,10 +800,10 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
774 /* memparse() will accept a K/M/G without a digit */ 800 /* memparse() will accept a K/M/G without a digit */
775 if (!isdigit(*args[0].from)) 801 if (!isdigit(*args[0].from))
776 goto bad_val; 802 goto bad_val;
777 size = memparse(args[0].from, &rest); 803 max_size_opt = memparse(args[0].from, &rest);
778 setsize = SIZE_STD; 804 max_val_type = SIZE_STD;
779 if (*rest == '%') 805 if (*rest == '%')
780 setsize = SIZE_PERCENT; 806 max_val_type = SIZE_PERCENT;
781 break; 807 break;
782 } 808 }
783 809
@@ -800,6 +826,17 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
800 break; 826 break;
801 } 827 }
802 828
829 case Opt_min_size: {
830 /* memparse() will accept a K/M/G without a digit */
831 if (!isdigit(*args[0].from))
832 goto bad_val;
833 min_size_opt = memparse(args[0].from, &rest);
834 min_val_type = SIZE_STD;
835 if (*rest == '%')
836 min_val_type = SIZE_PERCENT;
837 break;
838 }
839
803 default: 840 default:
804 pr_err("Bad mount option: \"%s\"\n", p); 841 pr_err("Bad mount option: \"%s\"\n", p);
805 return -EINVAL; 842 return -EINVAL;
@@ -807,15 +844,22 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
807 } 844 }
808 } 845 }
809 846
810 /* Do size after hstate is set up */ 847 /*
811 if (setsize > NO_SIZE) { 848 * Use huge page pool size (in hstate) to convert the size
812 struct hstate *h = pconfig->hstate; 849 * options to number of huge pages. If NO_SIZE, -1 is returned.
813 if (setsize == SIZE_PERCENT) { 850 */
814 size <<= huge_page_shift(h); 851 pconfig->max_hpages = hugetlbfs_size_to_hpages(pconfig->hstate,
815 size *= h->max_huge_pages; 852 max_size_opt, max_val_type);
816 do_div(size, 100); 853 pconfig->min_hpages = hugetlbfs_size_to_hpages(pconfig->hstate,
817 } 854 min_size_opt, min_val_type);
818 pconfig->nr_blocks = (size >> huge_page_shift(h)); 855
856 /*
857 * If max_size was specified, then min_size must be smaller
858 */
859 if (max_val_type > NO_SIZE &&
860 pconfig->min_hpages > pconfig->max_hpages) {
861 pr_err("minimum size can not be greater than maximum size\n");
862 return -EINVAL;
819 } 863 }
820 864
821 return 0; 865 return 0;
@@ -834,12 +878,13 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
834 878
835 save_mount_options(sb, data); 879 save_mount_options(sb, data);
836 880
837 config.nr_blocks = -1; /* No limit on size by default */ 881 config.max_hpages = -1; /* No limit on size by default */
838 config.nr_inodes = -1; /* No limit on number of inodes by default */ 882 config.nr_inodes = -1; /* No limit on number of inodes by default */
839 config.uid = current_fsuid(); 883 config.uid = current_fsuid();
840 config.gid = current_fsgid(); 884 config.gid = current_fsgid();
841 config.mode = 0755; 885 config.mode = 0755;
842 config.hstate = &default_hstate; 886 config.hstate = &default_hstate;
887 config.min_hpages = -1; /* No default minimum size */
843 ret = hugetlbfs_parse_options(data, &config); 888 ret = hugetlbfs_parse_options(data, &config);
844 if (ret) 889 if (ret)
845 return ret; 890 return ret;
@@ -853,8 +898,15 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
853 sbinfo->max_inodes = config.nr_inodes; 898 sbinfo->max_inodes = config.nr_inodes;
854 sbinfo->free_inodes = config.nr_inodes; 899 sbinfo->free_inodes = config.nr_inodes;
855 sbinfo->spool = NULL; 900 sbinfo->spool = NULL;
856 if (config.nr_blocks != -1) { 901 /*
857 sbinfo->spool = hugepage_new_subpool(config.nr_blocks); 902 * Allocate and initialize subpool if maximum or minimum size is
903 * specified. Any needed reservations (for minimim size) are taken
904 * taken when the subpool is created.
905 */
906 if (config.max_hpages != -1 || config.min_hpages != -1) {
907 sbinfo->spool = hugepage_new_subpool(config.hstate,
908 config.max_hpages,
909 config.min_hpages);
858 if (!sbinfo->spool) 910 if (!sbinfo->spool)
859 goto out_free; 911 goto out_free;
860 } 912 }