All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: Hillf Danton <dhillf@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	linux-mm@kvack.org, mgorman@suse.de,
	kamezawa.hiroyu@jp.fujitsu.com, viro@zeniv.linux.org.uk,
	hughd@google.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] hugetlbfs: Add new rw_semaphore to fix truncate/read race
Date: Wed, 29 Feb 2012 16:34:46 +0530	[thread overview]
Message-ID: <87ty29ew8h.fsf@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAJd=RBA05LqrUohAfO43ywZR_xwi4KygpzZP2zun=taKTLCvnQ@mail.gmail.com>

On Tue, 28 Feb 2012 20:17:28 +0800, Hillf Danton <dhillf@gmail.com> wrote:
> On Tue, Feb 28, 2012 at 6:15 PM, Aneesh Kumar K.V
> <aneesh.kumar@linux.vnet.ibm.com> wrote:
> >
> > Will update the patch with these details
> >
> 
> A scratch is cooked, based on the -next tree, for accelerating your redelivery,
> if you like it, in which i_mutex is eliminated directly and page lock is used.
> 
> -hd


This looks much better than what I had. 

> 
> 
> --- a/fs/hugetlbfs/inode.c	Tue Feb 28 19:43:32 2012
> +++ b/fs/hugetlbfs/inode.c	Tue Feb 28 19:56:50 2012
> @@ -245,17 +245,10 @@ static ssize_t hugetlbfs_read(struct fil
>  	loff_t isize;
>  	ssize_t retval = 0;
> 
> -	mutex_lock(&inode->i_mutex);
> -
>  	/* validate length */
>  	if (len == 0)
>  		goto out;
> 
> -	isize = i_size_read(inode);
> -	if (!isize)
> -		goto out;
> -
> -	end_index = (isize - 1) >> huge_page_shift(h);
>  	for (;;) {
>  		struct page *page;
>  		unsigned long nr, ret;
> @@ -263,6 +256,8 @@ static ssize_t hugetlbfs_read(struct fil
> 
>  		/* nr is the maximum number of bytes to copy from this page */
>  		nr = huge_page_size(h);
> +		isize = i_size_read(inode);
> +		end_index = isize >> huge_page_shift(h);


Should that be (isize - 1) >> huget_page_shift(h) ?


>  		if (index >= end_index) {
>  			if (index > end_index)
>  				goto out;
> @@ -274,7 +269,7 @@ static ssize_t hugetlbfs_read(struct fil
>  		nr = nr - offset;
> 
>  		/* Find the page */
> -		page = find_get_page(mapping, index);
> +		page = find_lock_page(mapping, index);
>  		if (unlikely(page == NULL)) {
>  			/*
>  			 * We have a HOLE, zero out the user-buffer for the
> @@ -286,17 +281,30 @@ static ssize_t hugetlbfs_read(struct fil
>  			else
>  				ra = 0;
>  		} else {
> +			unlock_page(page);
> +
> +			/* Without i_mutex held, check isize again */
> +			nr = huge_page_size(h);
> +			isize = i_size_read(inode);
> +			end_index = isize >> huge_page_shift(h);

same here (isize - 1) ?

> +			if (index == end_index) {
> +				nr = isize & ~huge_page_mask(h);


Is that correct ?  We calculate nr differently in the earlier part of the function

> +				if (nr <= offset) {
> +					page_cache_release(page);
> +					goto out;
> +				}
> +			}
> +			nr -= offset;
>  			/*
>  			 * We have the page, copy it to user space buffer.
>  			 */
>  			ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
>  			ret = ra;
> +			page_cache_release(page);
>  		}
>  		if (ra < 0) {
>  			if (retval == 0)
>  				retval = ra;
> -			if (page)
> -				page_cache_release(page);
>  			goto out;
>  		}
> 
> @@ -306,16 +314,12 @@ static ssize_t hugetlbfs_read(struct fil
>  		index += offset >> huge_page_shift(h);
>  		offset &= ~huge_page_mask(h);
> 
> -		if (page)
> -			page_cache_release(page);
> -
>  		/* short read or no more work */
>  		if ((ret != nr) || (len == 0))
>  			break;
>  	}
>  out:
>  	*ppos = ((loff_t)index << huge_page_shift(h)) + offset;
> -	mutex_unlock(&inode->i_mutex);
>  	return retval;
>  }
> 

I guess we need to closely look at the patch with respect to end-of-file
condition. I will also try to get some testing with the patch.

-aneesh

--
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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: Hillf Danton <dhillf@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	linux-mm@kvack.org, mgorman@suse.de,
	kamezawa.hiroyu@jp.fujitsu.com, viro@zeniv.linux.org.uk,
	hughd@google.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] hugetlbfs: Add new rw_semaphore to fix truncate/read race
Date: Wed, 29 Feb 2012 16:34:46 +0530	[thread overview]
Message-ID: <87ty29ew8h.fsf@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAJd=RBA05LqrUohAfO43ywZR_xwi4KygpzZP2zun=taKTLCvnQ@mail.gmail.com>

On Tue, 28 Feb 2012 20:17:28 +0800, Hillf Danton <dhillf@gmail.com> wrote:
> On Tue, Feb 28, 2012 at 6:15 PM, Aneesh Kumar K.V
> <aneesh.kumar@linux.vnet.ibm.com> wrote:
> >
> > Will update the patch with these details
> >
> 
> A scratch is cooked, based on the -next tree, for accelerating your redelivery,
> if you like it, in which i_mutex is eliminated directly and page lock is used.
> 
> -hd


This looks much better than what I had. 

> 
> 
> --- a/fs/hugetlbfs/inode.c	Tue Feb 28 19:43:32 2012
> +++ b/fs/hugetlbfs/inode.c	Tue Feb 28 19:56:50 2012
> @@ -245,17 +245,10 @@ static ssize_t hugetlbfs_read(struct fil
>  	loff_t isize;
>  	ssize_t retval = 0;
> 
> -	mutex_lock(&inode->i_mutex);
> -
>  	/* validate length */
>  	if (len == 0)
>  		goto out;
> 
> -	isize = i_size_read(inode);
> -	if (!isize)
> -		goto out;
> -
> -	end_index = (isize - 1) >> huge_page_shift(h);
>  	for (;;) {
>  		struct page *page;
>  		unsigned long nr, ret;
> @@ -263,6 +256,8 @@ static ssize_t hugetlbfs_read(struct fil
> 
>  		/* nr is the maximum number of bytes to copy from this page */
>  		nr = huge_page_size(h);
> +		isize = i_size_read(inode);
> +		end_index = isize >> huge_page_shift(h);


Should that be (isize - 1) >> huget_page_shift(h) ?


>  		if (index >= end_index) {
>  			if (index > end_index)
>  				goto out;
> @@ -274,7 +269,7 @@ static ssize_t hugetlbfs_read(struct fil
>  		nr = nr - offset;
> 
>  		/* Find the page */
> -		page = find_get_page(mapping, index);
> +		page = find_lock_page(mapping, index);
>  		if (unlikely(page == NULL)) {
>  			/*
>  			 * We have a HOLE, zero out the user-buffer for the
> @@ -286,17 +281,30 @@ static ssize_t hugetlbfs_read(struct fil
>  			else
>  				ra = 0;
>  		} else {
> +			unlock_page(page);
> +
> +			/* Without i_mutex held, check isize again */
> +			nr = huge_page_size(h);
> +			isize = i_size_read(inode);
> +			end_index = isize >> huge_page_shift(h);

same here (isize - 1) ?

> +			if (index == end_index) {
> +				nr = isize & ~huge_page_mask(h);


Is that correct ?  We calculate nr differently in the earlier part of the function

> +				if (nr <= offset) {
> +					page_cache_release(page);
> +					goto out;
> +				}
> +			}
> +			nr -= offset;
>  			/*
>  			 * We have the page, copy it to user space buffer.
>  			 */
>  			ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
>  			ret = ra;
> +			page_cache_release(page);
>  		}
>  		if (ra < 0) {
>  			if (retval == 0)
>  				retval = ra;
> -			if (page)
> -				page_cache_release(page);
>  			goto out;
>  		}
> 
> @@ -306,16 +314,12 @@ static ssize_t hugetlbfs_read(struct fil
>  		index += offset >> huge_page_shift(h);
>  		offset &= ~huge_page_mask(h);
> 
> -		if (page)
> -			page_cache_release(page);
> -
>  		/* short read or no more work */
>  		if ((ret != nr) || (len == 0))
>  			break;
>  	}
>  out:
>  	*ppos = ((loff_t)index << huge_page_shift(h)) + offset;
> -	mutex_unlock(&inode->i_mutex);
>  	return retval;
>  }
> 

I guess we need to closely look at the patch with respect to end-of-file
condition. I will also try to get some testing with the patch.

-aneesh


  reply	other threads:[~2012-02-29 11:05 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-26 18:19 [PATCH] hugetlbfs: Add new rw_semaphore to fix truncate/read race Aneesh Kumar K.V
2012-02-26 18:19 ` Aneesh Kumar K.V
2012-02-27 23:11 ` Andrew Morton
2012-02-27 23:11   ` Andrew Morton
2012-02-28  0:02   ` Al Viro
2012-02-28  0:02     ` Al Viro
2012-02-28 10:15   ` Aneesh Kumar K.V
2012-02-28 10:15     ` Aneesh Kumar K.V
2012-02-28 12:17     ` Hillf Danton
2012-02-28 12:17       ` Hillf Danton
2012-02-29 11:04       ` Aneesh Kumar K.V [this message]
2012-02-29 11:04         ` Aneesh Kumar K.V
2012-02-29 14:42         ` Hillf Danton
2012-02-29 14:42           ` Hillf Danton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ty29ew8h.fsf@linux.vnet.ibm.com \
    --to=aneesh.kumar@linux.vnet.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=dhillf@gmail.com \
    --cc=hughd@google.com \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.