[Devel] [PATCH rh7 1/4] tswap: do not populate on global reclaim

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jul 16 03:27:32 PDT 2015


Kirill, please review the patchset.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 07/16/2015 12:03 PM, Vladimir Davydov wrote:
> Tswap was introduced for storing swap cache pages that do not fit in
> container RAM limit in order to avoid costly swap out when there is
> enough free memory on the host. Therefore there is no point in moving
> swap cache pages to tswap on global memory shortage. Moreover, it is
> dangerous, because on tswap reclaim we do not actually free pages, but
> move them back to swap cache in the hope that they will be written back
> and freed soon. However, there is a chance that they won't, instead they
> can be moved back to tswap again. As a result of such a page ping-pong,
> the system may become unresponsive.
> 
> This patch therefore makes tswap only adopt swap cache pages on local
> reclaim (PF_MEMALLOC is unset on current). Since after this change it is
> valid to trigger global reclaim from inside tswap_frontswap_store, this
> patch also makes tswap_frontswap_store use GFP_NOIO instead of
> GFP_NOWAIT and issue radix tree preallocation before inserting a page to
> tswap_page_tree.
> 
> https://jira.sw.ru/browse/PSBM-34876
> 
> Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
> ---
>  mm/tswap.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/tswap.c b/mm/tswap.c
> index cdaa98ad2e2d..dc1253f8e5b2 100644
> --- a/mm/tswap.c
> +++ b/mm/tswap.c
> @@ -14,6 +14,8 @@
>  #include <linux/shrinker.h>
>  #include <linux/frontswap.h>
>  
> +#define TSWAP_GFP_MASK		(GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN)
> +
>  static RADIX_TREE(tswap_page_tree, GFP_ATOMIC | __GFP_NOWARN);
>  static DEFINE_SPINLOCK(tswap_lock);
>  
> @@ -67,6 +69,10 @@ static int tswap_insert_page(swp_entry_t entry, struct page *page)
>  {
>  	int err;
>  
> +	err = radix_tree_preload(TSWAP_GFP_MASK);
> +	if (err)
> +		return err;
> +
>  	set_page_private(page, entry.val);
>  	spin_lock(&tswap_lock);
>  	err = radix_tree_insert(&tswap_page_tree, entry.val, page);
> @@ -75,6 +81,8 @@ static int tswap_insert_page(swp_entry_t entry, struct page *page)
>  		tswap_nr_pages++;
>  	}
>  	spin_unlock(&tswap_lock);
> +
> +	radix_tree_preload_end();
>  	return err;
>  }
>  
> @@ -268,8 +276,10 @@ static int tswap_frontswap_store(unsigned type, pgoff_t offset,
>  	if (cache_page)
>  		goto copy;
>  
> -	cache_page = alloc_page(__GFP_HIGHMEM | __GFP_NORETRY |
> -				__GFP_NOMEMALLOC | __GFP_NOWARN);
> +	if (current->flags & PF_MEMALLOC)
> +		return -1;
> +
> +	cache_page = alloc_page(TSWAP_GFP_MASK | __GFP_HIGHMEM);
>  	if (!cache_page)
>  		return -1;
>  
> 



More information about the Devel mailing list