linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Hugh Dickins <hughd@google.com>
To: Huang Shijie <b32955@freescale.com>
Cc: akpm@linux-foundation.org, linux-mm@kvack.org, b20596@freescale.com
Subject: Re: [PATCH] swap : check the return value of swap_readpage()
Date: Fri, 14 Jan 2011 14:47:26 -0800 (PST)	[thread overview]
Message-ID: <alpine.LSU.2.00.1101141445070.5406@sister.anvils> (raw)
In-Reply-To: <1294997421-8971-1-git-send-email-b32955@freescale.com>

On Fri, 14 Jan 2011, Huang Shijie wrote:
> The read_swap_cache_async() does not check the return value
> of swap_readpage().
> 

Thanks, we may want to fix that.


> If swap_readpage() returns -ENOMEM, the read_swap_cache_async()
> still returns the `new_page` which has nothing. The caller will
> do some wrong operations on the `new_page` such as copy.
> 

But what's really wrong is not to be checking PageUptodate.
Looks like swapoff's try_to_unuse() never checked it (I'm largely
guilty of that), and my ksm_does_need_to_copy() would blindly copy
(from a !PageUptodate to a PageUptodate), averting the PageUptodate
check which comes later in do_swap_page().


> The patch fixs the problem.
> 

It may fix a part of the problem, but - forgive me for saying! -
your patch is not so beautiful that I want to push it as is.

I'm more worried by the cases when the read gets an error and fails:
we ought to be looking at what filemap.c does in it !PageUptodate case,
and following a similar strategy (perhaps we shall want to distinguish
the ENOMEM case, perhaps not: depends on the implementation).

Is this ENOMEM case something you noticed by looking at the source,
or something that has hit you in practice?  If the latter, then it's
more urgent to fix it: but I'd be wondering how it comes about that
bio's mempools have let you down, and even their GFP_KERNEL allocation
is failing?


> Also remove the unlock_ page() in swap_readpage() in the wrong case
> , since __delete_from_swap_cache() needs a locked page.

That change is only required because we're not checking PageUptodate
properly everywhere.

Hugh

> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>  mm/page_io.c    |    1 -
>  mm/swap_state.c |   12 +++++++-----
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/mm/page_io.c b/mm/page_io.c
> index 2dee975..5c759f2 100644
> --- a/mm/page_io.c
> +++ b/mm/page_io.c
> @@ -124,7 +124,6 @@ int swap_readpage(struct page *page)
>  	VM_BUG_ON(PageUptodate(page));
>  	bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read);
>  	if (bio == NULL) {
> -		unlock_page(page);
>  		ret = -ENOMEM;
>  		goto out;
>  	}
> diff --git a/mm/swap_state.c b/mm/swap_state.c
> index 5c8cfab..3bd7238 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -331,16 +331,18 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
>  		__set_page_locked(new_page);
>  		SetPageSwapBacked(new_page);
>  		err = __add_to_swap_cache(new_page, entry);
> +		radix_tree_preload_end();
>  		if (likely(!err)) {
> -			radix_tree_preload_end();
>  			/*
>  			 * Initiate read into locked page and return.
>  			 */
> -			lru_cache_add_anon(new_page);
> -			swap_readpage(new_page);
> -			return new_page;
> +			err = swap_readpage(new_page);
> +			if (likely(!err)) {
> +				lru_cache_add_anon(new_page);
> +				return new_page;
> +			}
> +			__delete_from_swap_cache(new_page);
>  		}
> -		radix_tree_preload_end();
>  		ClearPageSwapBacked(new_page);
>  		__clear_page_locked(new_page);
>  		/*
> -- 
> 1.7.3.2

--
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 policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2011-01-14 22:47 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-14  9:30 Huang Shijie
2011-01-14 22:47 ` Hugh Dickins [this message]
2011-01-16  5:17   ` Huang Shijie

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=alpine.LSU.2.00.1101141445070.5406@sister.anvils \
    --to=hughd@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=b20596@freescale.com \
    --cc=b32955@freescale.com \
    --cc=linux-mm@kvack.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox