On 2013/5/15 2:04, Luis Henriques wrote:

> Hi Jianguo,
> 
> On Fri, May 10, 2013 at 02:08:19PM +0800, Jianguo Wu wrote:
>> Hi Greg,
>> I rebase "[PATCH] hugetlbfs: fix mmap failure in unaligned size request" on 
>> 3.4,
>> could you please apply to 3.4-stable.
>>
>> Chagelog:
>>  - remove hstate_sizelog(), as 3.4 only support default hugepagesize for
>>    MAP_HUGETLB/SHM_HUGETLB.
> 
> Do you think this backport could also be applied to the 3.5 kernel?
> The original commit can't be applied, but I'm not sure that picking
> your backport is the right thing to do.
> 

Hi Luis,

I think it can be applied to 3.5.

Thanks,
Jianguo Wu.

> Cheers,
> --
> Luis
> 
>>
>>
>> From: Naoya Horiguchi <[email protected]>
>>
>> commit af73e4d9506d3b797509f3c030e7dcd554f7d9c4 upstream.
>>
>> The current kernel returns -EINVAL unless a given mmap length is
>> "almost" hugepage aligned.  This is because in sys_mmap_pgoff() the
>> given length is passed to vm_mmap_pgoff() as it is without being aligned
>> with hugepage boundary.
>>
>> This is a regression introduced in commit 40716e29243d ("hugetlbfs: fix
>> alignment of huge page requests"), where alignment code is pushed into
>> hugetlb_file_setup() and the variable len in caller side is not changed.
>>
>> To fix this, this patch partially reverts that commit, and adds
>> alignment code in caller side.  And it also introduces hstate_sizelog()
>> in order to get proper hstate to specified hugepage size.
>>
>> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=56881
>>
>> [[email protected]: fix warning when CONFIG_HUGETLB_PAGE=n]
>> Signed-off-by: Naoya Horiguchi <[email protected]>
>> Signed-off-by: Johannes Weiner <[email protected]>
>> Reported-by: <[email protected]>
>> Cc: Steven Truelove <[email protected]>
>> Cc: Jianguo Wu <[email protected]>
>> Cc: Hugh Dickins <[email protected]>
>> Cc: <[email protected]>
>> Signed-off-by: Andrew Morton <[email protected]>
>> Signed-off-by: Linus Torvalds <[email protected]>
>> Signed-off-by: Jianguo Wu <[email protected]>
>> ---
>>  fs/hugetlbfs/inode.c    |   20 ++++++++++----------
>>  include/linux/hugetlb.h |    9 ++++-----
>>  ipc/shm.c               |    4 +++-
>>  mm/mmap.c               |    6 +++++-
>>  4 files changed, 22 insertions(+), 17 deletions(-)
>>
>> diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
>> index 001ef01..36ad5b4 100644
>> --- a/fs/hugetlbfs/inode.c
>> +++ b/fs/hugetlbfs/inode.c
>> @@ -927,9 +927,13 @@ static int can_do_hugetlb_shm(void)
>>      return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
>>  }
>>  
>> -struct file *hugetlb_file_setup(const char *name, unsigned long addr,
>> -                            size_t size, vm_flags_t acctflag,
>> -                            struct user_struct **user, int creat_flags)
>> +/*
>> + * Note that size should be aligned to proper hugepage size in caller side,
>> + * otherwise hugetlb_reserve_pages reserves one less hugepages than 
>> intended.
>> + */
>> +struct file *hugetlb_file_setup(const char *name, size_t size,
>> +                            vm_flags_t acctflag, struct user_struct **user,
>> +                            int creat_flags)
>>  {
>>      int error = -ENOMEM;
>>      struct file *file;
>> @@ -937,8 +941,6 @@ struct file *hugetlb_file_setup(const char *name, 
>> unsigned long addr,
>>      struct path path;
>>      struct dentry *root;
>>      struct qstr quick_string;
>> -    struct hstate *hstate;
>> -    unsigned long num_pages;
>>  
>>      *user = NULL;
>>      if (!hugetlbfs_vfsmount)
>> @@ -972,12 +974,10 @@ struct file *hugetlb_file_setup(const char *name, 
>> unsigned long addr,
>>      if (!inode)
>>              goto out_dentry;
>>  
>> -    hstate = hstate_inode(inode);
>> -    size += addr & ~huge_page_mask(hstate);
>> -    num_pages = ALIGN(size, huge_page_size(hstate)) >>
>> -                    huge_page_shift(hstate);
>>      error = -ENOMEM;
>> -    if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag))
>> +    if (hugetlb_reserve_pages(inode, 0,
>> +                    size >> huge_page_shift(hstate_inode(inode)), NULL,
>> +                    acctflag))
>>              goto out_inode;
>>  
>>      d_instantiate(path.dentry, inode);
>> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
>> index 000837e..2c36a71 100644
>> --- a/include/linux/hugetlb.h
>> +++ b/include/linux/hugetlb.h
>> @@ -152,8 +152,7 @@ static inline struct hugetlbfs_sb_info 
>> *HUGETLBFS_SB(struct super_block *sb)
>>  
>>  extern const struct file_operations hugetlbfs_file_operations;
>>  extern const struct vm_operations_struct hugetlb_vm_ops;
>> -struct file *hugetlb_file_setup(const char *name, unsigned long addr,
>> -                            size_t size, vm_flags_t acct,
>> +struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t 
>> acct,
>>                              struct user_struct **user, int creat_flags);
>>  
>>  static inline int is_file_hugepages(struct file *file)
>> @@ -170,8 +169,8 @@ static inline int is_file_hugepages(struct file *file)
>>  
>>  #define is_file_hugepages(file)                     0
>>  static inline struct file *
>> -hugetlb_file_setup(const char *name, unsigned long addr, size_t size,
>> -            vm_flags_t acctflag, struct user_struct **user, int creat_flags)
>> +hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag,
>> +            struct user_struct **user, int creat_flags)
>>  {
>>      return ERR_PTR(-ENOSYS);
>>  }
>> @@ -294,7 +293,7 @@ static inline unsigned hstate_index_to_shift(unsigned 
>> index)
>>      return hstates[index].order + PAGE_SHIFT;
>>  }
>>  
>> -#else
>> +#else       /* CONFIG_HUGETLB_PAGE */
>>  struct hstate {};
>>  #define alloc_huge_page_node(h, nid) NULL
>>  #define alloc_bootmem_huge_page(h) NULL
>> diff --git a/ipc/shm.c b/ipc/shm.c
>> index 85d81b4..a02ef57 100644
>> --- a/ipc/shm.c
>> +++ b/ipc/shm.c
>> @@ -479,10 +479,12 @@ static int newseg(struct ipc_namespace *ns, struct 
>> ipc_params *params)
>>  
>>      sprintf (name, "SYSV%08x", key);
>>      if (shmflg & SHM_HUGETLB) {
>> +            size_t hugesize = ALIGN(size, huge_page_size(&default_hstate));
>> +
>>              /* hugetlb_file_setup applies strict accounting */
>>              if (shmflg & SHM_NORESERVE)
>>                      acctflag = VM_NORESERVE;
>> -            file = hugetlb_file_setup(name, 0, size, acctflag,
>> +            file = hugetlb_file_setup(name, hugesize, acctflag,
>>                                      &shp->mlock_user, HUGETLB_SHMFS_INODE);
>>      } else {
>>              /*
>> diff --git a/mm/mmap.c b/mm/mmap.c
>> index 3635d47..ed884dd 100644
>> --- a/mm/mmap.c
>> +++ b/mm/mmap.c
>> @@ -1130,15 +1130,19 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, 
>> unsigned long, len,
>>              file = fget(fd);
>>              if (!file)
>>                      goto out;
>> +            if (is_file_hugepages(file))
>> +                    len = ALIGN(len, huge_page_size(hstate_file(file)));
>>      } else if (flags & MAP_HUGETLB) {
>>              struct user_struct *user = NULL;
>> +
>> +            len = ALIGN(len, huge_page_size(&default_hstate));
>>              /*
>>               * VM_NORESERVE is used because the reservations will be
>>               * taken when vm_ops->mmap() is called
>>               * A dummy user value is used because we are not locking
>>               * memory so no accounting is necessary
>>               */
>> -            file = hugetlb_file_setup(HUGETLB_ANON_FILE, addr, len,
>> +            file = hugetlb_file_setup(HUGETLB_ANON_FILE, len,
>>                                              VM_NORESERVE, &user,
>>                                              HUGETLB_ANONHUGE_INODE);
>>              if (IS_ERR(file))
>> -- 
>> 1.7.6.1
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe stable" in
>> the body of a message to [email protected]
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> .
> 



--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to