[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: hugepage patches



Andrew,

New allocation of hugepages is an atomic operation.  Partial allocations
of hugepages is not a possibility.  Agree with the initial bug report
though that i_size could be getting mistakenly updated.  Please apply
this patch instead.

thanks,
rohit

--- fs/hugetlbfs/inode.c.7      Fri Feb  7 13:47:39 2003
+++ fs/hugetlbfs/inode.c        Fri Feb  7 13:48:17 2003
@@ -66,7 +66,7 @@
        vma->vm_ops = &hugetlb_vm_ops;
        ret = hugetlb_prefault(mapping, vma);
        len = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff <<
PAGE_SHIFT);
-       if (inode->i_size < len)
+       if (!ret && (inode->i_size < len))
                inode->i_size = len;
 
        up(&inode->i_sem);

> -----Original Message-----
> From: Andrew Morton [mailto:akpm@digeo.com] 
> Sent: Sunday, February 02, 2003 2:56 AM
> To: davem@redhat.com; rohit.seth@intel.com; 
> davidm@napali.hpl.hp.com; anton@samba.org; 
> wli@holomorphy.com; linux-mm@kvack.org
> Subject: Re: hugepage patches
> 
> 
> 7/4
> 
> hugetlbfs i_size fixes
> 
> 
> We're expanding hugetlbfs i_size in the wrong place.  If 
> someone attempts to mmap more pages than are available, 
> i_size is updated to reflect the attempted mapping size.
> 
> So set i_size only when pages are successfully added to the mapping.
> 
> i_size handling at truncate time is still a bit wrong - if 
> the mapping has pages at (say) page offset 100-200 and the 
> mappng is truncated to (say_ page offset 50, i_size should be 
> set to zero.  But it is instead set to 50*HPAGE_SIZE.  That's 
> harmless.
> 
> 
>  i386/mm/hugetlbpage.c    |    5 +++++
>  ia64/mm/hugetlbpage.c    |    0 
>  sparc64/mm/hugetlbpage.c |    0 
>  x86_64/mm/hugetlbpage.c  |    6 ++++++
>  hugetlbfs/inode.c        |    5 -----
>  5 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff -puN fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix 
> fs/hugetlbfs/inode.c
> --- 25/fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix	
> 2003-02-01 02:07:22.000000000 -0800
> +++ 25-akpm/fs/hugetlbfs/inode.c	2003-02-01 
> 02:07:22.000000000 -0800
> @@ -45,7 +45,6 @@ static int hugetlbfs_file_mmap(struct fi
>  {
>  	struct inode *inode =file->f_dentry->d_inode;
>  	struct address_space *mapping = inode->i_mapping;
> -	size_t len;
>  	int ret;
>  
>  	if (!capable(CAP_IPC_LOCK))
> @@ -66,10 +65,6 @@ static int hugetlbfs_file_mmap(struct fi
>  	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
>  	vma->vm_ops = &hugetlb_vm_ops;
>  	ret = hugetlb_prefault(mapping, vma);
> -	len = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff << 
> PAGE_SHIFT);
> -	if (inode->i_size < len)
> -		inode->i_size = len;
> -
>  	up(&inode->i_sem);
>  	return ret;
>  }
> diff -puN arch/i386/mm/hugetlbpage.c~hugetlbfs-i_size-fix 
> arch/i386/mm/hugetlbpage.c
> --- 25/arch/i386/mm/hugetlbpage.c~hugetlbfs-i_size-fix	
> 2003-02-01 02:07:22.000000000 -0800
> +++ 25-akpm/arch/i386/mm/hugetlbpage.c	2003-02-01 
> 02:07:22.000000000 -0800
> @@ -284,6 +284,7 @@ void zap_hugepage_range(struct vm_area_s  
> int hugetlb_prefault(struct address_space *mapping, struct 
> vm_area_struct *vma)  {
>  	struct mm_struct *mm = current->mm;
> +	struct inode *inode = mapping->host;
>  	unsigned long addr;
>  	int ret = 0;
>  
> @@ -307,6 +308,7 @@ int hugetlb_prefault(struct address_spac
>  			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
>  		page = find_get_page(mapping, idx);
>  		if (!page) {
> +			loff_t i_size;
>  			page = alloc_hugetlb_page();
>  			if (!page) {
>  				ret = -ENOMEM;
> @@ -318,6 +320,9 @@ int hugetlb_prefault(struct address_spac
>  				free_huge_page(page);
>  				goto out;
>  			}
> +			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
> +			if (i_size > inode->i_size)
> +				inode->i_size = i_size;
>  		}
>  		set_huge_pte(mm, vma, page, pte, vma->vm_flags 
> & VM_WRITE);
>  	}
> diff -puN arch/ia64/mm/hugetlbpage.c~hugetlbfs-i_size-fix 
> arch/ia64/mm/hugetlbpage.c diff -puN 
> arch/sparc64/mm/hugetlbpage.c~hugetlbfs-i_size-fix 
> arch/sparc64/mm/hugetlbpage.c diff -puN 
> arch/x86_64/mm/hugetlbpage.c~hugetlbfs-i_size-fix 
> arch/x86_64/mm/hugetlbpage.c
> --- 25/arch/x86_64/mm/hugetlbpage.c~hugetlbfs-i_size-fix	
> 2003-02-01 02:07:22.000000000 -0800
> +++ 25-akpm/arch/x86_64/mm/hugetlbpage.c	2003-02-01 
> 02:07:22.000000000 -0800
> @@ -205,6 +205,7 @@ void zap_hugepage_range(struct vm_area_s  
> int hugetlb_prefault(struct address_space *mapping, struct 
> vm_area_struct *vma)  {
>  	struct mm_struct *mm = current->mm;
> +	struct inode = mapping->host;
>  	unsigned long addr;
>  	int ret = 0;
>  
> @@ -228,6 +229,8 @@ int hugetlb_prefault(struct address_spac
>  			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
>  		page = find_get_page(mapping, idx);
>  		if (!page) {
> +			loff_t i_size;
> +
>  			page = alloc_hugetlb_page();
>  			if (!page) {
>  				ret = -ENOMEM;
> @@ -239,6 +242,9 @@ int hugetlb_prefault(struct address_spac
>  				free_huge_page(page);
>  				goto out;
>  			}
> +			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
> +			if (i_size > inode->i_size)
> +				inode->i_size = i_size;
>  		}
>  		set_huge_pte(mm, vma, page, pte, vma->vm_flags 
> & VM_WRITE);
>  	}
> 
> _
> 
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/